diff options
Diffstat (limited to 'libraries/evas/src/lib/cache/evas_cache_engine_image.c')
-rw-r--r-- | libraries/evas/src/lib/cache/evas_cache_engine_image.c | 699 |
1 files changed, 699 insertions, 0 deletions
diff --git a/libraries/evas/src/lib/cache/evas_cache_engine_image.c b/libraries/evas/src/lib/cache/evas_cache_engine_image.c new file mode 100644 index 0000000..8ae4392 --- /dev/null +++ b/libraries/evas/src/lib/cache/evas_cache_engine_image.c | |||
@@ -0,0 +1,699 @@ | |||
1 | #include <assert.h> | ||
2 | |||
3 | #include "evas_common.h" | ||
4 | #include "evas_private.h" | ||
5 | |||
6 | static void | ||
7 | _evas_cache_engine_image_make_dirty(Evas_Cache_Engine_Image *cache, | ||
8 | Engine_Image_Entry *eim) | ||
9 | { | ||
10 | eim->flags.cached = 1; | ||
11 | eim->flags.dirty = 1; | ||
12 | eim->flags.loaded = 1; | ||
13 | eim->flags.activ = 0; | ||
14 | cache->dirty = eina_inlist_prepend(cache->dirty, EINA_INLIST_GET(eim)); | ||
15 | } | ||
16 | |||
17 | static void | ||
18 | _evas_cache_engine_image_make_active(Evas_Cache_Engine_Image *cache, | ||
19 | Engine_Image_Entry *eim, | ||
20 | const char *key) | ||
21 | { | ||
22 | eim->flags.cached = 1; | ||
23 | eim->flags.activ = 1; | ||
24 | eim->flags.dirty = 0; | ||
25 | eina_hash_add(cache->activ, key, eim); | ||
26 | } | ||
27 | |||
28 | static void | ||
29 | _evas_cache_engine_image_make_inactive(Evas_Cache_Engine_Image *cache, | ||
30 | Engine_Image_Entry *eim, | ||
31 | const char *key) | ||
32 | { | ||
33 | eim->flags.cached = 1; | ||
34 | eim->flags.dirty = 0; | ||
35 | eim->flags.activ = 0; | ||
36 | eina_hash_add(cache->inactiv, key, eim); | ||
37 | cache->lru = eina_inlist_prepend(cache->lru, EINA_INLIST_GET(eim)); | ||
38 | cache->usage += cache->func.mem_size_get(eim); | ||
39 | } | ||
40 | |||
41 | static void | ||
42 | _evas_cache_engine_image_remove_activ(Evas_Cache_Engine_Image *cache, | ||
43 | Engine_Image_Entry *eim) | ||
44 | { | ||
45 | if (eim->flags.cached) | ||
46 | { | ||
47 | if (eim->flags.dirty) | ||
48 | { | ||
49 | cache->dirty = eina_inlist_remove(cache->dirty, EINA_INLIST_GET(eim)); | ||
50 | } | ||
51 | else | ||
52 | if (eim->flags.activ) | ||
53 | { | ||
54 | eina_hash_del(cache->activ, eim->cache_key, eim); | ||
55 | } | ||
56 | else | ||
57 | { | ||
58 | cache->usage -= cache->func.mem_size_get(eim); | ||
59 | eina_hash_del(cache->inactiv, eim->cache_key, eim); | ||
60 | cache->lru = eina_inlist_remove(cache->lru, EINA_INLIST_GET(eim)); | ||
61 | } | ||
62 | eim->flags.cached = 0; | ||
63 | eim->flags.dirty = 0; | ||
64 | eim->flags.activ = 0; | ||
65 | } | ||
66 | } | ||
67 | |||
68 | static Engine_Image_Entry * | ||
69 | _evas_cache_engine_image_alloc(Evas_Cache_Engine_Image *cache, | ||
70 | Image_Entry *ie, | ||
71 | const char *hkey) | ||
72 | { | ||
73 | Engine_Image_Entry *eim; | ||
74 | |||
75 | assert(cache); | ||
76 | |||
77 | if (cache->func.alloc) | ||
78 | eim = cache->func.alloc(); | ||
79 | else | ||
80 | eim = malloc(sizeof (Engine_Image_Entry)); | ||
81 | |||
82 | if (!eim) goto on_error; | ||
83 | memset(eim, 0, sizeof (Engine_Image_Entry)); | ||
84 | |||
85 | eim->cache = cache; | ||
86 | if (ie) | ||
87 | { | ||
88 | eim->w = ie->w; | ||
89 | eim->h = ie->h; | ||
90 | eim->src = ie; | ||
91 | eim->flags.need_parent = 1; | ||
92 | } | ||
93 | else | ||
94 | { | ||
95 | eim->w = -1; | ||
96 | eim->h = -1; | ||
97 | eim->flags.need_parent = 0; | ||
98 | eim->src = NULL; | ||
99 | } | ||
100 | |||
101 | eim->flags.cached = 0; | ||
102 | eim->references = 0; | ||
103 | eim->cache_key = hkey; | ||
104 | |||
105 | if (hkey) | ||
106 | _evas_cache_engine_image_make_active(cache, eim, hkey); | ||
107 | else | ||
108 | _evas_cache_engine_image_make_dirty(cache, eim); | ||
109 | |||
110 | return eim; | ||
111 | |||
112 | on_error: | ||
113 | if (eim) | ||
114 | evas_cache_engine_image_drop(eim); | ||
115 | eina_stringshare_del(hkey); | ||
116 | evas_cache_image_drop(ie); | ||
117 | return NULL; | ||
118 | } | ||
119 | |||
120 | static void | ||
121 | _evas_cache_engine_image_dealloc(Evas_Cache_Engine_Image *cache, Engine_Image_Entry *eim) | ||
122 | { | ||
123 | Image_Entry *im; | ||
124 | |||
125 | if (cache->func.debug) cache->func.debug("delete", eim); | ||
126 | |||
127 | _evas_cache_engine_image_remove_activ(cache, eim); | ||
128 | |||
129 | im = eim->src; | ||
130 | cache->func.destructor(eim); | ||
131 | if (im) evas_cache_image_drop(im); | ||
132 | |||
133 | if (cache->func.dealloc) | ||
134 | { | ||
135 | cache->func.dealloc(eim); | ||
136 | } | ||
137 | else | ||
138 | { | ||
139 | memset(eim, 0, sizeof (Engine_Image_Entry)); | ||
140 | free(eim); | ||
141 | } | ||
142 | } | ||
143 | |||
144 | EAPI int | ||
145 | evas_cache_engine_image_usage_get(Evas_Cache_Engine_Image *cache) | ||
146 | { | ||
147 | assert(cache != NULL); | ||
148 | |||
149 | return cache->usage; | ||
150 | } | ||
151 | |||
152 | EAPI int | ||
153 | evas_cache_engine_image_get(Evas_Cache_Engine_Image *cache) | ||
154 | { | ||
155 | assert(cache != NULL); | ||
156 | |||
157 | return cache->limit; | ||
158 | } | ||
159 | |||
160 | EAPI void | ||
161 | evas_cache_engine_image_set(Evas_Cache_Engine_Image *cache, int limit) | ||
162 | { | ||
163 | assert(cache != NULL); | ||
164 | |||
165 | cache->limit = limit; | ||
166 | } | ||
167 | |||
168 | EAPI Evas_Cache_Engine_Image * | ||
169 | evas_cache_engine_image_init(const Evas_Cache_Engine_Image_Func *cb, Evas_Cache_Image *parent) | ||
170 | { | ||
171 | Evas_Cache_Engine_Image *new; | ||
172 | |||
173 | new = malloc(sizeof (Evas_Cache_Engine_Image)); | ||
174 | if (!new) | ||
175 | return NULL; | ||
176 | |||
177 | new->func = *cb; | ||
178 | |||
179 | new->limit = 0; | ||
180 | new->usage = 0; | ||
181 | |||
182 | new->dirty = NULL; | ||
183 | new->lru = NULL; | ||
184 | new->activ = eina_hash_string_superfast_new(NULL); | ||
185 | new->inactiv = eina_hash_string_superfast_new(NULL); | ||
186 | |||
187 | new->parent = parent; | ||
188 | parent->references++; | ||
189 | |||
190 | new->brother = NULL; | ||
191 | |||
192 | return new; | ||
193 | } | ||
194 | |||
195 | EAPI Evas_Cache_Engine_Image * | ||
196 | evas_cache_engine_image_dup(const Evas_Cache_Engine_Image_Func *cb, Evas_Cache_Engine_Image *brother) | ||
197 | { | ||
198 | Evas_Cache_Engine_Image *new; | ||
199 | |||
200 | new = calloc(1, sizeof (Evas_Cache_Engine_Image)); | ||
201 | if (!new) | ||
202 | return NULL; | ||
203 | |||
204 | new->func = brother->func; | ||
205 | |||
206 | #define ORD(Func) if (cb->Func) new->func.Func = cb->Func; | ||
207 | |||
208 | ORD(key); | ||
209 | ORD(constructor); | ||
210 | ORD(destructor); | ||
211 | ORD(dirty_region); | ||
212 | ORD(dirty); | ||
213 | ORD(size_set); | ||
214 | ORD(update_data); | ||
215 | ORD(load); | ||
216 | ORD(mem_size_get); | ||
217 | ORD(debug); | ||
218 | |||
219 | #undef ORD | ||
220 | |||
221 | new->limit = -1; | ||
222 | new->usage = 0; | ||
223 | new->references = 1; | ||
224 | |||
225 | new->dirty = NULL; | ||
226 | new->activ = NULL; | ||
227 | |||
228 | new->parent = brother->parent; | ||
229 | new->parent->references++; | ||
230 | |||
231 | new->brother = brother; | ||
232 | brother->references++; | ||
233 | |||
234 | return new; | ||
235 | } | ||
236 | |||
237 | static Eina_Bool | ||
238 | _evas_cache_engine_image_free_cb(__UNUSED__ const Eina_Hash *hash, __UNUSED__ const void *key, void *data, void *fdata) | ||
239 | { | ||
240 | Eina_List **delete_list = fdata; | ||
241 | |||
242 | *delete_list = eina_list_prepend(*delete_list, data); | ||
243 | |||
244 | return EINA_TRUE; | ||
245 | } | ||
246 | |||
247 | EAPI void | ||
248 | evas_cache_engine_image_flush(Evas_Cache_Engine_Image *cache) | ||
249 | { | ||
250 | assert(cache != NULL); | ||
251 | |||
252 | while ((cache->lru) && (cache->limit < cache->usage)) | ||
253 | { | ||
254 | Engine_Image_Entry *eim; | ||
255 | |||
256 | eim = (Engine_Image_Entry *) cache->lru->last; | ||
257 | _evas_cache_engine_image_dealloc(cache, eim); | ||
258 | } | ||
259 | } | ||
260 | |||
261 | EAPI void | ||
262 | evas_cache_engine_image_shutdown(Evas_Cache_Engine_Image *cache) | ||
263 | { | ||
264 | Engine_Image_Entry *eim; | ||
265 | Eina_List *delete_list = NULL; | ||
266 | |||
267 | assert(cache != NULL); | ||
268 | |||
269 | if (cache->func.debug) cache->func.debug("shutdown-engine", NULL); | ||
270 | |||
271 | eina_hash_foreach(cache->inactiv, _evas_cache_engine_image_free_cb, &delete_list); | ||
272 | eina_hash_foreach(cache->activ, _evas_cache_engine_image_free_cb, &delete_list); | ||
273 | |||
274 | while (delete_list) | ||
275 | { | ||
276 | _evas_cache_engine_image_dealloc(cache, eina_list_data_get(delete_list)); | ||
277 | delete_list = eina_list_remove_list(delete_list, delete_list); | ||
278 | } | ||
279 | |||
280 | eina_hash_free(cache->inactiv); | ||
281 | eina_hash_free(cache->activ); | ||
282 | |||
283 | /* This is mad, I am about to destroy image still alive, but we need to prevent leak. */ | ||
284 | while (cache->dirty) | ||
285 | { | ||
286 | eim = (Engine_Image_Entry *) cache->dirty; | ||
287 | _evas_cache_engine_image_dealloc(cache, eim); | ||
288 | } | ||
289 | |||
290 | |||
291 | evas_cache_image_shutdown(cache->parent); | ||
292 | if (cache->brother) | ||
293 | evas_cache_engine_image_shutdown(cache->brother); | ||
294 | free(cache); | ||
295 | } | ||
296 | |||
297 | EAPI Engine_Image_Entry * | ||
298 | evas_cache_engine_image_request(Evas_Cache_Engine_Image *cache, | ||
299 | const char *file, const char *key, | ||
300 | RGBA_Image_Loadopts *lo, void *data, int *error) | ||
301 | { | ||
302 | Engine_Image_Entry *eim; | ||
303 | Image_Entry *im; | ||
304 | const char *ekey; | ||
305 | |||
306 | assert(cache != NULL); | ||
307 | |||
308 | *error = EVAS_LOAD_ERROR_NONE; | ||
309 | |||
310 | ekey = NULL; | ||
311 | eim = NULL; | ||
312 | |||
313 | im = evas_cache_image_request(cache->parent, file, key, lo, error); | ||
314 | if (!im) | ||
315 | goto on_error; | ||
316 | |||
317 | if (cache->func.key) | ||
318 | ekey = cache->func.key(im, file, key, lo, data); | ||
319 | else | ||
320 | ekey = eina_stringshare_add(im->cache_key); | ||
321 | if (!ekey) | ||
322 | { | ||
323 | *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED; | ||
324 | goto on_error; | ||
325 | } | ||
326 | |||
327 | eim = eina_hash_find(cache->activ, ekey); | ||
328 | if (eim) | ||
329 | { | ||
330 | evas_cache_image_drop(im); | ||
331 | goto on_ok; | ||
332 | } | ||
333 | |||
334 | eim = eina_hash_find(cache->inactiv, ekey); | ||
335 | if (eim) | ||
336 | { | ||
337 | _evas_cache_engine_image_remove_activ(cache, eim); | ||
338 | _evas_cache_engine_image_make_active(cache, eim, ekey); | ||
339 | evas_cache_image_drop(im); | ||
340 | goto on_ok; | ||
341 | } | ||
342 | |||
343 | eim = _evas_cache_engine_image_alloc(cache, im, ekey); | ||
344 | if (!eim) | ||
345 | { | ||
346 | *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED; | ||
347 | return NULL; | ||
348 | } | ||
349 | |||
350 | *error = cache->func.constructor(eim, data); | ||
351 | if (*error != EVAS_LOAD_ERROR_NONE) goto on_error; | ||
352 | if (cache->func.debug) | ||
353 | cache->func.debug("constructor-engine", eim); | ||
354 | |||
355 | on_ok: | ||
356 | eim->references++; | ||
357 | return eim; | ||
358 | |||
359 | on_error: | ||
360 | if (!eim) | ||
361 | { | ||
362 | if (im) evas_cache_image_drop(im); | ||
363 | if (ekey) eina_stringshare_del(ekey); | ||
364 | } | ||
365 | else | ||
366 | { | ||
367 | _evas_cache_engine_image_dealloc(cache, eim); | ||
368 | } | ||
369 | |||
370 | return NULL; | ||
371 | } | ||
372 | |||
373 | EAPI void | ||
374 | evas_cache_engine_image_drop(Engine_Image_Entry *eim) | ||
375 | { | ||
376 | Evas_Cache_Engine_Image *cache; | ||
377 | |||
378 | assert(eim); | ||
379 | assert(eim->cache); | ||
380 | |||
381 | eim->references--; | ||
382 | cache = eim->cache; | ||
383 | |||
384 | if (eim->flags.dirty) | ||
385 | { | ||
386 | _evas_cache_engine_image_dealloc(cache, eim); | ||
387 | return ; | ||
388 | } | ||
389 | |||
390 | if (eim->references == 0) | ||
391 | { | ||
392 | _evas_cache_engine_image_remove_activ(cache, eim); | ||
393 | _evas_cache_engine_image_make_inactive(cache, eim, eim->cache_key); | ||
394 | evas_cache_engine_image_flush(cache); | ||
395 | return ; | ||
396 | } | ||
397 | } | ||
398 | |||
399 | EAPI Engine_Image_Entry * | ||
400 | evas_cache_engine_image_dirty(Engine_Image_Entry *eim, unsigned int x, unsigned int y, unsigned int w, unsigned int h) | ||
401 | { | ||
402 | Engine_Image_Entry *eim_dirty = eim; | ||
403 | Image_Entry *im_dirty = NULL; | ||
404 | Image_Entry *im; | ||
405 | Evas_Cache_Engine_Image *cache; | ||
406 | unsigned char alloc_eim; | ||
407 | |||
408 | assert(eim); | ||
409 | assert(eim->cache); | ||
410 | |||
411 | cache = eim->cache; | ||
412 | if (!(eim->flags.dirty)) | ||
413 | { | ||
414 | alloc_eim = 0; | ||
415 | |||
416 | if (eim->flags.need_parent == 1) | ||
417 | { | ||
418 | im = eim->src; | ||
419 | im_dirty = evas_cache_image_dirty(im, x, y, w, h); | ||
420 | |||
421 | /* If im == im_dirty, this meens that we have only one reference to the eim. */ | ||
422 | if (im != im_dirty) | ||
423 | { | ||
424 | if (eim->references == 1) | ||
425 | { | ||
426 | _evas_cache_engine_image_remove_activ(cache, eim); | ||
427 | _evas_cache_engine_image_make_dirty(cache, eim); | ||
428 | |||
429 | eim->src = im_dirty; | ||
430 | } | ||
431 | else | ||
432 | alloc_eim = 1; | ||
433 | } | ||
434 | } | ||
435 | else | ||
436 | if (eim->references > 1) | ||
437 | { | ||
438 | alloc_eim = 1; | ||
439 | } | ||
440 | else | ||
441 | { | ||
442 | _evas_cache_engine_image_remove_activ(cache, eim_dirty); | ||
443 | _evas_cache_engine_image_make_dirty(cache, eim_dirty); | ||
444 | } | ||
445 | |||
446 | if (alloc_eim == 1) | ||
447 | { | ||
448 | int error; | ||
449 | |||
450 | eim_dirty = _evas_cache_engine_image_alloc(cache, im_dirty, NULL); | ||
451 | if (!eim_dirty) goto on_error; | ||
452 | |||
453 | eim_dirty->w = eim->w; | ||
454 | eim_dirty->h = eim->h; | ||
455 | eim_dirty->references = 1; | ||
456 | |||
457 | error = cache->func.dirty(eim_dirty, eim); | ||
458 | if (cache->func.debug) | ||
459 | cache->func.debug("dirty-engine", eim_dirty); | ||
460 | |||
461 | if (error != 0) goto on_error; | ||
462 | |||
463 | evas_cache_engine_image_drop(eim); | ||
464 | } | ||
465 | } | ||
466 | |||
467 | if (cache->func.dirty_region) | ||
468 | cache->func.dirty_region(eim_dirty, x, y, w, h); | ||
469 | if (cache->func.debug) | ||
470 | cache->func.debug("dirty-region-engine", eim_dirty); | ||
471 | |||
472 | return eim_dirty; | ||
473 | |||
474 | on_error: | ||
475 | if (eim) evas_cache_engine_image_drop(eim); | ||
476 | if (eim_dirty && eim_dirty != eim) | ||
477 | evas_cache_engine_image_drop(eim_dirty); | ||
478 | else | ||
479 | if (im_dirty) evas_cache_image_drop(im_dirty); | ||
480 | |||
481 | return NULL; | ||
482 | } | ||
483 | |||
484 | EAPI Engine_Image_Entry * | ||
485 | evas_cache_engine_image_alone(Engine_Image_Entry *eim, void *data) | ||
486 | { | ||
487 | Evas_Cache_Engine_Image *cache; | ||
488 | Image_Entry *im; | ||
489 | |||
490 | |||
491 | assert(eim); | ||
492 | assert(eim->cache); | ||
493 | |||
494 | cache = eim->cache; | ||
495 | im = evas_cache_image_alone(eim->src); | ||
496 | if (im != eim->src) | ||
497 | { | ||
498 | eim = _evas_cache_engine_image_alloc(cache, im, NULL); | ||
499 | if (!eim) goto on_error; | ||
500 | |||
501 | eim->references = 1; | ||
502 | |||
503 | if (cache->func.constructor(eim, data) != EVAS_LOAD_ERROR_NONE) | ||
504 | goto on_error; | ||
505 | } | ||
506 | /* FIXME */ | ||
507 | return eim; | ||
508 | |||
509 | on_error: | ||
510 | evas_cache_image_drop(im); | ||
511 | return NULL; | ||
512 | } | ||
513 | |||
514 | static Engine_Image_Entry * | ||
515 | _evas_cache_engine_image_push_dirty(Evas_Cache_Engine_Image *cache, Image_Entry *im, void *engine_data) | ||
516 | { | ||
517 | Engine_Image_Entry *eim; | ||
518 | int error; | ||
519 | |||
520 | eim = _evas_cache_engine_image_alloc(cache, im, NULL); | ||
521 | if (!eim) goto on_error; | ||
522 | eim->references = 1; | ||
523 | |||
524 | error = cache->func.update_data(eim, engine_data); | ||
525 | if (cache->func.debug) | ||
526 | cache->func.debug("dirty-update_data-engine", eim); | ||
527 | if (error != 0) goto on_error; | ||
528 | |||
529 | return eim; | ||
530 | |||
531 | on_error: | ||
532 | if (eim) | ||
533 | evas_cache_engine_image_drop(eim); | ||
534 | return NULL; | ||
535 | } | ||
536 | |||
537 | EAPI Engine_Image_Entry * | ||
538 | evas_cache_engine_image_copied_data(Evas_Cache_Engine_Image *cache, unsigned int w, unsigned int h, DATA32 *image_data, int alpha, int cspace, void *engine_data) | ||
539 | { | ||
540 | Image_Entry *im; | ||
541 | |||
542 | assert(cache); | ||
543 | |||
544 | im = evas_cache_image_copied_data(cache->parent, w, h, image_data, alpha, cspace); | ||
545 | |||
546 | return _evas_cache_engine_image_push_dirty(cache, im, engine_data); | ||
547 | } | ||
548 | |||
549 | EAPI Engine_Image_Entry * | ||
550 | evas_cache_engine_image_data(Evas_Cache_Engine_Image *cache, unsigned int w, unsigned int h, DATA32 *image_data, int alpha, int cspace, void *engine_data) | ||
551 | { | ||
552 | Image_Entry *im; | ||
553 | |||
554 | assert(cache); | ||
555 | |||
556 | im = evas_cache_image_data(cache->parent, w, h, image_data, alpha, cspace); | ||
557 | |||
558 | return _evas_cache_engine_image_push_dirty(cache, im, engine_data); | ||
559 | } | ||
560 | |||
561 | EAPI Engine_Image_Entry * | ||
562 | evas_cache_engine_image_size_set(Engine_Image_Entry *eim, unsigned int w, unsigned int h) | ||
563 | { | ||
564 | Evas_Cache_Engine_Image *cache; | ||
565 | Engine_Image_Entry *new; | ||
566 | Image_Entry *im; | ||
567 | const char *hkey; | ||
568 | int error; | ||
569 | |||
570 | assert(eim); | ||
571 | assert(eim->cache); | ||
572 | assert(eim->references > 0); | ||
573 | |||
574 | im = NULL; | ||
575 | cache = eim->cache; | ||
576 | |||
577 | if (eim->flags.need_parent == 1) | ||
578 | { | ||
579 | assert(eim->src); | ||
580 | |||
581 | if (eim->src->w == w | ||
582 | && eim->src->h == h) | ||
583 | return eim; | ||
584 | |||
585 | im = evas_cache_image_size_set(eim->src, w, h); | ||
586 | /* FIXME: Good idea to call update_data ? */ | ||
587 | if (im == eim->src) return eim; | ||
588 | eim->src = NULL; | ||
589 | } | ||
590 | |||
591 | hkey = (eim->references > 1 ) ? eina_stringshare_add(eim->cache_key) : NULL; | ||
592 | |||
593 | new = _evas_cache_engine_image_alloc(cache, im, hkey); | ||
594 | if (!new) goto on_error; | ||
595 | |||
596 | new->w = w; | ||
597 | new->h = h; | ||
598 | new->references = 1; | ||
599 | |||
600 | error = cache->func.size_set(new, eim); | ||
601 | if (error) goto on_error; | ||
602 | |||
603 | evas_cache_engine_image_drop(eim); | ||
604 | return new; | ||
605 | |||
606 | on_error: | ||
607 | if (new) | ||
608 | evas_cache_engine_image_drop(new); | ||
609 | else | ||
610 | if (im) | ||
611 | evas_cache_image_drop(im); | ||
612 | evas_cache_engine_image_drop(eim); | ||
613 | |||
614 | return NULL; | ||
615 | } | ||
616 | |||
617 | EAPI void | ||
618 | evas_cache_engine_image_load_data(Engine_Image_Entry *eim) | ||
619 | { | ||
620 | Evas_Cache_Engine_Image *cache; | ||
621 | int size = 0; | ||
622 | |||
623 | assert(eim); | ||
624 | assert(eim->src); | ||
625 | assert(eim->cache); | ||
626 | |||
627 | if (eim->flags.loaded) return; | ||
628 | |||
629 | if (eim->src) | ||
630 | evas_cache_image_load_data(eim->src); | ||
631 | |||
632 | cache = eim->cache; | ||
633 | if (cache->func.debug) | ||
634 | cache->func.debug("load-engine", eim); | ||
635 | |||
636 | if (eim->flags.dirty) | ||
637 | size = cache->func.mem_size_get(eim); | ||
638 | cache = eim->cache; | ||
639 | cache->func.load(eim, eim->src); | ||
640 | if (eim->flags.dirty) | ||
641 | cache->usage += cache->func.mem_size_get(eim) - size; | ||
642 | |||
643 | eim->flags.loaded = 1; | ||
644 | } | ||
645 | |||
646 | EAPI Engine_Image_Entry * | ||
647 | evas_cache_engine_image_engine(Evas_Cache_Engine_Image *cache, void *engine_data) | ||
648 | { | ||
649 | Engine_Image_Entry *eim; | ||
650 | Image_Entry *ie; | ||
651 | int error; | ||
652 | |||
653 | ie = evas_cache_image_empty(cache->parent); | ||
654 | if (!ie) return NULL; | ||
655 | |||
656 | eim = _evas_cache_engine_image_alloc(cache, ie, NULL); | ||
657 | if (!eim) goto on_error; | ||
658 | eim->references = 1; | ||
659 | |||
660 | error = cache->func.update_data(eim, engine_data); | ||
661 | if (cache->func.debug) | ||
662 | cache->func.debug("update_data-engine", eim); | ||
663 | |||
664 | if (error != 0) goto on_error; | ||
665 | |||
666 | return eim; | ||
667 | |||
668 | on_error: | ||
669 | if (!eim) | ||
670 | evas_cache_image_drop(ie); | ||
671 | else | ||
672 | evas_cache_engine_image_drop(eim); | ||
673 | |||
674 | return NULL; | ||
675 | } | ||
676 | |||
677 | EAPI void | ||
678 | evas_cache_engine_image_colorspace(Engine_Image_Entry *eim, int cspace, void *engine_data) | ||
679 | { | ||
680 | Evas_Cache_Engine_Image *cache = eim->cache; | ||
681 | |||
682 | assert(cache); | ||
683 | |||
684 | cache->func.destructor(eim); | ||
685 | evas_cache_image_colorspace(eim->src, cspace); | ||
686 | cache->func.constructor(eim, engine_data); | ||
687 | if (cache->func.debug) | ||
688 | cache->func.debug("cosntructor-colorspace-engine", eim); | ||
689 | } | ||
690 | |||
691 | EAPI void | ||
692 | evas_cache_engine_parent_not_needed(Engine_Image_Entry *eim) | ||
693 | { | ||
694 | assert(eim); | ||
695 | assert(eim->cache); | ||
696 | |||
697 | eim->flags.need_parent = 0; | ||
698 | evas_cache_image_data_not_needed(eim->src); | ||
699 | } | ||