2 * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
8 #include "evas_common.h"
9 #include "evas_private.h"
11 #define FREESTRC(Var) \
14 evas_stringshare_del(Var); \
18 static void _evas_cache_image_entry_delete(Evas_Cache_Image *cache, Image_Entry *ie);
21 _evas_cache_image_make_dirty(Evas_Cache_Image *cache,
27 im->flags.lru_nodata = 0;
28 cache->dirty = evas_object_list_prepend(cache->dirty, im);
32 evas_stringshare_del(im->cache_key);
38 _evas_cache_image_make_activ(Evas_Cache_Image *cache,
47 im->flags.lru_nodata = 0;
49 cache->activ = evas_hash_direct_add(cache->activ, key, im);
53 _evas_cache_image_make_dirty(cache, im);
58 _evas_cache_image_make_inactiv(Evas_Cache_Image *cache,
67 cache->inactiv = evas_hash_direct_add(cache->inactiv, key, im);
68 cache->lru = evas_object_list_prepend(cache->lru, im);
69 cache->usage += cache->func.mem_size_get(im);
73 _evas_cache_image_entry_delete(cache, im);
78 _evas_cache_image_remove_lru_nodata(Evas_Cache_Image *cache,
81 if (im->flags.lru_nodata)
83 im->flags.lru_nodata = 0;
84 cache->lru_nodata = evas_object_list_remove(cache->lru_nodata, im);
85 cache->usage -= cache->func.mem_size_get(im);
90 _evas_cache_image_activ_lru_nodata(Evas_Cache_Image *cache,
93 im->flags.need_data = 0;
94 im->flags.lru_nodata = 1;
95 cache->lru_nodata = evas_object_list_prepend(cache->lru_nodata, im);
96 cache->usage += cache->func.mem_size_get(im);
100 _evas_cache_image_remove_activ(Evas_Cache_Image *cache,
103 if (ie->flags.cached)
107 cache->activ = evas_hash_del(cache->activ, ie->cache_key, ie);
108 _evas_cache_image_remove_lru_nodata(cache, ie);
114 cache->dirty = evas_object_list_remove(cache->dirty, ie);
118 cache->inactiv = evas_hash_del(cache->inactiv, ie->cache_key, ie);
119 cache->lru = evas_object_list_remove(cache->lru, ie);
120 cache->usage -= cache->func.mem_size_get(ie);
123 ie->flags.cached = 0;
130 _evas_cache_image_entry_delete(Evas_Cache_Image *cache, Image_Entry *ie)
134 if (cache->func.debug)
135 cache->func.debug("deleting", ie);
137 cache->func.destructor(ie);
139 _evas_cache_image_remove_activ(cache, ie);
143 evas_stringshare_del(ie->cache_key);
144 ie->cache_key = NULL;
150 cache->func.surface_delete(ie);
151 cache->func.dealloc(ie);
155 _evas_cache_image_entry_new(Evas_Cache_Image *cache,
160 RGBA_Image_Loadopts *lo,
164 const char *cache_key;
166 ie = cache->func.alloc();
170 cache_key = hkey ? evas_stringshare_add(hkey) : NULL;
172 ie->flags.loaded = 0;
173 ie->flags.need_data = 1;
175 _evas_cache_image_make_activ(cache, ie, cache_key);
177 ie->space = EVAS_COLORSPACE_ARGB8888;
186 ie->file = file ? evas_stringshare_add(file) : NULL;
187 ie->key = key ? evas_stringshare_add(key) : NULL;
189 ie->timestamp = timestamp;
190 ie->laststat = time(NULL);
192 ie->load_opts.scale_down_by = 0;
193 ie->load_opts.dpi = 0;
203 *error = cache->func.constructor(ie);
206 _evas_cache_image_entry_delete(cache, ie);
210 if (cache->func.debug)
211 cache->func.debug("build", ie);
217 _evas_cache_image_entry_surface_alloc(Evas_Cache_Image *cache,
225 wmin = w > 0 ? w : 1;
226 hmin = h > 0 ? h : 1;
227 if (ie->allocated.w == wmin && ie->allocated.h == hmin)
230 if (cache->func.surface_alloc(ie, wmin, hmin))
237 ie->allocated.w = wmin;
238 ie->allocated.h = hmin;
242 evas_cache_image_usage_get(Evas_Cache_Image *cache)
244 assert(cache != NULL);
250 evas_cache_image_get(Evas_Cache_Image *cache)
252 assert(cache != NULL);
258 evas_cache_image_set(Evas_Cache_Image *cache, int limit)
260 assert(cache != NULL);
261 if (cache->limit == limit) return;
262 cache->limit = limit;
263 evas_cache_image_flush(cache);
266 EAPI Evas_Cache_Image *
267 evas_cache_image_init(const Evas_Cache_Image_Func *cb)
269 Evas_Cache_Image *new;
271 new = malloc(sizeof (Evas_Cache_Image));
282 new->lru_nodata = NULL;
292 _evas_cache_image_free_cb(const Evas_Hash *hash, const char *key, void *data, void *fdata)
294 Evas_Cache_Image *cache = fdata;
295 Image_Entry *im = data;
297 _evas_cache_image_entry_delete(cache, im);
303 evas_cache_image_shutdown(Evas_Cache_Image *cache)
307 assert(cache != NULL);
310 if (cache->references > 0)
315 im = (Image_Entry *) cache->lru;
316 _evas_cache_image_entry_delete(cache, im);
319 while (cache->lru_nodata)
321 im = (Image_Entry *) cache->lru_nodata;
322 _evas_cache_image_entry_delete(cache, im);
325 /* This is mad, I am about to destroy image still alive, but we need to prevent leak. */
328 im = (Image_Entry *) cache->dirty;
329 _evas_cache_image_entry_delete(cache, im);
332 evas_hash_foreach(cache->activ, _evas_cache_image_free_cb, cache);
333 evas_hash_free(cache->activ);
334 evas_hash_free(cache->inactiv);
342 evas_cache_image_request(Evas_Cache_Image *cache, const char *file, const char *key, RGBA_Image_Loadopts *lo, int *error)
347 Evas_Image_Load_Opts prevent;
352 assert(cache != NULL);
354 if (!file && !key) return NULL;
355 if (!file) return NULL;
358 (lo->scale_down_by == 0) &&
360 ((lo->w == 0) || (lo->h == 0))))
364 format = "%s//://%s";
366 format = "%s//://%p";
371 format = "%s//://%s//@/%i/%1.5f/%ix%i";
373 format = "%s//://%p//@/%i/%1.5f/%ix%i";
375 size = strlen(file) + (key ? strlen(key) : 6) + 64;
376 hkey = alloca(sizeof (char) * size);
377 snprintf(hkey, size, format, file, key, lo->scale_down_by, lo->dpi, lo->w, lo->h);
379 im = evas_hash_find(cache->activ, hkey);
388 if ((t - im->laststat) > STAT_GAP)
391 if (stat(file, &st) < 0) goto on_error;
394 if (st.st_mtime != im->timestamp) ok = 0;
398 _evas_cache_image_remove_activ(cache, im);
399 _evas_cache_image_make_dirty(cache, im);
402 im = evas_hash_find(cache->inactiv, hkey);
413 if ((t - im->laststat) > STAT_GAP)
416 if (stat(file, &st) < 0) goto on_error;
419 if (st.st_mtime != im->timestamp) ok = 0;
423 if (st.st_mtime != im->timestamp) ok = 0;
427 _evas_cache_image_remove_activ(cache, im);
428 _evas_cache_image_make_activ(cache, im, im->cache_key);
432 _evas_cache_image_entry_delete(cache, im);
437 if (stat(file, &st) < 0) return NULL;
440 im = _evas_cache_image_entry_new(cache, hkey, st.st_mtime, file, key, lo, error);
444 if (cache->func.debug)
445 cache->func.debug("request", im);
450 if (im->references > 1 && im->flags.lru_nodata)
451 _evas_cache_image_remove_lru_nodata(cache, im);
456 _evas_cache_image_entry_delete(cache, im);
461 evas_cache_image_drop(Image_Entry *im)
463 Evas_Cache_Image *cache;
471 if (im->references == 0)
475 _evas_cache_image_entry_delete(cache, im);
479 _evas_cache_image_remove_activ(cache, im);
480 _evas_cache_image_make_inactiv(cache, im, im->cache_key);
481 evas_cache_image_flush(cache);
486 evas_cache_image_data_not_needed(Image_Entry *im)
488 Evas_Cache_Image *cache;
495 if (im->references > 1) return ;
496 if (im->flags.dirty || !im->flags.need_data) return ;
498 _evas_cache_image_activ_lru_nodata(cache, im);
502 evas_cache_image_dirty(Image_Entry *im, int x, int y, int w, int h)
504 Image_Entry *im_dirty = im;
505 Evas_Cache_Image *cache;
511 if (!(im->flags.dirty))
513 if (im->references == 1) im_dirty = im;
518 im_dirty = _evas_cache_image_entry_new(cache, NULL, im->timestamp, im->file, im->key, &im->load_opts, &error);
519 if (!im_dirty) goto on_error;
521 if (cache->func.debug)
522 cache->func.debug("dirty-src", im);
523 error = cache->func.dirty(im_dirty, im);
524 if (cache->func.debug)
525 cache->func.debug("dirty-out", im_dirty);
527 if (error != 0) goto on_error;
529 im_dirty->references = 1;
531 evas_cache_image_drop(im);
534 _evas_cache_image_remove_activ(cache, im_dirty);
535 _evas_cache_image_make_dirty(cache, im_dirty);
538 if (cache->func.debug)
539 cache->func.debug("dirty-region", im_dirty);
540 if (cache->func.dirty_region)
541 cache->func.dirty_region(im_dirty, x, y, w, h);
546 if (im_dirty) _evas_cache_image_entry_delete(cache, im_dirty);
547 evas_cache_image_drop(im);
552 evas_cache_image_alone(Image_Entry *im)
554 Evas_Cache_Image *cache;
555 Image_Entry *im_dirty = im;
561 if (im->references == 1)
563 if (!(im->flags.dirty))
565 _evas_cache_image_remove_activ(cache, im);
566 _evas_cache_image_make_dirty(cache, im);
573 im_dirty = _evas_cache_image_entry_new(cache, NULL, im->timestamp, im->file, im->key, &im->load_opts, &error);
574 if (!im_dirty) goto on_error;
576 if (cache->func.debug)
577 cache->func.debug("dirty-src", im);
578 error = cache->func.dirty(im_dirty, im);
579 if (cache->func.debug)
580 cache->func.debug("dirty-out", im_dirty);
582 if (error != 0) goto on_error;
584 im_dirty->references = 1;
586 evas_cache_image_drop(im);
592 if (im_dirty) _evas_cache_image_entry_delete(cache, im_dirty);
593 evas_cache_image_drop(im);
598 evas_cache_image_copied_data(Evas_Cache_Image *cache, int w, int h, DATA32 *image_data, int alpha, int cspace)
604 if ((cspace == EVAS_COLORSPACE_YCBCR422P601_PL) ||
605 (cspace == EVAS_COLORSPACE_YCBCR422P709_PL))
608 im = _evas_cache_image_entry_new(cache, NULL, 0, NULL, NULL, NULL, NULL);
609 if (!im) return NULL;
612 im->flags.alpha = alpha;
614 _evas_cache_image_entry_surface_alloc(cache, im, w, h);
616 if (cache->func.copied_data(im, w, h, image_data, alpha, cspace) != 0)
618 _evas_cache_image_entry_delete(cache, im);
623 if (cache->func.debug)
624 cache->func.debug("copied-data", im);
629 evas_cache_image_data(Evas_Cache_Image *cache, int w, int h, DATA32 *image_data, int alpha, int cspace)
635 if ((cspace == EVAS_COLORSPACE_YCBCR422P601_PL) ||
636 (cspace == EVAS_COLORSPACE_YCBCR422P709_PL))
639 im = _evas_cache_image_entry_new(cache, NULL, 0, NULL, NULL, NULL, NULL);
642 im->flags.alpha = alpha;
644 if (cache->func.data(im, w, h, image_data, alpha, cspace) != 0)
646 _evas_cache_image_entry_delete(cache, im);
651 if (cache->func.debug)
652 cache->func.debug("data", im);
657 evas_cache_image_surface_alloc(Image_Entry *im, int w, int h)
659 Evas_Cache_Image *cache;
666 if ((im->space == EVAS_COLORSPACE_YCBCR422P601_PL) ||
667 (im->space == EVAS_COLORSPACE_YCBCR422P709_PL))
670 _evas_cache_image_entry_surface_alloc(cache, im, w, h);
672 if (cache->func.debug)
673 cache->func.debug("surface-alloc", im);
677 evas_cache_image_size_set(Image_Entry *im, int w, int h)
679 Evas_Cache_Image *cache;
685 assert(im->references > 0);
687 if ((im->space == EVAS_COLORSPACE_YCBCR422P601_PL) ||
688 (im->space == EVAS_COLORSPACE_YCBCR422P709_PL))
691 if ((im->w == w) && (im->h == h))
696 new = _evas_cache_image_entry_new(cache, NULL, 0, NULL, NULL, NULL, &error);
697 if (!new) goto on_error;
699 new->flags.alpha = im->flags.alpha;
700 new->space = im->space;
701 new->load_opts = im->load_opts;
703 _evas_cache_image_entry_surface_alloc(cache, new, w, h);
705 error = cache->func.size_set(new, im, w, h);
706 if (error != 0) goto on_error;
710 evas_cache_image_drop(im);
712 if (cache->func.debug)
713 cache->func.debug("size_set", new);
718 if (new) _evas_cache_image_entry_delete(cache, new);
719 evas_cache_image_drop(im);
724 evas_cache_image_load_data(Image_Entry *im)
726 Evas_Cache_Image *cache;
732 if (im->flags.loaded) return ;
736 error = cache->func.load(im);
738 if (cache->func.debug)
739 cache->func.debug("load", im);
743 _evas_cache_image_entry_surface_alloc(cache, im, im->w, im->h);
744 im->flags.loaded = 0;
749 im->flags.loaded = 1;
753 evas_cache_image_flush(Evas_Cache_Image *cache)
757 // printf("cache->limit = %i (used = %i)\n", cache->limit, cache->usage);
758 if (cache->limit == -1)
761 while ((cache->lru) && (cache->limit < cache->usage))
765 im = (Image_Entry *) cache->lru->last;
766 _evas_cache_image_entry_delete(cache, im);
769 while ((cache->lru_nodata) && (cache->limit < cache->usage))
773 im = (Image_Entry *) cache->lru_nodata->last;
774 _evas_cache_image_remove_lru_nodata(cache, im);
776 cache->func.surface_delete(im);
778 im->flags.loaded = 0;
785 evas_cache_image_empty(Evas_Cache_Image *cache)
789 new = _evas_cache_image_entry_new(cache, NULL, 0, NULL, NULL, NULL, NULL);
790 if (!new) return NULL;
798 evas_cache_image_colorspace(Image_Entry *im, int cspace)
800 Evas_Cache_Image *cache;
807 if (im->space == cspace) return ;
810 cache->func.color_space(im, cspace);
814 evas_cache_private_from_image_entry_get(Image_Entry *im)
816 Evas_Cache_Image *cache;
823 return (void*) cache->data;
827 evas_cache_private_get(Evas_Cache_Image *cache)
835 evas_cache_private_set(Evas_Cache_Image *cache, const void *data)
843 evas_cache_image_pixels(Image_Entry *im)
845 Evas_Cache_Image *cache;
852 return cache->func.surface_pixels(im);