forked from enlightenment/efl
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
This commit is contained in:
parent
ef84367fa9
commit
e38cf1f85f
|
@ -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))
|
||||
if (!evas_vg_node_interpolate(ep->typedata.vector->cur.vg, start->vg, end->vg, pos))
|
||||
{
|
||||
// can interpolate between two svg file
|
||||
eo_parent_set(container, root_vg);
|
||||
}
|
||||
else
|
||||
{
|
||||
// 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;
|
||||
if (ep->typedata.vector->cur.vg)
|
||||
eo_del(ep->typedata.vector->cur.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);
|
||||
_edje_dupe_vector_data(ed, chosen_desc->vg.id, w, h, &ep->typedata.vector->cur);
|
||||
|
||||
//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;
|
||||
}
|
||||
}
|
||||
eo_parent_set(ep->typedata.vector->cur.vg, root_vg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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>
|
||||
|
|
Loading…
Reference in New Issue