diff options
author | Subhransu Mohanty <sub.mohanty@samsung.com> | 2016-06-09 13:49:56 +0900 |
---|---|---|
committer | Jean-Philippe Andre <jp.andre@samsung.com> | 2016-06-09 13:49:56 +0900 |
commit | e38cf1f85f8957bd2fa17972572a0d39c09298bf (patch) | |
tree | 682731f89e8861e6a5c5d29982e63e184d7e0ccb /src | |
parent | ef84367fa9e97c1c6ae72a5bbdafd4a5f1272e83 (diff) | |
download | efl-e38cf1f85f8957bd2fa17972572a0d39c09298bf.tar.gz |
edje: cached the vg tree generation and fixed the interpolation betwwen two vg tree.
Reviewers: cedric, jpeg
Subscribers: cedric, jpeg
Differential Revision: https://phab.enlightenment.org/D4028
Diffstat (limited to 'src')
-rw-r--r-- | src/lib/edje/edje_calc.c | 174 | ||||
-rw-r--r-- | src/lib/edje/edje_load.c | 103 | ||||
-rw-r--r-- | src/lib/edje/edje_private.h | 25 |
3 files changed, 130 insertions, 172 deletions
diff --git a/src/lib/edje/edje_calc.c b/src/lib/edje/edje_calc.c index 5b2f4ab3a8..382e6d7f0f 100644 --- a/src/lib/edje/edje_calc.c +++ b/src/lib/edje/edje_calc.c @@ -3260,8 +3260,10 @@ _edje_svg_recalc_apply(Edje *ed, Edje_Real_Part *ep, Edje_Calc_Params *p3 EINA_U { int w, h; int new_svg = 0; - Efl_VG *vg_tree, *root_vg; - double sx, sy, vx, vy, vw, vh; + Efl_VG *root_vg; + double sx, sy; + Eina_Matrix3 matrix; + Edje_Vector_Data *start, *end; evas_object_geometry_get(ep->object, NULL, NULL, &w, &h); @@ -3279,74 +3281,42 @@ _edje_svg_recalc_apply(Edje *ed, Edje_Real_Part *ep, Edje_Calc_Params *p3 EINA_U } if (new_svg) // animation with svg id change { - Efl_VG *container; - if (ep->typedata.vector->cache.svg_id != new_svg) - { - //create it - vg_tree = _edje_create_vg_tree(ed->file->ef, new_svg, w, h, &vx, &vy, &vw, &vh); - if (vg_tree) - { - //1. clear the cache - if (ep->typedata.vector->cache.vg) - { - eo_unref(ep->typedata.vector->cache.vg); - ep->typedata.vector->cache.vg = NULL; - ep->typedata.vector->cache.svg_id = 0; - } - //2. update current - ep->typedata.vector->cache.svg_id = new_svg; - ep->typedata.vector->cache.x = vx; - ep->typedata.vector->cache.y = vy; - ep->typedata.vector->cache.w = vw; - ep->typedata.vector->cache.h = vh; - ep->typedata.vector->cache.vg = vg_tree; - } - } - // just do the interpolation - if (eo_parent_get(ep->typedata.vector->cur.vg)) - { - // remove it from the hirarchy - eo_ref(ep->typedata.vector->cur.vg); - eo_parent_set(ep->typedata.vector->cur.vg, NULL); - } - // create a container - container = evas_vg_container_add(NULL); - // reset the matrix. - Eina_Matrix3 matrix; - sx = w/ep->typedata.vector->cur.w; - sy = h/ep->typedata.vector->cur.h; - // for current vg + start = _edje_ref_vector_data(ed, chosen_desc->vg.id); + end = _edje_ref_vector_data(ed, new_svg); + + // for start vector + sx = w/start->w; + sy = h/start->h; eina_matrix3_identity(&matrix); - eina_matrix3_translate(&matrix, -ep->typedata.vector->cur.x, -ep->typedata.vector->cur.y); + eina_matrix3_translate(&matrix, -start->x, -start->y); eina_matrix3_scale(&matrix, sx, sy); - evas_vg_node_transformation_set(ep->typedata.vector->cur.vg, &matrix); - // for next vg - sx = w/ep->typedata.vector->cache.w; - sy = h/ep->typedata.vector->cache.h; + evas_vg_node_transformation_set(start->vg, &matrix); + + // for end vector + sx = w/end->w; + sy = h/end->h; eina_matrix3_identity(&matrix); - eina_matrix3_translate(&matrix, -ep->typedata.vector->cache.x, -ep->typedata.vector->cache.y); + eina_matrix3_translate(&matrix, -end->x, -end->y); eina_matrix3_scale(&matrix, sx, sy); - evas_vg_node_transformation_set(ep->typedata.vector->cache.vg, &matrix); + evas_vg_node_transformation_set(end->vg, &matrix); + // do the interpolation - if (evas_vg_node_interpolate(container, ep->typedata.vector->cur.vg, ep->typedata.vector->cache.vg, pos)) - { - // can interpolate between two svg file - eo_parent_set(container, root_vg); - } - else + if (!evas_vg_node_interpolate(ep->typedata.vector->cur.vg, start->vg, end->vg, pos)) { - // can't interpolate between 2 shape - // keep the current vg tree - eo_parent_set(ep->typedata.vector->cur.vg, root_vg); - // delete the container - eo_unref(container); + ERR(" Can't interpolate check the svg file \n"); } + // performance hack + // instead of duplicating the tree and applying the transformation + // i just updated the transformation matrix and reset it back to null. + // assumption is that the root vg will never have a transformation + eina_matrix3_identity(&matrix); + evas_vg_node_transformation_set(start->vg, &matrix); + evas_vg_node_transformation_set(end->vg, &matrix); } else { if (ep->typedata.vector->cur.svg_id == chosen_desc->vg.id) // no svg file change { - Eina_Matrix3 matrix; sx = w/ep->typedata.vector->cur.w; sy = h/ep->typedata.vector->cur.h; eina_matrix3_identity(&matrix); @@ -3357,88 +3327,12 @@ _edje_svg_recalc_apply(Edje *ed, Edje_Real_Part *ep, Edje_Calc_Params *p3 EINA_U } else { - Eina_Matrix3 matrix; - // check in cache if the vg tree already exists - if (ep->typedata.vector->cache.svg_id == chosen_desc->vg.id) - { - int id = ep->typedata.vector->cache.svg_id; - int vx = ep->typedata.vector->cache.x; - int vy = ep->typedata.vector->cache.y; - int vw = ep->typedata.vector->cache.w; - int vh = ep->typedata.vector->cache.h; - Efl_VG *vg = ep->typedata.vector->cache.vg; - - //1. update the cache from current. - ep->typedata.vector->cache.svg_id = ep->typedata.vector->cur.svg_id; - ep->typedata.vector->cache.vg = ep->typedata.vector->cur.vg; - ep->typedata.vector->cache.x = ep->typedata.vector->cur.x; - ep->typedata.vector->cache.y = ep->typedata.vector->cur.y; - ep->typedata.vector->cache.w = ep->typedata.vector->cur.w; - ep->typedata.vector->cache.h = ep->typedata.vector->cur.h; - eo_ref(ep->typedata.vector->cache.vg); - eo_parent_set(ep->typedata.vector->cache.vg, NULL); - - //2. update the root node - sx = w/vw; - sy = h/vh; - eina_matrix3_identity(&matrix); - eina_matrix3_translate(&matrix, -vx, -vy); - eina_matrix3_scale(&matrix, sx, sy); - evas_vg_node_transformation_set(vg, &matrix); - // update parent and ref - eo_parent_set(vg, root_vg); - - //3.update the cur - ep->typedata.vector->cur.svg_id = id; - ep->typedata.vector->cur.x = vx; - ep->typedata.vector->cur.y = vy; - ep->typedata.vector->cur.w = vw; - ep->typedata.vector->cur.h = vh; - ep->typedata.vector->cur.vg = vg; - } - else - { - //create it - vg_tree = _edje_create_vg_tree(ed->file->ef, chosen_desc->vg.id, w, h, &vx, &vy, &vw, &vh); - if (vg_tree) - { - //1. clear the cache - if (ep->typedata.vector->cache.vg) - { - eo_unref(ep->typedata.vector->cache.vg); - ep->typedata.vector->cache.vg = NULL; - ep->typedata.vector->cache.svg_id = 0; - } - // 2. move the current tree to cache - if (ep->typedata.vector->cur.vg) - { - eo_ref(ep->typedata.vector->cur.vg); - eo_parent_set(ep->typedata.vector->cur.vg, NULL); - // copy to the cache. - ep->typedata.vector->cache.svg_id = ep->typedata.vector->cur.svg_id; - ep->typedata.vector->cache.vg = ep->typedata.vector->cur.vg; - ep->typedata.vector->cache.x = ep->typedata.vector->cur.x; - ep->typedata.vector->cache.y = ep->typedata.vector->cur.y; - ep->typedata.vector->cache.w = ep->typedata.vector->cur.w; - ep->typedata.vector->cache.h = ep->typedata.vector->cur.h; - } - //3. update current - ep->typedata.vector->cur.svg_id = chosen_desc->vg.id; - ep->typedata.vector->cur.x = vx; - ep->typedata.vector->cur.y = vy; - ep->typedata.vector->cur.w = vw; - ep->typedata.vector->cur.h = vh; - ep->typedata.vector->cur.vg = vg_tree; - eo_parent_set(vg_tree, root_vg); - } - else - { - //1. clear current - ep->typedata.vector->cur.svg_id = 0; - eo_parent_set(ep->typedata.vector->cur.vg, NULL); - ep->typedata.vector->cur.vg = NULL; - } - } + if (ep->typedata.vector->cur.vg) + eo_del(ep->typedata.vector->cur.vg); + + _edje_dupe_vector_data(ed, chosen_desc->vg.id, w, h, &ep->typedata.vector->cur); + + eo_parent_set(ep->typedata.vector->cur.vg, root_vg); } } } diff --git a/src/lib/edje/edje_load.c b/src/lib/edje/edje_load.c index d1f6417ddb..e26eb5e0d4 100644 --- a/src/lib/edje/edje_load.c +++ b/src/lib/edje/edje_load.c @@ -27,6 +27,7 @@ struct _Edje_Drag_Items }; void _edje_file_add(Edje *ed, const Eina_File *f); +static void _edje_vector_data_free(Edje *ed); /* START - Nested part support */ #define _edje_smart_nested_type "Evas_Smart_Nested" @@ -1556,7 +1557,7 @@ _edje_file_del(Edje *ed) _edje_message_del(ed); _edje_block_violate(ed); _edje_var_shutdown(ed); - + _edje_vector_data_free(ed); if (!((ed->file) && (ed->collection))) { if (tev) @@ -2380,43 +2381,97 @@ _create_vg_node(Svg_Node *node, Efl_VG *parent) _apply_vg_property(node, vg); } -Efl_VG* -_edje_create_vg_tree(Eet_File *ef, int svg_id, double width, double height, - double *vx, double *vy, double *vw, double *vh) +static void +_edje_vector_data_free(Edje *ed) +{ + Edje_Vector_Data *vector; + + EINA_LIST_FREE(ed->vector_cache, vector) + { + if (vector->vg) eo_del(vector->vg); + free(vector); + } +} + +Edje_Vector_Data * +_edje_ref_vector_data(Edje *ed, int svg_id) { - double sx=1.0, sy=1.0; - Eina_Matrix3 matrix; - Efl_VG *root = NULL; - Svg_Node *child; Eina_List *l; - Svg_Node *node; + Edje_Vector_Data *vector; char svg_key[20]; Eet_Data_Descriptor *svg_node_eet; + Svg_Node *child; + Svg_Node *node; + Efl_VG *root = NULL; + + // check in the cache + EINA_LIST_FOREACH(ed->vector_cache, l, vector) + { + if (vector->svg_id == svg_id) + return vector; + } + + // create and put it in the cache. + vector = calloc(1, sizeof(Edje_Vector_Data)); + vector->svg_id = svg_id; snprintf(svg_key, sizeof(svg_key), "edje/vectors/%i", svg_id); svg_node_eet = _edje_svg_node_eet(); - node = eet_data_read(ef, svg_node_eet, svg_key); + node = eet_data_read(ed->file->ef, svg_node_eet, svg_key); - if (!node && (node->type != SVG_NODE_DOC)) return NULL; - if (node->node.doc.vw && node->node.doc.vh) + if (!node || (node->type != SVG_NODE_DOC)) + { + root = NULL; + } + else { - sx = width/node->node.doc.vw; - sy = height/node->node.doc.vh; root = evas_vg_container_add(NULL); + EINA_LIST_FOREACH(node->child, l, child) + { + _create_vg_node(child, root); + } + vector->x = node->node.doc.vx; + vector->y = node->node.doc.vy; + vector->w = node->node.doc.vw; + vector->h = node->node.doc.vh; + } + vector->vg = root; + ed->vector_cache = eina_list_append(ed->vector_cache, vector); + return vector; +} + +void +_edje_dupe_vector_data(Edje *ed, int svg_id, double width, double height, + Edje_Vector_Data *data) +{ + double sx=1.0, sy=1.0; + Edje_Vector_Data *vector; + Efl_VG *root; + Eina_Matrix3 matrix; + + vector = _edje_ref_vector_data(ed, svg_id); + if (!vector->vg) + { + data->vg = NULL; + } + + root = evas_vg_container_add(NULL); + efl_vg_dup(root, vector->vg); + + if (vector->w && vector->h) + { + sx = width/vector->w; + sy = height/vector->h; eina_matrix3_identity(&matrix); - eina_matrix3_translate(&matrix, -node->node.doc.vx, -node->node.doc.vy); + eina_matrix3_translate(&matrix, -vector->x, -vector->y); eina_matrix3_scale(&matrix, sx, sy); evas_vg_node_transformation_set(root, &matrix); } - EINA_LIST_FOREACH(node->child, l, child) - { - _create_vg_node(child, root); - } - *vx = node->node.doc.vx; - *vy = node->node.doc.vy; - *vw = node->node.doc.vw; - *vh = node->node.doc.vh; - return root; + data->vg = root; + data->x = vector->x; + data->y = vector->y; + data->w = vector->w; + data->h = vector->h; } diff --git a/src/lib/edje/edje_private.h b/src/lib/edje/edje_private.h index 7de6b58425..fbfc633eb7 100644 --- a/src/lib/edje/edje_private.h +++ b/src/lib/edje/edje_private.h @@ -370,6 +370,7 @@ typedef struct _Edje_Part_Limit Edje_Part_Limit; typedef struct _Edje_Part_Description_Vector Edje_Part_Description_Vector; typedef struct _Edje_Part_Description_Spec_Svg Edje_Part_Description_Spec_Svg; typedef struct _Edje_Real_Part_Vector Edje_Real_Part_Vector; +typedef struct _Edje_Vector_Data Edje_Vector_Data; typedef struct _Edje Edje; typedef struct _Edje_Real_Part_Text Edje_Real_Part_Text; @@ -1652,6 +1653,7 @@ struct _Edje Eina_List *subobjs; Eina_List *text_insert_filter_callbacks; Eina_List *markup_filter_callbacks; + Eina_List *vector_cache; /* list of Edje_Vector_Data */ Eina_List *groups; @@ -1935,14 +1937,17 @@ struct _Edje_Real_Part_Swallow } swallow_params; // 28 // FIXME: only if type SWALLOW }; +struct _Edje_Vector_Data +{ + int svg_id; + double x, y, w, h; + Eina_Bool preserve_aspect; + Efl_VG *vg; +}; + struct _Edje_Real_Part_Vector { - struct { - int svg_id; - double x, y, w, h; - Eina_Bool preserve_aspect; - Efl_VG *vg; - }cur, cache; + Edje_Vector_Data cur; }; struct _Edje_Real_Part @@ -3229,8 +3234,12 @@ enum _Svg_Style_Type EAPI Eet_Data_Descriptor * _edje_svg_node_eet(void); void _edje_svg_node_destroy_eet(void); -Efl_VG* _edje_create_vg_tree(Eet_File *ef, int svg_id, double width, double height, - double *vx, double *vy, double *vw, double *vh); + +void _edje_dupe_vector_data(Edje *ed, int svg_id, double width, double height, + Edje_Vector_Data *data); + +Edje_Vector_Data * _edje_ref_vector_data(Edje *ed, int svg_id); + #ifdef HAVE_LIBREMIX #include <remix/remix.h> |