jpeg pushed a commit to branch master. http://git.enlightenment.org/core/efl.git/commit/?id=49f79f0a73af72ce58aff8f583e9b12246e551ab
commit 49f79f0a73af72ce58aff8f583e9b12246e551ab Author: Jean-Philippe Andre <[email protected]> Date: Mon Sep 1 20:22:12 2014 +0900 Evas GL: Skip glClear() with direct rendering & transparent color When using direct rendering, glClear() should not do anything if the ClearColor was (0,0,0,0). The application would indeed expect a transparent output (so, see the widgets below the view), but glClear would erase the pixels instead. So add a quick check to skip glClear entirely in that specific case. --- src/modules/evas/engines/gl_common/evas_gl_api.c | 54 +++++++++++++++++++++- src/modules/evas/engines/gl_common/evas_gl_core.c | 5 ++ .../evas/engines/gl_common/evas_gl_core_private.h | 8 +++- 3 files changed, 63 insertions(+), 4 deletions(-) diff --git a/src/modules/evas/engines/gl_common/evas_gl_api.c b/src/modules/evas/engines/gl_common/evas_gl_api.c index 4133100..2f1ff14 100644 --- a/src/modules/evas/engines/gl_common/evas_gl_api.c +++ b/src/modules/evas/engines/gl_common/evas_gl_api.c @@ -308,6 +308,27 @@ compute_gl_coordinates(int win_w, int win_h, int rot, int clip_image, } static void +_evgl_glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) +{ + EVGL_Resource *rsc; + + if (!(rsc=_evgl_tls_resource_get())) + { + ERR("Unable to execute GL command. Error retrieving tls"); + return; + } + + if (_evgl_direct_enabled()) + { + rsc->clear_color.a = alpha; + rsc->clear_color.r = red; + rsc->clear_color.g = green; + rsc->clear_color.b = blue; + } + glClearColor(red, green, blue, alpha); +} + +static void _evgl_glClear(GLbitfield mask) { EVGL_Resource *rsc; @@ -338,6 +359,29 @@ _evgl_glClear(GLbitfield mask) { if (!(rsc->current_ctx->current_fbo)) { + /* Skip glClear() if clearing with transparent color + * Note: There will be side effects if the object itself is not + * marked as having an alpha channel! + */ + if (ctx->current_sfc->alpha && (mask & GL_COLOR_BUFFER_BIT)) + { + if ((rsc->clear_color.a == 0) && + (rsc->clear_color.r == 0) && + (rsc->clear_color.g == 0) && + (rsc->clear_color.b == 0)) + { + // Skip clear color as we don't want to write black + mask &= ~GL_COLOR_BUFFER_BIT; + } + else if (rsc->clear_color.a != 1.0) + { + // TODO: Draw a rectangle? This will never be the perfect solution though. + WRN("glClear() used with a semi-transparent color and direct rendering. " + "This will erase the previous contents of the evas!"); + } + if (!mask) return; + } + if ((!ctx->direct_scissor)) { glEnable(GL_SCISSOR_TEST); @@ -374,6 +418,8 @@ _evgl_glClear(GLbitfield mask) } glClear(mask); + + // TODO/FIXME: Restore previous client-side scissors. } else { @@ -887,7 +933,7 @@ void _evgld_glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) { EVGL_FUNC_BEGIN(); - glClearColor(red, green, blue, alpha); + _evgl_glClearColor(red, green, blue, alpha); GLERR(__FUNCTION__, __FILE__, __LINE__, ""); EVGL_FUNC_END(); } @@ -2386,7 +2432,7 @@ _normal_gl_api_get(Evas_GL_API *funcs) ORD(glBufferSubData); ORD(glCheckFramebufferStatus); // ORD(glClear); - ORD(glClearColor); +// ORD(glClearColor); // ORD(glClearDepthf); ORD(glClearStencil); ORD(glColorMask); @@ -2525,6 +2571,7 @@ _normal_gl_api_get(Evas_GL_API *funcs) // For Direct Rendering ORD(glClear); + ORD(glClearColor); ORD(glDisable); ORD(glEnable); ORD(glGetIntegerv); @@ -2551,6 +2598,7 @@ _direct_scissor_off_api_get(Evas_GL_API *funcs) #define ORD(f) EVAS_API_OVERRIDE(f, funcs,) // For Direct Rendering ORD(glClear); + ORD(glClearColor); ORD(glDisable); ORD(glEnable); ORD(glGetIntegerv); @@ -2719,6 +2767,8 @@ _debug_gl_api_get(Evas_GL_API *funcs) void _evgl_api_get(Evas_GL_API *funcs, int debug) { + memset(funcs, 0, sizeof(Evas_GL_API)); + if (debug) _debug_gl_api_get(funcs); else diff --git a/src/modules/evas/engines/gl_common/evas_gl_core.c b/src/modules/evas/engines/gl_common/evas_gl_core.c index c84017c..710cbae 100644 --- a/src/modules/evas/engines/gl_common/evas_gl_core.c +++ b/src/modules/evas/engines/gl_common/evas_gl_core.c @@ -1092,10 +1092,15 @@ _internal_config_set(EVGL_Surface *sfc, Evas_GL_Config *cfg) sfc->depth_stencil_fmt = evgl_engine->caps.fbo_fmts[i].depth_stencil_fmt; sfc->msaa_samples = evgl_engine->caps.fbo_fmts[i].samples; + // TODO: Implement surface reconfigure and add depth+stencil support + // Direct Rendering Option if ( (!stencil_bit) || (evgl_engine->direct_override) ) sfc->direct_fb_opt = cfg->options_bits & EVAS_GL_OPTIONS_DIRECT; + // Extra flags for direct rendering + sfc->alpha = (cfg->color_format == EVAS_GL_RGBA_8888); + cfg_index = i; break; } diff --git a/src/modules/evas/engines/gl_common/evas_gl_core_private.h b/src/modules/evas/engines/gl_common/evas_gl_core_private.h index 46063a2..a6214f7 100644 --- a/src/modules/evas/engines/gl_common/evas_gl_core_private.h +++ b/src/modules/evas/engines/gl_common/evas_gl_core_private.h @@ -93,8 +93,9 @@ struct _EVGL_Surface GLuint depth_stencil_buf; GLenum depth_stencil_fmt; - // Direct Rendering Option - int direct_fb_opt; + // Direct Rendering Options + unsigned direct_fb_opt : 1; + unsigned alpha : 1; int cfg_index; @@ -237,6 +238,9 @@ struct _EVGL_Resource Eina_Bool enabled : 1; } direct; + struct { + GLclampf r, g, b, a; + } clear_color; }; --
