15 #include "evas_common.h"
16 #include "evas_private.h"
21 // FIXME: cache server and threaded preload clash badly atm - disable
22 //#undef BUILD_ASYNC_PRELOAD
25 #ifdef BUILD_ASYNC_PRELOAD
26 typedef struct _Evas_Cache_Preload Evas_Cache_Preload;
28 struct _Evas_Cache_Preload
34 static LK(engine_lock);
36 static int _evas_cache_mutex_init = 0;
38 static Eina_Condition cond_wakeup;
40 static void _evas_cache_image_entry_preload_remove(Image_Entry *ie, const void *target);
43 #define FREESTRC(Var) \
46 eina_stringshare_del(Var); \
50 static void _evas_cache_image_dirty_add(Image_Entry *im);
51 static void _evas_cache_image_dirty_del(Image_Entry *im);
52 static void _evas_cache_image_activ_add(Image_Entry *im);
53 static void _evas_cache_image_activ_del(Image_Entry *im);
54 static void _evas_cache_image_lru_add(Image_Entry *im);
55 static void _evas_cache_image_lru_del(Image_Entry *im);
56 static void _evas_cache_image_lru_nodata_add(Image_Entry *im);
57 static void _evas_cache_image_lru_nodata_del(Image_Entry *im);
60 _evas_cache_image_dirty_add(Image_Entry *im)
62 if (im->flags.dirty) return;
63 _evas_cache_image_activ_del(im);
64 _evas_cache_image_lru_del(im);
65 _evas_cache_image_lru_nodata_del(im);
68 #ifdef EVAS_FRAME_QUEUING
71 im->cache->dirty = eina_inlist_prepend(im->cache->dirty, EINA_INLIST_GET(im));
72 #ifdef EVAS_FRAME_QUEUING
77 eina_stringshare_del(im->cache_key);
83 _evas_cache_image_dirty_del(Image_Entry *im)
85 if (!im->flags.dirty) return;
88 #ifdef EVAS_FRAME_QUEUING
91 im->cache->dirty = eina_inlist_remove(im->cache->dirty, EINA_INLIST_GET(im));
92 #ifdef EVAS_FRAME_QUEUING
98 _evas_cache_image_activ_add(Image_Entry *im)
100 if (im->flags.activ) return;
101 _evas_cache_image_dirty_del(im);
102 _evas_cache_image_lru_del(im);
103 _evas_cache_image_lru_nodata_del(im);
104 if (!im->cache_key) return;
106 im->flags.cached = 1;
107 #ifdef EVAS_FRAME_QUEUING
108 LKL(im->cache->lock);
110 eina_hash_direct_add(im->cache->activ, im->cache_key, im);
111 #ifdef EVAS_FRAME_QUEUING
112 LKU(im->cache->lock);
117 _evas_cache_image_activ_del(Image_Entry *im)
119 if (!im->flags.activ) return;
120 if (!im->cache_key) return;
122 im->flags.cached = 0;
123 #ifdef EVAS_FRAME_QUEUING
124 LKL(im->cache->lock);
126 eina_hash_del(im->cache->activ, im->cache_key, im);
127 #ifdef EVAS_FRAME_QUEUING
128 LKU(im->cache->lock);
133 _evas_cache_image_lru_add(Image_Entry *im)
135 if (im->flags.lru) return;
136 _evas_cache_image_dirty_del(im);
137 _evas_cache_image_activ_del(im);
138 _evas_cache_image_lru_nodata_del(im);
139 if (!im->cache_key) return;
141 im->flags.cached = 1;
142 #ifdef EVAS_FRAME_QUEUING
143 LKL(im->cache->lock);
145 eina_hash_direct_add(im->cache->inactiv, im->cache_key, im);
146 im->cache->lru = eina_inlist_prepend(im->cache->lru, EINA_INLIST_GET(im));
147 im->cache->usage += im->cache->func.mem_size_get(im);
148 #ifdef EVAS_FRAME_QUEUING
149 LKU(im->cache->lock);
154 _evas_cache_image_lru_del(Image_Entry *im)
156 if (!im->flags.lru) return;
157 if (!im->cache_key) return;
159 im->flags.cached = 0;
160 #ifdef EVAS_FRAME_QUEUING
161 LKL(im->cache->lock);
163 eina_hash_del(im->cache->inactiv, im->cache_key, im);
164 im->cache->lru = eina_inlist_remove(im->cache->lru, EINA_INLIST_GET(im));
165 im->cache->usage -= im->cache->func.mem_size_get(im);
166 #ifdef EVAS_FRAME_QUEUING
167 LKU(im->cache->lock);
172 _evas_cache_image_lru_nodata_add(Image_Entry *im)
174 if (im->flags.lru_nodata) return;
175 _evas_cache_image_dirty_del(im);
176 _evas_cache_image_activ_del(im);
177 _evas_cache_image_lru_del(im);
179 im->flags.cached = 1;
180 #ifdef EVAS_FRAME_QUEUING
181 LKL(im->cache->lock);
183 im->cache->lru_nodata = eina_inlist_prepend(im->cache->lru_nodata, EINA_INLIST_GET(im));
184 #ifdef EVAS_FRAME_QUEUING
185 LKU(im->cache->lock);
190 _evas_cache_image_lru_nodata_del(Image_Entry *im)
192 if (!im->flags.lru_nodata) return;
194 im->flags.cached = 0;
195 #ifdef EVAS_FRAME_QUEUING
196 LKL(im->cache->lock);
198 im->cache->lru_nodata = eina_inlist_remove(im->cache->lru_nodata, EINA_INLIST_GET(im));
199 #ifdef EVAS_FRAME_QUEUING
200 LKU(im->cache->lock);
205 _evas_cache_image_entry_delete(Evas_Cache_Image *cache, Image_Entry *ie)
208 if (cache->func.debug) cache->func.debug("deleting", ie);
209 #ifdef BUILD_ASYNC_PRELOAD
210 if (ie->flags.delete_me == 1) return;
213 ie->flags.delete_me = 1;
214 _evas_cache_image_entry_preload_remove(ie, NULL);
219 _evas_cache_image_dirty_del(ie);
220 _evas_cache_image_activ_del(ie);
221 _evas_cache_image_lru_del(ie);
222 _evas_cache_image_lru_nodata_del(ie);
224 cache->func.destructor(ie);
225 FREESTRC(ie->cache_key);
229 cache->func.surface_delete(ie);
231 #ifdef BUILD_ASYNC_PRELOAD
233 LKD(ie->lock_cancel);
235 #ifdef EVAS_FRAME_QUEUING
236 LKD(ie->lock_references);
238 cache->func.dealloc(ie);
242 _timestamp_compare(Image_Timestamp *tstamp, struct stat *st)
244 if (tstamp->mtime != st->st_mtime) return EINA_FALSE;
245 if (tstamp->size != st->st_size) return EINA_FALSE;
246 if (tstamp->ino != st->st_ino) return EINA_FALSE;
247 #ifdef _STAT_VER_LINUX
248 #if (defined __USE_MISC && defined st_mtime)
249 if (tstamp->mtime_nsec != (unsigned long int)st->st_mtim.tv_nsec)
252 if (tstamp->mtime_nsec != (unsigned long int)st->st_mtimensec)
260 _timestamp_build(Image_Timestamp *tstamp, struct stat *st)
262 tstamp->mtime = st->st_mtime;
263 tstamp->size = st->st_size;
264 tstamp->ino = st->st_ino;
265 #ifdef _STAT_VER_LINUX
266 #if (defined __USE_MISC && defined st_mtime)
267 tstamp->mtime_nsec = (unsigned long int)st->st_mtim.tv_nsec;
269 tstamp->mtime_nsec = (unsigned long int)st->st_mtimensec;
275 _evas_cache_image_entry_new(Evas_Cache_Image *cache,
277 Image_Timestamp *tstamp,
280 RGBA_Image_Loadopts *lo,
285 ie = cache->func.alloc();
288 *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
292 if (hkey) ie->cache_key = eina_stringshare_add(hkey);
293 ie->flags.need_data = 1;
294 ie->space = EVAS_COLORSPACE_ARGB8888;
298 if (file) ie->file = eina_stringshare_add(file);
299 if (key) ie->key = eina_stringshare_add(key);
300 if (tstamp) ie->tstamp = *tstamp;
301 else memset(&ie->tstamp, 0, sizeof(Image_Timestamp));
303 #ifdef EVAS_FRAME_QUEUING
304 LKI(ie->lock_references);
306 #ifdef BUILD_ASYNC_PRELOAD
308 LKI(ie->lock_cancel);
311 if (lo) ie->load_opts = *lo;
314 *error = cache->func.constructor(ie);
315 if (*error != EVAS_LOAD_ERROR_NONE)
317 _evas_cache_image_entry_delete(cache, ie);
321 if (cache->func.debug) cache->func.debug("build", ie);
322 if (ie->cache_key) _evas_cache_image_activ_add(ie);
323 else _evas_cache_image_dirty_add(ie);
328 _evas_cache_image_entry_surface_alloc__locked(Evas_Cache_Image *cache,
333 if ((ie->allocated.w == wmin) && (ie->allocated.h == hmin)) return;
334 if (cache->func.surface_alloc(ie, wmin, hmin))
341 ie->allocated.w = wmin;
342 ie->allocated.h = hmin;
346 _evas_cache_image_entry_surface_alloc(Evas_Cache_Image *cache,
347 Image_Entry *ie, int w, int h)
349 int wmin = w > 0 ? w : 1;
350 int hmin = h > 0 ? h : 1;
351 #ifdef BUILD_ASYNC_PRELOAD
354 _evas_cache_image_entry_surface_alloc__locked(cache, ie, wmin, hmin);
355 #ifdef BUILD_ASYNC_PRELOAD
360 #ifdef BUILD_ASYNC_PRELOAD
362 _evas_cache_image_async_heavy(void *data)
364 Evas_Cache_Image *cache;
365 Image_Entry *current;
372 pchannel = current->channel;
374 cache = current->cache;
376 if ((!current->flags.loaded) &&
377 ((Evas_Image_Load_Func*) current->info.module)->threadable)
379 error = cache->func.load(current);
380 if (cache->func.debug) cache->func.debug("load", current);
381 current->load_error = error;
382 if (error != EVAS_LOAD_ERROR_NONE)
384 current->flags.loaded = 0;
385 _evas_cache_image_entry_surface_alloc(cache, current,
386 current->w, current->h);
390 current->flags.loaded = 1;
393 current->channel = pchannel;
394 // check the unload cancel flag
395 LKL(current->lock_cancel);
396 if (current->unload_cancel)
398 current->unload_cancel = EINA_FALSE;
399 cache->func.surface_delete(current);
400 current->flags.loaded = 0;
401 current->flags.preload_done = 0;
403 LKU(current->lock_cancel);
408 _evas_cache_image_async_end(void *data)
410 Image_Entry *ie = (Image_Entry *)data;
411 Evas_Cache_Target *tmp;
413 ie->cache->preload = eina_list_remove(ie->cache->preload, ie);
414 ie->cache->pending = eina_list_remove(ie->cache->pending, ie);
416 ie->flags.preload_done = ie->flags.loaded;
417 while ((tmp = ie->targets))
419 evas_object_inform_call_image_preloaded((Evas_Object*) tmp->target);
420 ie->targets = (Evas_Cache_Target *)
421 eina_inlist_remove(EINA_INLIST_GET(ie->targets),
422 EINA_INLIST_GET(ie->targets));
428 _evas_cache_image_async_cancel(void *data)
430 Evas_Cache_Image *cache = NULL;
431 Image_Entry *ie = (Image_Entry *)data;
434 ie->cache->pending = eina_list_remove(ie->cache->pending, ie);
435 if ((ie->flags.delete_me) || (ie->flags.dirty))
437 ie->flags.delete_me = 0;
438 _evas_cache_image_entry_delete(ie->cache, ie);
441 if (ie->flags.loaded) _evas_cache_image_async_end(ie);
442 #ifdef EVAS_FRAME_QUEUING
443 LKL(ie->lock_references);
445 if (ie->references == 0)
447 _evas_cache_image_lru_add(ie);
450 #ifdef EVAS_FRAME_QUEUING
451 LKU(ie->lock_references);
453 if (cache) evas_cache_image_flush(cache);
456 // note - preload_add assumes a target is ONLY added ONCE to the image
457 // entry. make sure you only add once, or remove first, then add
459 _evas_cache_image_entry_preload_add(Image_Entry *ie, const void *target)
461 Evas_Cache_Target *tg;
463 if (ie->flags.preload_done) return 0;
464 tg = malloc(sizeof (Evas_Cache_Target));
468 ie->targets = (Evas_Cache_Target *)
469 eina_inlist_append(EINA_INLIST_GET(ie->targets), EINA_INLIST_GET(tg));
472 ie->cache->preload = eina_list_append(ie->cache->preload, ie);
473 ie->flags.pending = 0;
474 ie->preload = evas_preload_thread_run(_evas_cache_image_async_heavy,
475 _evas_cache_image_async_end,
476 _evas_cache_image_async_cancel,
483 _evas_cache_image_entry_preload_remove(Image_Entry *ie, const void *target)
487 Evas_Cache_Target *tg;
489 EINA_INLIST_FOREACH(ie->targets, tg)
491 if (tg->target == target)
493 // FIXME: No callback when we cancel only for one target ?
494 ie->targets = (Evas_Cache_Target *)
495 eina_inlist_remove(EINA_INLIST_GET(ie->targets),
496 EINA_INLIST_GET(tg));
504 Evas_Cache_Target *tg;
509 ie->targets = (Evas_Cache_Target *)
510 eina_inlist_remove(EINA_INLIST_GET(ie->targets),
511 EINA_INLIST_GET(tg));
516 if ((!ie->targets) && (ie->preload) && (!ie->flags.pending))
518 ie->cache->preload = eina_list_remove(ie->cache->preload, ie);
519 ie->cache->pending = eina_list_append(ie->cache->pending, ie);
520 ie->flags.pending = 1;
521 evas_preload_thread_cancel(ie->preload);
527 evas_cache_image_usage_get(Evas_Cache_Image *cache)
533 evas_cache_image_get(Evas_Cache_Image *cache)
539 evas_cache_image_set(Evas_Cache_Image *cache, unsigned int limit)
541 #ifdef EVAS_FRAME_QUEUING
544 if (cache->limit == limit)
546 #ifdef EVAS_FRAME_QUEUING
551 cache->limit = limit;
552 #ifdef EVAS_FRAME_QUEUING
555 evas_cache_image_flush(cache);
558 EAPI Evas_Cache_Image *
559 evas_cache_image_init(const Evas_Cache_Image_Func *cb)
561 Evas_Cache_Image *cache;
563 #ifdef BUILD_ASYNC_PRELOAD
564 if (_evas_cache_mutex_init++ == 0)
568 eina_condition_new(&cond_wakeup, &wakeup);
572 cache = calloc(1, sizeof(Evas_Cache_Image));
573 if (!cache) return NULL;
575 cache->inactiv = eina_hash_string_superfast_new(NULL);
576 cache->activ = eina_hash_string_superfast_new(NULL);
577 cache->references = 1;
578 #ifdef EVAS_FRAME_QUEUING
585 _evas_cache_image_free_cb(__UNUSED__ const Eina_Hash *hash, __UNUSED__ const void *key, void *data, void *fdata)
587 Eina_List **delete_list = fdata;
588 *delete_list = eina_list_prepend(*delete_list, data);
593 evas_cache_image_shutdown(Evas_Cache_Image *cache)
595 Eina_List *delete_list;
598 #ifdef EVAS_FRAME_QUEUING
602 if (cache->references != 0)
604 #ifdef EVAS_FRAME_QUEUING
609 #ifdef EVAS_FRAME_QUEUING
610 /* Release and destroy lock early ! */
615 #ifdef BUILD_ASYNC_PRELOAD
616 EINA_LIST_FREE(cache->preload, im)
618 /* By doing that we are protecting us from destroying image when the cache is no longer available. */
619 im->flags.delete_me = 1;
620 _evas_cache_image_entry_preload_remove(im, NULL);
622 evas_async_events_process();
626 im = (Image_Entry *)cache->lru;
627 _evas_cache_image_entry_delete(cache, im);
629 while (cache->lru_nodata)
631 im = (Image_Entry *)cache->lru_nodata;
632 _evas_cache_image_entry_delete(cache, im);
634 /* This is mad, I am about to destroy image still alive, but we need to prevent leak. */
637 im = (Image_Entry *)cache->dirty;
638 _evas_cache_image_entry_delete(cache, im);
641 eina_hash_foreach(cache->activ, _evas_cache_image_free_cb, &delete_list);
644 _evas_cache_image_entry_delete(cache, eina_list_data_get(delete_list));
645 delete_list = eina_list_remove_list(delete_list, delete_list);
648 #ifdef BUILD_ASYNC_PRELOAD
649 /* Now wait for all pending image to die */
650 while (cache->pending)
652 evas_async_events_process();
654 // the lazy bum who did eain threads and converted this code
655 // didn't bother to worry about Eina_Lock being a different type
656 // to a pthread mutex.
657 if (cache->pending) eina_condition_wait(&cond_wakeup);
661 eina_hash_free(cache->activ);
662 eina_hash_free(cache->inactiv);
665 #ifdef BUILD_ASYNC_PRELOAD
666 if (--_evas_cache_mutex_init == 0)
668 eina_condition_free(&cond_wakeup);
676 evas_cache_image_request(Evas_Cache_Image *cache, const char *file,
677 const char *key, RGBA_Image_Loadopts *lo, int *error)
679 const char *ckey = "(null)";
682 Evas_Image_Load_Opts prevent = { 0, 0, 0, 0, { 0, 0, 0, 0 }, 0 };
684 int stat_done = 0, stat_failed = 0;
688 Image_Timestamp tstamp;
690 if ((!file) || ((!file) && (!key)))
692 *error = EVAS_LOAD_ERROR_GENERIC;
696 /* generate hkey from file+key+load opts */
697 file_length = strlen(file);
698 key_length = key ? strlen(key) : 6;
699 size = file_length + key_length + 132;
700 hkey = alloca(sizeof (char) * size);
701 memcpy(hkey, file, file_length);
703 memcpy(hkey + size, "//://", 5);
706 memcpy(hkey + size, ckey, key_length);
710 (lo->scale_down_by == 0) &&
712 ((lo->w == 0) || (lo->h == 0)) &&
713 ((lo->region.w == 0) || (lo->region.h == 0)) &&
714 (lo->orientation == 0)
721 memcpy(hkey + size, "//@/", 4);
723 size += eina_convert_xtoa(lo->scale_down_by, hkey + size);
726 size += eina_convert_dtoa(lo->dpi, hkey + size);
729 size += eina_convert_xtoa(lo->w, hkey + size);
732 size += eina_convert_xtoa(lo->h, hkey + size);
735 size += eina_convert_xtoa(lo->region.x, hkey + size);
738 size += eina_convert_xtoa(lo->region.y, hkey + size);
741 size += eina_convert_xtoa(lo->region.w, hkey + size);
744 size += eina_convert_xtoa(lo->region.h, hkey + size);
755 /* find image by key in active hash */
756 #ifdef EVAS_FRAME_QUEUING
759 im = eina_hash_find(cache->activ, hkey);
760 #ifdef EVAS_FRAME_QUEUING
768 if (stat(file, &st) < 0)
773 else if (!_timestamp_compare(&(im->tstamp), &st)) ok = 0;
775 /* image we found doesn't match what's on disk (stat info wise)
776 * so dirty the active cache entry so we never find it again. this
777 * also implicitly guarantees that we only have 1 active copy
778 * of an image at a given key. we wither find it and keep re-reffing
779 * it or we dirty it and get it out */
780 _evas_cache_image_dirty_add(im);
784 /* find image by key in inactive/lru hash */
785 #ifdef EVAS_FRAME_QUEUING
788 im = eina_hash_find(cache->inactiv, hkey);
789 #ifdef EVAS_FRAME_QUEUING
799 if (stat(file, &st) < 0)
804 else if (!_timestamp_compare(&(im->tstamp), &st)) ok = 0;
806 else if (!_timestamp_compare(&(im->tstamp), &st)) ok = 0;
810 /* remove from lru and make it active again */
811 _evas_cache_image_lru_del(im);
812 _evas_cache_image_activ_add(im);
815 /* as avtive cache find - if we match in lru and its invalid, dirty */
816 _evas_cache_image_dirty_add(im);
819 if (stat_failed) goto on_stat_error;
823 if (stat(file, &st) < 0) goto on_stat_error;
825 _timestamp_build(&tstamp, &st);
826 im = _evas_cache_image_entry_new(cache, hkey, &tstamp, file, key,
828 if (!im) goto on_stat_error;
829 if (cache->func.debug) cache->func.debug("request", im);
832 *error = EVAS_LOAD_ERROR_NONE;
833 #ifdef EVAS_FRAME_QUEUING
834 LKL(im->lock_references);
837 #ifdef EVAS_FRAME_QUEUING
838 LKU(im->lock_references);
844 if ((errno == ENOENT) || (errno == ENOTDIR) ||
845 (errno == ENAMETOOLONG) || (errno == ELOOP))
849 *error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
851 else if ((errno == ENOMEM) || (errno == EOVERFLOW))
853 else if (errno == ENOMEM)
855 *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
856 else if (errno == EACCES)
857 *error = EVAS_LOAD_ERROR_PERMISSION_DENIED;
859 *error = EVAS_LOAD_ERROR_GENERIC;
861 if (im) _evas_cache_image_entry_delete(cache, im);
866 evas_cache_image_drop(Image_Entry *im)
868 Evas_Cache_Image *cache;
871 #ifdef EVAS_FRAME_QUEUING
872 LKL(im->lock_references);
875 if (im->references < 0) im->references = 0;
876 references = im->references;
877 #ifdef EVAS_FRAME_QUEUING
878 LKU(im->lock_references);
885 #ifdef EVAS_FRAME_QUEUING
888 if (im->ref_fq[0] != im->ref_fq[1])
898 #ifdef BUILD_ASYNC_PRELOAD
901 _evas_cache_image_entry_preload_remove(im, NULL);
908 _evas_cache_image_entry_delete(cache, im);
911 _evas_cache_image_lru_add(im);
912 if (cache) evas_cache_image_flush(cache);
917 evas_cache_image_data_not_needed(Image_Entry *im)
919 Evas_Cache_Image *cache;
922 /* FIXME: no one uses this api... well evas_cache_engine_parent_not_needed()
923 * does, but nothing uses that! */
925 #ifdef EVAS_FRAME_QUEUING
926 LKL(im->lock_references);
928 references = im->references;
929 #ifdef EVAS_FRAME_QUEUING
930 LKU(im->lock_references);
932 if (references > 1) return;
933 if ((im->flags.dirty) || (!im->flags.need_data)) return;
934 _evas_cache_image_lru_nodata_add(im);
938 evas_cache_image_dirty(Image_Entry *im, unsigned int x, unsigned int y, unsigned int w, unsigned int h)
940 Image_Entry *im_dirty = im;
941 Evas_Cache_Image *cache;
945 if (!(im->flags.dirty))
947 #ifdef EVAS_FRAME_QUEUING
948 LKL(im->lock_references);
950 references = im->references;
951 #ifdef EVAS_FRAME_QUEUING
952 LKU(im->lock_references);
955 // if ref 1 also copy if using shared cache as its read-only
956 if (references == 1) im_dirty = im;
963 evas_cache_image_copied_data(cache, im->w, im->h,
964 evas_cache_image_pixels(im),
965 im->flags.alpha, im->space);
966 if (!im_dirty) goto on_error;
967 if (cache->func.debug) cache->func.debug("dirty-src", im);
968 error = cache->func.dirty(im_dirty, im);
969 if (cache->func.debug) cache->func.debug("dirty-out", im_dirty);
970 #ifdef EVAS_FRAME_QUEUING
971 LKL(im_dirty->lock_references);
973 im_dirty->references = 1;
974 #ifdef EVAS_FRAME_QUEUING
975 LKU(im_dirty->lock_references);
977 evas_cache_image_drop(im);
979 _evas_cache_image_dirty_add(im_dirty);
982 if (cache->func.debug) cache->func.debug("dirty-region", im_dirty);
983 if (cache->func.dirty_region)
984 cache->func.dirty_region(im_dirty, x, y, w, h);
988 if (im_dirty) _evas_cache_image_entry_delete(cache, im_dirty);
989 evas_cache_image_drop(im);
994 evas_cache_image_alone(Image_Entry *im)
996 Evas_Cache_Image *cache;
997 Image_Entry *im_dirty = im;
1001 #ifdef EVAS_FRAME_QUEUING
1002 LKL(im->lock_references);
1004 references = im->references;
1005 #ifdef EVAS_FRAME_QUEUING
1006 LKU(im->lock_references);
1009 if (references <= 1)
1011 if (!im->flags.dirty) _evas_cache_image_dirty_add(im);
1017 im_dirty = evas_cache_image_copied_data(cache, im->w, im->h,
1018 evas_cache_image_pixels(im),
1021 if (!im_dirty) goto on_error;
1022 if (cache->func.debug) cache->func.debug("dirty-src", im);
1023 error = cache->func.dirty(im_dirty, im);
1024 if (cache->func.debug) cache->func.debug("dirty-out", im_dirty);
1025 #ifdef EVAS_FRAME_QUEUING
1026 LKL(im_dirty->lock_references);
1028 im_dirty->references = 1;
1029 #ifdef EVAS_FRAME_QUEUING
1030 LKU(im_dirty->lock_references);
1032 evas_cache_image_drop(im);
1037 if (im_dirty) _evas_cache_image_entry_delete(cache, im_dirty);
1038 evas_cache_image_drop(im);
1043 evas_cache_image_copied_data(Evas_Cache_Image *cache,
1044 unsigned int w, unsigned int h,
1045 DATA32 *image_data, int alpha, int cspace)
1049 if ((cspace == EVAS_COLORSPACE_YCBCR422P601_PL) ||
1050 (cspace == EVAS_COLORSPACE_YCBCR422P709_PL) ||
1051 (cspace == EVAS_COLORSPACE_YCBCR422601_PL))
1054 im = _evas_cache_image_entry_new(cache, NULL, NULL, NULL, NULL, NULL, NULL);
1055 if (!im) return NULL;
1057 im->flags.alpha = alpha;
1058 _evas_cache_image_entry_surface_alloc(cache, im, w, h);
1059 if (cache->func.copied_data(im, w, h, image_data, alpha, cspace) != 0)
1061 _evas_cache_image_entry_delete(cache, im);
1064 #ifdef EVAS_FRAME_QUEUING
1065 LKL(im->lock_references);
1068 #ifdef EVAS_FRAME_QUEUING
1069 LKU(im->lock_references);
1071 if (cache->func.debug) cache->func.debug("copied-data", im);
1076 evas_cache_image_data(Evas_Cache_Image *cache, unsigned int w, unsigned int h, DATA32 *image_data, int alpha, int cspace)
1080 if ((cspace == EVAS_COLORSPACE_YCBCR422P601_PL) ||
1081 (cspace == EVAS_COLORSPACE_YCBCR422P709_PL) ||
1082 (cspace == EVAS_COLORSPACE_YCBCR422601_PL))
1085 im = _evas_cache_image_entry_new(cache, NULL, NULL, NULL, NULL, NULL, NULL);
1086 if (!im) return NULL;
1089 im->flags.alpha = alpha;
1090 if (cache->func.data(im, w, h, image_data, alpha, cspace) != 0)
1092 _evas_cache_image_entry_delete(cache, im);
1095 #ifdef EVAS_FRAME_QUEUING
1096 LKL(im->lock_references);
1099 #ifdef EVAS_FRAME_QUEUING
1100 LKU(im->lock_references);
1102 if (cache->func.debug) cache->func.debug("data", im);
1107 evas_cache_image_surface_alloc(Image_Entry *im, unsigned int w, unsigned int h)
1109 Evas_Cache_Image *cache = im->cache;
1111 if ((im->space == EVAS_COLORSPACE_YCBCR422P601_PL) ||
1112 (im->space == EVAS_COLORSPACE_YCBCR422P709_PL) ||
1113 (im->space == EVAS_COLORSPACE_YCBCR422601_PL))
1116 _evas_cache_image_entry_surface_alloc(cache, im, w, h);
1117 if (cache->func.debug) cache->func.debug("surface-alloc", im);
1121 evas_cache_image_size_set(Image_Entry *im, unsigned int w, unsigned int h)
1123 Evas_Cache_Image *cache;
1124 Image_Entry *im2 = NULL;
1127 if ((im->space == EVAS_COLORSPACE_YCBCR422P601_PL) ||
1128 (im->space == EVAS_COLORSPACE_YCBCR422P709_PL) ||
1129 (im->space == EVAS_COLORSPACE_YCBCR422601_PL))
1131 if ((im->w == w) && (im->h == h)) return im;
1134 im2 = _evas_cache_image_entry_new(cache, NULL, NULL, NULL, NULL, NULL, &error);
1135 if (!im2) goto on_error;
1137 im2->flags.alpha = im->flags.alpha;
1138 im2->space = im->space;
1139 im2->load_opts = im->load_opts;
1140 _evas_cache_image_entry_surface_alloc(cache, im2, w, h);
1141 error = cache->func.size_set(im2, im, w, h);
1142 if (error != 0) goto on_error;
1143 #ifdef EVAS_FRAME_QUEUING
1144 LKL(im2->lock_references);
1146 im2->references = 1;
1147 #ifdef EVAS_FRAME_QUEUING
1148 LKU(im2->lock_references);
1150 evas_cache_image_drop(im);
1151 if (cache->func.debug) cache->func.debug("size_set", im2);
1155 if (im2) _evas_cache_image_entry_delete(cache, im2);
1156 evas_cache_image_drop(im);
1161 evas_cache_image_load_data(Image_Entry *im)
1163 #ifdef BUILD_ASYNC_PRELOAD
1164 Eina_Bool preload = EINA_FALSE;
1166 int error = EVAS_LOAD_ERROR_NONE;
1168 if ((im->flags.loaded) && (!im->flags.animated)) return error;
1169 #ifdef BUILD_ASYNC_PRELOAD
1172 preload = EINA_TRUE;
1173 if (!im->flags.pending)
1175 im->cache->preload = eina_list_remove(im->cache->preload, im);
1176 im->cache->pending = eina_list_append(im->cache->pending, im);
1177 im->flags.pending = 1;
1178 evas_preload_thread_cancel(im->preload);
1180 evas_async_events_process();
1184 eina_condition_wait(&cond_wakeup);
1186 evas_async_events_process();
1192 if ((im->flags.loaded) && (!im->flags.animated)) return error;
1195 im->flags.in_progress = EINA_TRUE;
1196 error = im->cache->func.load(im);
1197 im->flags.in_progress = EINA_FALSE;
1198 #ifdef BUILD_ASYNC_PRELOAD
1201 im->flags.loaded = 1;
1202 if (im->cache->func.debug) im->cache->func.debug("load", im);
1203 if (error != EVAS_LOAD_ERROR_NONE)
1205 _evas_cache_image_entry_surface_alloc(im->cache, im, im->w, im->h);
1206 im->flags.loaded = 0;
1208 #ifdef BUILD_ASYNC_PRELOAD
1209 if (preload) _evas_cache_image_async_end(im);
1215 evas_cache_image_unload_data(Image_Entry *im)
1217 if (im->flags.in_progress) return;
1218 evas_cache_image_preload_cancel(im, NULL);
1219 #ifdef BUILD_ASYNC_PRELOAD
1220 LKL(im->lock_cancel);
1221 if (LKT(im->lock) == EINA_FALSE) /* can't get image lock - busy async load */
1223 im->unload_cancel = EINA_TRUE;
1224 LKU(im->lock_cancel);
1227 LKU(im->lock_cancel);
1229 if ((!im->flags.loaded) || (!im->file) || (!im->info.module) ||
1232 #ifdef BUILD_ASYNC_PRELOAD
1237 im->cache->func.destructor(im);
1238 #ifdef BUILD_ASYNC_PRELOAD
1241 //FIXME: imagedataunload - inform owners
1245 _evas_cache_image_unload_cb(__UNUSED__ const Eina_Hash *hash, __UNUSED__ const void *key, void *data, __UNUSED__ void *fdata)
1247 evas_cache_image_unload_data(data);
1252 evas_cache_image_unload_all(Evas_Cache_Image *cache)
1256 EINA_INLIST_FOREACH(cache->lru, im) evas_cache_image_unload_data(im);
1257 EINA_INLIST_FOREACH(cache->lru_nodata, im) evas_cache_image_unload_data(im);
1258 eina_hash_foreach(cache->activ, _evas_cache_image_unload_cb, NULL);
1259 eina_hash_foreach(cache->inactiv, _evas_cache_image_unload_cb, NULL);
1263 evas_cache_image_is_loaded(Image_Entry *im)
1265 if (im->flags.loaded) return EINA_TRUE;
1270 evas_cache_image_preload_data(Image_Entry *im, const void *target)
1272 #ifdef BUILD_ASYNC_PRELOAD
1273 RGBA_Image *img = (RGBA_Image *)im;
1275 if ((im->flags.loaded) && (img->image.data))
1277 evas_object_inform_call_image_preloaded((Evas_Object *)target);
1280 im->flags.loaded = 0;
1281 if (!_evas_cache_image_entry_preload_add(im, target))
1282 evas_object_inform_call_image_preloaded((Evas_Object *)target);
1284 evas_cache_image_load_data(im);
1285 evas_object_inform_call_image_preloaded((Evas_Object *)target);
1290 evas_cache_image_preload_cancel(Image_Entry *im, const void *target)
1292 #ifdef BUILD_ASYNC_PRELOAD
1293 if (!target) return;
1294 _evas_cache_image_entry_preload_remove(im, target);
1301 static int total = 0;
1304 _dump_img(Image_Entry *im, const char *type)
1306 total += im->cache->func.mem_size_get(im);
1307 printf("%s: %4i: %4ib, %4ix%4i alloc[%4ix%4i] [%s] [%s]\n",
1310 im->cache->func.mem_size_get(im),
1311 im->w, im->h, im->allocated.w, im->allocated.h,
1316 _dump_cache_active(__UNUSED__ const Eina_Hash *hash, __UNUSED__ const void *key, void *data, void *fdata __UNUSED__)
1318 Image_Entry *im = data;
1319 _dump_img(im, "ACTIVE");
1324 _dump_cache(Evas_Cache_Image *cache)
1328 printf("--CACHE DUMP----------------------------------------------------\n");
1329 printf("cache: %ikb / %ikb\n",
1330 cache->usage / 1024,
1331 cache->limit / 1024);
1332 printf("................................................................\n");
1334 EINA_INLIST_FOREACH(cache->lru_nodata, im)
1335 _dump_img(im, "NODATA");
1336 EINA_INLIST_FOREACH(cache->lru, im)
1337 _dump_img(im, "DATA ");
1342 eina_hash_foreach(cache->activ, _dump_cache_active, NULL);
1347 evas_cache_image_flush(Evas_Cache_Image *cache)
1352 if (cache->limit == (unsigned int)-1) return -1;
1354 while ((cache->lru) && (cache->limit < (unsigned int)cache->usage))
1358 im = (Image_Entry *)cache->lru->last;
1359 _evas_cache_image_entry_delete(cache, im);
1362 while ((cache->lru_nodata) && (cache->limit < (unsigned int)cache->usage))
1366 im = (Image_Entry *) cache->lru_nodata->last;
1367 _evas_cache_image_lru_nodata_del(im);
1368 cache->func.surface_delete(im);
1369 im->flags.loaded = 0;
1372 return cache->usage;
1376 evas_cache_image_empty(Evas_Cache_Image *cache)
1380 im = _evas_cache_image_entry_new(cache, NULL, NULL, NULL, NULL, NULL, NULL);
1381 if (!im) return NULL;
1382 #ifdef EVAS_FRAME_QUEUING
1383 LKL(im->lock_references);
1386 #ifdef EVAS_FRAME_QUEUING
1387 LKU(im->lock_references);
1393 evas_cache_image_colorspace(Image_Entry *im, int cspace)
1395 if (im->space == cspace) return;
1397 im->cache->func.color_space(im, cspace);
1401 evas_cache_private_from_image_entry_get(Image_Entry *im)
1403 return (void *)im->cache->data;
1407 evas_cache_private_get(Evas_Cache_Image *cache)
1413 evas_cache_private_set(Evas_Cache_Image *cache, const void *data)
1415 cache->data = (void *)data;
1419 evas_cache_image_pixels(Image_Entry *im)
1421 return im->cache->func.surface_pixels(im);
1425 evas_cache_image_wakeup(void)
1427 #ifdef BUILD_ASYNC_PRELOAD
1428 if (_evas_cache_mutex_init > 0)
1429 eina_condition_broadcast(&cond_wakeup);