forked from enlightenment/efl
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.
This commit is contained in:
parent
cb5e88d20f
commit
49f79f0a73
|
@ -307,6 +307,27 @@ compute_gl_coordinates(int win_w, int win_h, int rot, int clip_image,
|
|||
//DBG( "\e[1;32m Img[%d %d %d %d] Original [%d %d %d %d] Transformed[%d %d %d %d] Clip[%d %d %d %d] Clipped[%d %d %d %d] \e[m", img_x, img_y, img_w, img_h, imgc[0], imgc[1], imgc[2], imgc[3], objc[0], objc[1], objc[2], objc[3], clip[0], clip[1], clip[2], clip[3], cc[0], cc[1], cc[2], cc[3]);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue