evas vg: optimize vg object internal connections. 32/195832/3
authorHermet Park <hermetpark@gmail.com>
Thu, 20 Dec 2018 05:42:38 +0000 (14:42 +0900)
committerSubhransu Mohanty <sub.mohanty@samsung.com>
Thu, 20 Dec 2018 06:23:14 +0000 (06:23 +0000)
Dectected huge amount of unnecessray internal events triggering
which were signaled via vg nodes.

By events, nodes were connected with each others,
and finally reaches to vg object to update its rendering properly.

However GFX_PATH_CHANGE signal is too commonly triggered for scenarios,
listening and response it is too burdensome.

We acutally don't need to do this if all nodes could share the
vg object. Nodes directly notify vg object to update it.

Next patch will come to remove stupid GFX_PATH_CHANGE that's aweful
in performance wise.

Change-Id: I5b92d2c05986670999b690255b1eb41688c8fb39

src/lib/evas/canvas/efl_canvas_vg_container.c
src/lib/evas/canvas/efl_canvas_vg_container.eo
src/lib/evas/canvas/efl_canvas_vg_gradient.c
src/lib/evas/canvas/efl_canvas_vg_gradient_linear.c
src/lib/evas/canvas/efl_canvas_vg_gradient_radial.c
src/lib/evas/canvas/efl_canvas_vg_node.c
src/lib/evas/canvas/efl_canvas_vg_object.c
src/lib/evas/canvas/efl_canvas_vg_shape.c
src/lib/evas/canvas/evas_vg_private.h

index addbf0c..b733db5 100644 (file)
@@ -286,7 +286,18 @@ _efl_canvas_vg_container_efl_canvas_vg_node_mask_set(Eo *obj,
 
    pd->mask.option = op;
    efl_replace(&pd->mask_src, mask);
-   _efl_canvas_vg_node_changed(obj);
+   efl_canvas_vg_node_change(obj);
+}
+
+static void
+_efl_canvas_vg_container_efl_object_parent_set(Eo *obj,
+                                               Efl_Canvas_Vg_Container_Data *cd,
+                                               Eo *parent)
+{
+   efl_parent_set(efl_super(obj, MY_CLASS), parent);
+
+   Efl_Canvas_Vg_Node_Data *nd = efl_data_scope_get(obj, EFL_CANVAS_VG_NODE_CLASS);
+   efl_canvas_vg_container_vg_obj_update(obj, nd);
 }
 
 EOLIAN static Efl_VG *
@@ -319,6 +330,32 @@ _efl_canvas_vg_container_efl_duplicate_duplicate(const Eo *obj,
    return container;
 }
 
+void
+efl_canvas_vg_container_vg_obj_update(Efl_VG *obj, Efl_Canvas_Vg_Node_Data *nd)
+{
+   if (!obj) return;
+
+   Efl_Canvas_Vg_Container_Data *cd = efl_data_scope_get(obj, MY_CLASS);
+   if (!cd) return;
+
+   Eina_List *l;
+   Efl_VG* child;
+
+   EINA_LIST_FOREACH(cd->children, l, child)
+     {
+        Efl_Canvas_Vg_Node_Data *child_nd =
+           efl_data_scope_get(child, EFL_CANVAS_VG_NODE_CLASS);
+
+        if (child_nd->vg_obj == nd->vg_obj) continue;
+
+        child_nd->vg_obj = nd->vg_obj;
+        child_nd->vd = nd->vd;
+
+        if (efl_isa(child, MY_CLASS))
+          efl_canvas_vg_container_vg_obj_update(child, child_nd);
+     }
+}
+
 EAPI Efl_VG*
 evas_vg_container_add(Efl_VG *parent)
 {
index 4060441..3d26efd 100644 (file)
@@ -18,6 +18,7 @@ class Efl.Canvas.Vg.Container (Efl.Canvas.Vg.Node)
    implements {
       Efl.Object.constructor;
       Efl.Object.destructor;
+      Efl.Object.parent { set; }
       Efl.Gfx.Path.bounds_get;
       Efl.Gfx.Path.interpolate;
       Efl.Duplicate.duplicate;
index 649643b..ad6761b 100644 (file)
@@ -23,7 +23,7 @@ _efl_canvas_vg_gradient_efl_gfx_gradient_stop_set(Eo *obj EINA_UNUSED,
    memcpy(pd->colors, colors, length * sizeof(Efl_Gfx_Gradient_Stop));
    pd->colors_count = length;
 
-   _efl_canvas_vg_node_changed(obj);
+   efl_canvas_vg_node_change(obj);
 }
 
 static void
@@ -43,7 +43,7 @@ _efl_canvas_vg_gradient_efl_gfx_gradient_spread_set(Eo *obj EINA_UNUSED,
 {
    pd->spread = spread;
 
-   _efl_canvas_vg_node_changed(obj);
+   efl_canvas_vg_node_change(obj);
 }
 
 static Efl_Gfx_Gradient_Spread
index fa35d29..ad3118f 100644 (file)
@@ -23,7 +23,7 @@ _efl_canvas_vg_gradient_linear_efl_gfx_gradient_linear_start_set(Eo *obj EINA_UN
    pd->start.x = x;
    pd->start.y = y;
 
-   _efl_canvas_vg_node_changed(obj);
+   efl_canvas_vg_node_change(obj);
 }
 
 static void
@@ -43,7 +43,7 @@ _efl_canvas_vg_gradient_linear_efl_gfx_gradient_linear_end_set(Eo *obj EINA_UNUS
    pd->end.x = x;
    pd->end.y = y;
 
-   _efl_canvas_vg_node_changed(obj);
+   efl_canvas_vg_node_change(obj);
 }
 
 static void
index 9ff537e..4146cdd 100644 (file)
@@ -22,7 +22,7 @@ _efl_canvas_vg_gradient_radial_efl_gfx_gradient_radial_center_set(Eo *obj EINA_U
    pd->center.x = x;
    pd->center.y = y;
 
-   _efl_canvas_vg_node_changed(obj);
+   efl_canvas_vg_node_change(obj);
 }
 
 static void
@@ -41,7 +41,7 @@ _efl_canvas_vg_gradient_radial_efl_gfx_gradient_radial_radius_set(Eo *obj EINA_U
 {
    pd->radius = r;
 
-   _efl_canvas_vg_node_changed(obj);
+   efl_canvas_vg_node_change(obj);
 }
 
 static double
@@ -59,7 +59,7 @@ _efl_canvas_vg_gradient_radial_efl_gfx_gradient_radial_focal_set(Eo *obj EINA_UN
    pd->focal.x = x;
    pd->focal.y = y;
 
-   _efl_canvas_vg_node_changed(obj);
+   efl_canvas_vg_node_change(obj);
 }
 
 static void
index dc2c4a3..e5cc6c9 100644 (file)
@@ -17,22 +17,26 @@ static const Efl_Canvas_Vg_Interpolation interpolation_identity = {
 };
 
 static void
-_efl_canvas_vg_node_property_changed(void *data, const Efl_Event *event EINA_UNUSED)
+_node_change(Efl_VG *obj, Efl_Canvas_Vg_Node_Data *nd)
 {
-   Efl_Canvas_Vg_Node_Data *pd = data;
-   Eo *parent;
+   if (nd->flags != EFL_GFX_CHANGE_FLAG_NONE) return;
+   nd->flags = EFL_GFX_CHANGE_FLAG_ALL;
 
-   if (!pd->flags) pd->flags = EFL_GFX_CHANGE_FLAG_ALL;
+   Eo *p = obj;
+   while ((p = efl_parent_get(p)))
+     {
+        Efl_Canvas_Vg_Node_Data *pnd = efl_data_scope_get(p, MY_CLASS);
+        if (!pnd || (pnd->flags != EFL_GFX_CHANGE_FLAG_NONE)) break;
+        pnd->flags = EFL_GFX_CHANGE_FLAG_ALL;
+     }
 
-   if (efl_invalidated_get(event->object)) return;
-   parent = efl_parent_get(event->object);
-   efl_event_callback_call(parent, event->desc, event->info);
+   efl_canvas_vg_object_change(nd->vd);
 }
 
 static void
 _efl_canvas_vg_node_transformation_set(Eo *obj,
-                                Efl_Canvas_Vg_Node_Data *pd,
-                                const Eina_Matrix3 *m)
+                                       Efl_Canvas_Vg_Node_Data *pd,
+                                       const Eina_Matrix3 *m)
 {
    if (pd->intp)
      {
@@ -56,7 +60,7 @@ _efl_canvas_vg_node_transformation_set(Eo *obj,
      }
 
    pd->flags |= EFL_GFX_CHANGE_FLAG_MATRIX;
-   _efl_canvas_vg_node_changed(obj);
+   _node_change(obj, pd);
 }
 
 const Eina_Matrix3 *
@@ -75,13 +79,13 @@ _efl_canvas_vg_node_mask_set(Eo *obj EINA_UNUSED,
 
 static void
 _efl_canvas_vg_node_origin_set(Eo *obj,
-                        Efl_Canvas_Vg_Node_Data *pd,
-                        double x, double y)
+                               Efl_Canvas_Vg_Node_Data *pd,
+                               double x, double y)
 {
    pd->x = x;
    pd->y = y;
 
-   _efl_canvas_vg_node_changed(obj);
+   _node_change(obj, pd);
 }
 
 static void
@@ -94,12 +98,14 @@ _efl_canvas_vg_node_origin_get(const Eo *obj EINA_UNUSED,
 }
 
 static void
-_efl_canvas_vg_node_efl_gfx_entity_position_set(Eo *obj EINA_UNUSED, Efl_Canvas_Vg_Node_Data *pd, Eina_Position2D pos)
+_efl_canvas_vg_node_efl_gfx_entity_position_set(Eo *obj,
+                                                Efl_Canvas_Vg_Node_Data *pd,
+                                                Eina_Position2D pos)
 {
    pd->x = (double) pos.x;
    pd->y = (double) pos.y;
 
-   _efl_canvas_vg_node_changed(obj);
+   _node_change(obj, pd);
 }
 
 static Eina_Position2D
@@ -110,12 +116,13 @@ _efl_canvas_vg_node_efl_gfx_entity_position_get(const Eo *obj EINA_UNUSED, Efl_C
 }
 
 static void
-_efl_canvas_vg_node_efl_gfx_entity_visible_set(Eo *obj EINA_UNUSED,
-                                      Efl_Canvas_Vg_Node_Data *pd, Eina_Bool v)
+_efl_canvas_vg_node_efl_gfx_entity_visible_set(Eo *obj,
+                                               Efl_Canvas_Vg_Node_Data *pd,
+                                               Eina_Bool v)
 {
    pd->visibility = v;
 
-   _efl_canvas_vg_node_changed(obj);
+   _node_change(obj, pd);
 }
 
 
@@ -127,9 +134,9 @@ _efl_canvas_vg_node_efl_gfx_entity_visible_get(const Eo *obj EINA_UNUSED,
 }
 
 static void
-_efl_canvas_vg_node_efl_gfx_color_color_set(Eo *obj EINA_UNUSED,
-                                    Efl_Canvas_Vg_Node_Data *pd,
-                                    int r, int g, int b, int a)
+_efl_canvas_vg_node_efl_gfx_color_color_set(Eo *obj,
+                                            Efl_Canvas_Vg_Node_Data *pd,
+                                            int r, int g, int b, int a)
 {
    if (r > 255) r = 255;
    if (r < 0) r = 0;
@@ -160,7 +167,7 @@ _efl_canvas_vg_node_efl_gfx_color_color_set(Eo *obj EINA_UNUSED,
    pd->b = b;
    pd->a = a;
 
-   _efl_canvas_vg_node_changed(obj);
+   _node_change(obj, pd);
 }
 
 static void
@@ -217,7 +224,7 @@ _efl_canvas_vg_node_parent_checked_get(Eo *obj,
 
 static Eo *
 _efl_canvas_vg_node_efl_object_constructor(Eo *obj,
-                                           Efl_Canvas_Vg_Node_Data *pd)
+                                           Efl_Canvas_Vg_Node_Data *nd)
 {
    Efl_Canvas_Vg_Container_Data *cd;
    Eo *parent;
@@ -230,10 +237,16 @@ _efl_canvas_vg_node_efl_object_constructor(Eo *obj,
         return NULL;
      }
 
-   efl_event_callback_add(obj, EFL_GFX_PATH_EVENT_CHANGED,
-                          _efl_canvas_vg_node_property_changed, pd);
-   pd->flags = EFL_GFX_CHANGE_FLAG_ALL;
-   pd->changed = EINA_TRUE;
+   if (parent)
+     {
+        Efl_Canvas_Vg_Node_Data *parent_nd =
+           efl_data_scope_get(parent, MY_CLASS);
+        nd->vg_obj = parent_nd->vg_obj;
+        nd->vd = parent_nd->vd;
+     }
+
+   nd->flags = EFL_GFX_CHANGE_FLAG_ALL;
+   nd->changed = EINA_TRUE;
 
    return obj;
 }
@@ -307,40 +320,31 @@ _efl_canvas_vg_node_efl_object_name_set(Eo *obj, Efl_Canvas_Vg_Node_Data *pd EIN
 
 static void
 _efl_canvas_vg_node_efl_object_parent_set(Eo *obj,
-                                Efl_Canvas_Vg_Node_Data *pd EINA_UNUSED,
-                                Eo *parent)
+                                          Efl_Canvas_Vg_Node_Data *nd,
+                                          Eo *parent)
 {
    Efl_Canvas_Vg_Container_Data *cd = NULL;
    Efl_Canvas_Vg_Container_Data *old_cd;
-   Efl_Canvas_Vg_Node_Data *nd;
    Efl_VG *old_parent;
-   Eina_Bool parent_container = EINA_TRUE;
-
-   nd = efl_data_scope_get(obj, MY_CLASS);
-
-   //No, prevent infinite calls parent_set() -> root_node_set() -> parent_set() -> ...
-   if (nd->parenting) return;
-
-   //Cut off root node from vg object if it does....
-   if (nd->vg_obj)
-     {
-        nd->parenting = EINA_TRUE;
-        evas_object_vg_root_node_set(nd->vg_obj, NULL);
-        nd->parenting = EINA_FALSE;
-        nd->vg_obj = NULL;
-     }
 
    if (efl_isa(parent, EFL_CANVAS_VG_CONTAINER_CLASS))
      cd = efl_data_scope_get(parent, EFL_CANVAS_VG_CONTAINER_CLASS);
    else if (efl_isa(parent, EFL_CANVAS_VG_OBJECT_CLASS))
-     parent_container = EINA_FALSE;
+     {
+        if (nd->vg_obj != parent)
+          {
+             nd->vg_obj = parent;
+             nd->vd = efl_data_scope_get(parent, EFL_CANVAS_VG_OBJECT_CLASS);
+             efl_canvas_vg_container_vg_obj_update(obj, nd);
+          }
+
+     }
    else if (parent)
      {
         ERR("parent(%p, class = %s) is not allowed by vg node(%p).",
             parent, efl_class_name_get(efl_class_get(parent)), obj);
         return;
      }
-   else parent_container = EINA_FALSE;
 
    if (!_efl_canvas_vg_node_parent_checked_get(obj, &old_parent, &old_cd))
      return;
@@ -350,6 +354,7 @@ _efl_canvas_vg_node_efl_object_parent_set(Eo *obj,
      {
         old_cd->children = eina_list_remove(old_cd->children, obj);
         eina_hash_del(old_cd->names, efl_name_get(efl_super(obj, MY_CLASS)), obj);
+        _node_change(old_parent, efl_data_scope_get(old_parent, MY_CLASS));
      }
 
    efl_parent_set(efl_super(obj, MY_CLASS), parent);
@@ -358,11 +363,19 @@ _efl_canvas_vg_node_efl_object_parent_set(Eo *obj,
      {
         cd->children = eina_list_append(cd->children, obj);
         _efl_canvas_vg_node_name_insert(obj, cd);
+
+        Efl_Canvas_Vg_Node_Data *parent_nd = efl_data_scope_get(parent, MY_CLASS);
+        _node_change(parent, parent_nd);
+
+        if (nd->vg_obj != parent_nd->vg_obj)
+          {
+             nd->vg_obj = parent_nd->vg_obj;
+             nd->vd = parent_nd->vd;
+             efl_canvas_vg_container_vg_obj_update(obj, nd);
+          }
      }
 
-   _efl_canvas_vg_node_changed(old_parent);
-   _efl_canvas_vg_node_changed(obj);
-   if (parent_container) _efl_canvas_vg_node_changed(parent);
+   _node_change(obj, nd);
 }
 
 static void
@@ -386,8 +399,8 @@ _efl_canvas_vg_node_efl_gfx_stack_raise(Eo *obj, Efl_Canvas_Vg_Node_Data *pd EIN
    cd->children = eina_list_remove_list(cd->children, lookup);
    cd->children = eina_list_append_relative_list(cd->children, obj, next);
 
-   _efl_canvas_vg_node_changed(parent);
-   return ;
+   _node_change(parent, efl_data_scope_get(parent, MY_CLASS));
+   return;
 
  on_error:
    ERR("Err");
@@ -395,8 +408,8 @@ _efl_canvas_vg_node_efl_gfx_stack_raise(Eo *obj, Efl_Canvas_Vg_Node_Data *pd EIN
 
 static void
 _efl_canvas_vg_node_efl_gfx_stack_stack_above(Eo *obj,
-                                       Efl_Canvas_Vg_Node_Data *pd EINA_UNUSED,
-                                       Efl_Gfx_Stack *above)
+                                              Efl_Canvas_Vg_Node_Data *pd EINA_UNUSED,
+                                              Efl_Gfx_Stack *above)
 {
    Efl_Canvas_Vg_Container_Data *cd;
    Eina_List *lookup, *ref;
@@ -416,8 +429,8 @@ _efl_canvas_vg_node_efl_gfx_stack_stack_above(Eo *obj,
    cd->children = eina_list_remove_list(cd->children, lookup);
    cd->children = eina_list_append_relative_list(cd->children, obj, ref);
 
-   _efl_canvas_vg_node_changed(parent);
-   return ;
+   _node_change(parent, efl_data_scope_get(parent, MY_CLASS));
+   return;
 
  on_error:
    ERR("Err");
@@ -425,8 +438,8 @@ _efl_canvas_vg_node_efl_gfx_stack_stack_above(Eo *obj,
 
 static void
 _efl_canvas_vg_node_efl_gfx_stack_stack_below(Eo *obj,
-                                       Efl_Canvas_Vg_Node_Data *pd EINA_UNUSED,
-                                       Efl_Gfx_Stack *below)
+                                              Efl_Canvas_Vg_Node_Data *pd EINA_UNUSED,
+                                              Efl_Gfx_Stack *below)
 {
    Efl_Canvas_Vg_Container_Data *cd;
    Eina_List *lookup, *ref;
@@ -446,8 +459,8 @@ _efl_canvas_vg_node_efl_gfx_stack_stack_below(Eo *obj,
    cd->children = eina_list_remove_list(cd->children, lookup);
    cd->children = eina_list_prepend_relative_list(cd->children, obj, ref);
 
-   _efl_canvas_vg_node_changed(parent);
-   return ;
+   _node_change(parent, efl_data_scope_get(parent, MY_CLASS));
+   return;
 
  on_error:
    ERR("Err");
@@ -469,13 +482,13 @@ _efl_canvas_vg_node_efl_gfx_stack_lower(Eo *obj, Efl_Canvas_Vg_Node_Data *pd EIN
    if (!lookup) goto on_error;
 
    prev = eina_list_prev(lookup);
-   if (!prev) return ;
+   if (!prev) return;
 
    cd->children = eina_list_remove_list(cd->children, lookup);
    cd->children = eina_list_prepend_relative_list(cd->children, obj, prev);
 
-   _efl_canvas_vg_node_changed(parent);
-   return ;
+   _node_change(parent, efl_data_scope_get(parent, MY_CLASS));
+   return;
 
  on_error:
    ERR("Err");
@@ -623,7 +636,11 @@ _efl_canvas_vg_node_interpolate_point(Eina_Point_3D *d,
 
 /* Warning! Node itself doesn't have any path. Don't call super class(Path)'s */
 static Eina_Bool
-_efl_canvas_vg_node_efl_gfx_path_interpolate(Eo *obj, Efl_Canvas_Vg_Node_Data *pd, const Efl_VG *from, const Efl_VG *to, double pos_map)
+_efl_canvas_vg_node_efl_gfx_path_interpolate(Eo *obj,
+                                             Efl_Canvas_Vg_Node_Data *pd,
+                                             const Efl_VG *from,
+                                             const Efl_VG *to,
+                                             double pos_map)
 {
    Efl_Canvas_Vg_Node_Data *fromd, *tod;
    double from_map;
@@ -700,18 +717,29 @@ _efl_canvas_vg_node_efl_gfx_path_interpolate(Eo *obj, Efl_Canvas_Vg_Node_Data *p
 
    pd->visibility = pos_map >= 0.5 ? tod->visibility : fromd->visibility;
 
-   _efl_canvas_vg_node_changed(obj);
+   _node_change(obj, pd);
 
    return EINA_TRUE;
 }
 
 void
-efl_canvas_vg_node_root_set(Efl_VG *node, Efl_VG *vg_obj)
+efl_canvas_vg_node_vg_obj_set(Efl_VG *node, Efl_VG *vg_obj, Efl_Canvas_Vg_Object_Data *vd)
 {
    Efl_Canvas_Vg_Node_Data *nd = efl_data_scope_get(node, MY_CLASS);
+   if (nd->vg_obj == vg_obj) return;
    nd->vg_obj = vg_obj;
+   nd->vd = vd;
+
+   //root node is always container.
+   efl_canvas_vg_container_vg_obj_update(node, nd);
 }
 
+void
+efl_canvas_vg_node_change(Eo *obj)
+{
+   if (!obj) return;
+   _node_change(obj, efl_data_scope_get(obj, EFL_CANVAS_VG_NODE_CLASS));
+}
 
 EOLIAN static Efl_VG *
 _efl_canvas_vg_node_efl_duplicate_duplicate(const Eo *obj, Efl_Canvas_Vg_Node_Data *pd)
index eb6377d..4aad6bd 100644 (file)
@@ -52,19 +52,6 @@ static const Evas_Object_Func object_func =
 };
 
 static void
-_evas_vg_tree_changed(void *data, const Efl_Event *event EINA_UNUSED)
-{
-   Evas_Object_Protected_Data *obj = data;
-   Efl_Canvas_Vg_Object_Data *pd = efl_data_scope_get(obj->object, MY_CLASS);
-
-   if (pd->changed) return;
-
-   pd->changed = EINA_TRUE;
-
-   evas_object_change(obj->object, obj);
-}
-
-static void
 _update_vgtree_viewport(Eo *obj, Efl_Canvas_Vg_Object_Data *pd)
 {
    double vb_w, vb_h, vp_w, vp_h, scale_w, scale_h, scale;
@@ -116,7 +103,7 @@ _evas_vg_resize(void *data, const Efl_Event *ev)
 EOLIAN static Efl_VG *
 _efl_canvas_vg_object_root_node_get(const Eo *obj, Efl_Canvas_Vg_Object_Data *pd)
 {
-   Efl_VG *root = NULL;
+   Efl_VG *root;
 
    if (pd->vg_entry)
      {
@@ -156,7 +143,10 @@ _efl_canvas_vg_object_root_node_set(Eo *eo_obj, Efl_Canvas_Vg_Object_Data *pd, E
 
    // detach/free the old root_node
    if (pd->user_entry && pd->user_entry->root)
-     efl_parent_set(pd->user_entry->root, NULL);
+     {
+        efl_canvas_vg_node_vg_obj_set(pd->user_entry->root, NULL, NULL);
+        efl_parent_set(pd->user_entry->root, NULL);
+     }
 
    if (root_node)
      {
@@ -174,8 +164,7 @@ _efl_canvas_vg_object_root_node_set(Eo *eo_obj, Efl_Canvas_Vg_Object_Data *pd, E
 
         // set the parent so that vg canvas can render it.
         efl_parent_set(pd->user_entry->root, pd->root);
-
-        efl_canvas_vg_node_root_set(root_node, eo_obj);
+        efl_canvas_vg_node_vg_obj_set(root_node, eo_obj, pd);
      }
    else if (pd->user_entry)
      {
@@ -458,14 +447,12 @@ _efl_canvas_vg_object_efl_object_constructor(Eo *eo_obj, Efl_Canvas_Vg_Object_Da
    obj->private_data = efl_data_ref(eo_obj, MY_CLASS);
    obj->type = o_type;
 
-   /* root node */
-   //FIXME: Well. I don't think this is necessary if user set a new root node...
+   /* default root node */
+   pd->obj = obj;
    pd->root = efl_add_ref(EFL_CANVAS_VG_CONTAINER_CLASS, NULL);
 
    eina_array_step_set(&pd->cleanup, sizeof(pd->cleanup), 8);
 
-   efl_event_callback_add(pd->root, EFL_GFX_PATH_EVENT_CHANGED, _evas_vg_tree_changed, obj);
-
    return eo_obj;
 }
 
index 106efec..728afb5 100644 (file)
@@ -17,6 +17,11 @@ struct _Efl_Canvas_Vg_Shape_Data
 };
 
 // FIXME: Use the renderer bounding box when it has been created instead of an estimation
+static void
+_efl_canvas_vg_shape_path_changed(void *data, const Efl_Event *event)
+{
+   efl_canvas_vg_node_change(event->object);
+}
 
 static void
 _efl_canvas_vg_shape_fill_set(Eo *obj EINA_UNUSED,
@@ -28,7 +33,7 @@ _efl_canvas_vg_shape_fill_set(Eo *obj EINA_UNUSED,
    pd->fill = efl_ref(f);
    efl_unref(tmp);
 
-   _efl_canvas_vg_node_changed(obj);
+   efl_canvas_vg_node_change(obj);
 }
 
 static Efl_Canvas_Vg_Node *
@@ -47,7 +52,7 @@ _efl_canvas_vg_shape_stroke_fill_set(Eo *obj EINA_UNUSED,
    pd->stroke.fill = efl_ref(f);
    efl_unref(tmp);
 
-   _efl_canvas_vg_node_changed(obj);
+   efl_canvas_vg_node_change(obj);
 }
 
 static Efl_Canvas_Vg_Node *
@@ -67,7 +72,7 @@ _efl_canvas_vg_shape_stroke_marker_set(Eo *obj EINA_UNUSED,
    pd->stroke.marker = efl_ref(m);
    efl_unref(tmp);
 
-   _efl_canvas_vg_node_changed(obj);
+   efl_canvas_vg_node_change(obj);
 }
 
 static Efl_Canvas_Vg_Shape *
@@ -135,6 +140,9 @@ _efl_canvas_vg_shape_efl_object_constructor(Eo *obj, Efl_Canvas_Vg_Shape_Data *p
    nd->render_pre = _efl_canvas_vg_shape_render_pre;
    nd->data = pd;
 
+   efl_event_callback_add(obj, EFL_GFX_PATH_EVENT_CHANGED,
+                          _efl_canvas_vg_shape_path_changed, pd);
+
    return obj;
 }
 
@@ -145,6 +153,9 @@ _efl_canvas_vg_shape_efl_object_destructor(Eo *obj, Efl_Canvas_Vg_Shape_Data *pd
    if (pd->stroke.fill) efl_unref(pd->stroke.fill);
    if (pd->stroke.marker) efl_unref(pd->stroke.marker);
 
+   efl_event_callback_del(obj, EFL_GFX_PATH_EVENT_CHANGED,
+                          _efl_canvas_vg_shape_path_changed, pd);
+
    efl_gfx_path_reset(obj);
    efl_destructor(efl_super(obj, MY_CLASS));
 }
index 904afec..ee41804 100644 (file)
@@ -43,6 +43,7 @@ struct _Efl_Canvas_Vg_Object_Data
    Efl_VG                    *root;
    Vg_Cache_Entry            *vg_entry;
    Vg_User_Entry             *user_entry; //holds the user set vg tree
+   Evas_Object_Protected_Data *obj;
    Eina_Rect                  fill;
    Eina_Rect                  viewbox;
    unsigned int               width, height;
@@ -63,7 +64,8 @@ struct _Efl_Canvas_Vg_Node_Data
 
    Ector_Renderer *renderer;
 
-   Efl_VG *vg_obj;    //...Not necessary!!
+   Efl_VG *vg_obj;
+   Efl_Canvas_Vg_Object_Data *vd;
 
    void (*render_pre)(Evas_Object_Protected_Data *vg_pd, Efl_VG *node,
          Efl_Canvas_Vg_Node_Data *nd, Ector_Surface *surface,
@@ -76,7 +78,6 @@ struct _Efl_Canvas_Vg_Node_Data
 
    Eina_Bool visibility : 1;
    Eina_Bool changed : 1;
-   Eina_Bool parenting : 1;
 };
 
 typedef struct _Vg_Mask
@@ -131,7 +132,17 @@ Eina_Bool                   evas_cache_vg_entry_file_save(Vg_Cache_Entry *vg_ent
 double                      evas_cache_vg_anim_duration_get(const Vg_Cache_Entry *vg_entry);
 unsigned int                evas_cache_vg_anim_frame_count_get(const Vg_Cache_Entry *vg_entry);
 Eina_Size2D                 evas_cache_vg_entry_default_size_get(const Vg_Cache_Entry *vg_entry);
-void                        efl_canvas_vg_node_root_set(Efl_VG *node, Efl_VG *vg_obj);
+void                        efl_canvas_vg_node_vg_obj_set(Efl_VG *node, Efl_VG *vg_obj, Efl_Canvas_Vg_Object_Data *vd);
+void                        efl_canvas_vg_node_change(Efl_VG *node);
+void                        efl_canvas_vg_container_vg_obj_update(Efl_VG *obj, Efl_Canvas_Vg_Node_Data *nd);
+
+static inline void
+efl_canvas_vg_object_change(Efl_Canvas_Vg_Object_Data *vd)
+{
+   if (!vd || vd->changed) return;
+   vd->changed = EINA_TRUE;
+   evas_object_change(vd->obj->object, vd->obj);
+}
 
 static inline Efl_Canvas_Vg_Node_Data *
 _evas_vg_render_pre(Evas_Object_Protected_Data *vg_pd, Efl_VG *child, Ector_Surface *surface, Eina_Matrix3 *transform, Ector_Buffer *mask, int mask_op)
@@ -142,14 +153,6 @@ _evas_vg_render_pre(Evas_Object_Protected_Data *vg_pd, Efl_VG *child, Ector_Surf
    return nd;
 }
 
-static inline void
-_efl_canvas_vg_node_changed(Eo *obj)
-{
-   Efl_Gfx_Path_Change_Event ev = { EFL_GFX_CHANGE_FLAG_FILL };
-
-   if (obj) efl_event_callback_call(obj, EFL_GFX_PATH_EVENT_CHANGED, &ev);
-}
-
 #define EFL_CANVAS_VG_COMPUTE_MATRIX(Current, Parent, Nd)                      \
   Eina_Matrix3 *Current = Nd->m;                                        \
   Eina_Matrix3 _matrix_tmp;                                             \