From d95b94e4148b1678fad597d8fbbdeae6509bfd1f Mon Sep 17 00:00:00 2001 From: Daekwang Ryu Date: Tue, 3 Mar 2015 21:09:25 +0900 Subject: [PATCH] Evas GL: Add hidden flags instead of env vars For Direct Override and Memory Optimization. This commit includes a lot of changes, but most of them are directly related to moving the global var into the surface. In particular, we must keep track of the DR surfaces, so we add them to a hash indexed by texture id. Change-Id: Iea696e279eac7e4ab4d130adb748936f2d97488c --- src/lib/evas/canvas/evas_object_image.c | 4 +- src/lib/evas/include/evas_private.h | 2 +- src/modules/evas/engines/gl_common/evas_gl_core.c | 115 ++++++++++++++++++--- src/modules/evas/engines/gl_common/evas_gl_core.h | 3 +- .../evas/engines/gl_common/evas_gl_core_private.h | 14 ++- src/modules/evas/engines/gl_generic/evas_engine.c | 4 +- 6 files changed, 115 insertions(+), 27 deletions(-) diff --git a/src/lib/evas/canvas/evas_object_image.c b/src/lib/evas/canvas/evas_object_image.c index 76ee8e6..8d1630e 100755 --- a/src/lib/evas/canvas/evas_object_image.c +++ b/src/lib/evas/canvas/evas_object_image.c @@ -2828,9 +2828,9 @@ evas_process_dirty_pixels(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj, // Check if we can do direct rendering... if (ENFN->gl_direct_override_get) - ENFN->gl_direct_override_get(output, &direct_override, &direct_force_off); + ENFN->gl_direct_override_get(output, NULL /*&direct_override*/, &direct_force_off); if (ENFN->gl_surface_direct_renderable_get) - direct_renderable = ENFN->gl_surface_direct_renderable_get(output, ns); + direct_renderable = ENFN->gl_surface_direct_renderable_get(output, ns, &direct_override); if ( ((direct_override) || ((direct_renderable) && diff --git a/src/lib/evas/include/evas_private.h b/src/lib/evas/include/evas_private.h index b3f95ae..f06980e 100755 --- a/src/lib/evas/include/evas_private.h +++ b/src/lib/evas/include/evas_private.h @@ -1294,7 +1294,7 @@ struct _Evas_Func void *(*gl_current_surface_get) (void *data); int (*gl_rotation_angle_get) (void *data); Eina_Bool (*gl_surface_query) (void *data, void *surface, int attr, void *value); - Eina_Bool (*gl_surface_direct_renderable_get) (void *data, Evas_Native_Surface *ns); +Eina_Bool (*gl_surface_direct_renderable_get) (void *data, Evas_Native_Surface *ns, Eina_Bool *direct_override); int (*image_load_error_get) (void *data, void *image); int (*font_run_end_get) (void *data, Evas_Font_Set *font, Evas_Font_Instance **script_fi, Evas_Font_Instance **cur_fi, Evas_Script_Type script, const Eina_Unicode *text, int run_len); 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 94b6097..38dec77 100755 --- a/src/modules/evas/engines/gl_common/evas_gl_core.c +++ b/src/modules/evas/engines/gl_common/evas_gl_core.c @@ -24,6 +24,13 @@ static void _surface_cap_print(int error); static void _surface_context_list_print(); static void _internal_resources_destroy(void *eng_data, EVGL_Resource *rsc); +// FIXME: This is a hidden option for Webkit-EFL on Tizen. +// They were setting env vars, which have a global impact on the whole application, +// including other Evas GL surfaces. Instead, they should request the DR and +// memory option only on a per-surface basis. +#define EVAS_GL_OPTIONS_DIRECT_MEMORY_OPTIMIZE 0x1000 +#define EVAS_GL_OPTIONS_DIRECT_OVERRIDE 0x2000 + //---------------------------------------------------------------// // Internal Resources: @@ -1590,6 +1597,33 @@ evgl_surface_create(void *eng_data, Evas_GL_Config *cfg, int w, int h) sfc->w = w; sfc->h = h; + // Check for Direct rendering override env var. + if (!evgl_engine->direct_override) + if ((s = getenv("EVAS_GL_DIRECT_OVERRIDE"))) + { + WRN("DIRECT_OVERRIDE flag is set to '%s' for the whole application. " + "This should never be done except for debugging purposes.", s); + direct_override = atoi(s); + if (direct_override == 1) + evgl_engine->direct_override = 1; + else + evgl_engine->direct_override = -1; + } + + // Check if Direct Rendering Memory Optimzation flag is on + // Creates resources on demand when it fallsback to fbo rendering + if (!evgl_engine->direct_mem_opt) + if ((s = getenv("EVAS_GL_DIRECT_MEM_OPT"))) + { + WRN("DIRECT_MEMORY_OPTIMIZE flag is set to '%s' for the whole application. " + "This should never be done except for debugging purposes.", s); + direct_mem_opt = atoi(s); + if (direct_mem_opt == 1) + evgl_engine->direct_mem_opt = 1; + else + evgl_engine->direct_mem_opt = -1; + } + // Set the internal config value if (!_internal_config_set(sfc, cfg)) { @@ -1598,6 +1632,26 @@ evgl_surface_create(void *eng_data, Evas_GL_Config *cfg, int w, int h) goto error; } + // Extra options allowed only if DR is set + if (sfc->direct_fb_opt) + { + if (cfg->options_bits & EVAS_GL_OPTIONS_DIRECT_MEMORY_OPTIMIZE) + { + DBG("Setting DIRECT_MEMORY_OPTIMIZE bit"); + sfc->direct_mem_opt = EINA_TRUE; + } + else if (evgl_engine->direct_mem_opt == 1) + sfc->direct_mem_opt = EINA_TRUE; + + if (cfg->options_bits & EVAS_GL_OPTIONS_DIRECT_OVERRIDE) + { + DBG("Setting DIRECT_OVERRIDE bit"); + sfc->direct_override = EINA_TRUE; + } + else if (evgl_engine->direct_override == 1) + sfc->direct_override = EINA_TRUE; + } + // Set the context current with resource context/surface if (!_internal_resource_make_current(eng_data, NULL)) { @@ -1630,7 +1684,7 @@ evgl_surface_create(void *eng_data, Evas_GL_Config *cfg, int w, int h) }; // Allocate resources for fallback unless the flag is on - if (!evgl_engine->direct_mem_opt) + if (!sfc->direct_mem_opt) { if (!_surface_buffers_allocate(eng_data, sfc, sfc->w, sfc->h, 0)) { @@ -1653,7 +1707,10 @@ evgl_surface_create(void *eng_data, Evas_GL_Config *cfg, int w, int h) evgl_engine->surfaces = eina_list_prepend(evgl_engine->surfaces, sfc); if (sfc->direct_fb_opt) - evgl_engine->direct_surfaces = eina_list_prepend(evgl_engine->direct_surfaces, sfc); + { + eina_hash_add(evgl_engine->direct_surfaces, &sfc->color_buf, sfc); + DBG("Added tex %d as direct surface: %p", sfc->color_buf, sfc); + } if (sfc->direct_fb_opt && (sfc->depth_fmt || sfc->stencil_fmt || sfc->depth_stencil_fmt)) @@ -1744,6 +1801,17 @@ evgl_pbuffer_surface_create(void *eng_data, Evas_GL_Config *cfg, goto error; } + // What is DR for PBuffer? + /* + if (sfc->direct_fb_opt) + { + if (cfg->options_bits & EVAS_GL_OPTIONS_DIRECT_MEMORY_OPTIMIZE) + sfc->direct_mem_opt = EINA_TRUE; + if (cfg->options_bits & EVAS_GL_OPTIONS_DIRECT_OVERRIDE) + sfc->direct_override = EINA_TRUE; + } + */ + // Create internal buffers if (!_surface_buffers_create(sfc)) { @@ -1753,7 +1821,7 @@ evgl_pbuffer_surface_create(void *eng_data, Evas_GL_Config *cfg, }; // Allocate resources for fallback unless the flag is on - if (!evgl_engine->direct_mem_opt) + if (!sfc->direct_mem_opt) { if (!_surface_buffers_allocate(eng_data, sfc, sfc->w, sfc->h, 0)) { @@ -1909,7 +1977,11 @@ evgl_surface_destroy(void *eng_data, EVGL_Surface *sfc) evgl_engine->surfaces = eina_list_remove(evgl_engine->surfaces, sfc); if (sfc->direct_fb_opt) - evgl_engine->direct_surfaces = eina_list_remove(evgl_engine->direct_surfaces, sfc); + { + eina_hash_del(evgl_engine->direct_surfaces, &texid, sfc); + DBG("Removed tex %d from the direct surface: %p", texid, sfc); + } + if (sfc->direct_fb_opt && (sfc->depth_fmt || sfc->stencil_fmt || sfc->depth_stencil_fmt)) { @@ -2135,7 +2207,7 @@ evgl_make_current(void *eng_data, EVGL_Surface *sfc, EVGL_Context *ctx) // Allocate or free resources depending on what mode (direct of fbo) it's // running only if the env var EVAS_GL_DIRECT_MEM_OPT is set. - if (evgl_engine->direct_mem_opt) + if (sfc->direct_mem_opt) { if (_evgl_direct_renderable(rsc, sfc)) { @@ -2286,7 +2358,7 @@ evgl_make_current(void *eng_data, EVGL_Surface *sfc, EVGL_Context *ctx) if ((ctx->current_sfc != sfc) || (ctx != sfc->current_ctx)) { sfc->current_ctx = ctx; - if ((evgl_engine->direct_mem_opt) && (evgl_engine->direct_override)) + if ((sfc->direct_mem_opt) && (sfc->direct_fb_opt)) { DBG("Not creating fallback surfaces even though it should. Use at OWN discretion!"); } @@ -2441,12 +2513,13 @@ evgl_direct_rendered() Eina_Bool evgl_native_surface_direct_opts_get(Evas_Native_Surface *ns, Eina_Bool *direct_render, - Eina_Bool *client_side_rotation) + Eina_Bool *client_side_rotation, + Eina_Bool *direct_override) { EVGL_Surface *sfc; - Eina_List *l; if (direct_render) *direct_render = EINA_FALSE; + if (direct_override) *direct_override = EINA_FALSE; if (client_side_rotation) *client_side_rotation = EINA_FALSE; if (!evgl_engine) return EINA_FALSE; @@ -2454,17 +2527,24 @@ evgl_native_surface_direct_opts_get(Evas_Native_Surface *ns, if (ns->data.opengl.framebuffer_id != 0) return EINA_FALSE; if (ns->data.opengl.texture_id == 0) return EINA_FALSE; - EINA_LIST_FOREACH(evgl_engine->direct_surfaces, l, sfc) + sfc = eina_hash_find(evgl_engine->direct_surfaces, &ns->data.opengl.texture_id); + if (!sfc) { - if (ns->data.opengl.texture_id == sfc->color_buf) - { - if (direct_render) *direct_render = sfc->direct_fb_opt; - if (client_side_rotation) *client_side_rotation = sfc->client_side_rotation; - // Note: Maybe we could promote this sfc in the list? - return EINA_TRUE; - } + DBG("Native surface %p (color_buf %d) was not found.", + ns, ns->data.opengl.texture_id); + return EINA_FALSE; + } + + if (evgl_engine->api_debug_mode) + { + DBG("Found native surface: texid:%u DR:%d DORR:%d CSR:%d", + ns->data.opengl.texture_id, (int) sfc->direct_fb_opt, + (int) sfc->direct_override, (int) sfc->client_side_rotation); } + if (direct_render) *direct_render = sfc->direct_fb_opt; + if (direct_override) *direct_override = sfc->direct_override; + if (client_side_rotation) *client_side_rotation = sfc->client_side_rotation; return EINA_TRUE; } @@ -2575,7 +2655,8 @@ evgl_direct_partial_info_clear() void evgl_direct_override_get(int *override, int *force_off) { - if (override) *override = evgl_engine->direct_override; + (void) override; + //if (override) *override = evgl_engine->direct_override; if (force_off) *force_off = evgl_engine->direct_force_off; } 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 9dcb5bb..d1d3053 100644 --- a/src/modules/evas/engines/gl_common/evas_gl_core.h +++ b/src/modules/evas/engines/gl_common/evas_gl_core.h @@ -46,7 +46,8 @@ void evgl_direct_info_clear(); Eina_Bool evgl_native_surface_direct_opts_get(Evas_Native_Surface *ns, Eina_Bool *direct_render, - Eina_Bool *client_side_rotation); + Eina_Bool *client_side_rotation, + Eina_Bool *direct_override); void evgl_direct_partial_info_set(int pres); void evgl_direct_partial_info_clear(); 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 f4e5e62..68ad25d 100755 --- a/src/modules/evas/engines/gl_common/evas_gl_core_private.h +++ b/src/modules/evas/engines/gl_common/evas_gl_core_private.h @@ -112,9 +112,14 @@ struct _EVGL_Surface unsigned gles1_indirect : 1; unsigned xpixmap : 1; + // Moved from evgl_engine + unsigned direct_override : 1; + unsigned direct_mem_opt : 1; + // Init Flag unsigned buffers_allocated : 1; + void *cfg; int cfg_index; @@ -292,9 +297,6 @@ struct _EVGL_Engine int resource_count; int main_tid; - int direct_override; - int direct_mem_opt; - // Add more debug logs (DBG levels 4 and 6) int api_debug_mode; @@ -304,10 +306,14 @@ struct _EVGL_Engine // Force Direct Scissoring off for Debug purposes int direct_scissor_off; + // Other DR flags for debugging purposes + int direct_override; // 0: invalid, -1: no, 1: yes + int direct_mem_opt; // 0: invalid, -1: no, 1: yes + // Keep track of all the current surfaces/contexts Eina_List *surfaces; Eina_List *contexts; - Eina_List *direct_surfaces; + Eina_Hash *direct_surfaces; // unsigned (texid) --> EVGL_Surface* Eina_List *direct_depth_stencil_surfaces; //void *engine_data; diff --git a/src/modules/evas/engines/gl_generic/evas_engine.c b/src/modules/evas/engines/gl_generic/evas_engine.c index b16aac2..99950f3 100755 --- a/src/modules/evas/engines/gl_generic/evas_engine.c +++ b/src/modules/evas/engines/gl_generic/evas_engine.c @@ -1250,14 +1250,14 @@ eng_gl_direct_override_get(void *data, int *override, int *force_off) } static Eina_Bool -eng_gl_surface_direct_renderable_get(void *data, Evas_Native_Surface *ns) +eng_gl_surface_direct_renderable_get(void *data, Evas_Native_Surface *ns, Eina_Bool *direct_override) { Render_Engine_GL_Generic *re = data; Eina_Bool direct_render, client_side_rotation; EVGLINIT(data, EINA_FALSE); if (!re || !ns) return EINA_FALSE; - if (!evgl_native_surface_direct_opts_get(ns, &direct_render, &client_side_rotation)) + if (!evgl_native_surface_direct_opts_get(ns, &direct_render, &client_side_rotation, direct_override)) return EINA_FALSE; if (!direct_render) -- 2.7.4