2008-07-21 09:44:58 -07:00
|
|
|
/*
|
|
|
|
* vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
|
|
|
|
*/
|
|
|
|
|
2008-11-05 09:21:04 -08:00
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
# include <config.h>
|
|
|
|
#endif
|
|
|
|
|
2007-07-16 00:25:35 -07:00
|
|
|
#include <stdlib.h>
|
|
|
|
#include <assert.h>
|
2008-11-05 09:21:04 -08:00
|
|
|
#include <sys/types.h>
|
|
|
|
#include <sys/stat.h>
|
|
|
|
|
|
|
|
#ifdef HAVE_EVIL
|
|
|
|
# include <Evil.h>
|
|
|
|
#endif
|
2007-07-16 00:25:35 -07:00
|
|
|
|
|
|
|
#include "evas_common.h"
|
|
|
|
#include "evas_private.h"
|
|
|
|
|
2009-05-01 00:11:07 -07:00
|
|
|
#ifdef EVAS_CSERVE
|
|
|
|
// FIXME: cache server and threaded preload clash badly atm - disable
|
2009-09-11 06:44:53 -07:00
|
|
|
//#undef BUILD_ASYNC_PRELOAD
|
2009-05-01 00:11:07 -07:00
|
|
|
#endif
|
|
|
|
|
2008-09-16 07:52:57 -07:00
|
|
|
#ifdef BUILD_ASYNC_PRELOAD
|
|
|
|
#include <pthread.h>
|
|
|
|
|
2009-01-19 06:06:09 -08:00
|
|
|
typedef struct _Evas_Cache_Preload Evas_Cache_Preload;
|
|
|
|
|
|
|
|
struct _Evas_Cache_Preload
|
2008-12-23 15:07:48 -08:00
|
|
|
{
|
|
|
|
EINA_INLIST;
|
|
|
|
Image_Entry *ie;
|
|
|
|
};
|
|
|
|
|
|
|
|
static Eina_Inlist *preload = NULL;
|
2008-09-16 07:52:57 -07:00
|
|
|
static Image_Entry *current = NULL;
|
|
|
|
|
2009-01-23 12:36:04 -08:00
|
|
|
static pthread_cond_t cond_done = PTHREAD_COND_INITIALIZER;
|
|
|
|
static pthread_cond_t cond_new = PTHREAD_COND_INITIALIZER;
|
|
|
|
static pthread_mutex_t mutex_new = PTHREAD_MUTEX_INITIALIZER;
|
2008-09-16 07:52:57 -07:00
|
|
|
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
|
|
|
|
static pthread_mutex_t mutex_surface_alloc = PTHREAD_MUTEX_INITIALIZER;
|
2009-01-23 12:36:04 -08:00
|
|
|
static pthread_t tid = 0;
|
2008-09-16 07:52:57 -07:00
|
|
|
|
2009-06-17 03:01:52 -07:00
|
|
|
static Eina_Bool running = EINA_FALSE;
|
2008-09-16 07:52:57 -07:00
|
|
|
|
2009-09-16 02:48:05 -07:00
|
|
|
static void *_evas_cache_background_load(void *);
|
2008-09-16 07:52:57 -07:00
|
|
|
#endif
|
|
|
|
|
2008-04-11 17:32:30 -07:00
|
|
|
#define FREESTRC(Var) \
|
|
|
|
if (Var) \
|
|
|
|
{ \
|
2008-10-15 07:38:34 -07:00
|
|
|
eina_stringshare_del(Var); \
|
2008-04-11 17:32:30 -07:00
|
|
|
Var = NULL; \
|
|
|
|
}
|
|
|
|
|
2008-05-09 12:04:49 -07:00
|
|
|
static void _evas_cache_image_entry_delete(Evas_Cache_Image *cache, Image_Entry *ie);
|
|
|
|
|
2008-04-11 17:32:30 -07:00
|
|
|
static void
|
|
|
|
_evas_cache_image_make_dirty(Evas_Cache_Image *cache,
|
2008-12-01 18:33:09 -08:00
|
|
|
Image_Entry *im)
|
2008-04-11 17:32:30 -07:00
|
|
|
{
|
2008-12-01 18:33:09 -08:00
|
|
|
im->flags.cached = 1;
|
|
|
|
im->flags.dirty = 1;
|
|
|
|
im->flags.activ = 0;
|
|
|
|
im->flags.lru_nodata = 0;
|
|
|
|
cache->dirty = eina_inlist_prepend(cache->dirty, EINA_INLIST_GET(im));
|
2008-04-11 17:32:30 -07:00
|
|
|
|
2008-12-01 18:33:09 -08:00
|
|
|
if (im->cache_key)
|
2008-04-11 17:32:30 -07:00
|
|
|
{
|
2008-12-01 18:33:09 -08:00
|
|
|
eina_stringshare_del(im->cache_key);
|
|
|
|
im->cache_key = NULL;
|
2008-04-11 17:32:30 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_evas_cache_image_make_activ(Evas_Cache_Image *cache,
|
|
|
|
Image_Entry *im,
|
|
|
|
const char *key)
|
|
|
|
{
|
|
|
|
im->cache_key = key;
|
|
|
|
if (key != NULL)
|
|
|
|
{
|
|
|
|
im->flags.cached = 1;
|
|
|
|
im->flags.activ = 1;
|
|
|
|
im->flags.lru_nodata = 0;
|
|
|
|
im->flags.dirty = 0;
|
2008-12-09 09:56:31 -08:00
|
|
|
eina_hash_direct_add(cache->activ, key, im);
|
2008-04-11 17:32:30 -07:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
_evas_cache_image_make_dirty(cache, im);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_evas_cache_image_make_inactiv(Evas_Cache_Image *cache,
|
|
|
|
Image_Entry *im,
|
|
|
|
const char *key)
|
|
|
|
{
|
2008-05-09 09:18:18 -07:00
|
|
|
if (im->cache_key)
|
|
|
|
{
|
|
|
|
im->flags.activ = 0;
|
|
|
|
im->flags.dirty = 0;
|
|
|
|
im->flags.cached = 1;
|
2008-12-09 09:56:31 -08:00
|
|
|
eina_hash_direct_add(cache->inactiv, key, im);
|
2008-10-17 04:23:18 -07:00
|
|
|
cache->lru = eina_inlist_prepend(cache->lru, EINA_INLIST_GET(im));
|
2008-12-01 18:33:09 -08:00
|
|
|
cache->usage += cache->func.mem_size_get(im);
|
2008-05-09 09:18:18 -07:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
_evas_cache_image_entry_delete(cache, im);
|
|
|
|
}
|
|
|
|
}
|
2008-04-11 17:32:30 -07:00
|
|
|
|
|
|
|
static void
|
|
|
|
_evas_cache_image_remove_lru_nodata(Evas_Cache_Image *cache,
|
|
|
|
Image_Entry *im)
|
|
|
|
{
|
|
|
|
if (im->flags.lru_nodata)
|
|
|
|
{
|
|
|
|
im->flags.lru_nodata = 0;
|
2008-10-17 04:23:18 -07:00
|
|
|
cache->lru_nodata = eina_inlist_remove(cache->lru_nodata, EINA_INLIST_GET(im));
|
2008-12-01 18:33:09 -08:00
|
|
|
cache->usage -= cache->func.mem_size_get(im);
|
2008-04-11 17:32:30 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_evas_cache_image_activ_lru_nodata(Evas_Cache_Image *cache,
|
|
|
|
Image_Entry *im)
|
|
|
|
{
|
|
|
|
im->flags.need_data = 0;
|
|
|
|
im->flags.lru_nodata = 1;
|
2008-10-17 04:23:18 -07:00
|
|
|
cache->lru_nodata = eina_inlist_prepend(cache->lru_nodata, EINA_INLIST_GET(im));
|
2008-04-11 17:32:30 -07:00
|
|
|
cache->usage += cache->func.mem_size_get(im);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_evas_cache_image_remove_activ(Evas_Cache_Image *cache,
|
|
|
|
Image_Entry *ie)
|
|
|
|
{
|
|
|
|
if (ie->flags.cached)
|
|
|
|
{
|
|
|
|
if (ie->flags.activ)
|
|
|
|
{
|
2008-12-09 09:56:31 -08:00
|
|
|
eina_hash_del(cache->activ, ie->cache_key, ie);
|
2008-04-11 17:32:30 -07:00
|
|
|
_evas_cache_image_remove_lru_nodata(cache, ie);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (ie->flags.dirty)
|
|
|
|
{
|
2008-10-17 04:23:18 -07:00
|
|
|
cache->dirty = eina_inlist_remove(cache->dirty, EINA_INLIST_GET(ie));
|
2008-04-11 17:32:30 -07:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2008-12-09 09:56:31 -08:00
|
|
|
eina_hash_del(cache->inactiv, ie->cache_key, ie);
|
2008-10-17 04:23:18 -07:00
|
|
|
cache->lru = eina_inlist_remove(cache->lru, EINA_INLIST_GET(ie));
|
2008-04-11 17:32:30 -07:00
|
|
|
cache->usage -= cache->func.mem_size_get(ie);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
ie->flags.cached = 0;
|
|
|
|
ie->flags.dirty = 0;
|
|
|
|
ie->flags.activ = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_evas_cache_image_entry_delete(Evas_Cache_Image *cache, Image_Entry *ie)
|
|
|
|
{
|
|
|
|
if (!ie) return ;
|
|
|
|
|
|
|
|
if (cache->func.debug)
|
|
|
|
cache->func.debug("deleting", ie);
|
|
|
|
|
|
|
|
cache->func.destructor(ie);
|
|
|
|
|
|
|
|
_evas_cache_image_remove_activ(cache, ie);
|
|
|
|
|
|
|
|
if (ie->cache_key)
|
|
|
|
{
|
2008-10-15 07:38:34 -07:00
|
|
|
eina_stringshare_del(ie->cache_key);
|
2008-04-11 17:32:30 -07:00
|
|
|
ie->cache_key = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
FREESTRC(ie->file);
|
|
|
|
FREESTRC(ie->key);
|
|
|
|
|
|
|
|
cache->func.surface_delete(ie);
|
2008-12-23 15:07:48 -08:00
|
|
|
|
|
|
|
#ifdef BUILD_ASYNC_PRELOAD
|
2009-03-13 22:08:08 -07:00
|
|
|
LKD(ie->lock);
|
2008-12-23 15:07:48 -08:00
|
|
|
#endif
|
|
|
|
|
2008-05-24 11:26:51 -07:00
|
|
|
cache->func.dealloc(ie);
|
2008-04-11 17:32:30 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static Image_Entry *
|
|
|
|
_evas_cache_image_entry_new(Evas_Cache_Image *cache,
|
|
|
|
const char *hkey,
|
|
|
|
time_t timestamp,
|
|
|
|
const char *file,
|
|
|
|
const char *key,
|
|
|
|
RGBA_Image_Loadopts *lo,
|
|
|
|
int *error)
|
|
|
|
{
|
|
|
|
Image_Entry *ie;
|
|
|
|
const char *cache_key;
|
|
|
|
|
|
|
|
ie = cache->func.alloc();
|
|
|
|
if (!ie)
|
|
|
|
return NULL;
|
|
|
|
|
2008-10-15 07:38:34 -07:00
|
|
|
cache_key = hkey ? eina_stringshare_add(hkey) : NULL;
|
2008-04-11 17:32:30 -07:00
|
|
|
|
|
|
|
ie->flags.loaded = 0;
|
|
|
|
ie->flags.need_data = 1;
|
|
|
|
|
|
|
|
_evas_cache_image_make_activ(cache, ie, cache_key);
|
|
|
|
|
|
|
|
ie->space = EVAS_COLORSPACE_ARGB8888;
|
|
|
|
ie->w = -1;
|
|
|
|
ie->h = -1;
|
2008-05-06 04:20:29 -07:00
|
|
|
ie->allocated.w = 0;
|
|
|
|
ie->allocated.h = 0;
|
2008-04-11 17:32:30 -07:00
|
|
|
|
|
|
|
ie->references = 0;
|
|
|
|
ie->cache = cache;
|
|
|
|
|
2008-10-15 07:38:34 -07:00
|
|
|
ie->file = file ? eina_stringshare_add(file) : NULL;
|
|
|
|
ie->key = key ? eina_stringshare_add(key) : NULL;
|
2008-04-11 17:32:30 -07:00
|
|
|
|
|
|
|
ie->timestamp = timestamp;
|
|
|
|
ie->laststat = time(NULL);
|
|
|
|
|
|
|
|
ie->load_opts.scale_down_by = 0;
|
|
|
|
ie->load_opts.dpi = 0;
|
|
|
|
ie->load_opts.w = 0;
|
|
|
|
ie->load_opts.h = 0;
|
2009-09-15 06:34:12 -07:00
|
|
|
ie->load_opts.region.x = 0;
|
|
|
|
ie->load_opts.region.y = 0;
|
|
|
|
ie->load_opts.region.w = 0;
|
|
|
|
ie->load_opts.region.h = 0;
|
2008-04-11 17:32:30 -07:00
|
|
|
ie->scale = 1;
|
|
|
|
|
2008-12-23 15:07:48 -08:00
|
|
|
#ifdef BUILD_ASYNC_PRELOAD
|
2009-03-13 22:08:08 -07:00
|
|
|
LKI(ie->lock);
|
2009-01-19 06:06:09 -08:00
|
|
|
ie->targets = NULL;
|
2008-12-23 15:07:48 -08:00
|
|
|
#endif
|
|
|
|
|
2008-04-11 17:32:30 -07:00
|
|
|
if (lo)
|
|
|
|
ie->load_opts = *lo;
|
|
|
|
|
|
|
|
if (file)
|
|
|
|
{
|
|
|
|
*error = cache->func.constructor(ie);
|
|
|
|
if (*error != 0)
|
|
|
|
{
|
|
|
|
_evas_cache_image_entry_delete(cache, ie);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (cache->func.debug)
|
|
|
|
cache->func.debug("build", ie);
|
|
|
|
|
|
|
|
return ie;
|
|
|
|
}
|
|
|
|
|
2008-12-26 04:50:55 -08:00
|
|
|
static void
|
|
|
|
_evas_cache_image_entry_surface_alloc__locked(Evas_Cache_Image *cache,
|
|
|
|
Image_Entry *ie,
|
|
|
|
int wmin,
|
|
|
|
int hmin)
|
|
|
|
{
|
|
|
|
if (ie->allocated.w == wmin && ie->allocated.h == hmin)
|
|
|
|
return ;
|
|
|
|
|
|
|
|
if (cache->func.surface_alloc(ie, wmin, hmin))
|
|
|
|
{
|
|
|
|
wmin = 0;
|
|
|
|
hmin = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
ie->w = wmin;
|
|
|
|
ie->h = hmin;
|
|
|
|
ie->allocated.w = wmin;
|
|
|
|
ie->allocated.h = hmin;
|
|
|
|
}
|
|
|
|
|
2008-04-11 17:32:30 -07:00
|
|
|
static void
|
|
|
|
_evas_cache_image_entry_surface_alloc(Evas_Cache_Image *cache,
|
|
|
|
Image_Entry *ie,
|
|
|
|
int w,
|
|
|
|
int h)
|
|
|
|
{
|
|
|
|
int wmin;
|
|
|
|
int hmin;
|
|
|
|
|
|
|
|
wmin = w > 0 ? w : 1;
|
|
|
|
hmin = h > 0 ? h : 1;
|
2008-05-06 04:20:29 -07:00
|
|
|
|
2008-09-16 07:52:57 -07:00
|
|
|
#ifdef BUILD_ASYNC_PRELOAD
|
|
|
|
pthread_mutex_lock(&mutex_surface_alloc);
|
|
|
|
#endif
|
2008-12-26 04:50:55 -08:00
|
|
|
_evas_cache_image_entry_surface_alloc__locked(cache, ie, wmin, hmin);
|
2008-09-16 07:52:57 -07:00
|
|
|
#ifdef BUILD_ASYNC_PRELOAD
|
|
|
|
pthread_mutex_unlock(&mutex_surface_alloc);
|
|
|
|
#endif
|
2008-04-11 17:32:30 -07:00
|
|
|
}
|
|
|
|
|
2008-09-16 07:52:57 -07:00
|
|
|
#ifdef BUILD_ASYNC_PRELOAD
|
2009-01-20 06:56:37 -08:00
|
|
|
static void
|
2009-01-23 14:23:03 -08:00
|
|
|
_evas_cache_image_async_call__locked(Image_Entry *im)
|
2009-01-20 06:56:37 -08:00
|
|
|
{
|
|
|
|
while (im->targets)
|
|
|
|
{
|
|
|
|
Evas_Cache_Target *tmp = im->targets;
|
2009-09-16 02:48:05 -07:00
|
|
|
|
2009-01-20 06:56:37 -08:00
|
|
|
evas_async_events_put(tmp->target, EVAS_CALLBACK_IMAGE_PRELOADED, NULL,
|
|
|
|
(void (*)(void*, Evas_Callback_Type, void*))evas_object_event_callback_call);
|
|
|
|
im->targets = (Evas_Cache_Target*) eina_inlist_remove(EINA_INLIST_GET(im->targets), EINA_INLIST_GET(im->targets));
|
|
|
|
free(tmp);
|
|
|
|
}
|
2009-01-23 14:21:04 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_evas_cache_image_async_call(Image_Entry *im)
|
|
|
|
{
|
|
|
|
pthread_mutex_lock(&mutex);
|
2009-01-23 14:23:03 -08:00
|
|
|
_evas_cache_image_async_call__locked(im);
|
2009-01-20 06:56:37 -08:00
|
|
|
pthread_mutex_unlock(&mutex);
|
|
|
|
}
|
|
|
|
|
2008-09-16 07:52:57 -07:00
|
|
|
static int
|
2009-01-19 06:06:09 -08:00
|
|
|
_evas_cache_image_entry_preload_add(Image_Entry *ie,
|
2008-09-16 07:52:57 -07:00
|
|
|
const void *target)
|
|
|
|
{
|
2009-01-19 06:06:09 -08:00
|
|
|
Evas_Cache_Target *tg;
|
2008-09-16 07:52:57 -07:00
|
|
|
int ret = 0;
|
|
|
|
|
|
|
|
pthread_mutex_lock(&mutex);
|
|
|
|
|
2009-01-19 06:06:09 -08:00
|
|
|
if (!ie->flags.loaded)
|
2008-09-16 07:52:57 -07:00
|
|
|
{
|
2009-01-19 06:06:09 -08:00
|
|
|
tg = malloc(sizeof (Evas_Cache_Target));
|
|
|
|
if (!tg) goto end;
|
|
|
|
|
|
|
|
tg->target = target;
|
|
|
|
ie->targets = (Evas_Cache_Target*) eina_inlist_append(EINA_INLIST_GET(ie->targets), EINA_INLIST_GET(tg));
|
2008-09-16 07:52:57 -07:00
|
|
|
|
2009-01-19 06:06:09 -08:00
|
|
|
if (!ie->flags.preload)
|
2008-09-16 07:52:57 -07:00
|
|
|
{
|
2009-01-19 06:06:09 -08:00
|
|
|
Evas_Cache_Preload *tmp;
|
|
|
|
|
|
|
|
tmp = malloc(sizeof (Evas_Cache_Preload));
|
|
|
|
if (!tmp) goto end;
|
|
|
|
|
|
|
|
tmp->ie = ie;
|
|
|
|
preload = eina_inlist_append(preload, EINA_INLIST_GET(tmp));
|
|
|
|
|
|
|
|
ie->flags.preload = 1;
|
2008-09-16 07:52:57 -07:00
|
|
|
|
2009-01-19 06:06:09 -08:00
|
|
|
if (!running)
|
|
|
|
{
|
2009-01-23 12:36:04 -08:00
|
|
|
if (tid)
|
|
|
|
{
|
2009-06-17 03:01:52 -07:00
|
|
|
running = EINA_TRUE;
|
2009-01-23 12:36:04 -08:00
|
|
|
pthread_cond_signal(&cond_new);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (pthread_create(&tid, NULL, _evas_cache_background_load, NULL) == 0)
|
2009-06-17 03:01:52 -07:00
|
|
|
running = EINA_TRUE;
|
2009-01-23 12:36:04 -08:00
|
|
|
}
|
2009-01-19 06:06:09 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
ret = 2;
|
|
|
|
}
|
2008-09-16 07:52:57 -07:00
|
|
|
ret = 1;
|
|
|
|
}
|
|
|
|
|
2009-01-19 06:06:09 -08:00
|
|
|
end:
|
2008-09-16 07:52:57 -07:00
|
|
|
pthread_mutex_unlock(&mutex);
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2009-01-20 06:56:37 -08:00
|
|
|
_evas_cache_image_entry_preload_remove(Image_Entry *ie, const void *target)
|
2008-09-16 07:52:57 -07:00
|
|
|
{
|
|
|
|
int ret = 0;
|
|
|
|
|
|
|
|
if (running)
|
|
|
|
{
|
|
|
|
pthread_mutex_lock(&mutex);
|
|
|
|
|
|
|
|
if (ie->flags.preload)
|
|
|
|
{
|
|
|
|
if (current == ie)
|
|
|
|
{
|
|
|
|
/* Wait until ie is processed. */
|
2009-01-23 12:36:04 -08:00
|
|
|
pthread_cond_wait(&cond_done, &mutex);
|
2008-09-16 07:52:57 -07:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2009-01-19 06:06:09 -08:00
|
|
|
Evas_Cache_Preload *l;
|
2008-12-23 15:07:48 -08:00
|
|
|
EINA_INLIST_FOREACH(preload, l)
|
|
|
|
{
|
|
|
|
if (l->ie == ie)
|
|
|
|
{
|
2009-01-20 06:56:37 -08:00
|
|
|
Evas_Cache_Target *tg;
|
2009-09-16 02:48:05 -07:00
|
|
|
|
|
|
|
if (target)
|
|
|
|
{
|
|
|
|
EINA_INLIST_FOREACH(ie->targets, tg)
|
|
|
|
{
|
|
|
|
if (tg->target == target)
|
|
|
|
{
|
|
|
|
ie->targets = (Evas_Cache_Target*) eina_inlist_remove(EINA_INLIST_GET(ie->targets), EINA_INLIST_GET(tg));
|
|
|
|
free(tg);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
_evas_cache_image_async_call__locked(ie);
|
|
|
|
|
|
|
|
while (ie->targets)
|
|
|
|
{
|
|
|
|
tg = ie->targets;
|
|
|
|
ie->targets = (Evas_Cache_Target*) eina_inlist_remove(EINA_INLIST_GET(ie->targets), EINA_INLIST_GET(tg));
|
|
|
|
free(tg);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-01-20 06:56:37 -08:00
|
|
|
if (!ie->targets)
|
|
|
|
{
|
|
|
|
preload = eina_inlist_remove(preload,
|
|
|
|
EINA_INLIST_GET(l));
|
|
|
|
free(l);
|
|
|
|
}
|
2009-09-16 02:48:05 -07:00
|
|
|
|
2008-12-23 15:07:48 -08:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2008-09-16 07:52:57 -07:00
|
|
|
ie->flags.preload = 0;
|
|
|
|
ret = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pthread_mutex_unlock(&mutex);
|
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2007-07-16 00:25:35 -07:00
|
|
|
EAPI int
|
|
|
|
evas_cache_image_usage_get(Evas_Cache_Image *cache)
|
|
|
|
{
|
|
|
|
assert(cache != NULL);
|
|
|
|
|
|
|
|
return cache->usage;
|
|
|
|
}
|
|
|
|
|
|
|
|
EAPI int
|
|
|
|
evas_cache_image_get(Evas_Cache_Image *cache)
|
|
|
|
{
|
|
|
|
assert(cache != NULL);
|
|
|
|
|
|
|
|
return cache->limit;
|
|
|
|
}
|
|
|
|
|
|
|
|
EAPI void
|
|
|
|
evas_cache_image_set(Evas_Cache_Image *cache, int limit)
|
|
|
|
{
|
|
|
|
assert(cache != NULL);
|
2007-12-13 21:57:16 -08:00
|
|
|
if (cache->limit == limit) return;
|
2007-07-16 00:25:35 -07:00
|
|
|
cache->limit = limit;
|
2007-12-13 21:57:16 -08:00
|
|
|
evas_cache_image_flush(cache);
|
2007-07-16 00:25:35 -07:00
|
|
|
}
|
|
|
|
|
2007-08-12 22:30:17 -07:00
|
|
|
EAPI Evas_Cache_Image *
|
2007-07-16 00:25:35 -07:00
|
|
|
evas_cache_image_init(const Evas_Cache_Image_Func *cb)
|
|
|
|
{
|
2007-08-12 22:30:17 -07:00
|
|
|
Evas_Cache_Image *new;
|
2007-07-16 00:25:35 -07:00
|
|
|
|
|
|
|
new = malloc(sizeof (Evas_Cache_Image));
|
|
|
|
if (!new)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
new->func = *cb;
|
|
|
|
|
2007-10-07 04:17:09 -07:00
|
|
|
new->limit = 0;
|
2007-07-16 00:25:35 -07:00
|
|
|
new->usage = 0;
|
|
|
|
|
|
|
|
new->dirty = NULL;
|
|
|
|
new->lru = NULL;
|
2008-04-11 17:32:30 -07:00
|
|
|
new->lru_nodata = NULL;
|
2008-12-09 09:56:31 -08:00
|
|
|
new->inactiv = eina_hash_string_superfast_new(NULL);
|
|
|
|
new->activ = eina_hash_string_superfast_new(NULL);
|
2007-07-16 00:25:35 -07:00
|
|
|
|
|
|
|
new->references = 1;
|
|
|
|
|
|
|
|
return new;
|
|
|
|
}
|
|
|
|
|
2009-06-17 03:01:52 -07:00
|
|
|
static Eina_Bool
|
2008-12-09 09:56:31 -08:00
|
|
|
_evas_cache_image_free_cb(__UNUSED__ const Eina_Hash *hash, __UNUSED__ const void *key, void *data, void *fdata)
|
2007-07-16 00:25:35 -07:00
|
|
|
{
|
2008-10-31 04:07:10 -07:00
|
|
|
Eina_List **delete_list = fdata;
|
2007-07-16 00:25:35 -07:00
|
|
|
|
2008-10-31 04:07:10 -07:00
|
|
|
*delete_list = eina_list_prepend(*delete_list, data);
|
2007-07-16 00:25:35 -07:00
|
|
|
|
2009-06-17 03:01:52 -07:00
|
|
|
return EINA_TRUE;
|
2007-07-16 00:25:35 -07:00
|
|
|
}
|
|
|
|
|
2009-01-23 13:08:35 -08:00
|
|
|
#ifdef BUILD_ASYNC_PRELOAD
|
|
|
|
static void
|
|
|
|
_evas_cache_image_entry_clear_preloaders(Image_Entry *ie)
|
|
|
|
{
|
|
|
|
while (ie->targets)
|
|
|
|
{
|
|
|
|
Evas_Cache_Target *t = ie->targets;
|
|
|
|
ie->targets = (Evas_Cache_Target *)
|
|
|
|
eina_inlist_remove(EINA_INLIST_GET(ie->targets),
|
|
|
|
EINA_INLIST_GET(ie->targets));
|
|
|
|
free(t);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2007-07-16 00:25:35 -07:00
|
|
|
EAPI void
|
|
|
|
evas_cache_image_shutdown(Evas_Cache_Image *cache)
|
|
|
|
{
|
2008-04-11 17:32:30 -07:00
|
|
|
Image_Entry *im;
|
2008-10-31 04:07:10 -07:00
|
|
|
Eina_List *delete_list;
|
2007-07-16 00:25:35 -07:00
|
|
|
|
|
|
|
assert(cache != NULL);
|
|
|
|
cache->references--;
|
|
|
|
|
|
|
|
if (cache->references > 0)
|
|
|
|
return ;
|
|
|
|
|
2009-01-22 16:09:10 -08:00
|
|
|
#ifdef BUILD_ASYNC_PRELOAD
|
|
|
|
pthread_mutex_lock(&mutex);
|
|
|
|
if (running)
|
|
|
|
{
|
2009-01-23 13:08:35 -08:00
|
|
|
Eina_Inlist *l, *l_next;
|
|
|
|
for (l = preload; l != NULL; l = l_next)
|
2009-01-22 16:09:10 -08:00
|
|
|
{
|
2009-01-23 13:08:35 -08:00
|
|
|
Evas_Cache_Preload *tmp = (Evas_Cache_Preload *)l;
|
2009-01-22 16:09:10 -08:00
|
|
|
Image_Entry *ie = tmp->ie;
|
|
|
|
|
2009-01-23 13:08:35 -08:00
|
|
|
l_next = l->next;
|
|
|
|
|
|
|
|
if (ie->cache != cache)
|
|
|
|
continue;
|
2009-01-22 16:09:10 -08:00
|
|
|
|
2009-01-23 13:08:35 -08:00
|
|
|
preload = eina_inlist_remove(preload, l);
|
|
|
|
_evas_cache_image_entry_clear_preloaders(ie);
|
|
|
|
free(l);
|
2009-01-22 16:09:10 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
pthread_mutex_unlock(&mutex);
|
|
|
|
#endif
|
|
|
|
|
2007-07-16 00:25:35 -07:00
|
|
|
while (cache->lru)
|
|
|
|
{
|
2008-04-11 17:32:30 -07:00
|
|
|
im = (Image_Entry *) cache->lru;
|
|
|
|
_evas_cache_image_entry_delete(cache, im);
|
|
|
|
}
|
2007-07-16 00:25:35 -07:00
|
|
|
|
2008-04-11 17:32:30 -07:00
|
|
|
while (cache->lru_nodata)
|
|
|
|
{
|
|
|
|
im = (Image_Entry *) cache->lru_nodata;
|
|
|
|
_evas_cache_image_entry_delete(cache, im);
|
2007-07-16 00:25:35 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
/* This is mad, I am about to destroy image still alive, but we need to prevent leak. */
|
|
|
|
while (cache->dirty)
|
|
|
|
{
|
2008-04-11 17:32:30 -07:00
|
|
|
im = (Image_Entry *) cache->dirty;
|
|
|
|
_evas_cache_image_entry_delete(cache, im);
|
2007-07-16 00:25:35 -07:00
|
|
|
}
|
|
|
|
|
2009-01-22 16:08:11 -08:00
|
|
|
delete_list = NULL;
|
2008-12-09 09:56:31 -08:00
|
|
|
eina_hash_foreach(cache->activ, _evas_cache_image_free_cb, &delete_list);
|
2008-10-31 04:07:10 -07:00
|
|
|
|
|
|
|
while (delete_list)
|
|
|
|
{
|
|
|
|
_evas_cache_image_entry_delete(cache, eina_list_data_get(delete_list));
|
|
|
|
delete_list = eina_list_remove_list(delete_list, delete_list);
|
|
|
|
}
|
|
|
|
|
2008-12-09 09:56:31 -08:00
|
|
|
eina_hash_free(cache->activ);
|
|
|
|
eina_hash_free(cache->inactiv);
|
2007-07-16 00:25:35 -07:00
|
|
|
|
|
|
|
free(cache);
|
|
|
|
}
|
|
|
|
|
2008-04-11 17:32:30 -07:00
|
|
|
#define STAT_GAP 2
|
|
|
|
|
|
|
|
EAPI Image_Entry *
|
2007-07-16 00:25:35 -07:00
|
|
|
evas_cache_image_request(Evas_Cache_Image *cache, const char *file, const char *key, RGBA_Image_Loadopts *lo, int *error)
|
|
|
|
{
|
2008-10-17 04:59:49 -07:00
|
|
|
const char *ckey = "(null)";
|
2007-08-12 22:30:17 -07:00
|
|
|
const char *format;
|
|
|
|
char *hkey;
|
2008-04-11 17:32:30 -07:00
|
|
|
Image_Entry *im;
|
2009-09-15 06:34:12 -07:00
|
|
|
Evas_Image_Load_Opts prevent = { 0, 0, 0, 0, 0, 0, 0, 0 };
|
2007-08-12 22:30:17 -07:00
|
|
|
int size;
|
2008-04-11 17:32:30 -07:00
|
|
|
int stat_done = 0;
|
2008-10-17 04:59:49 -07:00
|
|
|
int file_length;
|
|
|
|
int key_length;
|
2007-08-12 22:30:17 -07:00
|
|
|
struct stat st;
|
2007-07-16 00:25:35 -07:00
|
|
|
|
|
|
|
assert(cache != NULL);
|
|
|
|
|
|
|
|
if (!file && !key) return NULL;
|
|
|
|
if (!file) return NULL;
|
2008-10-17 04:59:49 -07:00
|
|
|
|
|
|
|
file_length = strlen(file);
|
|
|
|
key_length = key ? strlen(key) : 6;
|
|
|
|
|
2009-09-16 02:48:05 -07:00
|
|
|
size = file_length + key_length + 128;
|
2008-10-17 04:59:49 -07:00
|
|
|
hkey = alloca(sizeof (char) * size);
|
|
|
|
|
|
|
|
memcpy(hkey, file, file_length);
|
|
|
|
size = file_length;
|
|
|
|
|
|
|
|
memcpy(hkey + size, "//://", 5);
|
|
|
|
size += 5;
|
|
|
|
|
|
|
|
if (key) ckey = key;
|
|
|
|
memcpy(hkey + size, ckey, key_length);
|
|
|
|
size += key_length;
|
|
|
|
|
2007-07-16 00:25:35 -07:00
|
|
|
if ((!lo) ||
|
|
|
|
(lo &&
|
|
|
|
(lo->scale_down_by == 0) &&
|
2008-08-20 05:14:30 -07:00
|
|
|
(lo->dpi == 0.0) &&
|
2009-09-16 02:48:05 -07:00
|
|
|
((lo->w == 0) || (lo->h == 0)) &&
|
|
|
|
((lo->region.w == 0) || (lo->region.w == 0))
|
|
|
|
))
|
2007-07-16 00:25:35 -07:00
|
|
|
{
|
|
|
|
lo = &prevent;
|
2009-09-16 02:48:05 -07:00
|
|
|
// if (key)
|
|
|
|
// format = "%s//://%s";
|
|
|
|
// else
|
|
|
|
// format = "%s//://%p";
|
2007-07-16 00:25:35 -07:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2008-10-17 04:59:49 -07:00
|
|
|
memcpy(hkey + size, "//@/", 4);
|
|
|
|
size += 4;
|
|
|
|
|
|
|
|
size += eina_convert_xtoa(lo->scale_down_by, hkey + size);
|
|
|
|
|
|
|
|
hkey[size] = '/';
|
|
|
|
size += 1;
|
|
|
|
|
|
|
|
size += eina_convert_dtoa(lo->dpi, hkey + size);
|
|
|
|
|
|
|
|
hkey[size] = '/';
|
|
|
|
size += 1;
|
|
|
|
|
|
|
|
size += eina_convert_xtoa(lo->w, hkey + size);
|
|
|
|
|
|
|
|
hkey[size] = 'x';
|
|
|
|
size += 1;
|
|
|
|
|
|
|
|
size += eina_convert_xtoa(lo->h, hkey + size);
|
2009-09-16 02:48:05 -07:00
|
|
|
|
|
|
|
hkey[size] = '/';
|
|
|
|
size += 1;
|
|
|
|
|
|
|
|
size += eina_convert_xtoa(lo->region.x, hkey + size);
|
|
|
|
|
|
|
|
hkey[size] = '+';
|
|
|
|
size += 1;
|
|
|
|
|
|
|
|
size += eina_convert_xtoa(lo->region.y, hkey + size);
|
|
|
|
|
|
|
|
hkey[size] = '.';
|
|
|
|
size += 1;
|
|
|
|
|
|
|
|
size += eina_convert_xtoa(lo->region.w, hkey + size);
|
|
|
|
|
|
|
|
hkey[size] = 'x';
|
|
|
|
size += 1;
|
|
|
|
|
|
|
|
size += eina_convert_xtoa(lo->region.h, hkey + size);
|
2007-07-16 00:25:35 -07:00
|
|
|
}
|
2008-10-17 04:59:49 -07:00
|
|
|
|
|
|
|
hkey[size] = '\0';
|
2007-07-16 00:25:35 -07:00
|
|
|
|
2008-12-09 09:56:31 -08:00
|
|
|
im = eina_hash_find(cache->activ, hkey);
|
2007-07-16 00:25:35 -07:00
|
|
|
if (im)
|
2007-08-11 05:14:17 -07:00
|
|
|
{
|
2008-04-11 17:32:30 -07:00
|
|
|
time_t t;
|
|
|
|
int ok;
|
|
|
|
|
|
|
|
ok = 1;
|
|
|
|
t = time(NULL);
|
|
|
|
if ((t - im->laststat) > STAT_GAP)
|
|
|
|
{
|
|
|
|
stat_done = 1;
|
|
|
|
if (stat(file, &st) < 0) goto on_error;
|
|
|
|
|
|
|
|
im->laststat = t;
|
|
|
|
if (st.st_mtime != im->timestamp) ok = 0;
|
|
|
|
}
|
|
|
|
if (ok) goto on_ok;
|
2008-05-09 09:18:18 -07:00
|
|
|
|
|
|
|
_evas_cache_image_remove_activ(cache, im);
|
|
|
|
_evas_cache_image_make_dirty(cache, im);
|
2007-08-11 05:14:17 -07:00
|
|
|
}
|
2007-07-16 00:25:35 -07:00
|
|
|
|
2008-12-09 09:56:31 -08:00
|
|
|
im = eina_hash_find(cache->inactiv, hkey);
|
2007-07-16 00:25:35 -07:00
|
|
|
if (im)
|
|
|
|
{
|
2008-04-11 17:32:30 -07:00
|
|
|
int ok;
|
2007-07-16 00:25:35 -07:00
|
|
|
|
2008-04-11 17:32:30 -07:00
|
|
|
ok = 1;
|
|
|
|
if (!stat_done)
|
|
|
|
{
|
|
|
|
time_t t;
|
2007-07-16 00:25:35 -07:00
|
|
|
|
2008-04-11 17:32:30 -07:00
|
|
|
t = time(NULL);
|
|
|
|
if ((t - im->laststat) > STAT_GAP)
|
|
|
|
{
|
|
|
|
stat_done = 1;
|
|
|
|
if (stat(file, &st) < 0) goto on_error;
|
2007-07-16 00:25:35 -07:00
|
|
|
|
2008-04-11 17:32:30 -07:00
|
|
|
im->laststat = t;
|
|
|
|
if (st.st_mtime != im->timestamp) ok = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
if (st.st_mtime != im->timestamp) ok = 0;
|
|
|
|
|
|
|
|
if (ok)
|
|
|
|
{
|
|
|
|
_evas_cache_image_remove_activ(cache, im);
|
|
|
|
_evas_cache_image_make_activ(cache, im, im->cache_key);
|
|
|
|
goto on_ok;
|
|
|
|
}
|
2007-07-16 00:25:35 -07:00
|
|
|
|
2008-04-11 17:32:30 -07:00
|
|
|
_evas_cache_image_entry_delete(cache, im);
|
|
|
|
}
|
2007-07-16 00:25:35 -07:00
|
|
|
|
2008-04-11 17:32:30 -07:00
|
|
|
if (!stat_done)
|
2007-07-16 00:25:35 -07:00
|
|
|
{
|
2008-04-11 17:32:30 -07:00
|
|
|
if (stat(file, &st) < 0) return NULL;
|
2007-07-16 00:25:35 -07:00
|
|
|
}
|
|
|
|
|
2008-04-11 17:32:30 -07:00
|
|
|
im = _evas_cache_image_entry_new(cache, hkey, st.st_mtime, file, key, lo, error);
|
2009-05-09 20:06:49 -07:00
|
|
|
if (!im) return NULL;
|
2008-04-11 17:32:30 -07:00
|
|
|
|
2007-07-16 00:25:35 -07:00
|
|
|
if (cache->func.debug)
|
|
|
|
cache->func.debug("request", im);
|
|
|
|
|
2008-04-11 17:32:30 -07:00
|
|
|
on_ok:
|
2007-07-16 00:25:35 -07:00
|
|
|
*error = 0;
|
|
|
|
im->references++;
|
2008-04-11 17:32:30 -07:00
|
|
|
if (im->references > 1 && im->flags.lru_nodata)
|
|
|
|
_evas_cache_image_remove_lru_nodata(cache, im);
|
|
|
|
|
2007-07-16 00:25:35 -07:00
|
|
|
return im;
|
2008-04-11 17:32:30 -07:00
|
|
|
|
|
|
|
on_error:
|
|
|
|
_evas_cache_image_entry_delete(cache, im);
|
|
|
|
return NULL;
|
2007-07-16 00:25:35 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
EAPI void
|
2008-04-11 17:32:30 -07:00
|
|
|
evas_cache_image_drop(Image_Entry *im)
|
2007-07-16 00:25:35 -07:00
|
|
|
{
|
2007-08-12 22:30:17 -07:00
|
|
|
Evas_Cache_Image *cache;
|
2007-07-16 00:25:35 -07:00
|
|
|
|
|
|
|
assert(im);
|
|
|
|
assert(im->cache);
|
|
|
|
|
|
|
|
im->references--;
|
|
|
|
cache = im->cache;
|
|
|
|
|
|
|
|
if (im->references == 0)
|
|
|
|
{
|
2008-09-16 07:52:57 -07:00
|
|
|
#ifdef BUILD_ASYNC_PRELOAD
|
2009-01-20 06:56:37 -08:00
|
|
|
_evas_cache_image_entry_preload_remove(im, NULL);
|
2008-09-16 07:52:57 -07:00
|
|
|
#endif
|
|
|
|
|
2008-05-09 09:18:18 -07:00
|
|
|
if (im->flags.dirty)
|
|
|
|
{
|
|
|
|
_evas_cache_image_entry_delete(cache, im);
|
|
|
|
return ;
|
|
|
|
}
|
|
|
|
|
2008-04-11 17:32:30 -07:00
|
|
|
_evas_cache_image_remove_activ(cache, im);
|
2008-05-09 09:18:18 -07:00
|
|
|
_evas_cache_image_make_inactiv(cache, im, im->cache_key);
|
2007-08-08 16:41:31 -07:00
|
|
|
evas_cache_image_flush(cache);
|
2007-07-16 00:25:35 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-04-11 17:32:30 -07:00
|
|
|
EAPI void
|
|
|
|
evas_cache_image_data_not_needed(Image_Entry *im)
|
2007-07-16 00:25:35 -07:00
|
|
|
{
|
2007-08-12 22:30:17 -07:00
|
|
|
Evas_Cache_Image *cache;
|
2007-07-16 00:25:35 -07:00
|
|
|
|
|
|
|
assert(im);
|
|
|
|
assert(im->cache);
|
|
|
|
|
|
|
|
cache = im->cache;
|
2008-04-11 17:32:30 -07:00
|
|
|
|
|
|
|
if (im->references > 1) return ;
|
|
|
|
if (im->flags.dirty || !im->flags.need_data) return ;
|
|
|
|
|
|
|
|
_evas_cache_image_activ_lru_nodata(cache, im);
|
|
|
|
}
|
|
|
|
|
|
|
|
EAPI Image_Entry *
|
|
|
|
evas_cache_image_dirty(Image_Entry *im, int x, int y, int w, int h)
|
|
|
|
{
|
2008-12-01 18:33:09 -08:00
|
|
|
Image_Entry *im_dirty = im;
|
2008-04-11 17:32:30 -07:00
|
|
|
Evas_Cache_Image *cache;
|
|
|
|
|
|
|
|
assert(im);
|
|
|
|
assert(im->cache);
|
|
|
|
|
|
|
|
cache = im->cache;
|
|
|
|
if (!(im->flags.dirty))
|
2007-07-16 00:25:35 -07:00
|
|
|
{
|
2009-05-01 00:11:07 -07:00
|
|
|
#ifndef EVAS_CSERVE
|
|
|
|
// if ref 1 also copy if using shared cache as its read-only
|
2008-04-17 08:30:03 -07:00
|
|
|
if (im->references == 1) im_dirty = im;
|
2007-07-16 00:25:35 -07:00
|
|
|
else
|
2009-05-01 00:11:07 -07:00
|
|
|
#endif
|
2007-07-16 00:25:35 -07:00
|
|
|
{
|
|
|
|
int error;
|
|
|
|
|
2009-05-09 20:06:49 -07:00
|
|
|
im_dirty = evas_cache_image_copied_data
|
|
|
|
(cache, im->w, im->h,
|
|
|
|
evas_cache_image_pixels(im),
|
|
|
|
im->flags.alpha,
|
|
|
|
im->space);
|
|
|
|
if (!im_dirty) goto on_error;
|
|
|
|
if (cache->func.debug)
|
|
|
|
cache->func.debug("dirty-src", im);
|
|
|
|
error = cache->func.dirty(im_dirty, im);
|
|
|
|
if (cache->func.debug)
|
|
|
|
cache->func.debug("dirty-out", im_dirty);
|
|
|
|
/*
|
2008-04-11 17:32:30 -07:00
|
|
|
im_dirty = _evas_cache_image_entry_new(cache, NULL, im->timestamp, im->file, im->key, &im->load_opts, &error);
|
2007-07-16 00:25:35 -07:00
|
|
|
if (!im_dirty) goto on_error;
|
|
|
|
|
|
|
|
if (cache->func.debug)
|
|
|
|
cache->func.debug("dirty-src", im);
|
|
|
|
error = cache->func.dirty(im_dirty, im);
|
|
|
|
if (cache->func.debug)
|
|
|
|
cache->func.debug("dirty-out", im_dirty);
|
|
|
|
|
|
|
|
if (error != 0) goto on_error;
|
2009-05-09 20:06:49 -07:00
|
|
|
*/
|
2007-07-16 00:25:35 -07:00
|
|
|
im_dirty->references = 1;
|
|
|
|
|
|
|
|
evas_cache_image_drop(im);
|
|
|
|
}
|
|
|
|
|
2008-04-17 08:30:03 -07:00
|
|
|
_evas_cache_image_remove_activ(cache, im_dirty);
|
2008-04-11 17:32:30 -07:00
|
|
|
_evas_cache_image_make_dirty(cache, im_dirty);
|
2007-07-16 00:25:35 -07:00
|
|
|
}
|
2008-04-11 17:32:30 -07:00
|
|
|
|
2007-07-16 00:25:35 -07:00
|
|
|
if (cache->func.debug)
|
|
|
|
cache->func.debug("dirty-region", im_dirty);
|
|
|
|
if (cache->func.dirty_region)
|
|
|
|
cache->func.dirty_region(im_dirty, x, y, w, h);
|
2008-04-11 17:32:30 -07:00
|
|
|
|
2007-07-16 00:25:35 -07:00
|
|
|
return im_dirty;
|
2008-04-11 17:32:30 -07:00
|
|
|
|
|
|
|
on_error:
|
|
|
|
if (im_dirty) _evas_cache_image_entry_delete(cache, im_dirty);
|
2007-07-16 00:25:35 -07:00
|
|
|
evas_cache_image_drop(im);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2008-04-11 17:32:30 -07:00
|
|
|
EAPI Image_Entry *
|
|
|
|
evas_cache_image_alone(Image_Entry *im)
|
2007-07-16 00:25:35 -07:00
|
|
|
{
|
2008-04-11 17:32:30 -07:00
|
|
|
Evas_Cache_Image *cache;
|
|
|
|
Image_Entry *im_dirty = im;
|
2007-07-16 00:25:35 -07:00
|
|
|
|
|
|
|
assert(im);
|
|
|
|
assert(im->cache);
|
|
|
|
|
|
|
|
cache = im->cache;
|
|
|
|
if (im->references == 1)
|
|
|
|
{
|
2008-04-11 17:32:30 -07:00
|
|
|
if (!(im->flags.dirty))
|
2007-07-16 00:25:35 -07:00
|
|
|
{
|
2008-04-11 17:32:30 -07:00
|
|
|
_evas_cache_image_remove_activ(cache, im);
|
|
|
|
_evas_cache_image_make_dirty(cache, im);
|
2007-07-16 00:25:35 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
int error;
|
|
|
|
|
2009-05-09 20:06:49 -07:00
|
|
|
im_dirty = evas_cache_image_copied_data
|
|
|
|
(cache, im->w, im->h,
|
|
|
|
evas_cache_image_pixels(im),
|
|
|
|
im->flags.alpha,
|
|
|
|
im->space);
|
|
|
|
if (!im_dirty) goto on_error;
|
|
|
|
if (cache->func.debug)
|
|
|
|
cache->func.debug("dirty-src", im);
|
|
|
|
error = cache->func.dirty(im_dirty, im);
|
|
|
|
if (cache->func.debug)
|
|
|
|
cache->func.debug("dirty-out", im_dirty);
|
|
|
|
/*
|
2008-04-11 17:32:30 -07:00
|
|
|
im_dirty = _evas_cache_image_entry_new(cache, NULL, im->timestamp, im->file, im->key, &im->load_opts, &error);
|
2007-07-16 00:25:35 -07:00
|
|
|
if (!im_dirty) goto on_error;
|
|
|
|
|
|
|
|
if (cache->func.debug)
|
|
|
|
cache->func.debug("dirty-src", im);
|
|
|
|
error = cache->func.dirty(im_dirty, im);
|
|
|
|
if (cache->func.debug)
|
|
|
|
cache->func.debug("dirty-out", im_dirty);
|
|
|
|
|
|
|
|
if (error != 0) goto on_error;
|
2009-05-09 20:06:49 -07:00
|
|
|
*/
|
2007-07-16 00:25:35 -07:00
|
|
|
im_dirty->references = 1;
|
|
|
|
|
|
|
|
evas_cache_image_drop(im);
|
|
|
|
}
|
|
|
|
|
|
|
|
return im_dirty;
|
2007-08-09 07:44:36 -07:00
|
|
|
|
|
|
|
on_error:
|
2008-04-11 17:32:30 -07:00
|
|
|
if (im_dirty) _evas_cache_image_entry_delete(cache, im_dirty);
|
2007-07-16 00:25:35 -07:00
|
|
|
evas_cache_image_drop(im);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2008-04-11 17:32:30 -07:00
|
|
|
EAPI Image_Entry *
|
2007-07-16 00:25:35 -07:00
|
|
|
evas_cache_image_copied_data(Evas_Cache_Image *cache, int w, int h, DATA32 *image_data, int alpha, int cspace)
|
|
|
|
{
|
2008-04-11 17:32:30 -07:00
|
|
|
Image_Entry *im;
|
2007-07-16 00:25:35 -07:00
|
|
|
|
|
|
|
assert(cache);
|
|
|
|
|
2007-08-08 16:41:31 -07:00
|
|
|
if ((cspace == EVAS_COLORSPACE_YCBCR422P601_PL) ||
|
|
|
|
(cspace == EVAS_COLORSPACE_YCBCR422P709_PL))
|
2007-07-16 00:25:35 -07:00
|
|
|
w &= ~0x1;
|
|
|
|
|
2008-04-11 17:32:30 -07:00
|
|
|
im = _evas_cache_image_entry_new(cache, NULL, 0, NULL, NULL, NULL, NULL);
|
2007-07-16 00:25:35 -07:00
|
|
|
if (!im) return NULL;
|
2008-06-04 01:20:39 -07:00
|
|
|
|
2008-04-11 17:32:30 -07:00
|
|
|
im->space = cspace;
|
2008-06-03 02:09:39 -07:00
|
|
|
im->flags.alpha = alpha;
|
2008-04-11 17:32:30 -07:00
|
|
|
|
|
|
|
_evas_cache_image_entry_surface_alloc(cache, im, w, h);
|
2007-07-16 00:25:35 -07:00
|
|
|
|
|
|
|
if (cache->func.copied_data(im, w, h, image_data, alpha, cspace) != 0)
|
|
|
|
{
|
2008-04-11 17:32:30 -07:00
|
|
|
_evas_cache_image_entry_delete(cache, im);
|
2007-07-16 00:25:35 -07:00
|
|
|
return NULL;
|
|
|
|
}
|
2008-04-11 17:32:30 -07:00
|
|
|
im->references = 1;
|
2007-07-16 00:25:35 -07:00
|
|
|
|
2008-04-11 17:32:30 -07:00
|
|
|
if (cache->func.debug)
|
|
|
|
cache->func.debug("copied-data", im);
|
|
|
|
return im;
|
2007-07-16 00:25:35 -07:00
|
|
|
}
|
|
|
|
|
2008-04-11 17:32:30 -07:00
|
|
|
EAPI Image_Entry *
|
2007-07-16 00:25:35 -07:00
|
|
|
evas_cache_image_data(Evas_Cache_Image *cache, int w, int h, DATA32 *image_data, int alpha, int cspace)
|
|
|
|
{
|
2008-04-11 17:32:30 -07:00
|
|
|
Image_Entry *im;
|
2007-07-16 00:25:35 -07:00
|
|
|
|
|
|
|
assert(cache);
|
|
|
|
|
2008-06-10 07:21:06 -07:00
|
|
|
if ((cspace == EVAS_COLORSPACE_YCBCR422P601_PL) ||
|
|
|
|
(cspace == EVAS_COLORSPACE_YCBCR422P709_PL))
|
2008-06-10 02:20:41 -07:00
|
|
|
w &= ~0x1;
|
|
|
|
|
2008-04-11 17:32:30 -07:00
|
|
|
im = _evas_cache_image_entry_new(cache, NULL, 0, NULL, NULL, NULL, NULL);
|
|
|
|
im->w = w;
|
|
|
|
im->h = h;
|
2008-06-03 02:09:39 -07:00
|
|
|
im->flags.alpha = alpha;
|
2007-07-16 00:25:35 -07:00
|
|
|
|
|
|
|
if (cache->func.data(im, w, h, image_data, alpha, cspace) != 0)
|
|
|
|
{
|
2008-04-11 17:32:30 -07:00
|
|
|
_evas_cache_image_entry_delete(cache, im);
|
2007-07-16 00:25:35 -07:00
|
|
|
return NULL;
|
|
|
|
}
|
2008-04-11 17:32:30 -07:00
|
|
|
im->references = 1;
|
2007-07-16 00:25:35 -07:00
|
|
|
|
2008-04-11 17:32:30 -07:00
|
|
|
if (cache->func.debug)
|
|
|
|
cache->func.debug("data", im);
|
|
|
|
return im;
|
2007-07-16 00:25:35 -07:00
|
|
|
}
|
|
|
|
|
2008-04-11 17:32:30 -07:00
|
|
|
EAPI void
|
|
|
|
evas_cache_image_surface_alloc(Image_Entry *im, int w, int h)
|
|
|
|
{
|
|
|
|
Evas_Cache_Image *cache;
|
|
|
|
|
|
|
|
assert(im);
|
|
|
|
assert(im->cache);
|
|
|
|
|
|
|
|
cache = im->cache;
|
|
|
|
|
2008-06-10 02:20:41 -07:00
|
|
|
if ((im->space == EVAS_COLORSPACE_YCBCR422P601_PL) ||
|
|
|
|
(im->space == EVAS_COLORSPACE_YCBCR422P709_PL))
|
|
|
|
w &= ~0x1;
|
|
|
|
|
2008-04-11 17:32:30 -07:00
|
|
|
_evas_cache_image_entry_surface_alloc(cache, im, w, h);
|
|
|
|
|
|
|
|
if (cache->func.debug)
|
|
|
|
cache->func.debug("surface-alloc", im);
|
|
|
|
}
|
|
|
|
|
|
|
|
EAPI Image_Entry *
|
|
|
|
evas_cache_image_size_set(Image_Entry *im, int w, int h)
|
2007-07-16 00:25:35 -07:00
|
|
|
{
|
2007-08-12 22:30:17 -07:00
|
|
|
Evas_Cache_Image *cache;
|
2008-04-11 17:32:30 -07:00
|
|
|
Image_Entry *new;
|
2007-07-16 00:25:35 -07:00
|
|
|
int error;
|
|
|
|
|
|
|
|
assert(im);
|
|
|
|
assert(im->cache);
|
|
|
|
assert(im->references > 0);
|
|
|
|
|
2008-06-10 02:20:41 -07:00
|
|
|
if ((im->space == EVAS_COLORSPACE_YCBCR422P601_PL) ||
|
|
|
|
(im->space == EVAS_COLORSPACE_YCBCR422P709_PL))
|
|
|
|
w &= ~0x1;
|
|
|
|
|
2008-04-11 17:32:30 -07:00
|
|
|
if ((im->w == w) && (im->h == h))
|
2007-07-16 00:25:35 -07:00
|
|
|
return im;
|
|
|
|
|
|
|
|
cache = im->cache;
|
|
|
|
|
2008-04-11 17:32:30 -07:00
|
|
|
new = _evas_cache_image_entry_new(cache, NULL, 0, NULL, NULL, NULL, &error);
|
2007-07-16 00:25:35 -07:00
|
|
|
if (!new) goto on_error;
|
|
|
|
|
2008-06-04 01:20:39 -07:00
|
|
|
new->flags.alpha = im->flags.alpha;
|
2008-04-11 17:32:30 -07:00
|
|
|
new->space = im->space;
|
|
|
|
new->load_opts = im->load_opts;
|
2007-07-16 00:25:35 -07:00
|
|
|
|
2008-06-04 01:20:39 -07:00
|
|
|
_evas_cache_image_entry_surface_alloc(cache, new, w, h);
|
|
|
|
|
2008-04-11 17:32:30 -07:00
|
|
|
error = cache->func.size_set(new, im, w, h);
|
|
|
|
if (error != 0) goto on_error;
|
2007-07-16 00:25:35 -07:00
|
|
|
|
|
|
|
new->references = 1;
|
|
|
|
|
|
|
|
evas_cache_image_drop(im);
|
2008-04-11 17:32:30 -07:00
|
|
|
|
|
|
|
if (cache->func.debug)
|
|
|
|
cache->func.debug("size_set", new);
|
|
|
|
|
2007-07-16 00:25:35 -07:00
|
|
|
return new;
|
2008-04-11 17:32:30 -07:00
|
|
|
|
|
|
|
on_error:
|
|
|
|
if (new) _evas_cache_image_entry_delete(cache, new);
|
2007-07-16 00:25:35 -07:00
|
|
|
evas_cache_image_drop(im);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
EAPI void
|
2008-04-11 17:32:30 -07:00
|
|
|
evas_cache_image_load_data(Image_Entry *im)
|
2007-07-16 00:25:35 -07:00
|
|
|
{
|
2007-08-12 22:30:17 -07:00
|
|
|
Evas_Cache_Image *cache;
|
2008-04-11 17:32:30 -07:00
|
|
|
int error;
|
2007-07-16 00:25:35 -07:00
|
|
|
|
|
|
|
assert(im);
|
|
|
|
assert(im->cache);
|
2008-12-23 10:14:16 -08:00
|
|
|
cache = im->cache;
|
2007-07-16 00:25:35 -07:00
|
|
|
|
2008-04-11 17:32:30 -07:00
|
|
|
if (im->flags.loaded) return ;
|
|
|
|
|
2008-09-16 07:52:57 -07:00
|
|
|
#ifdef BUILD_ASYNC_PRELOAD
|
2008-12-23 15:07:48 -08:00
|
|
|
int preload = im->flags.preload;
|
2008-09-16 07:52:57 -07:00
|
|
|
/* We check a first time, to prevent useless lock. */
|
2009-01-20 06:56:37 -08:00
|
|
|
_evas_cache_image_entry_preload_remove(im, NULL);
|
2008-09-16 07:52:57 -07:00
|
|
|
if (im->flags.loaded) return ;
|
2009-03-13 22:08:08 -07:00
|
|
|
LKL(im->lock);
|
2008-09-16 07:52:57 -07:00
|
|
|
#endif
|
|
|
|
|
2008-04-11 17:32:30 -07:00
|
|
|
error = cache->func.load(im);
|
|
|
|
|
2008-12-23 15:07:48 -08:00
|
|
|
#ifdef BUILD_ASYNC_PRELOAD
|
2009-03-13 22:08:08 -07:00
|
|
|
LKU(im->lock);
|
2008-12-23 15:07:48 -08:00
|
|
|
#endif
|
|
|
|
|
2007-07-16 00:25:35 -07:00
|
|
|
if (cache->func.debug)
|
|
|
|
cache->func.debug("load", im);
|
|
|
|
|
2008-12-23 15:07:48 -08:00
|
|
|
#ifdef BUILD_ASYNC_PRELOAD
|
|
|
|
if (preload)
|
2009-01-19 06:06:09 -08:00
|
|
|
_evas_cache_image_async_call(im);
|
2008-12-23 15:07:48 -08:00
|
|
|
#endif
|
|
|
|
|
2008-04-11 17:32:30 -07:00
|
|
|
if (error)
|
|
|
|
{
|
|
|
|
_evas_cache_image_entry_surface_alloc(cache, im, im->w, im->h);
|
|
|
|
im->flags.loaded = 0;
|
2008-12-01 18:33:09 -08:00
|
|
|
|
2008-04-11 17:32:30 -07:00
|
|
|
return ;
|
|
|
|
}
|
2007-07-16 00:25:35 -07:00
|
|
|
|
2008-04-11 17:32:30 -07:00
|
|
|
im->flags.loaded = 1;
|
2007-07-16 00:25:35 -07:00
|
|
|
}
|
|
|
|
|
2008-09-16 07:52:57 -07:00
|
|
|
EAPI void
|
|
|
|
evas_cache_image_preload_data(Image_Entry *im, const void *target)
|
|
|
|
{
|
|
|
|
#ifdef BUILD_ASYNC_PRELOAD
|
|
|
|
Evas_Cache_Image *cache;
|
|
|
|
|
|
|
|
assert(im);
|
|
|
|
assert(im->cache);
|
|
|
|
|
2008-12-20 05:39:15 -08:00
|
|
|
if (im->flags.loaded)
|
|
|
|
{
|
2008-12-23 10:14:16 -08:00
|
|
|
evas_async_events_put(target, EVAS_CALLBACK_IMAGE_PRELOADED, NULL,
|
|
|
|
(void (*)(void*, Evas_Callback_Type, void*))evas_object_event_callback_call);
|
2008-12-20 05:39:15 -08:00
|
|
|
return ;
|
|
|
|
}
|
2008-09-16 07:52:57 -07:00
|
|
|
|
|
|
|
cache = im->cache;
|
|
|
|
|
2009-01-19 06:06:09 -08:00
|
|
|
if (!_evas_cache_image_entry_preload_add(im, target))
|
|
|
|
evas_async_events_put(target, EVAS_CALLBACK_IMAGE_PRELOADED, NULL,
|
|
|
|
(void (*)(void*, Evas_Callback_Type, void*))evas_object_event_callback_call);
|
2008-09-16 07:52:57 -07:00
|
|
|
#else
|
|
|
|
evas_cache_image_load_data(im);
|
|
|
|
|
2009-01-19 06:06:09 -08:00
|
|
|
evas_async_events_put(target, EVAS_CALLBACK_IMAGE_PRELOADED, NULL,
|
|
|
|
(void (*)(void*, Evas_Callback_Type, void*))evas_object_event_callback_call);
|
2008-09-16 07:52:57 -07:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
EAPI void
|
2009-01-20 06:56:37 -08:00
|
|
|
evas_cache_image_preload_cancel(Image_Entry *im, const void *target)
|
2008-09-16 07:52:57 -07:00
|
|
|
{
|
|
|
|
#ifdef BUILD_ASYNC_PRELOAD
|
|
|
|
Evas_Cache_Image *cache;
|
|
|
|
|
|
|
|
assert(im);
|
|
|
|
assert(im->cache);
|
2008-12-23 10:14:16 -08:00
|
|
|
cache = im->cache;
|
2008-09-16 07:52:57 -07:00
|
|
|
|
2009-01-20 06:56:37 -08:00
|
|
|
_evas_cache_image_entry_preload_remove(im, target);
|
2008-09-16 07:52:57 -07:00
|
|
|
#else
|
|
|
|
(void) im;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2007-07-16 00:25:35 -07:00
|
|
|
EAPI int
|
|
|
|
evas_cache_image_flush(Evas_Cache_Image *cache)
|
|
|
|
{
|
|
|
|
assert(cache);
|
|
|
|
|
|
|
|
if (cache->limit == -1)
|
|
|
|
return -1;
|
|
|
|
|
2007-08-08 16:41:31 -07:00
|
|
|
while ((cache->lru) && (cache->limit < cache->usage))
|
2007-07-16 00:25:35 -07:00
|
|
|
{
|
2008-04-11 17:32:30 -07:00
|
|
|
Image_Entry *im;
|
|
|
|
|
|
|
|
im = (Image_Entry *) cache->lru->last;
|
|
|
|
_evas_cache_image_entry_delete(cache, im);
|
|
|
|
}
|
|
|
|
|
|
|
|
while ((cache->lru_nodata) && (cache->limit < cache->usage))
|
|
|
|
{
|
|
|
|
Image_Entry *im;
|
|
|
|
|
|
|
|
im = (Image_Entry *) cache->lru_nodata->last;
|
|
|
|
_evas_cache_image_remove_lru_nodata(cache, im);
|
|
|
|
|
|
|
|
cache->func.surface_delete(im);
|
2007-07-16 00:25:35 -07:00
|
|
|
|
2008-04-11 17:32:30 -07:00
|
|
|
im->flags.loaded = 0;
|
2007-07-16 00:25:35 -07:00
|
|
|
}
|
2008-04-11 17:32:30 -07:00
|
|
|
|
2007-07-16 00:25:35 -07:00
|
|
|
return cache->usage;
|
|
|
|
}
|
|
|
|
|
2008-04-11 17:32:30 -07:00
|
|
|
EAPI Image_Entry *
|
2007-08-12 22:30:17 -07:00
|
|
|
evas_cache_image_empty(Evas_Cache_Image *cache)
|
2007-07-16 00:25:35 -07:00
|
|
|
{
|
2008-04-11 17:32:30 -07:00
|
|
|
Image_Entry *new;
|
2007-07-16 00:25:35 -07:00
|
|
|
|
2008-04-11 17:32:30 -07:00
|
|
|
new = _evas_cache_image_entry_new(cache, NULL, 0, NULL, NULL, NULL, NULL);
|
|
|
|
if (!new) return NULL;
|
2007-07-16 00:25:35 -07:00
|
|
|
|
|
|
|
new->references = 1;
|
|
|
|
|
|
|
|
return new;
|
|
|
|
}
|
|
|
|
|
|
|
|
EAPI void
|
2008-04-11 17:32:30 -07:00
|
|
|
evas_cache_image_colorspace(Image_Entry *im, int cspace)
|
2007-07-16 00:25:35 -07:00
|
|
|
{
|
2008-04-11 17:32:30 -07:00
|
|
|
Evas_Cache_Image *cache;
|
|
|
|
|
|
|
|
assert(im);
|
|
|
|
assert(im->cache);
|
|
|
|
|
|
|
|
cache = im->cache;
|
|
|
|
|
|
|
|
if (im->space == cspace) return ;
|
2007-07-16 00:25:35 -07:00
|
|
|
|
2008-04-11 17:32:30 -07:00
|
|
|
im->space = cspace;
|
|
|
|
cache->func.color_space(im, cspace);
|
2007-07-16 00:25:35 -07:00
|
|
|
}
|
2008-05-30 06:33:40 -07:00
|
|
|
|
|
|
|
EAPI void *
|
|
|
|
evas_cache_private_from_image_entry_get(Image_Entry *im)
|
|
|
|
{
|
|
|
|
Evas_Cache_Image *cache;
|
|
|
|
|
|
|
|
assert(im);
|
|
|
|
assert(im->cache);
|
|
|
|
|
|
|
|
cache = im->cache;
|
|
|
|
|
|
|
|
return (void*) cache->data;
|
|
|
|
}
|
|
|
|
|
|
|
|
EAPI void *
|
|
|
|
evas_cache_private_get(Evas_Cache_Image *cache)
|
|
|
|
{
|
|
|
|
assert(cache);
|
|
|
|
|
|
|
|
return cache->data;
|
|
|
|
}
|
|
|
|
|
|
|
|
EAPI void
|
|
|
|
evas_cache_private_set(Evas_Cache_Image *cache, const void *data)
|
|
|
|
{
|
|
|
|
assert(cache);
|
|
|
|
|
2008-12-23 10:14:16 -08:00
|
|
|
cache->data = (void *)data;
|
2008-05-30 06:33:40 -07:00
|
|
|
}
|
2008-06-03 02:09:39 -07:00
|
|
|
|
|
|
|
EAPI DATA32 *
|
|
|
|
evas_cache_image_pixels(Image_Entry *im)
|
|
|
|
{
|
|
|
|
Evas_Cache_Image *cache;
|
|
|
|
|
|
|
|
assert(im);
|
|
|
|
assert(im->cache);
|
|
|
|
|
|
|
|
cache = im->cache;
|
|
|
|
|
|
|
|
return cache->func.surface_pixels(im);
|
|
|
|
}
|
2008-09-16 07:52:57 -07:00
|
|
|
|
|
|
|
#ifdef BUILD_ASYNC_PRELOAD
|
|
|
|
static void*
|
|
|
|
_evas_cache_background_load(void *data)
|
|
|
|
{
|
|
|
|
(void) data;
|
2009-09-16 02:48:05 -07:00
|
|
|
|
|
|
|
restart:
|
2008-09-16 07:52:57 -07:00
|
|
|
while (preload)
|
|
|
|
{
|
|
|
|
pthread_mutex_lock(&mutex);
|
2008-12-23 15:07:48 -08:00
|
|
|
if (preload)
|
|
|
|
{
|
2009-01-19 06:06:09 -08:00
|
|
|
Evas_Cache_Preload *tmp = (Evas_Cache_Preload*) preload;
|
2009-09-16 02:48:05 -07:00
|
|
|
|
2009-01-19 06:06:09 -08:00
|
|
|
current = tmp->ie;
|
2008-12-23 15:07:48 -08:00
|
|
|
preload = eina_inlist_remove(preload, preload);
|
2009-01-19 06:06:09 -08:00
|
|
|
|
|
|
|
free(tmp);
|
2008-12-23 15:07:48 -08:00
|
|
|
}
|
2008-09-16 07:52:57 -07:00
|
|
|
|
|
|
|
pthread_mutex_unlock(&mutex);
|
|
|
|
|
|
|
|
if (current)
|
|
|
|
{
|
|
|
|
Evas_Cache_Image *cache;
|
|
|
|
int error;
|
2009-09-11 06:44:53 -07:00
|
|
|
int pchannel;
|
2008-09-16 07:52:57 -07:00
|
|
|
|
2009-03-13 22:08:08 -07:00
|
|
|
LKL(current->lock);
|
2009-09-11 06:44:53 -07:00
|
|
|
pchannel = current->channel;
|
|
|
|
current->channel++;
|
2008-09-16 07:52:57 -07:00
|
|
|
cache = current->cache;
|
|
|
|
|
2009-09-16 02:48:05 -07:00
|
|
|
if (!current->flags.loaded)
|
|
|
|
{
|
|
|
|
error = cache->func.load(current);
|
|
|
|
if (cache->func.debug)
|
|
|
|
cache->func.debug("load", current);
|
|
|
|
|
|
|
|
if (error)
|
|
|
|
{
|
|
|
|
_evas_cache_image_entry_surface_alloc(cache, current,
|
|
|
|
current->w, current->h);
|
|
|
|
current->flags.loaded = 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
current->flags.loaded = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-09-16 07:52:57 -07:00
|
|
|
current->flags.preload = 0;
|
|
|
|
|
2009-09-11 06:44:53 -07:00
|
|
|
current->channel = pchannel;
|
2009-03-13 22:08:08 -07:00
|
|
|
LKU(current->lock);
|
2008-12-23 10:14:16 -08:00
|
|
|
|
2009-01-19 06:06:09 -08:00
|
|
|
_evas_cache_image_async_call(current);
|
2008-12-23 10:14:16 -08:00
|
|
|
current = NULL;
|
|
|
|
}
|
2008-09-16 07:52:57 -07:00
|
|
|
|
2009-01-23 12:36:04 -08:00
|
|
|
pthread_cond_signal(&cond_done);
|
2008-09-16 07:52:57 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
pthread_mutex_lock(&mutex);
|
|
|
|
if (preload)
|
|
|
|
{
|
|
|
|
pthread_mutex_unlock(&mutex);
|
|
|
|
goto restart;
|
|
|
|
}
|
|
|
|
|
2009-06-17 03:01:52 -07:00
|
|
|
running = EINA_FALSE;
|
2008-09-16 07:52:57 -07:00
|
|
|
pthread_mutex_unlock(&mutex);
|
|
|
|
|
2009-01-23 12:36:04 -08:00
|
|
|
pthread_mutex_lock(&mutex_new);
|
|
|
|
pthread_cond_wait(&cond_new, &mutex_new);
|
|
|
|
pthread_mutex_unlock(&mutex_new);
|
|
|
|
goto restart;
|
|
|
|
|
2008-09-16 07:52:57 -07:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
#endif
|