diff --git a/src/backend/gl/gl_common.c b/src/backend/gl/gl_common.c index 78101624..02e7bb16 100644 --- a/src/backend/gl/gl_common.c +++ b/src/backend/gl/gl_common.c @@ -16,6 +16,26 @@ #include "backend/gl/gl_common.h" +#define P_PAINTREG_START(var) \ + do { \ + region_t reg_new; \ + int nrects; \ + const rect_t *rects; \ + pixman_region32_init_rect(®_new, dx, dy, width, height); \ + pixman_region32_intersect(®_new, ®_new, (region_t *)reg_tgt); \ + rects = pixman_region32_rectangles(®_new, &nrects); \ + glBegin(GL_QUADS); \ + \ + for (int ri = 0; ri < nrects; ++ri) { \ + rect_t var = rects[ri]; + +#define P_PAINTREG_END() \ + } \ + glEnd(); \ + pixman_region32_fini(®_new); \ + } \ + while (0) + struct gl_data {}; GLuint gl_create_shader(GLenum shader_type, const char *shader_str) { diff --git a/src/backend/gl/gl_common.h b/src/backend/gl/gl_common.h index 6c1e60f4..9aa423f5 100644 --- a/src/backend/gl/gl_common.h +++ b/src/backend/gl/gl_common.h @@ -144,23 +144,3 @@ static inline void gl_free_blur_shader(gl_blur_shader_t *shader) { shader->prog = 0; shader->frag_shader = 0; } - -#define P_PAINTREG_START(var) \ - do { \ - region_t reg_new; \ - int nrects; \ - const rect_t *rects; \ - pixman_region32_init_rect(®_new, dx, dy, width, height); \ - pixman_region32_intersect(®_new, ®_new, (region_t *)reg_tgt); \ - rects = pixman_region32_rectangles(®_new, &nrects); \ - glBegin(GL_QUADS); \ - \ - for (int ri = 0; ri < nrects; ++ri) { \ - rect_t var = rects[ri]; - -#define P_PAINTREG_END() \ - } \ - glEnd(); \ - pixman_region32_fini(®_new); \ - } \ - while (0) diff --git a/src/backend/meson.build b/src/backend/meson.build index 8fa0715c..f1926b94 100644 --- a/src/backend/meson.build +++ b/src/backend/meson.build @@ -6,7 +6,9 @@ if get_option('new_backends') # enable opengl if get_option('opengl') srcs += [ files('gl/gl_common.c', 'gl/glx.c') ] - deps += [ dependency('gl', required: true) ] - cflags += [ '-DGL_GLEXT_PROTOTYPES' ] endif endif + +if get_option('opengl') + srcs += [ files('gl/gl_common.c') ] +endif diff --git a/src/log.c b/src/log.c index 9f801106..e3f50bd0 100644 --- a/src/log.c +++ b/src/log.c @@ -10,7 +10,7 @@ #ifdef CONFIG_OPENGL #include -#include "opengl.h" +#include "backend/gl/gl_common.h" #endif #include "compiler.h" @@ -328,7 +328,7 @@ static const struct log_ops glx_string_marker_logger_ops = { }; struct log_target *glx_string_marker_logger_new(void) { - if (!glx_hasglext("GL_GREMEDY_string_marker")) { + if (!gl_has_extension("GL_GREMEDY_string_marker")) { return NULL; } diff --git a/src/opengl.c b/src/opengl.c index 66654917..1dca3984 100644 --- a/src/opengl.c +++ b/src/opengl.c @@ -24,6 +24,7 @@ #include "utils.h" #include "win.h" #include "region.h" +#include "backend/gl/gl_common.h" #include "opengl.h" @@ -359,7 +360,7 @@ glx_init(session_t *ps, bool need_render) { // Check GL_ARB_texture_non_power_of_two, requires a GLX context and // must precede FBConfig fetching if (need_render) - psglx->has_texture_non_power_of_two = glx_hasglext( + psglx->has_texture_non_power_of_two = gl_has_extension( "GL_ARB_texture_non_power_of_two"); // Acquire function addresses @@ -455,7 +456,7 @@ glx_destroy(session_t *ps) { glx_free_prog_main(ps, &ps->glx_prog_win); - glx_check_err(ps); + gl_check_err(); // Free FBConfigs for (int i = 0; i <= OPENGL_MAX_DEPTH; ++i) { @@ -609,7 +610,7 @@ glx_init_blur(session_t *ps) { sprintf(pc, FRAG_SHADER_BLUR_SUFFIX, texture_func, sum); assert(strlen(shader_str) < len); - ppass->frag_shader = glx_create_shader(GL_FRAGMENT_SHADER, shader_str); + ppass->frag_shader = gl_create_shader(GL_FRAGMENT_SHADER, shader_str); free(shader_str); } @@ -619,7 +620,7 @@ glx_init_blur(session_t *ps) { } // Build program - ppass->prog = glx_create_program(&ppass->frag_shader, 1); + ppass->prog = gl_create_program(&ppass->frag_shader, 1); if (!ppass->prog) { log_error("Failed to create GLSL program."); return false; @@ -649,7 +650,7 @@ glx_init_blur(session_t *ps) { } - glx_check_err(ps); + gl_check_err(); return true; } @@ -664,7 +665,7 @@ glx_load_prog_main(session_t *ps, assert(pprogram); // Build program - pprogram->prog = glx_create_program_from_str(vshader_str, fshader_str); + pprogram->prog = gl_create_program_from_str(vshader_str, fshader_str); if (!pprogram->prog) { log_error("Failed to create GLSL program."); return false; @@ -682,7 +683,7 @@ glx_load_prog_main(session_t *ps, P_GET_UNIFM_LOC("tex", unifm_tex); #undef P_GET_UNIFM_LOC - glx_check_err(ps); + gl_check_err(); return true; } @@ -831,7 +832,7 @@ glx_bind_pixmap(session_t *ps, glx_texture_t **pptex, xcb_pixmap_t pixmap, glBindTexture(ptex->target, 0); glDisable(ptex->target); - glx_check_err(ps); + gl_check_err(); return true; } @@ -854,7 +855,7 @@ glx_release_pixmap(session_t *ps, glx_texture_t *ptex) { ptex->glpixmap = 0; } - glx_check_err(ps); + gl_check_err(); } /** @@ -881,7 +882,7 @@ glx_set_clip(session_t *ps, const region_t *reg) { rects[0].x2-rects[0].x1, rects[0].y2-rects[0].y1); } - glx_check_err(ps); + gl_check_err(); } #define P_PAINTREG_START(var) \ @@ -1134,7 +1135,7 @@ glx_blur_dst_end: free_glx_bc(ps, pbc); } - glx_check_err(ps); + gl_check_err(); return ret; } @@ -1169,7 +1170,7 @@ glx_dim_dst(session_t *ps, int dx, int dy, int width, int height, float z, glColor4f(0.0f, 0.0f, 0.0f, 0.0f); glDisable(GL_BLEND); - glx_check_err(ps); + gl_check_err(); return true; } @@ -1379,149 +1380,7 @@ glx_render(session_t *ps, const glx_texture_t *ptex, if (has_prog) glUseProgram(0); - glx_check_err(ps); + gl_check_err(); return true; } - -/** - * @brief Get tightly packed RGB888 data from GL front buffer. - * - * Don't expect any sort of decent performance. - * - * @returns tightly packed RGB888 data of the size of the screen, - * to be freed with `free()` - */ -unsigned char * -glx_take_screenshot(session_t *ps, int *out_length) { - int length = 3 * ps->root_width * ps->root_height; - GLint unpack_align_old = 0; - glGetIntegerv(GL_UNPACK_ALIGNMENT, &unpack_align_old); - assert(unpack_align_old > 0); - glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - auto buf = ccalloc(length, unsigned char); - glReadBuffer(GL_FRONT); - glReadPixels(0, 0, ps->root_width, ps->root_height, GL_RGB, - GL_UNSIGNED_BYTE, buf); - glReadBuffer(GL_BACK); - glPixelStorei(GL_UNPACK_ALIGNMENT, unpack_align_old); - if (out_length) - *out_length = sizeof(unsigned char) * length; - return buf; -} - -GLuint -glx_create_shader(GLenum shader_type, const char *shader_str) { - log_trace("glx_create_shader(): ===\n%s\n===", shader_str); - - bool success = false; - GLuint shader = glCreateShader(shader_type); - if (!shader) { - log_error("Failed to create shader with type %#x.", shader_type); - goto glx_create_shader_end; - } - glShaderSource(shader, 1, &shader_str, NULL); - glCompileShader(shader); - - // Get shader status - { - GLint status = GL_FALSE; - glGetShaderiv(shader, GL_COMPILE_STATUS, &status); - if (GL_FALSE == status) { - GLint log_len = 0; - glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &log_len); - if (log_len) { - char log[log_len + 1]; - glGetShaderInfoLog(shader, log_len, NULL, log); - log_error("Failed to compile shader with type %d: %s", shader_type, log); - } - goto glx_create_shader_end; - } - } - - success = true; - -glx_create_shader_end: - if (shader && !success) { - glDeleteShader(shader); - shader = 0; - } - - return shader; -} - -GLuint -glx_create_program(const GLuint * const shaders, int nshaders) { - bool success = false; - GLuint program = glCreateProgram(); - if (!program) { - log_error("Failed to create program."); - goto glx_create_program_end; - } - - for (int i = 0; i < nshaders; ++i) - glAttachShader(program, shaders[i]); - glLinkProgram(program); - - // Get program status - { - GLint status = GL_FALSE; - glGetProgramiv(program, GL_LINK_STATUS, &status); - if (GL_FALSE == status) { - GLint log_len = 0; - glGetProgramiv(program, GL_INFO_LOG_LENGTH, &log_len); - if (log_len) { - char log[log_len + 1]; - glGetProgramInfoLog(program, log_len, NULL, log); - log_error("Failed to link program: %s", log); - } - goto glx_create_program_end; - } - } - success = true; - -glx_create_program_end: - if (program) { - for (int i = 0; i < nshaders; ++i) - glDetachShader(program, shaders[i]); - } - if (program && !success) { - glDeleteProgram(program); - program = 0; - } - - return program; -} - -/** - * @brief Create a program from vertex and fragment shader strings. - */ -GLuint -glx_create_program_from_str(const char *vert_shader_str, - const char *frag_shader_str) { - GLuint vert_shader = 0; - GLuint frag_shader = 0; - GLuint prog = 0; - - if (vert_shader_str) - vert_shader = glx_create_shader(GL_VERTEX_SHADER, vert_shader_str); - if (frag_shader_str) - frag_shader = glx_create_shader(GL_FRAGMENT_SHADER, frag_shader_str); - - GLuint shaders[2]; - unsigned int count = 0; - if (vert_shader) - shaders[count++] = vert_shader; - if (frag_shader) - shaders[count++] = frag_shader; - assert(count <= sizeof(shaders) / sizeof(shaders[0])); - if (count) - prog = glx_create_program(shaders, count); - - if (vert_shader) - glDeleteShader(vert_shader); - if (frag_shader) - glDeleteShader(frag_shader); - - return prog; -} diff --git a/src/opengl.h b/src/opengl.h index 47af38e5..adc9d413 100644 --- a/src/opengl.h +++ b/src/opengl.h @@ -33,56 +33,6 @@ typedef struct glx_fbconfig { bool y_inverted; } glx_fbconfig_t; -#ifdef DEBUG_GLX_ERR - -/** - * Get a textual representation of an OpenGL error. - */ -static inline const char * -glx_dump_err_str(GLenum err) { - switch (err) { - CASESTRRET(GL_NO_ERROR); - CASESTRRET(GL_INVALID_ENUM); - CASESTRRET(GL_INVALID_VALUE); - CASESTRRET(GL_INVALID_OPERATION); - CASESTRRET(GL_INVALID_FRAMEBUFFER_OPERATION); - CASESTRRET(GL_OUT_OF_MEMORY); - CASESTRRET(GL_STACK_UNDERFLOW); - CASESTRRET(GL_STACK_OVERFLOW); - } - - return NULL; -} - -/** - * Check for GLX error. - * - * http://blog.nobel-joergensen.com/2013/01/29/debugging-opengl-using-glgeterror/ - */ -static inline void -glx_check_err_(session_t *ps, const char *func, int line) { - if (!ps->psglx->context) return; - - GLenum err = GL_NO_ERROR; - - while (GL_NO_ERROR != (err = glGetError())) { - const char *errtext = glx_dump_err_str(err); - if (errtext) { - log_printf(tls_logger, LOG_LEVEL_ERROR, func, "GLX error at line %d: %s", line, - errtext); - } - else { - log_printf(tls_logger, LOG_LEVEL_ERROR, func, "GLX error at line %d: %d", line, - err); - } - } -} - -#define glx_check_err(ps) glx_check_err_(ps, __func__, __LINE__) -#else -#define glx_check_err(ps) ((void) 0) -#endif - /** * Check if a word is in string. */ @@ -123,24 +73,6 @@ glx_hasglxext(session_t *ps, const char *ext) { return found; } -/** - * Check if a GLX extension exists. - */ -static inline bool -glx_hasglext(const char *ext) { - const char *gl_exts = (const char *) glGetString(GL_EXTENSIONS); - if (!gl_exts) { - log_error("Failed get GL extension list."); - return false; - } - - bool found = wd_is_in_str(gl_exts, ext); - if (!found) - log_info("Missing GL extension %s.", ext); - - return found; -} - bool glx_dim_dst(session_t *ps, int dx, int dy, int width, int height, float z, GLfloat factor, const region_t *reg_tgt);