From 46488e9d2dfc5f7679f26762efa345627978fcee Mon Sep 17 00:00:00 2001 From: Joogab Yun Date: Thu, 22 Dec 2016 15:30:41 +0900 Subject: [PATCH] 1. Evas GL: Direct rendering render to map fix if target buffer is not window surface then do FBO rendering 2. Evas GL: Disable direct rendering if there is a map The engine itself (gl_generic) will detect whether the target surface (canvas where to draw the gl stuff) is the window backbuffer or not. Direct rendering should also be disabled even if direct override flag is set. Change-Id: Iae31395f3247c9c9fa8a4359594585af95829777 --- src/modules/evas/engines/gl_common/evas_gl_api.c | 114 +++++++++++---------- .../evas/engines/gl_common/evas_gl_api_ext.c | 7 +- .../evas/engines/gl_common/evas_gl_api_gles1.c | 15 +-- src/modules/evas/engines/gl_common/evas_gl_core.c | 73 ++++++------- src/modules/evas/engines/gl_common/evas_gl_core.h | 2 +- .../evas/engines/gl_common/evas_gl_core_private.h | 5 + src/modules/evas/engines/gl_generic/evas_engine.c | 16 ++- 7 files changed, 127 insertions(+), 105 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 7be99e6..24a411d 100644 --- a/src/modules/evas/engines/gl_common/evas_gl_api.c +++ b/src/modules/evas/engines/gl_common/evas_gl_api.c @@ -96,7 +96,10 @@ _evgl_glBindFramebuffer(GLenum target, GLuint framebuffer) { if (_evgl_direct_enabled()) { - glBindFramebuffer(target, 0); + if (ctx->map_tex) + glBindFramebuffer(target, ctx->current_fbo); + else + glBindFramebuffer(target, 0); if (rsc->direct.partial.enabled) { @@ -535,7 +538,7 @@ _evgl_glClear(GLbitfield mask) if (_evgl_direct_enabled()) { - if ((!(rsc->current_ctx->current_fbo) && rsc->current_ctx->version == EVAS_GL_GLES_2_X) || + if (((!(rsc->current_ctx->current_fbo) || rsc->current_ctx->map_tex) && rsc->current_ctx->version == EVAS_GL_GLES_2_X) || (!(rsc->current_ctx->current_draw_fbo) && rsc->current_ctx->version == EVAS_GL_GLES_3_X)) { /* Skip glClear() if clearing with transparent color @@ -948,7 +951,7 @@ _evgl_glGetFloatv(GLenum pname, GLfloat* params) if (ctx->version == EVAS_GL_GLES_2_X) { // Only need to handle it if it's directly rendering to the window - if (!(rsc->current_ctx->current_fbo)) + if (!(rsc->current_ctx->current_fbo) || rsc->current_ctx->map_tex) { if (pname == GL_SCISSOR_BOX) { @@ -961,6 +964,7 @@ _evgl_glGetFloatv(GLenum pname, GLfloat* params) return; } } + /* Temporary Fixes to avoid Webkit issue else if (pname == GL_VIEWPORT) { if (ctx->viewport_updated) @@ -969,9 +973,9 @@ _evgl_glGetFloatv(GLenum pname, GLfloat* params) return; } } - + */ // If it hasn't been initialized yet, return img object size - if ((pname == GL_SCISSOR_BOX) || (pname == GL_VIEWPORT)) + if ((pname == GL_SCISSOR_BOX) )//|| (pname == GL_VIEWPORT)) { params[0] = (GLfloat)0.0; params[1] = (GLfloat)0.0; @@ -997,6 +1001,7 @@ _evgl_glGetFloatv(GLenum pname, GLfloat* params) return; } } + /* Temporary Fixes to avoid Webkit issue else if (pname == GL_VIEWPORT) { if (ctx->viewport_updated) @@ -1005,6 +1010,7 @@ _evgl_glGetFloatv(GLenum pname, GLfloat* params) return; } } + */ // If it hasn't been initialized yet, return img object size if ((pname == GL_SCISSOR_BOX) )//|| (pname == GL_VIEWPORT)) { @@ -1029,13 +1035,8 @@ _evgl_glGetFloatv(GLenum pname, GLfloat* params) { if (pname == GL_FRAMEBUFFER_BINDING) { - rsc = _evgl_tls_resource_get(); - ctx = rsc ? rsc->current_ctx : NULL; - if (ctx) - { - *params = (GLfloat)ctx->current_fbo; - return; - } + *params = (GLfloat)ctx->current_fbo; + return; } } else if (ctx->version == EVAS_GL_GLES_3_X) @@ -1197,38 +1198,46 @@ _evgl_glGetIntegerv(GLenum pname, GLint* params) if (_evgl_direct_enabled()) { if (ctx->version == EVAS_GL_GLES_2_X) - { - // Only need to handle it if it's directly rendering to the window - if (!(rsc->current_ctx->current_fbo)) - { - if (pname == GL_SCISSOR_BOX) - { - if (ctx->scissor_updated) - { - memcpy(params, ctx->scissor_coord, sizeof(int)*4); - return; - } - } - else if (pname == GL_VIEWPORT) - { - if (ctx->viewport_updated) - { - memcpy(params, ctx->viewport_coord, sizeof(int)*4); - return; - } - } - - // If it hasn't been initialized yet, return img object size - if ((pname == GL_SCISSOR_BOX) || (pname == GL_VIEWPORT)) - { - params[0] = 0; - params[1] = 0; - params[2] = (GLint)rsc->direct.img.w; - params[3] = (GLint)rsc->direct.img.h; - return; - } - } - } + { + // Only need to handle it if it's directly rendering to the window + if (!(rsc->current_ctx->current_fbo) || rsc->current_ctx->map_tex) + { + if (pname == GL_SCISSOR_BOX) + { + if (ctx->scissor_updated) + { + memcpy(params, ctx->scissor_coord, sizeof(int)*4); + } + else + { + params[0] = 0; + params[1] = 0; + params[2] = (GLint)rsc->direct.img.w; + params[3] = (GLint)rsc->direct.img.h; + } + return; + } + else if (pname == GL_VIEWPORT) + { + /* Temporary Fixes to avoid Webkit issue + if (ctx->viewport_updated) + { + memcpy(params, ctx->viewport_coord, sizeof(int)*4); + return; + } + */ + } + // If it hasn't been initialized yet, return img object size + else if (pname == GL_FRAMEBUFFER_BINDING) + { + if (rsc->current_ctx->map_tex) + { + params[0] = rsc->current_ctx->current_fbo; + return; + } + } + } + } else if (ctx->version == EVAS_GL_GLES_3_X) { // Only need to handle it if it's directly rendering to the window @@ -1251,7 +1260,7 @@ _evgl_glGetIntegerv(GLenum pname, GLint* params) } } // If it hasn't been initialized yet, return img object size - if ((pname == GL_SCISSOR_BOX) )//|| (pname == GL_VIEWPORT)) + if ((pname == GL_SCISSOR_BOX) || (pname == GL_VIEWPORT)) { params[0] = 0; params[1] = 0; @@ -1274,13 +1283,8 @@ _evgl_glGetIntegerv(GLenum pname, GLint* params) { if (pname == GL_FRAMEBUFFER_BINDING) { - rsc = _evgl_tls_resource_get(); - ctx = rsc ? rsc->current_ctx : NULL; - if (ctx) - { - *params = ctx->current_fbo; - return; - } + *params = ctx->current_fbo; + return; } } else if (ctx->version == EVAS_GL_GLES_3_X) @@ -1481,7 +1485,7 @@ _evgl_glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum forma if (_evgl_direct_enabled()) { - if ((!(rsc->current_ctx->current_fbo) && rsc->current_ctx->version == EVAS_GL_GLES_2_X) || + if (((!(rsc->current_ctx->current_fbo) || rsc->current_ctx->map_tex) && rsc->current_ctx->version == EVAS_GL_GLES_2_X) || (!(rsc->current_ctx->current_read_fbo) && rsc->current_ctx->version == EVAS_GL_GLES_3_X)) { compute_gl_coordinates(rsc->direct.win_w, rsc->direct.win_h, @@ -1534,7 +1538,7 @@ _evgl_glScissor(GLint x, GLint y, GLsizei width, GLsizei height) if (_evgl_direct_enabled()) { - if ((!(rsc->current_ctx->current_fbo) && rsc->current_ctx->version == EVAS_GL_GLES_2_X) || + if (((!(rsc->current_ctx->current_fbo) || rsc->current_ctx->map_tex) && rsc->current_ctx->version == EVAS_GL_GLES_2_X) || (!(rsc->current_ctx->current_draw_fbo) && rsc->current_ctx->version == EVAS_GL_GLES_3_X)) { // Direct rendering to canvas @@ -1622,7 +1626,7 @@ _evgl_glViewport(GLint x, GLint y, GLsizei width, GLsizei height) if (_evgl_direct_enabled()) { - if ((!(rsc->current_ctx->current_fbo) && rsc->current_ctx->version == EVAS_GL_GLES_2_X) || + if (((!(rsc->current_ctx->current_fbo) || rsc->current_ctx->map_tex) && rsc->current_ctx->version == EVAS_GL_GLES_2_X) || (!(rsc->current_ctx->current_draw_fbo) && rsc->current_ctx->version == EVAS_GL_GLES_3_X)) { if ((!ctx->direct_scissor)) diff --git a/src/modules/evas/engines/gl_common/evas_gl_api_ext.c b/src/modules/evas/engines/gl_common/evas_gl_api_ext.c index 36ee210..52b268b 100644 --- a/src/modules/evas/engines/gl_common/evas_gl_api_ext.c +++ b/src/modules/evas/engines/gl_common/evas_gl_api_ext.c @@ -455,7 +455,12 @@ _evgl_glDiscardFramebufferEXT(GLenum target, GLsizei numAttachments, const GLenu return; } - if (!_evgl_direct_enabled()) + if (_evgl_direct_enabled()) + { + if (ctx->map_tex) + target_is_fbo = EINA_TRUE; + } + else { if (ctx->current_fbo == 0) target_is_fbo = EINA_TRUE; diff --git a/src/modules/evas/engines/gl_common/evas_gl_api_gles1.c b/src/modules/evas/engines/gl_common/evas_gl_api_gles1.c index 295e203..c40f5df 100644 --- a/src/modules/evas/engines/gl_common/evas_gl_api_gles1.c +++ b/src/modules/evas/engines/gl_common/evas_gl_api_gles1.c @@ -535,8 +535,7 @@ _evgl_gles1_glClear(GLbitfield mask) EVGL_FUNC_BEGIN(); if (_evgl_direct_enabled()) { - if (!(rsc->current_ctx->current_fbo)) - //|| rsc->current_ctx->map_tex) + if (!(rsc->current_ctx->current_fbo) || rsc->current_ctx->map_tex) { /* Skip glClear() if clearing with transparent color * Note: There will be side effects if the object itself is not @@ -1041,8 +1040,7 @@ _evgl_gles1_glGetIntegerv(GLenum pname, GLint *params) } // Only need to handle it if it's directly rendering to the window - if (!(rsc->current_ctx->current_fbo)) - //|| rsc->current_ctx->map_tex) + if (!(rsc->current_ctx->current_fbo) || rsc->current_ctx->map_tex) { if (pname == GL_SCISSOR_BOX) { @@ -1492,8 +1490,7 @@ _evgl_gles1_glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum EVGL_FUNC_BEGIN(); if (_evgl_direct_enabled()) { - if (!(rsc->current_ctx->current_fbo)) - //|| rsc->current_ctx->map_tex) + if (!(rsc->current_ctx->current_fbo) || rsc->current_ctx->map_tex) { compute_gl_coordinates(rsc->direct.win_w, rsc->direct.win_h, rsc->direct.rot, 1, @@ -1590,8 +1587,7 @@ _evgl_gles1_glScissor(GLint x, GLint y, GLsizei width, GLsizei height) if (_evgl_direct_enabled()) { - if (!(rsc->current_ctx->current_fbo)) - //|| rsc->current_ctx->map_tex) + if (!(rsc->current_ctx->current_fbo) || rsc->current_ctx->map_tex) { if ((ctx->direct_scissor) && (!ctx->scissor_enabled)) { @@ -1838,8 +1834,7 @@ _evgl_gles1_glViewport(GLint x, GLint y, GLsizei width, GLsizei height) EVGL_FUNC_BEGIN(); if (_evgl_direct_enabled()) { - if (!(rsc->current_ctx->current_fbo)) - //|| rsc->current_ctx->map_tex) + if (!(rsc->current_ctx->current_fbo) || rsc->current_ctx->map_tex) { if ((!ctx->direct_scissor)) { 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 51303ae..f765de3 100644 --- a/src/modules/evas/engines/gl_common/evas_gl_core.c +++ b/src/modules/evas/engines/gl_common/evas_gl_core.c @@ -2616,25 +2616,18 @@ evgl_make_current(void *eng_data, EVGL_Surface *sfc, EVGL_Context *ctx) } else { - if (sfc->direct_override) - { - DBG("Not creating fallback surfaces even though it should. Use at OWN discretion!"); - } - else - { - // Create internal buffers if not yet created - if (!sfc->buffers_allocated) - { - if (dbg) DBG("Allocating buffers for sfc %p", sfc); - if (!_surface_buffers_allocate(eng_data, sfc, sfc->w, sfc->h, ctx->version)) - { - ERR("Unable Create Specificed Surfaces. Unsupported format!"); - evas_gl_common_error_set(eng_data, EVAS_GL_BAD_ALLOC); - return 0; - } - sfc->buffers_allocated = 1; - } - } + // Create internal buffers if not yet created + if (!sfc->buffers_allocated) + { + if (dbg) DBG("Allocating buffers for sfc %p", sfc); + if (!_surface_buffers_allocate(eng_data, sfc, sfc->w, sfc->h, ctx->version)) + { + ERR("Unable Create Specificed Surfaces. Unsupported format!"); + evas_gl_common_error_set(eng_data, EVAS_GL_BAD_ALLOC); + return 0; + } + sfc->buffers_allocated = 1; + } } } else @@ -2751,6 +2744,17 @@ evgl_make_current(void *eng_data, EVGL_Surface *sfc, EVGL_Context *ctx) } else { + if (rsc->direct.map_tex) + { + if (rsc->direct.partial.enabled) + evgl_direct_partial_render_end(); + _framebuffer_bind(ctx->surface_fbo, ctx->version); + ctx->current_fbo = ctx->surface_fbo; + _texture_attach_2d(rsc->direct.map_tex, GL_COLOR_ATTACHMENT0, 0, sfc->msaa_samples, ctx->version); + ctx->map_tex = rsc->direct.map_tex; + } + else + { // This is to transition from FBO rendering to direct rendering glGetIntegerv_evgl_thread_cmd(GL_FRAMEBUFFER_BINDING, &curr_fbo); if (ctx->surface_fbo == (GLuint)curr_fbo) @@ -2777,6 +2781,8 @@ evgl_make_current(void *eng_data, EVGL_Surface *sfc, EVGL_Context *ctx) } } } + ctx->map_tex = 0; + } } rsc->direct.rendered = 1; @@ -2825,23 +2831,16 @@ evgl_make_current(void *eng_data, EVGL_Surface *sfc, EVGL_Context *ctx) if ((rsc->current_ctx != ctx) || (ctx->current_sfc != sfc) || (rsc->direct.rendered)) { sfc->current_ctx = ctx; - if ((sfc->direct_mem_opt) && (sfc->direct_override)) - { - DBG("Not creating fallback surfaces even though it should. Use at OWN discretion!"); - } - else - { - // If it's transitioning from direct render to fbo render - // Call end tiling - if (rsc->direct.partial.enabled) - evgl_direct_partial_render_end(); + // If it's transitioning from direct render to fbo render + // Call end tiling + if (rsc->direct.partial.enabled) + evgl_direct_partial_render_end(); - if (!_surface_buffers_fbo_set(sfc, ctx->surface_fbo, ctx->version)) - { - ERR("Attaching buffers to context fbo failed. Engine: %p Surface: %p Context FBO: %u", evgl_engine, sfc, ctx->surface_fbo); - evas_gl_common_error_set(eng_data, EVAS_GL_BAD_CONTEXT); - return 0; - } + if (!_surface_buffers_fbo_set(sfc, ctx->surface_fbo, ctx->version)) + { + ERR("Attaching buffers to context fbo failed. Engine: %p Surface: %p Context FBO: %u", evgl_engine, sfc, ctx->surface_fbo); + evas_gl_common_error_set(eng_data, EVAS_GL_BAD_CONTEXT); + return 0; } // Bind to the previously bound buffer @@ -3058,7 +3057,7 @@ evgl_native_surface_direct_opts_get(Evas_Native_Surface *ns, } void -evgl_direct_info_set(int win_w, int win_h, int rot, +evgl_direct_info_set(int win_w, int win_h, int rot, unsigned int map_tex, int img_x, int img_y, int img_w, int img_h, int clip_x, int clip_y, int clip_w, int clip_h, int render_op, void *surface) @@ -3090,6 +3089,7 @@ evgl_direct_info_set(int win_w, int win_h, int rot, rsc->direct.win_w = win_w; rsc->direct.win_h = win_h; rsc->direct.rot = rot; + rsc->direct.map_tex = map_tex; rsc->direct.img.x = img_x; rsc->direct.img.y = img_y; @@ -3119,6 +3119,7 @@ evgl_direct_info_clear(void) if (!(rsc=_evgl_tls_resource_get())) return; + rsc->direct.map_tex = 0; rsc->direct.enabled = EINA_FALSE; } diff --git a/src/modules/evas/engines/gl_common/evas_gl_core.h b/src/modules/evas/engines/gl_common/evas_gl_core.h index e1e6764..82d17b8 100644 --- a/src/modules/evas/engines/gl_common/evas_gl_core.h +++ b/src/modules/evas/engines/gl_common/evas_gl_core.h @@ -71,7 +71,7 @@ Eina_Bool evgl_safe_extension_get(const char *name, void **pfuncptr); int evgl_direct_rendered(void); void evgl_direct_override_get(Eina_Bool *override, Eina_Bool *force_off); -void evgl_direct_info_set(int win_w, int win_h, int rot, +void evgl_direct_info_set(int win_w, int win_h, int rot, unsigned int map_tex, int img_x, int img_y, int img_w, int img_h, int clip_x, int clip_y, int clip_w, int clip_h, int render_op, void *surface); 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 12cc6b0..954e11e 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 @@ -177,6 +177,9 @@ struct _EVGL_Context GLuint current_draw_fbo; //for GLES3 GLuint current_read_fbo; //for GLES3 + // Map texture + GLuint map_tex; + // Direct Rendering Related unsigned scissor_enabled : 1; unsigned scissor_updated : 1; @@ -284,6 +287,8 @@ struct _EVGL_Resource int win_w; int win_h; + GLuint map_tex; + struct { int x, y, w, h; } img; diff --git a/src/modules/evas/engines/gl_generic/evas_engine.c b/src/modules/evas/engines/gl_generic/evas_engine.c index 9c5ccb0..d98a84c 100644 --- a/src/modules/evas/engines/gl_generic/evas_engine.c +++ b/src/modules/evas/engines/gl_generic/evas_engine.c @@ -1085,6 +1085,7 @@ eng_image_draw(void *data, void *context, void *surface, void *image, int src_x, Evas_Engine_GL_Context *gl_context; Render_Engine_GL_Generic *re = data; Evas_GL_Image *im = image; + Evas_GL_Image *surf = surface; Evas_Native_Surface *n; if (!im) return EINA_FALSE; @@ -1095,9 +1096,16 @@ eng_image_draw(void *data, void *context, void *surface, void *image, int src_x, if (eng_gl_image_direct_get(data, image)) { + int map_tex = 0; void *direct_surface = NULL; gl_context->dc = context; + if (surface != gl_context->def_surface) + { + map_tex = surf->tex->pt->texture; + dst_y = gl_context->h - dst_y - dst_h; + } + if ((gl_context->master_clip.enabled) && (gl_context->master_clip.w > 0) && (gl_context->master_clip.h > 0)) @@ -1117,7 +1125,8 @@ eng_image_draw(void *data, void *context, void *surface, void *image, int src_x, // Set necessary info for direct rendering evgl_direct_info_set(gl_context->w, gl_context->h, - gl_context->rot, + map_tex?0:gl_context->rot, + map_tex, dst_x, dst_y, dst_w, dst_h, gl_context->dc->clip.x, gl_context->dc->clip.y, @@ -1681,7 +1690,10 @@ eng_gl_surface_direct_renderable_get(void *data, Evas_Native_Surface *ns, Eina_B gl_context = re->window_gl_context_get(re->software.ob); if (gl_context->def_surface != sfc) - return EINA_FALSE; + { + *override = EINA_FALSE; + return EINA_FALSE; + } return EINA_TRUE; } -- 2.7.4