summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSubhransu Mohanty <sub.mohanty@samsung.com>2016-06-09 13:49:56 +0900
committerJean-Philippe Andre <jp.andre@samsung.com>2016-06-09 13:49:56 +0900
commite38cf1f85f8957bd2fa17972572a0d39c09298bf (patch)
tree682731f89e8861e6a5c5d29982e63e184d7e0ccb /src
parentef84367fa9e97c1c6ae72a5bbdafd4a5f1272e83 (diff)
downloadefl-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.c174
-rw-r--r--src/lib/edje/edje_load.c103
-rw-r--r--src/lib/edje/edje_private.h25
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>