jpeg pushed a commit to branch master.

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

commit a6951397f619d5f5c2491ec75f26b2facae476ff
Author: Jean-Philippe Andre <jp.an...@samsung.com>
Date:   Fri Feb 10 16:08:58 2017 +0900

    evas: Optimize redraws of snapshot objects
    
    If anything in the canvas needs redraw and a snapshot object
    happens to intersect with the update region then it was redrawn,
    even if all objects below it hadn't changed. This has an insane
    performance impact when you apply a blur filter on the snapshot
    object. Walking the object list will always be cheaper than
    rendering the snapshot!
    
    Note: Added a FIXME comment and forced clean_them to be true
    because some odd behaviour happens when breaking with GDB and
    the array snapshot_objects keeps growing at each frame (I guess
    only if we miss a frame or something like that).
---
 src/lib/evas/canvas/evas_object_image.c | 11 +++++++---
 src/lib/evas/canvas/evas_render.c       | 39 +++++++++++++++++++++++++++++----
 src/lib/evas/include/evas_private.h     |  2 +-
 3 files changed, 44 insertions(+), 8 deletions(-)

diff --git a/src/lib/evas/canvas/evas_object_image.c 
b/src/lib/evas/canvas/evas_object_image.c
index 641e8a4..a3f7e48 100644
--- a/src/lib/evas/canvas/evas_object_image.c
+++ b/src/lib/evas/canvas/evas_object_image.c
@@ -3567,9 +3567,9 @@ _evas_object_image_video_overlay_do(Evas_Object *eo_obj)
 }
 
 void *
-_evas_object_image_surface_get(Evas_Object *eo, Evas_Object_Protected_Data 
*obj)
+_evas_object_image_surface_get(Evas_Object_Protected_Data *obj, Eina_Bool 
create)
 {
-   Evas_Image_Data *pd = efl_data_scope_get(eo, MY_CLASS);
+   Evas_Image_Data *pd = obj->private_data;
 
    if (pd->engine_data &&
        (pd->cur->image.w == obj->cur->geometry.w) &&
@@ -3577,7 +3577,12 @@ _evas_object_image_surface_get(Evas_Object *eo, 
Evas_Object_Protected_Data *obj)
      return pd->engine_data;
 
    if (pd->engine_data)
-     ENFN->image_free(ENDT, pd->engine_data);
+     {
+        ENFN->image_free(ENDT, pd->engine_data);
+        pd->engine_data = NULL;
+     }
+
+   if (!create) return pd->engine_data;
 
    // FIXME: alpha forced to 1 for now, need to figure out Evas alpha here
    EINA_COW_IMAGE_STATE_WRITE_BEGIN(pd, state_write)
diff --git a/src/lib/evas/canvas/evas_render.c 
b/src/lib/evas/canvas/evas_render.c
index 5de9847..a13c693 100644
--- a/src/lib/evas/canvas/evas_render.c
+++ b/src/lib/evas/canvas/evas_render.c
@@ -2738,6 +2738,31 @@ _is_obj_in_rect(Evas_Object *eo_obj, 
Evas_Object_Protected_Data *obj,
 #endif
 
 static Eina_Bool
+_snapshot_needs_redraw(Evas_Public_Data *evas, Evas_Object_Protected_Data 
*snap)
+{
+   const int x = snap->cur->geometry.x;
+   const int y = snap->cur->geometry.y;
+   const int w = snap->cur->geometry.w;
+   const int h = snap->cur->geometry.h;
+   Evas_Object_Protected_Data *obj;
+   Evas_Active_Entry *ent;
+   void *surface;
+
+   surface = _evas_object_image_surface_get(snap, EINA_FALSE);
+   if (!surface) return EINA_TRUE;
+
+   EINA_INARRAY_FOREACH(&evas->active_objects, ent)
+     {
+        obj = ent->obj;
+        if (obj == snap) break;
+        if (!obj->is_smart && obj->changed &&
+            evas_object_is_in_output_rect(obj->object, obj, x, y, w, h))
+          return EINA_TRUE;
+     }
+   return EINA_FALSE;
+}
+
+static Eina_Bool
 evas_render_updates_internal_loop(Evas *eo_e, Evas_Public_Data *evas,
                                   void *surface, void *context,
                                   Evas_Object_Protected_Data *top,
@@ -3089,7 +3114,7 @@ evas_render_updates_internal(Evas *eo_e,
      {
         for (i = 0; i < e->snapshot_objects.count; i++)
           {
-             obj = (Evas_Object_Protected_Data 
*)eina_array_data_get(&e->snapshot_objects, i);
+             obj = eina_array_data_get(&e->snapshot_objects, i);
 
              if (evas_object_is_visible(obj->object, obj))
                ENFN->output_redraws_rect_add(ENDT,
@@ -3173,7 +3198,7 @@ evas_render_updates_internal(Evas *eo_e,
                {
                   Eina_Rectangle output, cr, ur;
 
-                  obj = (Evas_Object_Protected_Data 
*)eina_array_data_get(&e->snapshot_objects, j);
+                  obj = eina_array_data_get(&e->snapshot_objects, j);
 
                   EINA_RECTANGLE_SET(&output,
                                      obj->cur->geometry.x,
@@ -3182,7 +3207,8 @@ evas_render_updates_internal(Evas *eo_e,
                                      obj->cur->geometry.h);
                   EINA_RECTANGLE_SET(&ur, ux, uy, uw, uh);
 
-                  if (eina_rectangle_intersection(&ur, &output))
+                  if (eina_rectangle_intersection(&ur, &output) &&
+                      _snapshot_needs_redraw(evas, obj))
                     {
                        void *pseudo_canvas;
                        unsigned int restore_offset = offset;
@@ -3191,7 +3217,7 @@ evas_render_updates_internal(Evas *eo_e,
                                           ur.x - output.x, ur.y - output.y,
                                           ur.w, ur.h);
 
-                       pseudo_canvas = 
_evas_object_image_surface_get(obj->object, obj);
+                       pseudo_canvas = _evas_object_image_surface_get(obj, 
EINA_TRUE);
 
                        RD(0, "  SNAPSHOT %s [sfc:%p ur:%d,%d %dx%d]\n", 
RDNAME(obj), pseudo_canvas, ur.x, ur.y, ur.w, ur.h);
                        ctx = ENFN->context_new(ENDT);
@@ -3209,6 +3235,11 @@ evas_render_updates_internal(Evas *eo_e,
                        obj->changed = EINA_TRUE;
 
                        offset = restore_offset;
+
+                       // FIXME: For some reason the arrays are not cleaned and
+                       // snapshot objects keep being added to it... only when
+                       // I break in GDB. Normal render flow is fine. Odd.
+                       clean_them = EINA_TRUE;
                     }
                }
              eina_evlog("-render_snapshots", eo_e, 0.0, NULL);
diff --git a/src/lib/evas/include/evas_private.h 
b/src/lib/evas/include/evas_private.h
index f3d74d2..02e14f2 100644
--- a/src/lib/evas/include/evas_private.h
+++ b/src/lib/evas/include/evas_private.h
@@ -2033,7 +2033,7 @@ void *efl_input_hold_legacy_info_fill(Efl_Input_Hold 
*evt, Evas_Event_Flags **pf
 
 Eina_Bool evas_vg_loader_svg(Evas_Object *vg, const Eina_File *f, const char 
*key EINA_UNUSED);
 
-void *_evas_object_image_surface_get(Evas_Object *eo, 
Evas_Object_Protected_Data *obj);
+void *_evas_object_image_surface_get(Evas_Object_Protected_Data *obj, 
Eina_Bool create);
 Eina_Bool _evas_image_proxy_source_clip_get(const Eo *eo_obj);
 
 void _evas_focus_dispatch_event(Evas_Object_Protected_Data *obj,

-- 


Reply via email to