X-Git-Url: https://gerrit.akraino.org/r/gitweb?a=blobdiff_plain;f=src%2Ftype3_AndroidCloud%2Fanbox-master%2Fsrc%2Fanbox%2Fgraphics%2Fprogram_family.cpp;fp=src%2Ftype3_AndroidCloud%2Fanbox-master%2Fsrc%2Fanbox%2Fgraphics%2Fprogram_family.cpp;h=4d85f4796989055ae652b51cdb54d3bdfd7b3a30;hb=e26c1ec581be598521517829adba8c8dd23a768f;hp=0000000000000000000000000000000000000000;hpb=6699c1aea74eeb0eb400e6299079f0c7576f716f;p=iec.git diff --git a/src/type3_AndroidCloud/anbox-master/src/anbox/graphics/program_family.cpp b/src/type3_AndroidCloud/anbox-master/src/anbox/graphics/program_family.cpp new file mode 100644 index 0000000..4d85f47 --- /dev/null +++ b/src/type3_AndroidCloud/anbox-master/src/anbox/graphics/program_family.cpp @@ -0,0 +1,96 @@ +/* + * Copyright © 2015 Canonical Ltd. + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 3, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * Authored by: Daniel van Vugt + */ + +#include "anbox/graphics/program_family.h" + +#include "anbox/graphics/emugl/DispatchTables.h" + +#include +#include + +namespace anbox { +namespace graphics { +void ProgramFamily::Shader::init(GLenum type, const GLchar* src) { + if (!id) { + id = s_gles2.glCreateShader(type); + if (id) { + s_gles2.glShaderSource(id, 1, &src, NULL); + s_gles2.glCompileShader(id); + GLint ok; + s_gles2.glGetShaderiv(id, GL_COMPILE_STATUS, &ok); + if (!ok) { + GLchar log[1024]; + s_gles2.glGetShaderInfoLog(id, sizeof log - 1, NULL, log); + log[sizeof log - 1] = '\0'; + s_gles2.glDeleteShader(id); + id = 0; + throw std::runtime_error(std::string("Compile failed: ") + log + + " for:\n" + src); + } + } + } +} + +ProgramFamily::~ProgramFamily() noexcept { + // shader and program lifetimes are managed manually, so that we don't + // need any reference counting or to worry about how many copy constructions + // might have been followed by destructor calls during container resizes. + + for (auto& p : program) { + if (p.second.id) s_gles2.glDeleteProgram(p.second.id); + } + + for (auto& v : vshader) { + if (v.second.id) s_gles2.glDeleteShader(v.second.id); + } + + for (auto& f : fshader) { + if (f.second.id) s_gles2.glDeleteShader(f.second.id); + } +} + +GLuint ProgramFamily::add_program(const GLchar* const vshader_src, + const GLchar* const fshader_src) { + auto& v = vshader[vshader_src]; + if (!v.id) v.init(GL_VERTEX_SHADER, vshader_src); + + auto& f = fshader[fshader_src]; + if (!f.id) f.init(GL_FRAGMENT_SHADER, fshader_src); + + auto& p = program[{v.id, f.id}]; + if (!p.id) { + p.id = s_gles2.glCreateProgram(); + s_gles2.glAttachShader(p.id, v.id); + s_gles2.glAttachShader(p.id, f.id); + s_gles2.glLinkProgram(p.id); + GLint ok; + s_gles2.glGetProgramiv(p.id, GL_LINK_STATUS, &ok); + if (!ok) { + GLchar log[1024]; + s_gles2.glGetProgramInfoLog(p.id, sizeof log - 1, NULL, log); + log[sizeof log - 1] = '\0'; + s_gles2.glDeleteShader(p.id); + p.id = 0; + throw std::runtime_error(std::string("Link failed: ") + log); + } + } + + return p.id; +} +} // namespace graphics +} // namespace anbox