summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorsubhransu mohanty <sub.mohanty@samsung.com>2017-10-27 09:11:02 +0900
committerJean-Philippe Andre <jp.andre@samsung.com>2017-10-27 14:58:38 +0900
commit64231ae699858b34d65f6e27d665a1411ff1bcf0 (patch)
treed62003b960d325d8d91e9688003055ee96f28159 /src
parentbf79ec359d7f7c6bbb5d6cd5dbb22d233551ae58 (diff)
evas/vg: Added vg tree caching support
Diffstat (limited to 'src')
-rw-r--r--src/Makefile_Evas.am5
-rw-r--r--src/lib/evas/canvas/evas_main.c2
-rw-r--r--src/lib/evas/canvas/evas_vg_private.h43
-rw-r--r--src/lib/evas/vg/evas_vg_cache.c328
4 files changed, 373 insertions, 5 deletions
diff --git a/src/Makefile_Evas.am b/src/Makefile_Evas.am
index bc2c0ab..5657ed3 100644
--- a/src/Makefile_Evas.am
+++ b/src/Makefile_Evas.am
@@ -311,6 +311,11 @@ lib/evas/canvas/render2/evas_render2_th_main.c \
311lib/evas/canvas/render2/region.c \ 311lib/evas/canvas/render2/region.c \
312lib/evas/canvas/render2/region.h 312lib/evas/canvas/render2/region.h
313 313
314 # Vg
315 lib_evas_libevas_la_SOURCES += \
316 lib/evas/vg/evas_vg_cache.c
317
318
314# Cache 319# Cache
315lib_evas_libevas_la_SOURCES += \ 320lib_evas_libevas_la_SOURCES += \
316lib/evas/cache/evas_cache_image.c \ 321lib/evas/cache/evas_cache_image.c \
diff --git a/src/lib/evas/canvas/evas_main.c b/src/lib/evas/canvas/evas_main.c
index bcc2334..9efd0ca 100644
--- a/src/lib/evas/canvas/evas_main.c
+++ b/src/lib/evas/canvas/evas_main.c
@@ -84,6 +84,7 @@ evas_init(void)
84#endif 84#endif
85 _evas_preload_thread_init(); 85 _evas_preload_thread_init();
86 evas_filter_init(); 86 evas_filter_init();
87 evas_cache_vg_init();
87 88
88 if (!evas_thread_init()) 89 if (!evas_thread_init())
89 goto shutdown_filter; 90 goto shutdown_filter;
@@ -146,6 +147,7 @@ evas_shutdown(void)
146 if (evas_cserve2_use_get()) 147 if (evas_cserve2_use_get())
147 evas_cserve2_shutdown(); 148 evas_cserve2_shutdown();
148#endif 149#endif
150 evas_cache_vg_shutdown();
149 151
150 _efl_gfx_map_shutdown(); 152 _efl_gfx_map_shutdown();
151 153
diff --git a/src/lib/evas/canvas/evas_vg_private.h b/src/lib/evas/canvas/evas_vg_private.h
index d3e151a..dda171b 100644
--- a/src/lib/evas/canvas/evas_vg_private.h
+++ b/src/lib/evas/canvas/evas_vg_private.h
@@ -3,18 +3,41 @@
3 3
4#include <Ector.h> 4#include <Ector.h>
5 5
6typedef struct _Efl_VG_Data Efl_VG_Data; 6typedef struct _Efl_VG_Data Efl_VG_Data;
7typedef struct _Efl_VG_Container_Data Efl_VG_Container_Data; 7typedef struct _Efl_VG_Container_Data Efl_VG_Container_Data;
8typedef struct _Efl_VG_Gradient_Data Efl_VG_Gradient_Data; 8typedef struct _Efl_VG_Gradient_Data Efl_VG_Gradient_Data;
9typedef struct _Efl_VG_Interpolation Efl_VG_Interpolation; 9typedef struct _Efl_VG_Interpolation Efl_VG_Interpolation;
10 10
11typedef struct _Efl_Canvas_Vg_Data Efl_Canvas_Vg_Data; 11
12typedef struct _Efl_Canvas_Vg_Data Efl_Canvas_Vg_Data;
13
14typedef struct _Evas_Cache_Vg_Entry Evas_Cache_Vg_Entry;
15typedef struct _Evas_Cache_Vg Evas_Cache_Vg;
16
17struct _Evas_Cache_Vg
18{
19 Eina_Hash *vg_hash;
20 Eina_Hash *active;
21 int ref;
22};
23
24struct _Evas_Cache_Vg_Entry
25{
26 char *hash_key;
27 Eina_Stringshare *file;
28 Eina_Stringshare *key;
29 int w;
30 int h;
31 Efl_VG *root;
32 int ref;
33};
12 34
13struct _Efl_Canvas_Vg_Data 35struct _Efl_Canvas_Vg_Data
14{ 36{
15 void *engine_data; 37 void *engine_data;
16 Efl_VG *root; 38 Efl_VG *root;
17 Efl_VG *vg_tree; 39 Efl_VG *vg_tree;
40 Evas_Cache_Vg_Entry *vg_entry;
18 Eina_Rect fill; 41 Eina_Rect fill;
19 Eina_Rect viewbox; 42 Eina_Rect viewbox;
20 unsigned int width, height; 43 unsigned int width, height;
@@ -70,6 +93,16 @@ struct _Efl_VG_Interpolation
70 Eina_Point_3D skew; 93 Eina_Point_3D skew;
71}; 94};
72 95
96
97void evas_cache_vg_init(void);
98void evas_cache_vg_shutdown(void);
99Evas_Cache_Vg_Entry* evas_cache_vg_entry_find(const char *file, const char *key, int w, int h);
100Efl_VG* evas_cache_vg_tree_get(Evas_Cache_Vg_Entry *svg_entry);
101void evas_cache_vg_entry_del(Evas_Cache_Vg_Entry *svg_entry);
102Vg_File_Data * evas_cache_vg_file_info(const char *file, const char *key);
103
104Eina_Bool evas_vg_save_to_file(Vg_File_Data *evg_data, const char *file, const char *key, const char *flags);
105
73static inline Efl_VG_Data * 106static inline Efl_VG_Data *
74_evas_vg_render_pre(Efl_VG *child, Ector_Surface *s, Eina_Matrix3 *m) 107_evas_vg_render_pre(Efl_VG *child, Ector_Surface *s, Eina_Matrix3 *m)
75{ 108{
diff --git a/src/lib/evas/vg/evas_vg_cache.c b/src/lib/evas/vg/evas_vg_cache.c
new file mode 100644
index 0000000..dae36cc
--- /dev/null
+++ b/src/lib/evas/vg/evas_vg_cache.c
@@ -0,0 +1,328 @@
1#ifdef HAVE_CONFIG_H
2# include <config.h>
3#endif
4
5#include "evas_common_private.h"
6#include "evas_private.h"
7#include "evas_vg_private.h"
8
9static Evas_Cache_Vg* vg_cache = NULL;
10
11struct ext_loader_s
12{
13 unsigned int length;
14 const char *extension;
15 const char *loader;
16};
17
18#define MATCHING(Ext, Module) { sizeof(Ext)-1, Ext, Module }
19
20static const struct ext_loader_s loaders[] =
21{ /* map extensions to loaders to use for good first-guess tries */
22 MATCHING(".eet", "eet"),
23 MATCHING(".edj", "eet"),
24 MATCHING(".svg", "svg"),
25 MATCHING(".svgz", "svg"),
26 MATCHING(".svg.gz", "svg")
27};
28
29static Evas_Module *
30_find_loader_module(const char *file)
31{
32 const char *loader = NULL, *end;
33 Evas_Module *em = NULL;
34 unsigned int i;
35 int len, len2;
36 len = strlen(file);
37 end = file + len;
38 for (i = 0; i < (sizeof (loaders) / sizeof(struct ext_loader_s)); i++)
39 {
40 len2 = loaders[i].length;
41 if (len2 > len) continue;
42 if (!strcasecmp(end - len2, loaders[i].extension))
43 {
44 loader = loaders[i].loader;
45 break;
46 }
47 }
48 if (loader)
49 em = evas_module_find_type(EVAS_MODULE_TYPE_VG_LOADER, loader);
50 return em;
51}
52
53Vg_File_Data *
54_vg_load_from_file(const char *file, const char *key)
55{
56 Evas_Module *em;
57 Evas_Vg_Load_Func *loader;
58 int error = EVAS_LOAD_ERROR_GENERIC;
59 Vg_File_Data *evg_data = NULL;
60
61 em = _find_loader_module(file);
62 if (em)
63 {
64 loader = em->functions;
65 evg_data = loader->file_data(file, key, &error);
66 }
67 return evg_data;
68}
69
70
71// evg file save
72struct ext_saver_s
73{
74 unsigned int length;
75 const char *extension;
76 const char *saver;
77};
78
79static const struct ext_saver_s savers[] =
80{ /* map extensions to savers to use for good first-guess tries */
81 MATCHING(".eet", "eet"),
82 MATCHING(".edj", "eet")
83};
84
85static Evas_Module *
86_find_saver_module(const char *file)
87{
88 const char *saver = NULL, *end;
89 Evas_Module *em = NULL;
90 unsigned int i;
91 int len, len2;
92 len = strlen(file);
93 end = file + len;
94 for (i = 0; i < (sizeof (savers) / sizeof(struct ext_saver_s)); i++)
95 {
96 len2 = savers[i].length;
97 if (len2 > len) continue;
98 if (!strcasecmp(end - len2, savers[i].extension))
99 {
100 saver = savers[i].saver;
101 break;
102 }
103 }
104 if (saver)
105 em = evas_module_find_type(EVAS_MODULE_TYPE_VG_SAVER, saver);
106 return em;
107}
108
109Eina_Bool
110evas_vg_save_to_file(Vg_File_Data *evg_data, const char *file, const char *key, const char *flags)
111{
112 Evas_Module *em;
113 Evas_Vg_Save_Func *saver;
114 int error = EVAS_LOAD_ERROR_GENERIC;
115 int compress = 9;
116
117 if (!file) return EINA_FALSE;
118
119 if (flags)
120 {
121 char *p, *pp;
122 char *tflags;
123
124 tflags = alloca(strlen(flags) + 1);
125 strcpy(tflags, flags);
126 p = tflags;
127 while (p)
128 {
129 pp = strchr(p, ' ');
130 if (pp) *pp = 0;
131 sscanf(p, "compress=%i", &compress);
132 if (pp) p = pp + 1;
133 else break;
134 }
135 }
136
137 em = _find_saver_module(file);
138 if (em)
139 {
140 saver = em->functions;
141 error = saver->vg_save(evg_data, file, key, compress);
142 }
143
144 if (error)
145 return EINA_FALSE;
146
147 return EINA_TRUE;
148}
149
150
151
152static void
153_evas_cache_vg_data_free_cb(void *data)
154{
155 Vg_File_Data *val = data;
156
157 efl_del(val->root);
158 free(val);
159}
160
161static void
162_evas_cache_svg_entry_free_cb(void *data)
163{
164 Evas_Cache_Vg_Entry *entry = data;
165
166 eina_stringshare_del(entry->file);
167 eina_stringshare_del(entry->key);
168 free(entry->hash_key);
169 efl_del(entry->root);
170 free(entry);
171}
172
173void
174evas_cache_vg_init(void)
175{
176 if (vg_cache)
177 {
178 vg_cache->ref++;
179 return;
180 }
181 vg_cache = calloc(1, sizeof(Evas_Cache_Vg));
182 vg_cache->vg_hash = eina_hash_string_superfast_new(_evas_cache_vg_data_free_cb);
183 vg_cache->active = eina_hash_string_superfast_new(_evas_cache_svg_entry_free_cb);
184 vg_cache->ref++;
185}
186
187void
188evas_cache_vg_shutdown(void)
189{
190 if (!vg_cache) return;
191 vg_cache->ref--;
192 if (vg_cache->ref) return;
193 eina_hash_free(vg_cache->vg_hash);
194 eina_hash_free(vg_cache->active);
195 free(vg_cache);
196 vg_cache = NULL;
197}
198
199Vg_File_Data *
200evas_cache_vg_file_info(const char *file, const char *key)
201{
202 Vg_File_Data *vd;
203 Eina_Strbuf *hash_key;
204
205 hash_key = eina_strbuf_new();
206 eina_strbuf_append_printf(hash_key, "%s/%s", file, key);
207 vd = eina_hash_find(vg_cache->vg_hash, eina_strbuf_string_get(hash_key));
208 if (!vd)
209 {
210 vd = _vg_load_from_file(file, key);
211 eina_hash_add(vg_cache->vg_hash, eina_strbuf_string_get(hash_key), vd);
212 }
213 eina_strbuf_free(hash_key);
214 return vd;
215}
216
217static void
218_apply_transformation(Efl_VG *root, double w, double h, Vg_File_Data *vg_data)
219{
220 double sx = 0, sy= 0, scale;
221 Eina_Matrix3 m;
222
223 if (vg_data->view_box.w)
224 sx = w/vg_data->view_box.w;
225 if (vg_data->view_box.h)
226 sy = h/vg_data->view_box.h;
227 scale = sx < sy ? sx: sy;
228 eina_matrix3_identity(&m);
229 // allign hcenter and vcenter
230 if (vg_data->preserve_aspect)
231 {
232 eina_matrix3_translate(&m, (w - vg_data->view_box.w * scale)/2.0, (h - vg_data->view_box.h * scale)/2.0);
233 eina_matrix3_scale(&m, scale, scale);
234 eina_matrix3_translate(&m, -vg_data->view_box.x, -vg_data->view_box.y);
235 }
236 else
237 {
238 eina_matrix3_scale(&m, sx, sy);
239 eina_matrix3_translate(&m, -vg_data->view_box.x, -vg_data->view_box.y);
240 }
241 evas_vg_node_transformation_set(root, &m);
242}
243
244static Efl_VG *
245_evas_vg_dup_vg_tree(Vg_File_Data *fd, double w, double h)
246{
247
248 Efl_VG *root;
249
250 if (!fd) return NULL;
251 if ( !w || !h ) return NULL;
252
253 root = evas_vg_container_add(NULL);
254 evas_vg_node_dup(root, fd->root);
255 _apply_transformation(root, w, h, fd);
256
257 return root;
258}
259
260static void
261_evas_cache_svg_vg_tree_update(Evas_Cache_Vg_Entry *entry)
262{
263 Vg_File_Data *src_vg = NULL;
264 if(!entry) return;
265
266 if (!entry->file)
267 {
268 entry->root = NULL;
269 return;
270 }
271
272 src_vg = evas_cache_vg_file_info(entry->file, entry->key);
273
274 entry->root = _evas_vg_dup_vg_tree(src_vg, entry->w, entry->h);
275 eina_stringshare_del(entry->file);
276 eina_stringshare_del(entry->key);
277 entry->file = NULL;
278 entry->key = NULL;
279}
280
281Evas_Cache_Vg_Entry*
282evas_cache_vg_entry_find(const char *file, const char *key,
283 int w, int h)
284{
285 Evas_Cache_Vg_Entry* se;
286 Eina_Strbuf *hash_key;
287
288 if (!vg_cache) return NULL;
289
290 hash_key = eina_strbuf_new();
291 eina_strbuf_append_printf(hash_key, "%s/%s/%d/%d",
292 file, key, w, h);
293 se = eina_hash_find(vg_cache->active, eina_strbuf_string_get(hash_key));
294 if (!se)
295 {
296 se = calloc(1, sizeof(Evas_Cache_Vg_Entry));
297 se->file = eina_stringshare_add(file);
298 se->key = eina_stringshare_add(key);
299 se->w = w;
300 se->h = h;
301 se->hash_key = eina_strbuf_string_steal(hash_key);
302 eina_hash_direct_add(vg_cache->active, se->hash_key, se);
303 }
304 eina_strbuf_free(hash_key);
305 se->ref++;
306 return se;
307}
308
309Efl_VG*
310evas_cache_vg_tree_get(Evas_Cache_Vg_Entry *entry)
311{
312 if (entry->root) return entry->root;
313
314 if (entry->file)
315 {
316 _evas_cache_svg_vg_tree_update(entry);
317 }
318 return entry->root;
319}
320
321void
322evas_cache_vg_entry_del(Evas_Cache_Vg_Entry *svg_entry)
323{
324 if (!svg_entry) return;
325
326 svg_entry->ref--;
327}
328