jpeg pushed a commit to branch master.

http://git.enlightenment.org/core/efl.git/commit/?id=a14492ef73c9267042c5bf505080d0e90af394de

commit a14492ef73c9267042c5bf505080d0e90af394de
Author: Jean-Philippe Andre <jp.an...@samsung.com>
Date:   Tue Mar 3 16:38:52 2015 +0900

    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
---
 src/lib/evas/canvas/evas_object_image.c            | 37 +++++++---
 src/lib/evas/include/evas_private.h                |  2 +
 .../evas/engines/gl_common/evas_gl_common.h        |  1 +
 src/modules/evas/engines/gl_common/evas_gl_core.c  | 81 +++++++++++++++-------
 src/modules/evas/engines/gl_common/evas_gl_core.h  |  2 +-
 src/modules/evas/engines/gl_generic/evas_engine.c  | 43 ++++++++++--
 .../evas/engines/software_generic/evas_engine.c    |  2 +
 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 63f777f..e4aa448 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,
              if (ENFN->image_native_get)
                {
                   Evas_Native_Surface *ns;
+
                   ns = ENFN->image_native_get(ENDT, o->engine_data);
-                  if ( (ns) &&
-                       (ns->type == EVAS_NATIVE_SURFACE_OPENGL) &&
-                       (ns->data.opengl.texture_id) &&
-                       (!ns->data.opengl.framebuffer_id) )
+                  if (ns)
                     {
                        Eina_Bool direct_renderable = EINA_FALSE;
 
@@ -2880,6 +2878,8 @@ evas_process_dirty_pixels(Evas_Object *eo_obj, 
Evas_Object_Protected_Data *obj,
                          {
                             if (ENFN->gl_get_pixels_set)
                               ENFN->gl_get_pixels_set(output, 
o->pixels->func.get_pixels, o->pixels->func.get_pixels_data, eo_obj);
+                            if (ENFN->gl_image_direct_set)
+                              ENFN->gl_image_direct_set(output, 
o->engine_data, EINA_TRUE);
                             o->direct_render = EINA_TRUE;
                          }
                        else
@@ -2919,9 +2919,28 @@ evas_process_dirty_pixels(Evas_Object *eo_obj, 
Evas_Object_Protected_Data *obj,
    else
      {
         // Check if the it's not dirty but it has direct rendering
-        if (o->direct_render)
+        if (o->direct_render && ENFN->image_native_get)
           {
-             ENFN->gl_get_pixels_set(output, o->pixels->func.get_pixels, 
o->pixels->func.get_pixels_data, eo_obj);
+             Evas_Native_Surface *ns;
+             ns = ENFN->image_native_get(output, o->engine_data);
+             if (ENFN->gl_direct_override_get)
+               ENFN->gl_direct_override_get(output, &direct_override, 
&direct_force_off);
+             if (ENFN->gl_surface_direct_renderable_get)
+               ENFN->gl_surface_direct_renderable_get(output, ns, 
&direct_override);
+
+             if (direct_override && !direct_force_off)
+               {
+                  // always use direct rendering
+                  ENFN->gl_get_pixels_set(output, o->pixels->func.get_pixels, 
o->pixels->func.get_pixels_data, eo_obj);
+               }
+             else
+               {
+                  // Auto-fallback to FBO rendering (for perf & power 
consumption)
+                  o->pixels->func.get_pixels(o->pixels->func.get_pixels_data, 
obj->object);
+                  //if (ENFN->get_pixels_render_post)
+                    //ENFN->get_pixels_render_post(output);
+                  o->direct_render = EINA_FALSE;
+               }
           }
      }
 
@@ -3019,9 +3038,9 @@ evas_object_image_render(Evas_Object *eo_obj, 
Evas_Object_Protected_Data *obj, v
 
    // Clear out the pixel get stuff..
    if (ENFN->gl_get_pixels_set)
-     {
-        ENFN->gl_get_pixels_set(output, NULL, NULL, NULL);
-     }
+     ENFN->gl_get_pixels_set(output, NULL, NULL, NULL);
+   if (ENFN->gl_image_direct_set)
+     ENFN->gl_image_direct_set(output, o->engine_data, EINA_FALSE);
 
    Evas_Object_Protected_Data *source =
       (o->cur->source ?
diff --git a/src/lib/evas/include/evas_private.h 
b/src/lib/evas/include/evas_private.h
index e01eb38..fe241d2 100644
--- a/src/lib/evas/include/evas_private.h
+++ b/src/lib/evas/include/evas_private.h
@@ -1309,6 +1309,8 @@ struct _Evas_Func
    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 *override);
+   void (*gl_image_direct_set)           (void *data, void *image, Eina_Bool 
direct);
+   int  (*gl_image_direct_get)           (void *data, void *image);
 
    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_common.h 
b/src/modules/evas/engines/gl_common/evas_gl_common.h
index 6a93c2c..3602319 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
    unsigned char    alpha : 1;
    unsigned char    tex_only : 1;
    unsigned char    locked : 1; // gl_surface_lock/unlock
+   unsigned char    direct : 1; // evas gl direct renderable
 };
 
 struct _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 757f4ba..1155e90 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)
 
    if (sfc->direct_fb_opt)
      {
-        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->gles1_indirect)
+          {
+             eina_hash_add(evgl_engine->direct_surfaces, &sfc->color_buf, sfc);
+             DBG("Added tex %d as direct surface: %p", sfc->color_buf, sfc);
+          }
+        else
+          {
+             eina_hash_add(evgl_engine->direct_surfaces, 
&sfc->gles1_sfc_native, sfc);
+             DBG("Added tex %d as direct surface: %p", sfc->gles1_sfc_native, 
sfc);
+          }
      }
 
    if (sfc->direct_fb_opt &&
@@ -2362,7 +2370,7 @@ evgl_make_current(void *eng_data, EVGL_Surface *sfc, 
EVGL_Context *ctx)
         if (dbg) DBG("Surface sfc %p is a normal surface.", sfc);
 
         // Attach fbo and the buffers
-        if ((ctx->current_sfc != sfc) || (ctx != sfc->current_ctx))
+        if ((rsc->current_ctx != ctx) || (ctx->current_sfc != sfc) || 
(rsc->direct.rendered))
           {
              sfc->current_ctx = ctx;
              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)
         return 0;
      }
 
-   ns->type = EVAS_NATIVE_SURFACE_OPENGL;
-   ns->version = EVAS_NATIVE_SURFACE_VERSION;
-   ns->data.opengl.texture_id = sfc->color_buf;
-   ns->data.opengl.framebuffer_id = sfc->color_buf;
-   ns->data.opengl.x = 0;
-   ns->data.opengl.y = 0;
-   ns->data.opengl.w = sfc->w;
-   ns->data.opengl.h = sfc->h;
-
-   if (sfc->direct_fb_opt)
-      ns->data.opengl.framebuffer_id = 0;
+   if (!sfc->gles1_indirect)
+     {
+        ns->type = EVAS_NATIVE_SURFACE_OPENGL;
+        ns->version = EVAS_NATIVE_SURFACE_VERSION;
+        ns->data.opengl.texture_id = sfc->color_buf;
+        ns->data.opengl.framebuffer_id = sfc->color_buf;
+        ns->data.opengl.x = 0;
+        ns->data.opengl.y = 0;
+        ns->data.opengl.w = sfc->w;
+        ns->data.opengl.h = sfc->h;
+     }
+   else
+     {
+        ns->type = EVAS_NATIVE_SURFACE_X11;
+        ns->version = EVAS_NATIVE_SURFACE_VERSION;
+        ns->data.x11.pixmap = (unsigned long)(intptr_t)sfc->gles1_sfc_native;
+        ns->data.x11.visual = sfc->gles1_sfc_visual;
+     }
 
    return 1;
 }
@@ -2503,24 +2518,42 @@ Eina_Bool
 evgl_native_surface_direct_opts_get(Evas_Native_Surface *ns,
                                     Eina_Bool *direct_render,
                                     Eina_Bool *client_side_rotation,
-                                    Eina_Bool *override)
+                                    Eina_Bool *direct_override)
 {
    EVGL_Surface *sfc;
 
-   if (override) *override = EINA_FALSE;
    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;
-   if (!ns || (ns->type != EVAS_NATIVE_SURFACE_OPENGL)) return EINA_FALSE;
-   if (ns->data.opengl.framebuffer_id != 0) return EINA_FALSE;
-   if (ns->data.opengl.texture_id == 0) return EINA_FALSE;
+   if (!ns) return EINA_FALSE;
 
-   sfc = eina_hash_find(evgl_engine->direct_surfaces, 
&ns->data.opengl.texture_id);
-   if (!sfc)
+   if (ns->type == EVAS_NATIVE_SURFACE_OPENGL &&
+       ns->data.opengl.texture_id)
+     {
+        sfc = eina_hash_find(evgl_engine->direct_surfaces, 
&ns->data.opengl.texture_id);
+        if (!sfc)
+          {
+             DBG("Native surface %p (color_buf %d) was not found.",
+                 ns, ns->data.opengl.texture_id);
+             return EINA_FALSE;
+          }
+     }
+   else if (ns->type == EVAS_NATIVE_SURFACE_X11 &&
+            ns->data.x11.pixmap)
+     {
+        sfc = eina_hash_find(evgl_engine->direct_surfaces, 
&ns->data.x11.pixmap);
+        if (!sfc)
+          {
+             DBG("Native surface %p (pixmap %x) was not found.",
+                 ns, ns->data.x11.pixmap);
+             return EINA_FALSE;
+          }
+     }
+   else
      {
-        DBG("Native surface %p (color_buf %d) was not found.",
-            ns, ns->data.opengl.texture_id);
+        ERR("Only EVAS_NATIVE_SURFACE_OPENGL or EVAS_NATIVE_SURFACE_X11 can be 
used for direct rendering");
         return EINA_FALSE;
      }
 
@@ -2532,7 +2565,7 @@ evgl_native_surface_direct_opts_get(Evas_Native_Surface 
*ns,
      }
 
    if (direct_render) *direct_render = sfc->direct_fb_opt;
-   if (override) *override |= sfc->direct_override;
+   if (direct_override) *direct_override |= sfc->direct_override;
    if (client_side_rotation) *client_side_rotation = sfc->client_side_rotation;
    return EINA_TRUE;
 }
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 585c1a3..7eeca5d 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();
 Eina_Bool    evgl_native_surface_direct_opts_get(Evas_Native_Surface *ns,
                                                  Eina_Bool *direct_render,
                                                  Eina_Bool 
*client_side_rotation,
-                                                 Eina_Bool *override);
+                                                 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_generic/evas_engine.c 
b/src/modules/evas/engines/gl_generic/evas_engine.c
index 81361be..3f199ed 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 @@
 
 static int _evas_engine_GL_log_dom = -1;
 
+static int eng_gl_image_direct_get(void *data EINA_UNUSED, void *image);
+
 static void
 eng_rectangle_draw(void *data, void *context, void *surface, int x, int y, int 
w, int h, Eina_Bool do_async EINA_UNUSED)
 {
@@ -817,10 +819,10 @@ eng_image_draw(void *data, void *context, void *surface, 
void *image, int src_x,
    gl_context = re->window_gl_context_get(re->software.ob);
    re->window_use(re->software.ob);
 
-   if ((n) && (n->type == EVAS_NATIVE_SURFACE_OPENGL) &&
-       (n->data.opengl.framebuffer_id == 0) &&
-       re->func.get_pixels)
+   if (eng_gl_image_direct_get(data, image))
      {
+        unsigned int texid;
+
         gl_context->dc = context;
         if ((gl_context->master_clip.enabled) &&
             (gl_context->master_clip.w > 0) &&
@@ -830,6 +832,16 @@ eng_image_draw(void *data, void *context, void *surface, 
void *image, int src_x,
              evgl_direct_partial_info_set(gl_context->preserve_bit);
           }
 
+        if (n->type == EVAS_NATIVE_SURFACE_OPENGL)
+          texid = n->data.opengl.texture_id;
+        else if (n->type == EVAS_NATIVE_SURFACE_X11)
+          texid = n->data.x11.pixmap;
+        else
+          {
+             ERR("This native surface type is not supported for direct 
rendering");
+             return EINA_FALSE;
+          }
+
         // Set necessary info for direct rendering
         evgl_direct_info_set(gl_context->w,
                              gl_context->h,
@@ -839,7 +851,7 @@ eng_image_draw(void *data, void *context, void *surface, 
void *image, int src_x,
                              gl_context->dc->clip.y,
                              gl_context->dc->clip.w,
                              gl_context->dc->clip.h,
-                             n->data.opengl.texture_id);
+                             texid);
 
         // Call pixel get function
         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)
 #endif
 }
 
+static int
+eng_gl_image_direct_get(void *data EINA_UNUSED, void *image)
+{
+   Evas_GL_Image *im = image;
+   if (!im) return EINA_FALSE;
+   return im->direct;
+}
+
+static void
+eng_gl_image_direct_set(void *data, void *image, Eina_Bool direct)
+{
+   Render_Engine_GL_Generic *re = data;
+   Evas_GL_Image *im = image;
+
+   if (!im) return;
+   if (im->native.data && direct && re && re->func.get_pixels)
+     im->direct = EINA_TRUE;
+   else
+     im->direct = EINA_FALSE;
+}
+
 //--------------------------------//
 
 static int
@@ -2114,6 +2147,8 @@ module_open(Evas_Module *em)
    // gl_current_context_get is in engine
    ORD(gl_current_surface_get);
    ORD(gl_rotation_angle_get);
+   ORD(gl_image_direct_get);
+   ORD(gl_image_direct_set);
 
    ORD(image_load_error_get);
 
diff --git a/src/modules/evas/engines/software_generic/evas_engine.c 
b/src/modules/evas/engines/software_generic/evas_engine.c
index b923997..205baad 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 =
      NULL, // need software mesa for gl rendering <- gl_rotation_angle_get
      NULL, // need software mesa for gl rendering <- gl_surface_query
      NULL, // need software mesa for gl rendering <- 
gl_surface_direct_renderable_get
+     NULL, // need software mesa for gl rendering <- gl_image_direct_set
+     NULL, // need software mesa for gl rendering <- gl_image_direct_get
      eng_image_load_error_get,
      eng_font_run_font_end_get,
      eng_image_animated_get,

-- 


Reply via email to