diff --git a/release/files_common b/release/files_common index f15b8472f5..6dd9dcefbb 100644 --- a/release/files_common +++ b/release/files_common @@ -186,7 +186,8 @@ selfdrive/common/version.h selfdrive/common/framebuffer.h selfdrive/common/framebuffer.cc -selfdrive/common/glutil.[c,h] +selfdrive/common/glutil.cc +selfdrive/common/glutil.h selfdrive/common/touch.[c,h] selfdrive/common/swaglog.h selfdrive/common/swaglog.cc diff --git a/selfdrive/common/SConscript b/selfdrive/common/SConscript index d980d98ba8..567706f60a 100644 --- a/selfdrive/common/SConscript +++ b/selfdrive/common/SConscript @@ -11,7 +11,7 @@ _common = fxn('common', common_libs, LIBS="json11") files = [ 'clutil.cc', - 'glutil.c', + 'glutil.cc', 'visionimg.cc', ] diff --git a/selfdrive/common/glutil.c b/selfdrive/common/glutil.c deleted file mode 100644 index e208891e2b..0000000000 --- a/selfdrive/common/glutil.c +++ /dev/null @@ -1,69 +0,0 @@ -#include -#include - -#include "glutil.h" - -GLuint load_shader(GLenum shaderType, const char *src) { - GLint status = 0, len = 0; - GLuint shader; - - if (!(shader = glCreateShader(shaderType))) - return 0; - - glShaderSource(shader, 1, &src, NULL); - glCompileShader(shader); - glGetShaderiv(shader, GL_COMPILE_STATUS, &status); - - if (status) - return shader; - - glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &len); - if (len) { - char *msg = (char*)malloc(len); - if (msg) { - glGetShaderInfoLog(shader, len, NULL, msg); - msg[len-1] = 0; - fprintf(stderr, "error compiling shader:\n%s\n", msg); - free(msg); - } - } - glDeleteShader(shader); - return 0; -} - -GLuint load_program(const char *vert_src, const char *frag_src) { - GLuint vert, frag, prog; - GLint status = 0, len = 0; - - if (!(vert = load_shader(GL_VERTEX_SHADER, vert_src))) - return 0; - if (!(frag = load_shader(GL_FRAGMENT_SHADER, frag_src))) - goto fail_frag; - if (!(prog = glCreateProgram())) - goto fail_prog; - - glAttachShader(prog, vert); - glAttachShader(prog, frag); - glLinkProgram(prog); - - glGetProgramiv(prog, GL_LINK_STATUS, &status); - if (status) - return prog; - - glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &len); - if (len) { - char *buf = (char*) malloc(len); - if (buf) { - glGetProgramInfoLog(prog, len, NULL, buf); - buf[len-1] = 0; - fprintf(stderr, "error linking program:\n%s\n", buf); - free(buf); - } - } - glDeleteProgram(prog); -fail_prog: - glDeleteShader(frag); -fail_frag: - glDeleteShader(vert); - return 0; -} diff --git a/selfdrive/common/glutil.cc b/selfdrive/common/glutil.cc new file mode 100644 index 0000000000..77cb826272 --- /dev/null +++ b/selfdrive/common/glutil.cc @@ -0,0 +1,63 @@ +#include +#include +#include +#include + +#include "glutil.h" + +static GLuint load_shader(GLenum shaderType, const char *src) { + GLint status = 0, len = 0; + GLuint shader = glCreateShader(shaderType); + assert(shader != 0); + + glShaderSource(shader, 1, &src, NULL); + glCompileShader(shader); + glGetShaderiv(shader, GL_COMPILE_STATUS, &status); + if (!status) { + glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &len); + if (len) { + std::string msg(len, '\0'); + glGetShaderInfoLog(shader, len, NULL, msg.data()); + fprintf(stderr, "error compiling shader:\n%s\n", msg.c_str()); + } + assert(0); + } + return shader; +} + +GLShader::GLShader(const char *vert_src, const char *frag_src) { + GLint status = 0, len = 0; + prog = glCreateProgram(); + assert(prog != 0); + + vert = load_shader(GL_VERTEX_SHADER, vert_src); + frag = load_shader(GL_FRAGMENT_SHADER, frag_src); + glAttachShader(prog, vert); + glAttachShader(prog, frag); + glLinkProgram(prog); + + glGetProgramiv(prog, GL_LINK_STATUS, &status); + if (!status) { + glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &len); + if (len) { + std::string msg(len, '\0'); + glGetProgramInfoLog(prog, len, NULL, msg.data()); + fprintf(stderr, "error linking program:\n%s\n", msg.c_str()); + } + assert(0); + } +} + +GLShader::~GLShader() { + glDeleteProgram(prog); + glDeleteShader(frag); + glDeleteShader(vert); +} + +GLuint GLShader::getUniformLocation(const char *name) { + auto it = uniform_loc_map.find(name); + if (it == uniform_loc_map.end()) { + it = uniform_loc_map.insert(it, {name, glGetUniformLocation(prog, name)}); + } + return it->second; +} diff --git a/selfdrive/common/glutil.h b/selfdrive/common/glutil.h index d907b09e78..dff87821fb 100644 --- a/selfdrive/common/glutil.h +++ b/selfdrive/common/glutil.h @@ -1,21 +1,20 @@ -#ifndef COMMON_GLUTIL_H -#define COMMON_GLUTIL_H +#pragma once #ifdef __APPLE__ #include #else #include #endif +#include -#ifdef __cplusplus -extern "C" { -#endif - -GLuint load_shader(GLenum shaderType, const char *src); -GLuint load_program(const char *vert_src, const char *frag_src); +class GLShader { +public: + GLShader(const char *vert_src, const char *frag_src); + ~GLShader(); + GLuint getUniformLocation(const char * name); + GLuint prog = 0; -#ifdef __cplusplus -} -#endif - -#endif +private: + GLuint vert = 0, frag = 0; + std::map uniform_loc_map; +}; diff --git a/selfdrive/ui/paint.cc b/selfdrive/ui/paint.cc index ab92bd064f..5b714069a8 100644 --- a/selfdrive/ui/paint.cc +++ b/selfdrive/ui/paint.cc @@ -11,11 +11,6 @@ #define NANOVG_GLES3_IMPLEMENTATION #include "nanovg_gl.h" #include "nanovg_gl_utils.h" - -extern "C"{ -#include "common/glutil.h" -} - #include "paint.hpp" #include "sidebar.hpp" @@ -166,9 +161,9 @@ static void draw_frame(UIState *s) { #endif } - glUseProgram(s->frame_program); - glUniform1i(s->frame_texture_loc, 0); - glUniformMatrix4fv(s->frame_transform_loc, 1, GL_TRUE, out_mat->v); + glUseProgram(s->gl_shader->prog); + glUniform1i(s->gl_shader->getUniformLocation("uTexture"), 0); + glUniformMatrix4fv(s->gl_shader->getUniformLocation("uTransform"), 1, GL_TRUE, out_mat->v); assert(glGetError() == GL_NO_ERROR); glEnableVertexAttribArray(0); @@ -575,14 +570,9 @@ void ui_nvg_init(UIState *s) { } // init gl - s->frame_program = load_program(frame_vertex_shader, frame_fragment_shader); - assert(s->frame_program); - - s->frame_pos_loc = glGetAttribLocation(s->frame_program, "aPosition"); - s->frame_texcoord_loc = glGetAttribLocation(s->frame_program, "aTexCoord"); - - s->frame_texture_loc = glGetUniformLocation(s->frame_program, "uTexture"); - s->frame_transform_loc = glGetUniformLocation(s->frame_program, "uTransform"); + s->gl_shader = std::make_unique(frame_vertex_shader, frame_fragment_shader); + GLint frame_pos_loc = glGetAttribLocation(s->gl_shader->prog, "aPosition"); + GLint frame_texcoord_loc = glGetAttribLocation(s->gl_shader->prog, "aTexCoord"); glViewport(0, 0, s->fb_w, s->fb_h); @@ -617,11 +607,11 @@ void ui_nvg_init(UIState *s) { glGenBuffers(1, &s->frame_vbo[i]); glBindBuffer(GL_ARRAY_BUFFER, s->frame_vbo[i]); glBufferData(GL_ARRAY_BUFFER, sizeof(frame_coords), frame_coords, GL_STATIC_DRAW); - glEnableVertexAttribArray(s->frame_pos_loc); - glVertexAttribPointer(s->frame_pos_loc, 2, GL_FLOAT, GL_FALSE, + glEnableVertexAttribArray(frame_pos_loc); + glVertexAttribPointer(frame_pos_loc, 2, GL_FLOAT, GL_FALSE, sizeof(frame_coords[0]), (const void *)0); - glEnableVertexAttribArray(s->frame_texcoord_loc); - glVertexAttribPointer(s->frame_texcoord_loc, 2, GL_FLOAT, GL_FALSE, + glEnableVertexAttribArray(frame_texcoord_loc); + glVertexAttribPointer(frame_texcoord_loc, 2, GL_FLOAT, GL_FALSE, sizeof(frame_coords[0]), (const void *)(sizeof(float) * 2)); glGenBuffers(1, &s->frame_ibo[i]); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, s->frame_ibo[i]); diff --git a/selfdrive/ui/ui.hpp b/selfdrive/ui/ui.hpp index fc9ae251e8..23045d46ed 100644 --- a/selfdrive/ui/ui.hpp +++ b/selfdrive/ui/ui.hpp @@ -24,6 +24,7 @@ #include "common/framebuffer.h" #include "common/modeldata.h" #include "common/params.h" +#include "common/glutil.h" #include "sound.hpp" #include "visionipc.h" #include "visionipc_client.h" @@ -171,11 +172,9 @@ typedef struct UIState { cereal::UiLayoutState::App active_app; // graphics - GLuint frame_program; + std::unique_ptr gl_shader; std::unique_ptr texture[UI_BUF_COUNT]; - GLint frame_pos_loc, frame_texcoord_loc; - GLint frame_texture_loc, frame_transform_loc; GLuint frame_vao[2], frame_vbo[2], frame_ibo[2]; mat4 rear_frame_mat, front_frame_mat;