Revert "Rollback to previous package. evas_1.0.0.001+svn.62695slp2+build31"
[framework/uifw/evas.git] / src / lib / cache / evas_cache_image.c
1 #ifdef HAVE_CONFIG_H
2 # include <config.h>
3 #endif
4
5 #include <stdlib.h>
6 #include <assert.h>
7 #include <sys/types.h>
8 #include <sys/stat.h>
9 #include <errno.h>
10
11 #ifdef HAVE_EVIL
12 # include <Evil.h>
13 #endif
14
15 #include "evas_common.h"
16 #include "evas_private.h"
17
18 //#define CACHEDUMP 1
19
20 #ifdef EVAS_CSERVE
21 // FIXME: cache server and threaded preload clash badly atm - disable
22 //#undef BUILD_ASYNC_PRELOAD
23 #endif
24
25 #ifdef BUILD_ASYNC_PRELOAD
26 typedef struct _Evas_Cache_Preload Evas_Cache_Preload;
27
28 struct _Evas_Cache_Preload
29 {
30    EINA_INLIST;
31    Image_Entry *ie;
32 };
33
34 static LK(engine_lock);
35 static LK(wakeup);
36 static int _evas_cache_mutex_init = 0;
37
38 static Eina_Condition cond_wakeup;
39
40 static void _evas_cache_image_entry_preload_remove(Image_Entry *ie, const void *target);
41 #endif
42
43 #define FREESTRC(Var)             \
44    if (Var)                       \
45    {                              \
46       eina_stringshare_del(Var);  \
47       Var = NULL;                 \
48    }
49
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);
58
59 static void
60 _evas_cache_image_dirty_add(Image_Entry *im)
61 {
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);
66    im->flags.dirty = 1;
67    im->flags.cached = 1;
68 #ifdef EVAS_FRAME_QUEUING
69    LKL(im->cache->lock);
70 #endif
71    im->cache->dirty = eina_inlist_prepend(im->cache->dirty, EINA_INLIST_GET(im));
72 #ifdef EVAS_FRAME_QUEUING
73    LKU(im->cache->lock);
74 #endif
75    if (im->cache_key)
76      {
77         eina_stringshare_del(im->cache_key);
78         im->cache_key = NULL;
79      }
80 }
81
82 static void
83 _evas_cache_image_dirty_del(Image_Entry *im)
84 {
85    if (!im->flags.dirty) return;
86    im->flags.dirty = 0;
87    im->flags.cached = 0;
88 #ifdef EVAS_FRAME_QUEUING
89    LKL(im->cache->lock);
90 #endif
91    im->cache->dirty = eina_inlist_remove(im->cache->dirty, EINA_INLIST_GET(im));
92 #ifdef EVAS_FRAME_QUEUING
93    LKU(im->cache->lock);
94 #endif
95 }
96
97 static void
98 _evas_cache_image_activ_add(Image_Entry *im)
99 {
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;
105    im->flags.activ = 1;
106    im->flags.cached = 1;
107 #ifdef EVAS_FRAME_QUEUING
108    LKL(im->cache->lock);
109 #endif
110    eina_hash_direct_add(im->cache->activ, im->cache_key, im);
111 #ifdef EVAS_FRAME_QUEUING
112    LKU(im->cache->lock);
113 #endif
114 }
115
116 static void
117 _evas_cache_image_activ_del(Image_Entry *im)
118 {
119    if (!im->flags.activ) return;
120    if (!im->cache_key) return;
121    im->flags.activ = 0;
122    im->flags.cached = 0;
123 #ifdef EVAS_FRAME_QUEUING
124    LKL(im->cache->lock);
125 #endif
126    eina_hash_del(im->cache->activ, im->cache_key, im);
127 #ifdef EVAS_FRAME_QUEUING
128    LKU(im->cache->lock);
129 #endif
130 }
131
132 static void
133 _evas_cache_image_lru_add(Image_Entry *im)
134 {
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;
140    im->flags.lru = 1;
141    im->flags.cached = 1;
142 #ifdef EVAS_FRAME_QUEUING
143    LKL(im->cache->lock);
144 #endif
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);
150 #endif
151 }
152
153 static void
154 _evas_cache_image_lru_del(Image_Entry *im)
155 {
156    if (!im->flags.lru) return;
157    if (!im->cache_key) return;
158    im->flags.lru = 0;
159    im->flags.cached = 0;
160 #ifdef EVAS_FRAME_QUEUING
161    LKL(im->cache->lock);
162 #endif
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);
168 #endif
169 }
170
171 static void
172 _evas_cache_image_lru_nodata_add(Image_Entry *im)
173 {
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);
178    im->flags.lru = 1;
179    im->flags.cached = 1;
180 #ifdef EVAS_FRAME_QUEUING
181    LKL(im->cache->lock);
182 #endif
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);
186 #endif
187 }
188
189 static void
190 _evas_cache_image_lru_nodata_del(Image_Entry *im)
191 {
192    if (!im->flags.lru_nodata) return;
193    im->flags.lru = 0;
194    im->flags.cached = 0;
195 #ifdef EVAS_FRAME_QUEUING
196    LKL(im->cache->lock);
197 #endif
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);
201 #endif
202 }
203
204 static void
205 _evas_cache_image_entry_delete(Evas_Cache_Image *cache, Image_Entry *ie)
206 {
207    if (!ie) return;
208    if (cache->func.debug) cache->func.debug("deleting", ie);
209 #ifdef BUILD_ASYNC_PRELOAD
210    if (ie->flags.delete_me == 1) return;
211    if (ie->preload)
212      {
213         ie->flags.delete_me = 1;
214         _evas_cache_image_entry_preload_remove(ie, NULL);
215         return;
216      }
217 #endif
218
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);
223
224    cache->func.destructor(ie);
225    FREESTRC(ie->cache_key);
226    FREESTRC(ie->file);
227    FREESTRC(ie->key);
228    ie->cache = NULL;
229    cache->func.surface_delete(ie);
230
231 #ifdef BUILD_ASYNC_PRELOAD
232    LKD(ie->lock);
233    LKD(ie->lock_cancel);
234 #endif
235 #ifdef EVAS_FRAME_QUEUING
236    LKD(ie->lock_references);
237 #endif
238    cache->func.dealloc(ie);
239 }
240
241 static Eina_Bool
242 _timestamp_compare(Image_Timestamp *tstamp, struct stat *st)
243 {
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)
250       return EINA_FALSE;
251 #else
252    if (tstamp->mtime_nsec != (unsigned long int)st->st_mtimensec)
253       return EINA_FALSE;
254 #endif
255 #endif
256    return EINA_TRUE;
257 }
258
259 static void
260 _timestamp_build(Image_Timestamp *tstamp, struct stat *st)
261 {
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;
268 #else
269    tstamp->mtime_nsec = (unsigned long int)st->st_mtimensec;
270 #endif
271 #endif
272 }
273
274 static Image_Entry *
275 _evas_cache_image_entry_new(Evas_Cache_Image *cache,
276                             const char *hkey,
277                             Image_Timestamp *tstamp,
278                             const char *file,
279                             const char *key,
280                             RGBA_Image_Loadopts *lo,
281                             int *error)
282 {
283    Image_Entry  *ie;
284
285    ie = cache->func.alloc();
286    if (!ie)
287      {
288         *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
289         return NULL;
290      }
291    ie->cache = cache;
292    if (hkey) ie->cache_key = eina_stringshare_add(hkey);
293    ie->flags.need_data = 1;
294    ie->space = EVAS_COLORSPACE_ARGB8888;
295    ie->w = -1;
296    ie->h = -1;
297    ie->scale = 1;
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));
302
303 #ifdef EVAS_FRAME_QUEUING
304    LKI(ie->lock_references);
305 #endif
306 #ifdef BUILD_ASYNC_PRELOAD
307    LKI(ie->lock);
308    LKI(ie->lock_cancel); 
309 #endif
310    
311    if (lo) ie->load_opts = *lo;
312    if (ie->file)
313      {
314         *error = cache->func.constructor(ie);
315         if (*error != EVAS_LOAD_ERROR_NONE)
316           {
317              _evas_cache_image_entry_delete(cache, ie);
318              return NULL;
319           }
320      }
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);
324    return ie;
325 }
326
327 static void
328 _evas_cache_image_entry_surface_alloc__locked(Evas_Cache_Image *cache,
329                                               Image_Entry *ie,
330                                               unsigned int wmin,
331                                               unsigned int hmin)
332 {
333    if ((ie->allocated.w == wmin) && (ie->allocated.h == hmin)) return;
334    if (cache->func.surface_alloc(ie, wmin, hmin))
335      {
336         wmin = 0;
337         hmin = 0;
338      }
339    ie->w = wmin;
340    ie->h = hmin;
341    ie->allocated.w = wmin;
342    ie->allocated.h = hmin;
343 }
344
345 static void
346 _evas_cache_image_entry_surface_alloc(Evas_Cache_Image *cache,
347                                       Image_Entry *ie, int w, int h)
348 {
349    int wmin = w > 0 ? w : 1;
350    int hmin = h > 0 ? h : 1;
351 #ifdef BUILD_ASYNC_PRELOAD
352    LKL(engine_lock);
353 #endif
354    _evas_cache_image_entry_surface_alloc__locked(cache, ie, wmin, hmin);
355 #ifdef BUILD_ASYNC_PRELOAD
356    LKU(engine_lock);
357 #endif
358 }
359
360 #ifdef BUILD_ASYNC_PRELOAD
361 static void
362 _evas_cache_image_async_heavy(void *data)
363 {
364    Evas_Cache_Image *cache;
365    Image_Entry *current;
366    int error;
367    int pchannel;
368
369    current = data;
370
371    LKL(current->lock);
372    pchannel = current->channel;
373    current->channel++;
374    cache = current->cache;
375
376    if ((!current->flags.loaded) && 
377        ((Evas_Image_Load_Func*) current->info.module)->threadable)
378      {
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)
383           {
384              current->flags.loaded = 0;
385              _evas_cache_image_entry_surface_alloc(cache, current,
386                                                    current->w, current->h);
387           }
388         else
389           {
390              current->flags.loaded = 1;
391           }
392      }
393    current->channel = pchannel;
394    // check the unload cancel flag
395    LKL(current->lock_cancel);
396    if (current->unload_cancel)
397      {
398         current->unload_cancel = EINA_FALSE;
399         cache->func.surface_delete(current);
400         current->flags.loaded = 0;
401         current->flags.preload_done = 0;
402      }
403    LKU(current->lock_cancel);
404    LKU(current->lock);
405 }
406
407 static void
408 _evas_cache_image_async_end(void *data)
409 {
410    Image_Entry *ie = (Image_Entry *)data;
411    Evas_Cache_Target *tmp;
412
413    ie->cache->preload = eina_list_remove(ie->cache->preload, ie);
414    ie->cache->pending = eina_list_remove(ie->cache->pending, ie);
415    ie->preload = NULL;
416    ie->flags.preload_done = ie->flags.loaded;
417    while ((tmp = ie->targets))
418      {
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));
423         free(tmp);
424      }
425 }
426
427 static void
428 _evas_cache_image_async_cancel(void *data)
429 {
430    Evas_Cache_Image *cache = NULL;
431    Image_Entry *ie = (Image_Entry *)data;
432    
433    ie->preload = NULL;
434    ie->cache->pending = eina_list_remove(ie->cache->pending, ie);
435    if ((ie->flags.delete_me) || (ie->flags.dirty))
436      {
437         ie->flags.delete_me = 0;
438         _evas_cache_image_entry_delete(ie->cache, ie);
439         return;
440      }
441    if (ie->flags.loaded) _evas_cache_image_async_end(ie);
442 #ifdef EVAS_FRAME_QUEUING
443    LKL(ie->lock_references);
444 #endif
445    if (ie->references == 0)
446      {
447         _evas_cache_image_lru_add(ie);
448         cache = ie->cache;
449      }
450 #ifdef EVAS_FRAME_QUEUING
451    LKU(ie->lock_references);
452 #endif
453    if (cache) evas_cache_image_flush(cache);
454 }
455
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
458 static int
459 _evas_cache_image_entry_preload_add(Image_Entry *ie, const void *target)
460 {
461    Evas_Cache_Target *tg;
462
463    if (ie->flags.preload_done) return 0;
464
465    tg = malloc(sizeof (Evas_Cache_Target));
466    if (!tg) return 0;
467
468    tg->target = target;
469    ie->targets = (Evas_Cache_Target *)
470       eina_inlist_append(EINA_INLIST_GET(ie->targets), EINA_INLIST_GET(tg));
471    if (!ie->preload)
472      {
473         ie->cache->preload = eina_list_append(ie->cache->preload, ie);
474         ie->flags.pending = 0;
475         ie->preload = evas_preload_thread_run(_evas_cache_image_async_heavy,
476                                               _evas_cache_image_async_end,
477                                               _evas_cache_image_async_cancel,
478                                               ie);
479      }
480    return 1;
481 }
482
483 static void
484 _evas_cache_image_entry_preload_remove(Image_Entry *ie, const void *target)
485 {
486    if (target)
487      {
488         Evas_Cache_Target *tg;
489
490         EINA_INLIST_FOREACH(ie->targets, tg)
491           {
492              if (tg->target == target)
493                {
494                   // FIXME: No callback when we cancel only for one target ?
495                   ie->targets = (Evas_Cache_Target *)
496                      eina_inlist_remove(EINA_INLIST_GET(ie->targets),
497                                         EINA_INLIST_GET(tg));
498                   free(tg);
499                   break;
500                }
501           }
502      }
503    else
504      {
505         Evas_Cache_Target *tg;
506
507         while (ie->targets)
508           {
509              tg = ie->targets;
510              ie->targets = (Evas_Cache_Target *)
511                 eina_inlist_remove(EINA_INLIST_GET(ie->targets),
512                                    EINA_INLIST_GET(tg));
513              free(tg);
514           }
515      }
516
517    if ((!ie->targets) && (ie->preload) && (!ie->flags.pending))
518      {
519         ie->cache->preload = eina_list_remove(ie->cache->preload, ie);
520         ie->cache->pending = eina_list_append(ie->cache->pending, ie);
521         ie->flags.pending = 1;
522         evas_preload_thread_cancel(ie->preload);
523      }
524 }
525 #endif
526
527 EAPI int
528 evas_cache_image_usage_get(Evas_Cache_Image *cache)
529 {
530    return cache->usage;
531 }
532
533 EAPI int
534 evas_cache_image_get(Evas_Cache_Image *cache)
535 {
536    return cache->limit;
537 }
538
539 EAPI void
540 evas_cache_image_set(Evas_Cache_Image *cache, unsigned int limit)
541 {
542 #ifdef EVAS_FRAME_QUEUING
543    LKL(cache->lock);
544 #endif
545    if (cache->limit == limit)
546      {
547 #ifdef EVAS_FRAME_QUEUING
548         LKU(cache->lock);
549 #endif
550         return;
551      }
552    cache->limit = limit;
553 #ifdef EVAS_FRAME_QUEUING
554    LKU(cache->lock);
555 #endif
556    evas_cache_image_flush(cache);
557 }
558
559 EAPI Evas_Cache_Image *
560 evas_cache_image_init(const Evas_Cache_Image_Func *cb)
561 {
562    Evas_Cache_Image *cache;
563
564 #ifdef BUILD_ASYNC_PRELOAD
565    if (_evas_cache_mutex_init++ == 0)
566      {
567         LKI(engine_lock);
568         LKI(wakeup);
569         eina_condition_new(&cond_wakeup, &wakeup);
570      }
571 #endif
572
573    cache = calloc(1, sizeof(Evas_Cache_Image));
574    if (!cache) return NULL;
575    cache->func = *cb;
576    cache->inactiv = eina_hash_string_superfast_new(NULL);
577    cache->activ = eina_hash_string_superfast_new(NULL);
578    cache->references = 1;
579 #ifdef EVAS_FRAME_QUEUING
580    LKI(cache->lock);
581 #endif
582    return cache;
583 }
584
585 static Eina_Bool
586 _evas_cache_image_free_cb(__UNUSED__ const Eina_Hash *hash, __UNUSED__ const void *key, void *data, void *fdata)
587 {
588    Eina_List **delete_list = fdata;
589    *delete_list = eina_list_prepend(*delete_list, data);
590    return EINA_TRUE;
591 }
592
593 EAPI void
594 evas_cache_image_shutdown(Evas_Cache_Image *cache)
595 {
596    Eina_List *delete_list;
597    Image_Entry  *im;
598
599 #ifdef EVAS_FRAME_QUEUING
600    LKL(cache->lock);
601 #endif
602    cache->references--;
603    if (cache->references != 0)
604      {
605 #ifdef EVAS_FRAME_QUEUING
606         LKU(cache->lock);
607 #endif
608         return;
609      }
610 #ifdef EVAS_FRAME_QUEUING
611    /* Release and destroy lock early ! */
612    LKU(cache->lock);
613    LKD(cache->lock);
614 #endif
615
616 #ifdef BUILD_ASYNC_PRELOAD
617    EINA_LIST_FREE(cache->preload, im)
618      {
619         /* By doing that we are protecting us from destroying image when the cache is no longer available. */
620         im->flags.delete_me = 1;
621         _evas_cache_image_entry_preload_remove(im, NULL);
622      }
623    evas_async_events_process();
624 #endif
625    while (cache->lru)
626      {
627         im = (Image_Entry *)cache->lru;
628         _evas_cache_image_entry_delete(cache, im);
629      }
630    while (cache->lru_nodata)
631      {
632         im = (Image_Entry *)cache->lru_nodata;
633         _evas_cache_image_entry_delete(cache, im);
634      }
635    /* This is mad, I am about to destroy image still alive, but we need to prevent leak. */
636    while (cache->dirty)
637      {
638         im = (Image_Entry *)cache->dirty;
639         _evas_cache_image_entry_delete(cache, im);
640      }
641    delete_list = NULL;
642    eina_hash_foreach(cache->activ, _evas_cache_image_free_cb, &delete_list);
643    while (delete_list)
644      {
645         _evas_cache_image_entry_delete(cache, eina_list_data_get(delete_list));
646         delete_list = eina_list_remove_list(delete_list, delete_list);
647      }
648
649 #ifdef BUILD_ASYNC_PRELOAD
650    /* Now wait for all pending image to die */
651    while (cache->pending)
652      {
653         evas_async_events_process();
654         LKL(wakeup);
655         // the lazy bum who did eain threads and converted this code
656         // didn't bother to worry about Eina_Lock being a different type
657         // to a pthread mutex.
658         if (cache->pending) eina_condition_wait(&cond_wakeup);
659         LKU(wakeup);
660      }
661 #endif
662    eina_hash_free(cache->activ);
663    eina_hash_free(cache->inactiv);
664    free(cache);
665
666 #ifdef BUILD_ASYNC_PRELOAD
667    if (--_evas_cache_mutex_init == 0)
668      {
669         eina_condition_free(&cond_wakeup);
670         LKD(engine_lock);
671         LKD(wakeup);
672      }
673 #endif
674 }
675
676 EAPI Image_Entry *
677 evas_cache_image_request(Evas_Cache_Image *cache, const char *file, 
678                          const char *key, RGBA_Image_Loadopts *lo, int *error)
679 {
680    const char           *ckey = "(null)";
681    char                 *hkey;
682    Image_Entry          *im;
683    Evas_Image_Load_Opts  prevent = { 0, 0.0, 0, 0, 0, { 0, 0, 0, 0 }, EINA_FALSE };
684    size_t                size;
685    int                   stat_done = 0, stat_failed = 0;
686    size_t                file_length;
687    size_t                key_length;
688    struct stat           st;
689    Image_Timestamp       tstamp;
690
691    if ((!file) || ((!file) && (!key)))
692      {
693         *error = EVAS_LOAD_ERROR_GENERIC;
694         return NULL;
695      }
696
697    /* generate hkey from file+key+load opts */
698    file_length = strlen(file);
699    key_length = key ? strlen(key) : 6;
700    size = file_length + key_length + 132;
701    hkey = alloca(sizeof (char) * size);
702    memcpy(hkey, file, file_length);
703    size = file_length;
704    memcpy(hkey + size, "//://", 5);
705    size += 5;
706    if (key) ckey = key;
707    memcpy(hkey + size, ckey, key_length);
708    size += key_length;
709    if ((!lo) ||
710        (lo &&
711         (lo->scale_down_by == 0) &&
712         (lo->dpi == 0.0) &&
713         ((lo->w == 0) || (lo->h == 0)) &&
714         ((lo->region.w == 0) || (lo->region.h == 0)) &&
715         (lo->orientation == 0)
716         ))
717      {
718         lo = &prevent;
719      }
720    else
721      {
722         memcpy(hkey + size, "//@/", 4);
723         size += 4;
724         size += eina_convert_xtoa(lo->scale_down_by, hkey + size);
725         hkey[size] = '/';
726         size += 1;
727         size += eina_convert_dtoa(lo->dpi, hkey + size);
728         hkey[size] = '/';
729         size += 1;
730         size += eina_convert_xtoa(lo->w, hkey + size);
731         hkey[size] = 'x';
732         size += 1;
733         size += eina_convert_xtoa(lo->h, hkey + size);
734         hkey[size] = '/';
735         size += 1;
736         size += eina_convert_xtoa(lo->region.x, hkey + size);
737         hkey[size] = '+';
738         size += 1;
739         size += eina_convert_xtoa(lo->region.y, hkey + size);
740         hkey[size] = '.';
741         size += 1;
742         size += eina_convert_xtoa(lo->region.w, hkey + size);
743         hkey[size] = 'x';
744         size += 1;
745         size += eina_convert_xtoa(lo->region.h, hkey + size);
746
747         if (lo->orientation)
748           {
749              hkey[size] = '/';
750              size += 1;
751              hkey[size] = 'o';
752              size += 1;
753           }
754      }
755    hkey[size] = '\0';
756
757    /* find image by key in active hash */
758 #ifdef EVAS_FRAME_QUEUING
759    LKL(cache->lock);
760 #endif
761    im = eina_hash_find(cache->activ, hkey);
762 #ifdef EVAS_FRAME_QUEUING
763    LKU(cache->lock);
764 #endif
765    if (im)
766      {
767         int ok = 1;
768
769         stat_done = 1;
770         if (stat(file, &st) < 0)
771            {
772               stat_failed = 1;
773               ok = 0;
774            }
775         else if (!_timestamp_compare(&(im->tstamp), &st)) ok = 0;
776         if (ok) goto on_ok;
777         /* image we found doesn't match what's on disk (stat info wise)
778          * so dirty the active cache entry so we never find it again. this
779          * also implicitly guarantees that we only have 1 active copy
780          * of an image at a given key. we wither find it and keep re-reffing
781          * it or we dirty it and get it out */
782         _evas_cache_image_dirty_add(im);
783         im = NULL;
784      }
785
786    /* find image by key in inactive/lru hash */
787 #ifdef EVAS_FRAME_QUEUING
788    LKL(cache->lock);
789 #endif
790    im = eina_hash_find(cache->inactiv, hkey);
791 #ifdef EVAS_FRAME_QUEUING
792    LKU(cache->lock);
793 #endif
794    if (im)
795      {
796         int ok = 1;
797
798         if (!stat_done)
799           {
800              stat_done = 1;
801              if (stat(file, &st) < 0)
802                {
803                   stat_failed = 1;
804                   ok = 0;
805                }
806              else if (!_timestamp_compare(&(im->tstamp), &st)) ok = 0;
807           }
808         else if (!_timestamp_compare(&(im->tstamp), &st)) ok = 0;
809
810         if (ok)
811           {
812              /* remove from lru and make it active again */
813              _evas_cache_image_lru_del(im);
814              _evas_cache_image_activ_add(im);
815              goto on_ok;
816           }
817         /* as avtive cache find - if we match in lru and its invalid, dirty */
818         _evas_cache_image_dirty_add(im);
819         im = NULL;
820      }
821    if (stat_failed) goto on_stat_error;
822    
823    if (!stat_done)
824      {
825         if (stat(file, &st) < 0) goto on_stat_error;
826      }
827    _timestamp_build(&tstamp, &st);
828    im = _evas_cache_image_entry_new(cache, hkey, &tstamp, file, key, 
829                                     lo, error);
830    if (!im) goto on_stat_error;
831    if (cache->func.debug) cache->func.debug("request", im);
832
833  on_ok:
834    *error = EVAS_LOAD_ERROR_NONE;
835 #ifdef EVAS_FRAME_QUEUING
836    LKL(im->lock_references);
837 #endif
838    im->references++;
839 #ifdef EVAS_FRAME_QUEUING
840    LKU(im->lock_references);
841 #endif
842    return im;
843
844  on_stat_error:
845 #ifndef _WIN32
846    if ((errno == ENOENT) || (errno == ENOTDIR) ||
847        (errno == ENAMETOOLONG) || (errno == ELOOP))
848 #else
849    if (errno == ENOENT)
850 #endif
851      *error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
852 #ifndef _WIN32
853    else if ((errno == ENOMEM) || (errno == EOVERFLOW))
854 #else
855    else if (errno == ENOMEM)
856 #endif
857      *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
858    else if (errno == EACCES)
859      *error = EVAS_LOAD_ERROR_PERMISSION_DENIED;
860    else
861      *error = EVAS_LOAD_ERROR_GENERIC;
862
863    if (im) _evas_cache_image_entry_delete(cache, im);
864    return NULL;
865 }
866
867 EAPI void
868 evas_cache_image_drop(Image_Entry *im)
869 {
870    Evas_Cache_Image *cache;
871    int references;
872
873 #ifdef EVAS_FRAME_QUEUING
874    LKL(im->lock_references);
875 #endif
876    im->references--;
877    if (im->references < 0) im->references = 0;
878    references = im->references;
879 #ifdef EVAS_FRAME_QUEUING
880    LKU(im->lock_references);
881 #endif
882    
883    cache = im->cache;
884
885    if (references == 0)
886      {
887 #ifdef EVAS_FRAME_QUEUING
888         LKL(im->ref_fq_add);
889         LKL(im->ref_fq_del);
890         if (im->ref_fq[0] != im->ref_fq[1])
891           {
892              LKU(im->ref_fq_add);
893              LKU(im->ref_fq_del);
894              return;
895           }
896         LKU(im->ref_fq_add);
897         LKU(im->ref_fq_del);
898 #endif
899
900 #ifdef BUILD_ASYNC_PRELOAD
901         if (im->preload)
902           {
903              _evas_cache_image_entry_preload_remove(im, NULL);
904              return;
905           }
906 #endif
907
908         if (im->flags.dirty)
909           {
910              _evas_cache_image_entry_delete(cache, im);
911              return;
912           }
913         _evas_cache_image_lru_add(im);
914         if (cache) evas_cache_image_flush(cache);
915      }
916 }
917
918 EAPI void
919 evas_cache_image_data_not_needed(Image_Entry *im)
920 {
921    Evas_Cache_Image *cache;
922    int references;
923
924    /* FIXME: no one uses this api... well evas_cache_engine_parent_not_needed()
925     * does, but nothing uses that! */
926    cache = im->cache;
927 #ifdef EVAS_FRAME_QUEUING
928    LKL(im->lock_references);
929 #endif
930    references = im->references;
931 #ifdef EVAS_FRAME_QUEUING
932    LKU(im->lock_references);
933 #endif
934    if (references > 1) return;
935    if ((im->flags.dirty) || (!im->flags.need_data)) return;
936    _evas_cache_image_lru_nodata_add(im);
937 }
938
939 EAPI Image_Entry *
940 evas_cache_image_dirty(Image_Entry *im, unsigned int x, unsigned int y, unsigned int w, unsigned int h)
941 {
942    Image_Entry *im_dirty = im;
943    Evas_Cache_Image *cache;
944    int references;
945
946    cache = im->cache;
947    if (!(im->flags.dirty))
948      {
949 #ifdef EVAS_FRAME_QUEUING
950         LKL(im->lock_references);
951 #endif
952         references = im->references;
953 #ifdef EVAS_FRAME_QUEUING
954         LKU(im->lock_references);
955 #endif
956 #ifndef EVAS_CSERVE
957         // if ref 1 also copy if using shared cache as its read-only
958         if (references == 1) im_dirty = im;
959         else
960 #endif
961           {
962              int error;
963              
964              im_dirty = 
965                 evas_cache_image_copied_data(cache, im->w, im->h, 
966                                              evas_cache_image_pixels(im), 
967                                              im->flags.alpha, im->space);
968              if (!im_dirty) goto on_error;
969              if (cache->func.debug) cache->func.debug("dirty-src", im);
970              error = cache->func.dirty(im_dirty, im);
971              if (cache->func.debug) cache->func.debug("dirty-out", im_dirty);
972 #ifdef EVAS_FRAME_QUEUING
973              LKL(im_dirty->lock_references);
974 #endif
975              im_dirty->references = 1;
976 #ifdef EVAS_FRAME_QUEUING
977              LKU(im_dirty->lock_references);
978 #endif
979              evas_cache_image_drop(im);
980           }
981         _evas_cache_image_dirty_add(im_dirty);
982      }
983    
984    if (cache->func.debug) cache->func.debug("dirty-region", im_dirty);
985    if (cache->func.dirty_region)
986       cache->func.dirty_region(im_dirty, x, y, w, h);
987    return im_dirty;
988
989 on_error:
990    if (im_dirty) _evas_cache_image_entry_delete(cache, im_dirty);
991    evas_cache_image_drop(im);
992    return NULL;
993 }
994
995 EAPI Image_Entry *
996 evas_cache_image_alone(Image_Entry *im)
997 {
998    Evas_Cache_Image *cache;
999    Image_Entry *im_dirty = im;
1000    int references;
1001
1002    cache = im->cache;
1003 #ifdef EVAS_FRAME_QUEUING
1004    LKL(im->lock_references);
1005 #endif
1006    references = im->references;
1007 #ifdef EVAS_FRAME_QUEUING
1008    LKU(im->lock_references);
1009 #endif
1010
1011    if (references <= 1)
1012      {
1013         if (!im->flags.dirty) _evas_cache_image_dirty_add(im);
1014      }
1015    else
1016      {
1017         int error;
1018
1019         im_dirty = evas_cache_image_copied_data(cache, im->w, im->h, 
1020                                                 evas_cache_image_pixels(im), 
1021                                                 im->flags.alpha, 
1022                                                 im->space);
1023         if (!im_dirty) goto on_error;
1024         if (cache->func.debug) cache->func.debug("dirty-src", im);
1025         error = cache->func.dirty(im_dirty, im);
1026         if (cache->func.debug) cache->func.debug("dirty-out", im_dirty);
1027 #ifdef EVAS_FRAME_QUEUING
1028         LKL(im_dirty->lock_references);
1029 #endif
1030         im_dirty->references = 1;
1031 #ifdef EVAS_FRAME_QUEUING
1032         LKU(im_dirty->lock_references);
1033 #endif
1034         evas_cache_image_drop(im);
1035      }
1036    return im_dirty;
1037    
1038 on_error:
1039    if (im_dirty) _evas_cache_image_entry_delete(cache, im_dirty);
1040    evas_cache_image_drop(im);
1041    return NULL;
1042 }
1043
1044 EAPI Image_Entry *
1045 evas_cache_image_copied_data(Evas_Cache_Image *cache, 
1046                              unsigned int w, unsigned int h, 
1047                              DATA32 *image_data, int alpha, int cspace)
1048 {
1049    Image_Entry *im;
1050    
1051    if ((cspace == EVAS_COLORSPACE_YCBCR422P601_PL) ||
1052        (cspace == EVAS_COLORSPACE_YCBCR422P709_PL) ||
1053        (cspace == EVAS_COLORSPACE_YCBCR422601_PL))
1054       w &= ~0x1;
1055    
1056    im = _evas_cache_image_entry_new(cache, NULL, NULL, NULL, NULL, NULL, NULL);
1057    if (!im) return NULL;
1058    im->space = cspace;
1059    im->flags.alpha = alpha;
1060    _evas_cache_image_entry_surface_alloc(cache, im, w, h);
1061    if (cache->func.copied_data(im, w, h, image_data, alpha, cspace) != 0)
1062      {
1063         _evas_cache_image_entry_delete(cache, im);
1064         return NULL;
1065      }
1066 #ifdef EVAS_FRAME_QUEUING
1067    LKL(im->lock_references);
1068 #endif
1069    im->references = 1;
1070 #ifdef EVAS_FRAME_QUEUING
1071    LKU(im->lock_references);
1072 #endif
1073    if (cache->func.debug) cache->func.debug("copied-data", im);
1074    return im;
1075 }
1076
1077 EAPI Image_Entry *
1078 evas_cache_image_data(Evas_Cache_Image *cache, unsigned int w, unsigned int h, DATA32 *image_data, int alpha, int cspace)
1079 {
1080    Image_Entry *im;
1081
1082    if ((cspace == EVAS_COLORSPACE_YCBCR422P601_PL) ||
1083        (cspace == EVAS_COLORSPACE_YCBCR422P709_PL) ||
1084        (cspace == EVAS_COLORSPACE_YCBCR422601_PL))
1085       w &= ~0x1;
1086    
1087    im = _evas_cache_image_entry_new(cache, NULL, NULL, NULL, NULL, NULL, NULL);
1088    if (!im) return NULL;
1089    im->w = w;
1090    im->h = h;
1091    im->flags.alpha = alpha;
1092    if (cache->func.data(im, w, h, image_data, alpha, cspace) != 0)
1093      {
1094         _evas_cache_image_entry_delete(cache, im);
1095         return NULL;
1096      }
1097 #ifdef EVAS_FRAME_QUEUING
1098    LKL(im->lock_references);
1099 #endif
1100    im->references = 1;
1101 #ifdef EVAS_FRAME_QUEUING
1102    LKU(im->lock_references);
1103 #endif
1104    if (cache->func.debug) cache->func.debug("data", im);
1105    return im;
1106 }
1107
1108 EAPI void
1109 evas_cache_image_surface_alloc(Image_Entry *im, unsigned int w, unsigned int h)
1110 {
1111    Evas_Cache_Image *cache = im->cache;
1112    
1113    if ((im->space == EVAS_COLORSPACE_YCBCR422P601_PL) ||
1114        (im->space == EVAS_COLORSPACE_YCBCR422P709_PL) ||
1115        (im->space == EVAS_COLORSPACE_YCBCR422601_PL))
1116      w &= ~0x1;
1117
1118    _evas_cache_image_entry_surface_alloc(cache, im, w, h);
1119    if (cache->func.debug) cache->func.debug("surface-alloc", im);
1120 }
1121
1122 EAPI Image_Entry *
1123 evas_cache_image_size_set(Image_Entry *im, unsigned int w, unsigned int h)
1124 {
1125    Evas_Cache_Image *cache;
1126    Image_Entry *im2 = NULL;
1127    int error;
1128
1129    if ((im->space == EVAS_COLORSPACE_YCBCR422P601_PL) ||
1130        (im->space == EVAS_COLORSPACE_YCBCR422P709_PL) ||
1131        (im->space == EVAS_COLORSPACE_YCBCR422601_PL))
1132      w &= ~0x1;
1133    if ((im->w == w) && (im->h == h)) return im;
1134
1135    cache = im->cache;
1136    im2 = _evas_cache_image_entry_new(cache, NULL, NULL, NULL, NULL, NULL, &error);
1137    if (!im2) goto on_error;
1138
1139    im2->flags.alpha = im->flags.alpha;
1140    im2->space = im->space;
1141    im2->load_opts = im->load_opts;
1142    _evas_cache_image_entry_surface_alloc(cache, im2, w, h);
1143    error = cache->func.size_set(im2, im, w, h);
1144    if (error != 0) goto on_error;
1145 #ifdef EVAS_FRAME_QUEUING
1146    LKL(im2->lock_references);
1147 #endif
1148    im2->references = 1;
1149 #ifdef EVAS_FRAME_QUEUING
1150    LKU(im2->lock_references);
1151 #endif
1152    evas_cache_image_drop(im);
1153    if (cache->func.debug) cache->func.debug("size_set", im2);
1154    return im2;
1155
1156  on_error:
1157    if (im2) _evas_cache_image_entry_delete(cache, im2);
1158    evas_cache_image_drop(im);
1159    return NULL;
1160 }
1161
1162 EAPI int
1163 evas_cache_image_load_data(Image_Entry *im)
1164 {
1165 #ifdef BUILD_ASYNC_PRELOAD
1166    Eina_Bool preload = EINA_FALSE;
1167 #endif
1168    int error = EVAS_LOAD_ERROR_NONE;
1169
1170    if ((im->flags.loaded) && (!im->flags.animated)) return error;
1171 #ifdef BUILD_ASYNC_PRELOAD
1172    if (im->preload)
1173      {
1174         preload = EINA_TRUE;
1175         if (!im->flags.pending)
1176           {
1177              im->cache->preload = eina_list_remove(im->cache->preload, im);
1178              im->cache->pending = eina_list_append(im->cache->pending, im);
1179              im->flags.pending = 1;
1180              evas_preload_thread_cancel(im->preload);
1181           }
1182         evas_async_events_process();
1183         LKL(wakeup);
1184         while (im->preload)
1185           {
1186              eina_condition_wait(&cond_wakeup);
1187              LKU(wakeup);
1188              evas_async_events_process();
1189              LKL(wakeup);
1190           }
1191         LKU(wakeup);
1192      }
1193    
1194    if ((im->flags.loaded) && (!im->flags.animated)) return error;
1195    LKL(im->lock);
1196 #endif
1197    im->flags.in_progress = EINA_TRUE;
1198    error = im->cache->func.load(im);
1199    im->flags.in_progress = EINA_FALSE;
1200 #ifdef BUILD_ASYNC_PRELOAD
1201    LKU(im->lock);
1202 #endif
1203    im->flags.loaded = 1;
1204    if (im->cache->func.debug) im->cache->func.debug("load", im);
1205    if (error != EVAS_LOAD_ERROR_NONE)
1206      {
1207         _evas_cache_image_entry_surface_alloc(im->cache, im, im->w, im->h);
1208         im->flags.loaded = 0;
1209      }
1210 #ifdef BUILD_ASYNC_PRELOAD
1211    if (preload) _evas_cache_image_async_end(im);
1212 #endif
1213    return error;
1214 }
1215
1216 EAPI void
1217 evas_cache_image_unload_data(Image_Entry *im)
1218 {
1219    if (im->flags.in_progress) return;
1220    evas_cache_image_preload_cancel(im, NULL);
1221 #ifdef BUILD_ASYNC_PRELOAD
1222    LKL(im->lock_cancel);
1223    if (LKT(im->lock) == EINA_FALSE) /* can't get image lock - busy async load */
1224      {
1225         im->unload_cancel = EINA_TRUE;
1226         LKU(im->lock_cancel);
1227         return;
1228      }
1229    LKU(im->lock_cancel);
1230 #endif
1231    if ((!im->flags.loaded) || (!im->file) || (!im->info.module) || 
1232        (im->flags.dirty))
1233      {
1234 #ifdef BUILD_ASYNC_PRELOAD
1235         LKU(im->lock);
1236 #endif
1237         return;
1238      }
1239    im->cache->func.destructor(im);
1240 #ifdef BUILD_ASYNC_PRELOAD
1241    LKU(im->lock);
1242 #endif
1243    //FIXME: imagedataunload - inform owners
1244 }
1245
1246 static Eina_Bool
1247 _evas_cache_image_unload_cb(__UNUSED__ const Eina_Hash *hash, __UNUSED__ const void *key, void *data, __UNUSED__ void *fdata)
1248 {
1249    evas_cache_image_unload_data(data);
1250    return EINA_TRUE;
1251 }
1252
1253 EAPI void
1254 evas_cache_image_unload_all(Evas_Cache_Image *cache)
1255 {
1256    Image_Entry *im;
1257
1258    EINA_INLIST_FOREACH(cache->lru, im) evas_cache_image_unload_data(im);
1259    EINA_INLIST_FOREACH(cache->lru_nodata, im) evas_cache_image_unload_data(im);
1260    eina_hash_foreach(cache->activ, _evas_cache_image_unload_cb, NULL);
1261    eina_hash_foreach(cache->inactiv, _evas_cache_image_unload_cb, NULL);
1262 }
1263
1264 EAPI Eina_Bool
1265 evas_cache_image_is_loaded(Image_Entry *im)
1266 {
1267   if (im->flags.loaded) return EINA_TRUE;
1268   return EINA_FALSE;
1269 }
1270
1271 EAPI void
1272 evas_cache_image_preload_data(Image_Entry *im, const void *target)
1273 {
1274 #ifdef BUILD_ASYNC_PRELOAD
1275    RGBA_Image *img = (RGBA_Image *)im;
1276    
1277    if ((im->flags.loaded) && (img->image.data))
1278      {
1279         evas_object_inform_call_image_preloaded((Evas_Object *)target);
1280         return;
1281      }
1282    im->flags.loaded = 0;
1283    if (!_evas_cache_image_entry_preload_add(im, target))
1284       evas_object_inform_call_image_preloaded((Evas_Object *)target);
1285 #else
1286    evas_cache_image_load_data(im);
1287    evas_object_inform_call_image_preloaded((Evas_Object *)target);
1288 #endif
1289 }
1290
1291 EAPI void
1292 evas_cache_image_preload_cancel(Image_Entry *im, const void *target)
1293 {
1294 #ifdef BUILD_ASYNC_PRELOAD
1295    if (!target) return;
1296    _evas_cache_image_entry_preload_remove(im, target);
1297 #else
1298    (void)im;
1299 #endif
1300 }
1301
1302 #ifdef CACHEDUMP
1303 static int total = 0;
1304
1305 static void
1306 _dump_img(Image_Entry *im, const char *type)
1307 {
1308    total += im->cache->func.mem_size_get(im);
1309    printf("%s: %4i: %4ib, %4ix%4i alloc[%4ix%4i] [%s] [%s]\n",
1310           type,
1311           im->references,
1312           im->cache->func.mem_size_get(im),
1313           im->w, im->h, im->allocated.w, im->allocated.h,
1314           im->file, im->key);
1315 }
1316
1317 static Eina_Bool
1318 _dump_cache_active(__UNUSED__ const Eina_Hash *hash, __UNUSED__ const void *key, void *data, void *fdata __UNUSED__)
1319 {
1320    Image_Entry *im = data;
1321    _dump_img(im, "ACTIVE");
1322    return EINA_TRUE;
1323 }
1324
1325 static void
1326 _dump_cache(Evas_Cache_Image *cache)
1327 {
1328    Image_Entry *im;
1329    
1330    printf("--CACHE DUMP----------------------------------------------------\n");
1331    printf("cache: %ikb / %ikb\n",
1332           cache->usage / 1024,
1333           cache->limit / 1024);
1334    printf("................................................................\n");
1335    total = 0;
1336    EINA_INLIST_FOREACH(cache->lru_nodata, im)
1337       _dump_img(im, "NODATA");
1338    EINA_INLIST_FOREACH(cache->lru, im)
1339       _dump_img(im, "DATA  ");
1340    printf("tot: %i\n"
1341           "usg: %i\n",
1342           total,
1343           cache->usage);
1344    eina_hash_foreach(cache->activ, _dump_cache_active, NULL);
1345 }
1346 #endif
1347
1348 EAPI int
1349 evas_cache_image_flush(Evas_Cache_Image *cache)
1350 {
1351 #ifdef CACHEDUMP
1352   _dump_cache(cache);
1353 #endif  
1354    if (cache->limit == (unsigned int)-1) return -1;
1355
1356    while ((cache->lru) && (cache->limit < (unsigned int)cache->usage))
1357      {
1358         Image_Entry *im;
1359         
1360         im = (Image_Entry *)cache->lru->last;
1361         _evas_cache_image_entry_delete(cache, im);
1362      }
1363    
1364    while ((cache->lru_nodata) && (cache->limit < (unsigned int)cache->usage))
1365      {
1366         Image_Entry *im;
1367         
1368         im = (Image_Entry *) cache->lru_nodata->last;
1369         _evas_cache_image_lru_nodata_del(im);
1370         cache->func.surface_delete(im);
1371         im->flags.loaded = 0;
1372      }
1373
1374    return cache->usage;
1375 }
1376
1377 EAPI Image_Entry *
1378 evas_cache_image_empty(Evas_Cache_Image *cache)
1379 {
1380    Image_Entry *im;
1381
1382    im = _evas_cache_image_entry_new(cache, NULL, NULL, NULL, NULL, NULL, NULL);
1383    if (!im) return NULL;
1384 #ifdef EVAS_FRAME_QUEUING
1385    LKL(im->lock_references);
1386 #endif
1387    im->references = 1;
1388 #ifdef EVAS_FRAME_QUEUING
1389    LKU(im->lock_references);
1390 #endif
1391    return im;
1392 }
1393
1394 EAPI void
1395 evas_cache_image_colorspace(Image_Entry *im, int cspace)
1396 {
1397    if (im->space == cspace) return;
1398    im->space = cspace;
1399    im->cache->func.color_space(im, cspace);
1400 }
1401
1402 EAPI void *
1403 evas_cache_private_from_image_entry_get(Image_Entry *im)
1404 {
1405    return (void *)im->cache->data;
1406 }
1407
1408 EAPI void *
1409 evas_cache_private_get(Evas_Cache_Image *cache)
1410 {
1411    return cache->data;
1412 }
1413
1414 EAPI void
1415 evas_cache_private_set(Evas_Cache_Image *cache, const void *data)
1416 {
1417    cache->data = (void *)data;
1418 }
1419
1420 EAPI DATA32 *
1421 evas_cache_image_pixels(Image_Entry *im)
1422 {
1423    return im->cache->func.surface_pixels(im);
1424 }
1425
1426 EAPI void
1427 evas_cache_image_wakeup(void)
1428 {
1429 #ifdef BUILD_ASYNC_PRELOAD
1430    if (_evas_cache_mutex_init > 0)
1431      eina_condition_broadcast(&cond_wakeup);
1432 #endif
1433 }