4d85f4796989055ae652b51cdb54d3bdfd7b3a30
[iec.git] / src / type3_AndroidCloud / anbox-master / src / anbox / graphics / program_family.cpp
1 /*
2  * Copyright © 2015 Canonical Ltd.
3  *
4  * This program is free software: you can redistribute it and/or modify it
5  * under the terms of the GNU General Public License version 3,
6  * as published by the Free Software Foundation.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
15  *
16  * Authored by: Daniel van Vugt <daniel.van.vugt@canonical.com>
17  */
18
19 #include "anbox/graphics/program_family.h"
20
21 #include "anbox/graphics/emugl/DispatchTables.h"
22
23 #include <string>
24 #include <stdexcept>
25
26 namespace anbox {
27 namespace graphics {
28 void ProgramFamily::Shader::init(GLenum type, const GLchar* src) {
29   if (!id) {
30     id = s_gles2.glCreateShader(type);
31     if (id) {
32       s_gles2.glShaderSource(id, 1, &src, NULL);
33       s_gles2.glCompileShader(id);
34       GLint ok;
35       s_gles2.glGetShaderiv(id, GL_COMPILE_STATUS, &ok);
36       if (!ok) {
37         GLchar log[1024];
38         s_gles2.glGetShaderInfoLog(id, sizeof log - 1, NULL, log);
39         log[sizeof log - 1] = '\0';
40         s_gles2.glDeleteShader(id);
41         id = 0;
42         throw std::runtime_error(std::string("Compile failed: ") + log +
43                                  " for:\n" + src);
44       }
45     }
46   }
47 }
48
49 ProgramFamily::~ProgramFamily() noexcept {
50   // shader and program lifetimes are managed manually, so that we don't
51   // need any reference counting or to worry about how many copy constructions
52   // might have been followed by destructor calls during container resizes.
53
54   for (auto& p : program) {
55     if (p.second.id) s_gles2.glDeleteProgram(p.second.id);
56   }
57
58   for (auto& v : vshader) {
59     if (v.second.id) s_gles2.glDeleteShader(v.second.id);
60   }
61
62   for (auto& f : fshader) {
63     if (f.second.id) s_gles2.glDeleteShader(f.second.id);
64   }
65 }
66
67 GLuint ProgramFamily::add_program(const GLchar* const vshader_src,
68                                   const GLchar* const fshader_src) {
69   auto& v = vshader[vshader_src];
70   if (!v.id) v.init(GL_VERTEX_SHADER, vshader_src);
71
72   auto& f = fshader[fshader_src];
73   if (!f.id) f.init(GL_FRAGMENT_SHADER, fshader_src);
74
75   auto& p = program[{v.id, f.id}];
76   if (!p.id) {
77     p.id = s_gles2.glCreateProgram();
78     s_gles2.glAttachShader(p.id, v.id);
79     s_gles2.glAttachShader(p.id, f.id);
80     s_gles2.glLinkProgram(p.id);
81     GLint ok;
82     s_gles2.glGetProgramiv(p.id, GL_LINK_STATUS, &ok);
83     if (!ok) {
84       GLchar log[1024];
85       s_gles2.glGetProgramInfoLog(p.id, sizeof log - 1, NULL, log);
86       log[sizeof log - 1] = '\0';
87       s_gles2.glDeleteShader(p.id);
88       p.id = 0;
89       throw std::runtime_error(std::string("Link failed: ") + log);
90     }
91   }
92
93   return p.id;
94 }
95 }  // namespace graphics
96 }  // namespace anbox