raster pushed a commit to branch master.

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

commit a479745e4ffaf0e252a350ffe11de439faebbb67
Author: Carsten Haitzler (Rasterman) <[email protected]>
Date:   Tue Nov 15 11:22:14 2016 +0900

    evas - add a prepare stage for objects before render
    
    preparing an object is a good idea. especially with gl. you want to do
    texture uploads BEFORE using textures all in one batch. otherwise this
    may mean the gl implementation has to make a copy of your data in a
    tmp location then copy it in later when texture becomes "unused" as it
    may be in use at the moment, or it may have to stall and wait.
    
    i have seen somewhere around 7-10% speedups on nvidia and intel
    drivers with this on given a very special test case i brewed up (1000
    32x32 images where i change 1 pixel every frame). this should have
    impact really when we are modifying textures a lot. this is all i've
    implemented for now, but this should/would/could do much more like
    re-order map, proxy renders to render FIRST in a pre-render list
    instead of inline and to pre-render fbo/buffer content for complex
    objects like text or textblock etc.
---
 src/lib/evas/canvas/evas_object_image.c                 | 16 ++++++++++++++++
 src/lib/evas/canvas/evas_object_line.c                  |  1 +
 src/lib/evas/canvas/evas_object_polygon.c               |  1 +
 src/lib/evas/canvas/evas_object_rectangle.c             |  1 +
 src/lib/evas/canvas/evas_object_smart.c                 |  1 +
 src/lib/evas/canvas/evas_object_text.c                  |  1 +
 src/lib/evas/canvas/evas_object_textblock.c             |  1 +
 src/lib/evas/canvas/evas_object_textgrid.c              |  1 +
 src/lib/evas/canvas/evas_object_vg.c                    |  1 +
 src/lib/evas/canvas/evas_render.c                       | 16 +++++++++++++++-
 src/lib/evas/include/evas_private.h                     |  6 ++++++
 src/modules/evas/engines/gl_generic/evas_engine.c       | 12 ++++++++++++
 src/modules/evas/engines/software_generic/evas_engine.c |  9 +++++++++
 13 files changed, 66 insertions(+), 1 deletion(-)

diff --git a/src/lib/evas/canvas/evas_object_image.c 
b/src/lib/evas/canvas/evas_object_image.c
index 77a5a05..c2b923f 100644
--- a/src/lib/evas/canvas/evas_object_image.c
+++ b/src/lib/evas/canvas/evas_object_image.c
@@ -51,6 +51,7 @@ static int evas_object_image_get_opaque_rect(Evas_Object 
*eo_obj,
                                             void *type_private_data,
                                             Evas_Coord *x, Evas_Coord *y, 
Evas_Coord *w, Evas_Coord *h);
 static int evas_object_image_can_map(Evas_Object *eo_obj);
+static void evas_object_image_render_prepare(Evas_Object *obj, 
Evas_Object_Protected_Data *pd);
 
 static void evas_object_image_filled_resize_listener(void *data, Evas *eo_e, 
Evas_Object *eo_obj, void *einfo);
 
@@ -78,6 +79,7 @@ static const Evas_Object_Func object_func =
      evas_object_image_has_opaque_rect,
      evas_object_image_get_opaque_rect,
      evas_object_image_can_map,
+     evas_object_image_render_prepare, // render_prepare
      NULL
 };
 
@@ -111,6 +113,20 @@ Eina_Cow *evas_object_image_load_opts_cow = NULL;
 Eina_Cow *evas_object_image_pixels_cow = NULL;
 Eina_Cow *evas_object_image_state_cow = NULL;
 
+static void
+evas_object_image_render_prepare(Evas_Object *eo_obj, 
Evas_Object_Protected_Data *obj)
+{
+   Evas_Image_Data *o = efl_data_scope_get(eo_obj, MY_CLASS);
+
+   // if image data not loaded or in texture then upload
+   if ((o->cur->u.file) || (o->written) || (o->cur->frame != 0))
+     {
+        if (o->engine_data) ENFN->image_prepare(ENDT, o->engine_data);
+        return;
+     }
+   // XXX: if image is a proxy, PREPEND to prerender list in evas canvas
+}
+
 void
 _evas_image_cleanup(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj, 
Evas_Image_Data *o)
 {
diff --git a/src/lib/evas/canvas/evas_object_line.c 
b/src/lib/evas/canvas/evas_object_line.c
index 00d8076..d5fc7b3 100644
--- a/src/lib/evas/canvas/evas_object_line.c
+++ b/src/lib/evas/canvas/evas_object_line.c
@@ -85,6 +85,7 @@ static const Evas_Object_Func object_func =
    NULL,
    NULL,
    NULL,
+   NULL, // render_prepare
    NULL
 };
 
diff --git a/src/lib/evas/canvas/evas_object_polygon.c 
b/src/lib/evas/canvas/evas_object_polygon.c
index 7ed779b..355f6ea 100644
--- a/src/lib/evas/canvas/evas_object_polygon.c
+++ b/src/lib/evas/canvas/evas_object_polygon.c
@@ -75,6 +75,7 @@ static const Evas_Object_Func object_func =
      NULL,
      NULL,
      NULL,
+     NULL, // render_prepare
      NULL
 };
 
diff --git a/src/lib/evas/canvas/evas_object_rectangle.c 
b/src/lib/evas/canvas/evas_object_rectangle.c
index 50a9248..6c0fe9e 100644
--- a/src/lib/evas/canvas/evas_object_rectangle.c
+++ b/src/lib/evas/canvas/evas_object_rectangle.c
@@ -83,6 +83,7 @@ static const Evas_Object_Func object_func =
      NULL,
      NULL,
      NULL,
+     NULL, // render_prepare
      evas_object_rectangle_render2_walk
 };
 
diff --git a/src/lib/evas/canvas/evas_object_smart.c 
b/src/lib/evas/canvas/evas_object_smart.c
index 4689951..51338c5 100644
--- a/src/lib/evas/canvas/evas_object_smart.c
+++ b/src/lib/evas/canvas/evas_object_smart.c
@@ -119,6 +119,7 @@ static const Evas_Object_Func object_func =
    NULL,
    NULL,
    NULL,
+   NULL, // render_prepare
    NULL
 };
 
diff --git a/src/lib/evas/canvas/evas_object_text.c 
b/src/lib/evas/canvas/evas_object_text.c
index 2e8c2f7..fbd9b24 100644
--- a/src/lib/evas/canvas/evas_object_text.c
+++ b/src/lib/evas/canvas/evas_object_text.c
@@ -143,6 +143,7 @@ static const Evas_Object_Func object_func =
      NULL,
      NULL,
      NULL,
+     NULL, // render_prepare
      NULL
 };
 
diff --git a/src/lib/evas/canvas/evas_object_textblock.c 
b/src/lib/evas/canvas/evas_object_textblock.c
index 29d8cb9..6451d7b 100644
--- a/src/lib/evas/canvas/evas_object_textblock.c
+++ b/src/lib/evas/canvas/evas_object_textblock.c
@@ -622,6 +622,7 @@ static const Evas_Object_Func object_func =
      NULL,
      NULL,
      NULL,
+     NULL, // render_prepare
      NULL
 };
 
diff --git a/src/lib/evas/canvas/evas_object_textgrid.c 
b/src/lib/evas/canvas/evas_object_textgrid.c
index 1942a4c..e98be12 100644
--- a/src/lib/evas/canvas/evas_object_textgrid.c
+++ b/src/lib/evas/canvas/evas_object_textgrid.c
@@ -144,6 +144,7 @@ static const Evas_Object_Func object_func =
    NULL,
    NULL,
    NULL,
+   NULL, // render_prepare
    NULL
 };
 
diff --git a/src/lib/evas/canvas/evas_object_vg.c 
b/src/lib/evas/canvas/evas_object_vg.c
index 5617f9f..ae89f1a 100644
--- a/src/lib/evas/canvas/evas_object_vg.c
+++ b/src/lib/evas/canvas/evas_object_vg.c
@@ -57,6 +57,7 @@ static const Evas_Object_Func object_func =
      NULL,
      NULL,
      NULL,
+     NULL, // render_prepare
      NULL
 };
 
diff --git a/src/lib/evas/canvas/evas_render.c 
b/src/lib/evas/canvas/evas_render.c
index e1542fa..a807278 100644
--- a/src/lib/evas/canvas/evas_render.c
+++ b/src/lib/evas/canvas/evas_render.c
@@ -2725,7 +2725,16 @@ evas_render_updates_internal(Evas *eo_e,
         e->engine.func->output_redraws_rect_del(e->engine.data.output,
                                                 r->x, r->y, r->w, r->h);
      }
-   /* build obscure objects list of active objects that obscure */
+
+   static int prepare = -1;
+   if (prepare == -1)
+     {
+        if (getenv("EVAS_PREPARE")) prepare = !!atoi(getenv("EVAS_PREPARE"));
+        else prepare = 1;
+     }
+   /* build obscure objects list of active objects that obscure as well
+    * as objects that may need data (image data loads, texture updates,
+    * pre-render buffers/fbo's etc.) that are not up to date yet */
    for (i = 0; i < e->active_objects.count; ++i)
      {
         obj = eina_array_data_get(&e->active_objects, i);
@@ -2742,6 +2751,11 @@ evas_render_updates_internal(Evas *eo_e,
                      (!obj->is_smart)))
           /*     obscuring_objects = eina_list_append(obscuring_objects, obj); 
*/
           OBJ_ARRAY_PUSH(&e->obscuring_objects, obj);
+        if (prepare)
+          {
+             if (obj->func->render_prepare)
+               obj->func->render_prepare(eo_obj, obj);
+          }
      }
    eina_evlog("-render_phase5", eo_e, 0.0, NULL);
 
diff --git a/src/lib/evas/include/evas_private.h 
b/src/lib/evas/include/evas_private.h
index 65e7023..398109c 100644
--- a/src/lib/evas/include/evas_private.h
+++ b/src/lib/evas/include/evas_private.h
@@ -1289,6 +1289,10 @@ struct _Evas_Object_Func
                            Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, 
Evas_Coord *h);
 
    int (*can_map) (Evas_Object *obj);
+// new - add to prepare list during render if object needs some pre-render
+// preparation - may include rendering content to buffer or loading data
+// from disk or uploading to texture etc.
+   void (*render_prepare) (Evas_Object *obj, Evas_Object_Protected_Data *pd);
 
 // new render2 functions
 
@@ -1384,6 +1388,8 @@ struct _Evas_Func
    /* new api for direct data set (not put) */
    void *(*image_data_slice_add)           (void *data, void *image, const 
Eina_Slice *slice, Eina_Bool copy, int w, int h, int stride, Evas_Colorspace 
space, int plane, Eina_Bool alpha);
 
+   void (*image_prepare)                   (void *data, void *image);
+
    int (*image_native_init)                (void *data, 
Evas_Native_Surface_Type type);
    void (*image_native_shutdown)           (void *data, 
Evas_Native_Surface_Type type);
    void *(*image_native_set)               (void *data, void *image, void 
*native);
diff --git a/src/modules/evas/engines/gl_generic/evas_engine.c 
b/src/modules/evas/engines/gl_generic/evas_engine.c
index 8cff9b9..09cc24b 100644
--- a/src/modules/evas/engines/gl_generic/evas_engine.c
+++ b/src/modules/evas/engines/gl_generic/evas_engine.c
@@ -3089,6 +3089,16 @@ fail:
    return NULL;
 }
 
+static void
+eng_image_prepare(void *engdata EINA_UNUSED, void *image)
+{
+   Evas_GL_Image *im = image;
+
+   if (!im) return;
+   evas_gl_common_image_update(im->gc, im);
+}
+
+
 static int
 module_open(Evas_Module *em)
 {
@@ -3174,6 +3184,8 @@ module_open(Evas_Module *em)
    ORD(image_data_maps_get);
    ORD(image_data_slice_add);
 
+   ORD(image_prepare);
+
    ORD(font_cache_flush);
    ORD(font_cache_set);
    ORD(font_cache_get);
diff --git a/src/modules/evas/engines/software_generic/evas_engine.c 
b/src/modules/evas/engines/software_generic/evas_engine.c
index baf3e46..0ea4cf2 100644
--- a/src/modules/evas/engines/software_generic/evas_engine.c
+++ b/src/modules/evas/engines/software_generic/evas_engine.c
@@ -1938,6 +1938,14 @@ fail:
 }
 
 static void
+eng_image_prepare(void *engdata EINA_UNUSED, void *image EINA_UNUSED)
+{
+   // software rendering doesnt want/need to prepare at this point
+   // XXX: though this could push along any loading threads or start
+   // some thread jobs for loading in the bg.
+}
+
+static void
 _image_flip_horizontal(DATA32 *pixels_out, const DATA32 *pixels_in,
                        int iw, int ih)
 {
@@ -4649,6 +4657,7 @@ static Evas_Func func =
      eng_image_data_unmap,
      eng_image_data_maps_get,
      eng_image_data_slice_add,
+     eng_image_prepare,
      eng_image_native_init,
      eng_image_native_shutdown,
      eng_image_native_set,

-- 


Reply via email to