summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJean-Philippe Andre <jp.andre@samsung.com>2015-03-03 16:38:52 +0900
committerJean-Philippe Andre <jp.andre@samsung.com>2015-03-03 18:11:32 +0900
commita14492ef73c9267042c5bf505080d0e90af394de (patch)
tree2d7d9e5b1532f3a6a7beeca278a3050763911116
parenta8e79114db5a050abcfa1fc66298dadd32bba7c1 (diff)
Evas GL: Automatic fallback to indirect rendering when the scene has
not changed. Automatically fallback to indirect rendering on FBO or X11 Pixmap if the Evas Object Image is not marked as dirty. This should improve the performance and/or power consumption in those rare cases where this area of the canvas needs to be redrawn but the GL content has not changed. @feature
-rw-r--r--src/lib/evas/canvas/evas_object_image.c37
-rw-r--r--src/lib/evas/include/evas_private.h2
-rw-r--r--src/modules/evas/engines/gl_common/evas_gl_common.h1
-rw-r--r--src/modules/evas/engines/gl_common/evas_gl_core.c81
-rw-r--r--src/modules/evas/engines/gl_common/evas_gl_core.h2
-rw-r--r--src/modules/evas/engines/gl_generic/evas_engine.c43
-rw-r--r--src/modules/evas/engines/software_generic/evas_engine.c2
7 files changed, 130 insertions, 38 deletions
diff --git a/src/lib/evas/canvas/evas_object_image.c b/src/lib/evas/canvas/evas_object_image.c
index 63f777f04a..e4aa44863d 100644
--- a/src/lib/evas/canvas/evas_object_image.c
+++ b/src/lib/evas/canvas/evas_object_image.c
@@ -2853,11 +2853,9 @@ evas_process_dirty_pixels(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj,
2853 if (ENFN->image_native_get) 2853 if (ENFN->image_native_get)
2854 { 2854 {
2855 Evas_Native_Surface *ns; 2855 Evas_Native_Surface *ns;
2856
2856 ns = ENFN->image_native_get(ENDT, o->engine_data); 2857 ns = ENFN->image_native_get(ENDT, o->engine_data);
2857 if ( (ns) && 2858 if (ns)
2858 (ns->type == EVAS_NATIVE_SURFACE_OPENGL) &&
2859 (ns->data.opengl.texture_id) &&
2860 (!ns->data.opengl.framebuffer_id) )
2861 { 2859 {
2862 Eina_Bool direct_renderable = EINA_FALSE; 2860 Eina_Bool direct_renderable = EINA_FALSE;
2863 2861
@@ -2880,6 +2878,8 @@ evas_process_dirty_pixels(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj,
2880 { 2878 {
2881 if (ENFN->gl_get_pixels_set) 2879 if (ENFN->gl_get_pixels_set)
2882 ENFN->gl_get_pixels_set(output, o->pixels->func.get_pixels, o->pixels->func.get_pixels_data, eo_obj); 2880 ENFN->gl_get_pixels_set(output, o->pixels->func.get_pixels, o->pixels->func.get_pixels_data, eo_obj);
2881 if (ENFN->gl_image_direct_set)
2882 ENFN->gl_image_direct_set(output, o->engine_data, EINA_TRUE);
2883 o->direct_render = EINA_TRUE; 2883 o->direct_render = EINA_TRUE;
2884 } 2884 }
2885 else 2885 else
@@ -2919,9 +2919,28 @@ evas_process_dirty_pixels(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj,
2919 else 2919 else
2920 { 2920 {
2921 // Check if the it's not dirty but it has direct rendering 2921 // Check if the it's not dirty but it has direct rendering
2922 if (o->direct_render) 2922 if (o->direct_render && ENFN->image_native_get)
2923 { 2923 {
2924 ENFN->gl_get_pixels_set(output, o->pixels->func.get_pixels, o->pixels->func.get_pixels_data, eo_obj); 2924 Evas_Native_Surface *ns;
2925 ns = ENFN->image_native_get(output, o->engine_data);
2926 if (ENFN->gl_direct_override_get)
2927 ENFN->gl_direct_override_get(output, &direct_override, &direct_force_off);
2928 if (ENFN->gl_surface_direct_renderable_get)
2929 ENFN->gl_surface_direct_renderable_get(output, ns, &direct_override);
2930
2931 if (direct_override && !direct_force_off)
2932 {
2933 // always use direct rendering
2934 ENFN->gl_get_pixels_set(output, o->pixels->func.get_pixels, o->pixels->func.get_pixels_data, eo_obj);
2935 }
2936 else
2937 {
2938 // Auto-fallback to FBO rendering (for perf & power consumption)
2939 o->pixels->func.get_pixels(o->pixels->func.get_pixels_data, obj->object);
2940 //if (ENFN->get_pixels_render_post)
2941 //ENFN->get_pixels_render_post(output);
2942 o->direct_render = EINA_FALSE;
2943 }
2925 } 2944 }
2926 } 2945 }
2927 2946
@@ -3019,9 +3038,9 @@ evas_object_image_render(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj, v
3019 3038
3020 // Clear out the pixel get stuff.. 3039 // Clear out the pixel get stuff..
3021 if (ENFN->gl_get_pixels_set) 3040 if (ENFN->gl_get_pixels_set)
3022 { 3041 ENFN->gl_get_pixels_set(output, NULL, NULL, NULL);
3023 ENFN->gl_get_pixels_set(output, NULL, NULL, NULL); 3042 if (ENFN->gl_image_direct_set)
3024 } 3043 ENFN->gl_image_direct_set(output, o->engine_data, EINA_FALSE);
3025 3044
3026 Evas_Object_Protected_Data *source = 3045 Evas_Object_Protected_Data *source =
3027 (o->cur->source ? 3046 (o->cur->source ?
diff --git a/src/lib/evas/include/evas_private.h b/src/lib/evas/include/evas_private.h
index e01eb38e83..fe241d29e7 100644
--- a/src/lib/evas/include/evas_private.h
+++ b/src/lib/evas/include/evas_private.h
@@ -1309,6 +1309,8 @@ struct _Evas_Func
1309 int (*gl_rotation_angle_get) (void *data); 1309 int (*gl_rotation_angle_get) (void *data);
1310 Eina_Bool (*gl_surface_query) (void *data, void *surface, int attr, void *value); 1310 Eina_Bool (*gl_surface_query) (void *data, void *surface, int attr, void *value);
1311 Eina_Bool (*gl_surface_direct_renderable_get) (void *data, Evas_Native_Surface *ns, Eina_Bool *override); 1311 Eina_Bool (*gl_surface_direct_renderable_get) (void *data, Evas_Native_Surface *ns, Eina_Bool *override);
1312 void (*gl_image_direct_set) (void *data, void *image, Eina_Bool direct);
1313 int (*gl_image_direct_get) (void *data, void *image);
1312 1314
1313 int (*image_load_error_get) (void *data, void *image); 1315 int (*image_load_error_get) (void *data, void *image);
1314 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); 1316 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_common.h b/src/modules/evas/engines/gl_common/evas_gl_common.h
index 6a93c2c879..3602319ad7 100644
--- a/src/modules/evas/engines/gl_common/evas_gl_common.h
+++ b/src/modules/evas/engines/gl_common/evas_gl_common.h
@@ -623,6 +623,7 @@ struct _Evas_GL_Image
623 unsigned char alpha : 1; 623 unsigned char alpha : 1;
624 unsigned char tex_only : 1; 624 unsigned char tex_only : 1;
625 unsigned char locked : 1; // gl_surface_lock/unlock 625 unsigned char locked : 1; // gl_surface_lock/unlock
626 unsigned char direct : 1; // evas gl direct renderable
626}; 627};
627 628
628struct _Evas_GL_Font_Texture 629struct _Evas_GL_Font_Texture
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 757f4ba4d5..1155e901cc 100644
--- a/src/modules/evas/engines/gl_common/evas_gl_core.c
+++ b/src/modules/evas/engines/gl_common/evas_gl_core.c
@@ -1690,8 +1690,16 @@ evgl_surface_create(void *eng_data, Evas_GL_Config *cfg, int w, int h)
1690 1690
1691 if (sfc->direct_fb_opt) 1691 if (sfc->direct_fb_opt)
1692 { 1692 {
1693 eina_hash_add(evgl_engine->direct_surfaces, &sfc->color_buf, sfc); 1693 if (!sfc->gles1_indirect)
1694 DBG("Added tex %d as direct surface: %p", sfc->color_buf, sfc); 1694 {
1695 eina_hash_add(evgl_engine->direct_surfaces, &sfc->color_buf, sfc);
1696 DBG("Added tex %d as direct surface: %p", sfc->color_buf, sfc);
1697 }
1698 else
1699 {
1700 eina_hash_add(evgl_engine->direct_surfaces, &sfc->gles1_sfc_native, sfc);
1701 DBG("Added tex %d as direct surface: %p", sfc->gles1_sfc_native, sfc);
1702 }
1695 } 1703 }
1696 1704
1697 if (sfc->direct_fb_opt && 1705 if (sfc->direct_fb_opt &&
@@ -2362,7 +2370,7 @@ evgl_make_current(void *eng_data, EVGL_Surface *sfc, EVGL_Context *ctx)
2362 if (dbg) DBG("Surface sfc %p is a normal surface.", sfc); 2370 if (dbg) DBG("Surface sfc %p is a normal surface.", sfc);
2363 2371
2364 // Attach fbo and the buffers 2372 // Attach fbo and the buffers
2365 if ((ctx->current_sfc != sfc) || (ctx != sfc->current_ctx)) 2373 if ((rsc->current_ctx != ctx) || (ctx->current_sfc != sfc) || (rsc->direct.rendered))
2366 { 2374 {
2367 sfc->current_ctx = ctx; 2375 sfc->current_ctx = ctx;
2368 if ((evgl_engine->direct_mem_opt) && (evgl_engine->direct_override)) 2376 if ((evgl_engine->direct_mem_opt) && (evgl_engine->direct_override))
@@ -2469,17 +2477,24 @@ evgl_native_surface_get(EVGL_Surface *sfc, Evas_Native_Surface *ns)
2469 return 0; 2477 return 0;
2470 } 2478 }
2471 2479
2472 ns->type = EVAS_NATIVE_SURFACE_OPENGL; 2480 if (!sfc->gles1_indirect)
2473 ns->version = EVAS_NATIVE_SURFACE_VERSION; 2481 {
2474 ns->data.opengl.texture_id = sfc->color_buf; 2482 ns->type = EVAS_NATIVE_SURFACE_OPENGL;
2475 ns->data.opengl.framebuffer_id = sfc->color_buf; 2483 ns->version = EVAS_NATIVE_SURFACE_VERSION;
2476 ns->data.opengl.x = 0; 2484 ns->data.opengl.texture_id = sfc->color_buf;
2477 ns->data.opengl.y = 0; 2485 ns->data.opengl.framebuffer_id = sfc->color_buf;
2478 ns->data.opengl.w = sfc->w; 2486 ns->data.opengl.x = 0;
2479 ns->data.opengl.h = sfc->h; 2487 ns->data.opengl.y = 0;
2480 2488 ns->data.opengl.w = sfc->w;
2481 if (sfc->direct_fb_opt) 2489 ns->data.opengl.h = sfc->h;
2482 ns->data.opengl.framebuffer_id = 0; 2490 }
2491 else
2492 {
2493 ns->type = EVAS_NATIVE_SURFACE_X11;
2494 ns->version = EVAS_NATIVE_SURFACE_VERSION;
2495 ns->data.x11.pixmap = (unsigned long)(intptr_t)sfc->gles1_sfc_native;
2496 ns->data.x11.visual = sfc->gles1_sfc_visual;
2497 }
2483 2498
2484 return 1; 2499 return 1;
2485} 2500}
@@ -2503,24 +2518,42 @@ Eina_Bool
2503evgl_native_surface_direct_opts_get(Evas_Native_Surface *ns, 2518evgl_native_surface_direct_opts_get(Evas_Native_Surface *ns,
2504 Eina_Bool *direct_render, 2519 Eina_Bool *direct_render,
2505 Eina_Bool *client_side_rotation, 2520 Eina_Bool *client_side_rotation,
2506 Eina_Bool *override) 2521 Eina_Bool *direct_override)
2507{ 2522{
2508 EVGL_Surface *sfc; 2523 EVGL_Surface *sfc;
2509 2524
2510 if (override) *override = EINA_FALSE;
2511 if (direct_render) *direct_render = EINA_FALSE; 2525 if (direct_render) *direct_render = EINA_FALSE;
2526 if (direct_override) *direct_override = EINA_FALSE;
2512 if (client_side_rotation) *client_side_rotation = EINA_FALSE; 2527 if (client_side_rotation) *client_side_rotation = EINA_FALSE;
2513 2528
2514 if (!evgl_engine) return EINA_FALSE; 2529 if (!evgl_engine) return EINA_FALSE;
2515 if (!ns || (ns->type != EVAS_NATIVE_SURFACE_OPENGL)) return EINA_FALSE; 2530 if (!ns) return EINA_FALSE;
2516 if (ns->data.opengl.framebuffer_id != 0) return EINA_FALSE;
2517 if (ns->data.opengl.texture_id == 0) return EINA_FALSE;
2518 2531
2519 sfc = eina_hash_find(evgl_engine->direct_surfaces, &ns->data.opengl.texture_id); 2532 if (ns->type == EVAS_NATIVE_SURFACE_OPENGL &&
2520 if (!sfc) 2533 ns->data.opengl.texture_id)
2534 {
2535 sfc = eina_hash_find(evgl_engine->direct_surfaces, &ns->data.opengl.texture_id);
2536 if (!sfc)
2537 {
2538 DBG("Native surface %p (color_buf %d) was not found.",
2539 ns, ns->data.opengl.texture_id);
2540 return EINA_FALSE;
2541 }
2542 }
2543 else if (ns->type == EVAS_NATIVE_SURFACE_X11 &&
2544 ns->data.x11.pixmap)
2545 {
2546 sfc = eina_hash_find(evgl_engine->direct_surfaces, &ns->data.x11.pixmap);
2547 if (!sfc)
2548 {
2549 DBG("Native surface %p (pixmap %x) was not found.",
2550 ns, ns->data.x11.pixmap);
2551 return EINA_FALSE;
2552 }
2553 }
2554 else
2521 { 2555 {
2522 DBG("Native surface %p (color_buf %d) was not found.", 2556 ERR("Only EVAS_NATIVE_SURFACE_OPENGL or EVAS_NATIVE_SURFACE_X11 can be used for direct rendering");
2523 ns, ns->data.opengl.texture_id);
2524 return EINA_FALSE; 2557 return EINA_FALSE;
2525 } 2558 }
2526 2559
@@ -2532,7 +2565,7 @@ evgl_native_surface_direct_opts_get(Evas_Native_Surface *ns,
2532 } 2565 }
2533 2566
2534 if (direct_render) *direct_render = sfc->direct_fb_opt; 2567 if (direct_render) *direct_render = sfc->direct_fb_opt;
2535 if (override) *override |= sfc->direct_override; 2568 if (direct_override) *direct_override |= sfc->direct_override;
2536 if (client_side_rotation) *client_side_rotation = sfc->client_side_rotation; 2569 if (client_side_rotation) *client_side_rotation = sfc->client_side_rotation;
2537 return EINA_TRUE; 2570 return EINA_TRUE;
2538} 2571}
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 585c1a388c..7eeca5d6a5 100644
--- a/src/modules/evas/engines/gl_common/evas_gl_core.h
+++ b/src/modules/evas/engines/gl_common/evas_gl_core.h
@@ -47,7 +47,7 @@ void evgl_direct_info_clear();
47Eina_Bool evgl_native_surface_direct_opts_get(Evas_Native_Surface *ns, 47Eina_Bool evgl_native_surface_direct_opts_get(Evas_Native_Surface *ns,
48 Eina_Bool *direct_render, 48 Eina_Bool *direct_render,
49 Eina_Bool *client_side_rotation, 49 Eina_Bool *client_side_rotation,
50 Eina_Bool *override); 50 Eina_Bool *direct_override);
51 51
52void evgl_direct_partial_info_set(int pres); 52void evgl_direct_partial_info_set(int pres);
53void evgl_direct_partial_info_clear(); 53void evgl_direct_partial_info_clear();
diff --git a/src/modules/evas/engines/gl_generic/evas_engine.c b/src/modules/evas/engines/gl_generic/evas_engine.c
index 81361beb7d..3f199ed59a 100644
--- a/src/modules/evas/engines/gl_generic/evas_engine.c
+++ b/src/modules/evas/engines/gl_generic/evas_engine.c
@@ -28,6 +28,8 @@
28 28
29static int _evas_engine_GL_log_dom = -1; 29static int _evas_engine_GL_log_dom = -1;
30 30
31static int eng_gl_image_direct_get(void *data EINA_UNUSED, void *image);
32
31static void 33static void
32eng_rectangle_draw(void *data, void *context, void *surface, int x, int y, int w, int h, Eina_Bool do_async EINA_UNUSED) 34eng_rectangle_draw(void *data, void *context, void *surface, int x, int y, int w, int h, Eina_Bool do_async EINA_UNUSED)
33{ 35{
@@ -817,10 +819,10 @@ eng_image_draw(void *data, void *context, void *surface, void *image, int src_x,
817 gl_context = re->window_gl_context_get(re->software.ob); 819 gl_context = re->window_gl_context_get(re->software.ob);
818 re->window_use(re->software.ob); 820 re->window_use(re->software.ob);
819 821
820 if ((n) && (n->type == EVAS_NATIVE_SURFACE_OPENGL) && 822 if (eng_gl_image_direct_get(data, image))
821 (n->data.opengl.framebuffer_id == 0) &&
822 re->func.get_pixels)
823 { 823 {
824 unsigned int texid;
825
824 gl_context->dc = context; 826 gl_context->dc = context;
825 if ((gl_context->master_clip.enabled) && 827 if ((gl_context->master_clip.enabled) &&
826 (gl_context->master_clip.w > 0) && 828 (gl_context->master_clip.w > 0) &&
@@ -830,6 +832,16 @@ eng_image_draw(void *data, void *context, void *surface, void *image, int src_x,
830 evgl_direct_partial_info_set(gl_context->preserve_bit); 832 evgl_direct_partial_info_set(gl_context->preserve_bit);
831 } 833 }
832 834
835 if (n->type == EVAS_NATIVE_SURFACE_OPENGL)
836 texid = n->data.opengl.texture_id;
837 else if (n->type == EVAS_NATIVE_SURFACE_X11)
838 texid = n->data.x11.pixmap;
839 else
840 {
841 ERR("This native surface type is not supported for direct rendering");
842 return EINA_FALSE;
843 }
844
833 // Set necessary info for direct rendering 845 // Set necessary info for direct rendering
834 evgl_direct_info_set(gl_context->w, 846 evgl_direct_info_set(gl_context->w,
835 gl_context->h, 847 gl_context->h,
@@ -839,7 +851,7 @@ eng_image_draw(void *data, void *context, void *surface, void *image, int src_x,
839 gl_context->dc->clip.y, 851 gl_context->dc->clip.y,
840 gl_context->dc->clip.w, 852 gl_context->dc->clip.w,
841 gl_context->dc->clip.h, 853 gl_context->dc->clip.h,
842 n->data.opengl.texture_id); 854 texid);
843 855
844 // Call pixel get function 856 // Call pixel get function
845 re->func.get_pixels(re->func.get_pixels_data, re->func.obj); 857 re->func.get_pixels(re->func.get_pixels_data, re->func.obj);
@@ -1533,6 +1545,27 @@ eng_gl_surface_query(void *data, void *surface, int attr, void *value)
1533#endif 1545#endif
1534} 1546}
1535 1547
1548static int
1549eng_gl_image_direct_get(void *data EINA_UNUSED, void *image)
1550{
1551 Evas_GL_Image *im = image;
1552 if (!im) return EINA_FALSE;
1553 return im->direct;
1554}
1555
1556static void
1557eng_gl_image_direct_set(void *data, void *image, Eina_Bool direct)
1558{
1559 Render_Engine_GL_Generic *re = data;
1560 Evas_GL_Image *im = image;
1561
1562 if (!im) return;
1563 if (im->native.data && direct && re && re->func.get_pixels)
1564 im->direct = EINA_TRUE;
1565 else
1566 im->direct = EINA_FALSE;
1567}
1568
1536//--------------------------------// 1569//--------------------------------//
1537 1570
1538static int 1571static int
@@ -2114,6 +2147,8 @@ module_open(Evas_Module *em)
2114 // gl_current_context_get is in engine 2147 // gl_current_context_get is in engine
2115 ORD(gl_current_surface_get); 2148 ORD(gl_current_surface_get);
2116 ORD(gl_rotation_angle_get); 2149 ORD(gl_rotation_angle_get);
2150 ORD(gl_image_direct_get);
2151 ORD(gl_image_direct_set);
2117 2152
2118 ORD(image_load_error_get); 2153 ORD(image_load_error_get);
2119 2154
diff --git a/src/modules/evas/engines/software_generic/evas_engine.c b/src/modules/evas/engines/software_generic/evas_engine.c
index b9239979e4..205baad172 100644
--- a/src/modules/evas/engines/software_generic/evas_engine.c
+++ b/src/modules/evas/engines/software_generic/evas_engine.c
@@ -3572,6 +3572,8 @@ static Evas_Func func =
3572 NULL, // need software mesa for gl rendering <- gl_rotation_angle_get 3572 NULL, // need software mesa for gl rendering <- gl_rotation_angle_get
3573 NULL, // need software mesa for gl rendering <- gl_surface_query 3573 NULL, // need software mesa for gl rendering <- gl_surface_query
3574 NULL, // need software mesa for gl rendering <- gl_surface_direct_renderable_get 3574 NULL, // need software mesa for gl rendering <- gl_surface_direct_renderable_get
3575 NULL, // need software mesa for gl rendering <- gl_image_direct_set
3576 NULL, // need software mesa for gl rendering <- gl_image_direct_get
3575 eng_image_load_error_get, 3577 eng_image_load_error_get,
3576 eng_font_run_font_end_get, 3578 eng_font_run_font_end_get,
3577 eng_image_animated_get, 3579 eng_image_animated_get,