jpeg pushed a commit to branch master. http://git.enlightenment.org/core/efl.git/commit/?id=e4a11c008c124f246ba410f6398e22559ba6ab00
commit e4a11c008c124f246ba410f6398e22559ba6ab00 Author: Jean-Philippe Andre <[email protected]> Date: Tue Dec 9 18:35:35 2014 +0900 Evas GL: Fix scissors with direct rendering If an app calls glDisable(SCISSORS) and uses direct rendering, then the DR scissors were dropped and so glClear would erase the contents of the entire canvas, instead of being restricted to the image object. --- src/modules/evas/engines/gl_common/evas_gl_api.c | 111 +++++++++++++++++++-- .../evas/engines/gl_common/evas_gl_core_private.h | 10 +- 2 files changed, 108 insertions(+), 13 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 ed8f501..2e3f980 100644 --- a/src/modules/evas/engines/gl_common/evas_gl_api.c +++ b/src/modules/evas/engines/gl_common/evas_gl_api.c @@ -451,8 +451,66 @@ _evgl_glEnable(GLenum cap) ctx = evas_gl_common_current_context_get(); - if (cap == GL_SCISSOR_TEST) - if (ctx) ctx->scissor_enabled = 1; + if (ctx && (cap == GL_SCISSOR_TEST)) + { + ctx->scissor_enabled = 1; + + if (_evgl_direct_enabled()) + { + EVGL_Resource *rsc = _evgl_tls_resource_get(); + int oc[4] = {0,0,0,0}, nc[4] = {0,0,0,0}, cc[4] = {0,0,0,0}; + + if (!ctx->current_fbo) + { + // Direct rendering to canvas + if (!ctx->scissor_updated) + { + compute_gl_coordinates(rsc->direct.win_w, rsc->direct.win_h, + rsc->direct.rot, 0, + 0, 0, 0, 0, + rsc->direct.img.x, rsc->direct.img.y, + rsc->direct.img.w, rsc->direct.img.h, + rsc->direct.clip.x, rsc->direct.clip.y, + rsc->direct.clip.w, rsc->direct.clip.h, + oc, nc, cc); + glScissor(cc[0], cc[1], cc[2], cc[3]); + } + else + { + compute_gl_coordinates(rsc->direct.win_w, rsc->direct.win_h, + rsc->direct.rot, 1, + ctx->scissor_coord[0], ctx->scissor_coord[1], + ctx->scissor_coord[2], ctx->scissor_coord[3], + rsc->direct.img.x, rsc->direct.img.y, + rsc->direct.img.w, rsc->direct.img.h, + rsc->direct.clip.x, rsc->direct.clip.y, + rsc->direct.clip.w, rsc->direct.clip.h, + oc, nc, cc); + glScissor(nc[0], nc[1], nc[2], nc[3]); + } + ctx->direct_scissor = 1; + } + else + { + // Bound to an FBO, reset scissors to user data + if (ctx->scissor_updated) + { + glScissor(ctx->scissor_coord[0], ctx->scissor_coord[1], + ctx->scissor_coord[2], ctx->scissor_coord[3]); + } + else if (ctx->direct_scissor) + { + // Back to the default scissors (here: max texture size) + glScissor(0, 0, evgl_engine->caps.max_w, evgl_engine->caps.max_h); + } + ctx->direct_scissor = 0; + } + + glEnable(GL_SCISSOR_TEST); + return; + } + } + glEnable(cap); } @@ -463,8 +521,43 @@ _evgl_glDisable(GLenum cap) ctx = evas_gl_common_current_context_get(); - if (cap == GL_SCISSOR_TEST) - if (ctx) ctx->scissor_enabled = 0; + if (ctx && (cap == GL_SCISSOR_TEST)) + { + ctx->scissor_enabled = 0; + + if (_evgl_direct_enabled()) + { + if (!ctx->current_fbo) + { + // Restore default scissors for direct rendering + int oc[4] = {0,0,0,0}, nc[4] = {0,0,0,0}, cc[4] = {0,0,0,0}; + EVGL_Resource *rsc = _evgl_tls_resource_get(); + + compute_gl_coordinates(rsc->direct.win_w, rsc->direct.win_h, + rsc->direct.rot, 1, + 0, 0, rsc->direct.img.w, rsc->direct.img.h, + rsc->direct.img.x, rsc->direct.img.y, + rsc->direct.img.w, rsc->direct.img.h, + rsc->direct.clip.x, rsc->direct.clip.y, + rsc->direct.clip.w, rsc->direct.clip.h, + oc, nc, cc); + + RECTS_CLIP_TO_RECT(nc[0], nc[1], nc[2], nc[3], cc[0], cc[1], cc[2], cc[3]); + glScissor(nc[0], nc[1], nc[2], nc[3]); + + ctx->direct_scissor = 1; + glEnable(GL_SCISSOR_TEST); + } + else + { + // Bound to an FBO, disable scissors for real + ctx->direct_scissor = 0; + glDisable(GL_SCISSOR_TEST); + } + return; + } + } + glDisable(cap); } @@ -506,8 +599,7 @@ _evgl_glGetIntegerv(GLenum pname, GLint* params) return; } } - - if (pname == GL_VIEWPORT) + else if (pname == GL_VIEWPORT) { if (ctx->viewport_updated) { @@ -722,6 +814,7 @@ _evgl_glScissor(GLint x, GLint y, GLsizei width, GLsizei height) { if (!(rsc->current_ctx->current_fbo)) { + // Direct rendering to canvas if ((ctx->direct_scissor) && (!ctx->scissor_enabled)) { glDisable(GL_SCISSOR_TEST); @@ -747,11 +840,12 @@ _evgl_glScissor(GLint x, GLint y, GLsizei width, GLsizei height) ctx->direct_scissor = 0; - // Check....!!!! + // Mark user scissor_coord as valid ctx->scissor_updated = 1; } else { + // Bound to an FBO, use these new scissors if ((ctx->direct_scissor) && (!ctx->scissor_enabled)) { glDisable(GL_SCISSOR_TEST); @@ -760,7 +854,8 @@ _evgl_glScissor(GLint x, GLint y, GLsizei width, GLsizei height) glScissor(x, y, width, height); - ctx->scissor_updated = 0; + // Why did we set this flag to 0??? + //ctx->scissor_updated = 0; } } else 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 4da0aa4..ec30529 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 @@ -157,12 +157,12 @@ struct _EVGL_Context GLuint current_fbo; // Direct Rendering Related - int scissor_enabled; - int scissor_updated; - int scissor_coord[4]; - int direct_scissor; + int scissor_enabled : 1; + int scissor_updated : 1; + int direct_scissor : 1; + int viewport_updated : 1; - int viewport_updated; + int scissor_coord[4]; int viewport_coord[4]; // Partial Rendering --
