evas: add support for engine specific extention during thread task.

This commit is contained in:
Cedric Bail 2013-05-31 12:55:14 +09:00
parent cd57e792bc
commit ad5d75dfcd
8 changed files with 94 additions and 18 deletions

View File

@ -1,13 +1,11 @@
#ifndef _EVAS_CACHE_H #ifndef _EVAS_CACHE_H
#define _EVAS_CACHE_H #define _EVAS_CACHE_H
typedef struct _Evas_Cache_Image Evas_Cache_Image; typedef struct _Evas_Cache_Image Evas_Cache_Image;
typedef struct _Evas_Cache_Image_Func Evas_Cache_Image_Func; typedef struct _Evas_Cache_Image_Func Evas_Cache_Image_Func;
typedef struct _Evas_Cache_Engine_Image Evas_Cache_Engine_Image; typedef struct _Evas_Cache_Engine_Image Evas_Cache_Engine_Image;
typedef struct _Evas_Cache_Engine_Image_Func Evas_Cache_Engine_Image_Func; typedef struct _Evas_Cache_Engine_Image_Func Evas_Cache_Engine_Image_Func;
struct _Evas_Cache_Image_Func struct _Evas_Cache_Image_Func
{ {
Image_Entry *(*alloc)(void); Image_Entry *(*alloc)(void);
@ -167,7 +165,8 @@ EAPI Engine_Image_Entry* evas_cache_engine_image_size_set(Engine_Image_Entr
EAPI void evas_cache_engine_image_load_data(Engine_Image_Entry *eim); EAPI void evas_cache_engine_image_load_data(Engine_Image_Entry *eim);
EAPI void evas_cache_image_preload_data(Image_Entry *im, const void *target); EAPI void evas_cache_image_preload_data(Image_Entry *im, const void *target,
Evas_Engine_Thread_Task_Cb func, const void *engine_data, const void *custom_data);
EAPI void evas_cache_image_preload_cancel(Image_Entry *im, const void *target); EAPI void evas_cache_image_preload_cancel(Image_Entry *im, const void *target);
EAPI void evas_cache_image_wakeup(void); EAPI void evas_cache_image_wakeup(void);

View File

@ -31,6 +31,8 @@ static int _evas_cache_mutex_init = 0;
static Eina_Condition cond_wakeup; static Eina_Condition cond_wakeup;
static const Image_Entry_Task dummy_task = { NULL, NULL, NULL };
static void _evas_cache_image_entry_preload_remove(Image_Entry *ie, const void *target); static void _evas_cache_image_entry_preload_remove(Image_Entry *ie, const void *target);
#define FREESTRC(Var) \ #define FREESTRC(Var) \
@ -177,6 +179,8 @@ _evas_cache_image_lru_nodata_del(Image_Entry *im)
static void static void
_evas_cache_image_entry_delete(Evas_Cache_Image *cache, Image_Entry *ie) _evas_cache_image_entry_delete(Evas_Cache_Image *cache, Image_Entry *ie)
{ {
Image_Entry_Task *task;
if (!ie) return; if (!ie) return;
if (cache->func.debug) cache->func.debug("deleting", ie); if (cache->func.debug) cache->func.debug("deleting", ie);
if (ie->flags.delete_me == 1) return; if (ie->flags.delete_me == 1) return;
@ -187,6 +191,9 @@ _evas_cache_image_entry_delete(Evas_Cache_Image *cache, Image_Entry *ie)
return; return;
} }
EINA_LIST_FREE(ie->tasks, task)
if (task != &dummy_task) free(task);
_evas_cache_image_dirty_del(ie); _evas_cache_image_dirty_del(ie);
_evas_cache_image_activ_del(ie); _evas_cache_image_activ_del(ie);
_evas_cache_image_lru_del(ie); _evas_cache_image_lru_del(ie);
@ -201,6 +208,7 @@ _evas_cache_image_entry_delete(Evas_Cache_Image *cache, Image_Entry *ie)
LKD(ie->lock); LKD(ie->lock);
LKD(ie->lock_cancel); LKD(ie->lock_cancel);
LKD(ie->lock_task);
cache->func.dealloc(ie); cache->func.dealloc(ie);
} }
@ -271,7 +279,8 @@ _evas_cache_image_entry_new(Evas_Cache_Image *cache,
else memset(&ie->tstamp, 0, sizeof(Image_Timestamp)); else memset(&ie->tstamp, 0, sizeof(Image_Timestamp));
LKI(ie->lock); LKI(ie->lock);
LKI(ie->lock_cancel); LKI(ie->lock_cancel);
LKI(ie->lock_task);
if (lo) ie->load_opts = *lo; if (lo) ie->load_opts = *lo;
if (ie->file || ie->f) if (ie->file || ie->f)
@ -323,6 +332,7 @@ _evas_cache_image_async_heavy(void *data)
{ {
Evas_Cache_Image *cache; Evas_Cache_Image *cache;
Image_Entry *current; Image_Entry *current;
Image_Entry_Task *task;
int error; int error;
int pchannel; int pchannel;
@ -348,6 +358,17 @@ _evas_cache_image_async_heavy(void *data)
else else
{ {
current->flags.loaded = 1; current->flags.loaded = 1;
LKL(current->lock_task);
EINA_LIST_FREE(current->tasks, task)
{
if (task != &dummy_task)
{
task->cb((void *) task->engine_data, current, (void *) task->custom_data);
free(task);
}
}
LKU(current->lock_task);
} }
} }
current->channel = pchannel; current->channel = pchannel;
@ -368,6 +389,7 @@ static void
_evas_cache_image_async_end(void *data) _evas_cache_image_async_end(void *data)
{ {
Image_Entry *ie = (Image_Entry *)data; Image_Entry *ie = (Image_Entry *)data;
Image_Entry_Task *task;
Evas_Cache_Target *tmp; Evas_Cache_Target *tmp;
ie->cache->preload = eina_list_remove(ie->cache->preload, ie); ie->cache->preload = eina_list_remove(ie->cache->preload, ie);
@ -382,6 +404,9 @@ _evas_cache_image_async_end(void *data)
EINA_INLIST_GET(ie->targets)); EINA_INLIST_GET(ie->targets));
free(tmp); free(tmp);
} }
EINA_LIST_FREE(ie->tasks, task)
if (task != &dummy_task) free(task);
} }
static void static void
@ -410,18 +435,41 @@ _evas_cache_image_async_cancel(void *data)
// note - preload_add assumes a target is ONLY added ONCE to the image // note - preload_add assumes a target is ONLY added ONCE to the image
// entry. make sure you only add once, or remove first, then add // entry. make sure you only add once, or remove first, then add
static int static int
_evas_cache_image_entry_preload_add(Image_Entry *ie, const void *target) _evas_cache_image_entry_preload_add(Image_Entry *ie, const void *target,
Evas_Engine_Thread_Task_Cb func, const void *engine_data, const void *custom_data)
{ {
Evas_Cache_Target *tg; Evas_Cache_Target *tg;
Image_Entry_Task *task;
if (ie->flags.preload_done) return 0; if (ie->flags.preload_done) return 0;
tg = malloc(sizeof (Evas_Cache_Target)); tg = malloc(sizeof (Evas_Cache_Target));
if (!tg) return 0; if (!tg) return 0;
tg->target = target; tg->target = target;
if (func == NULL && engine_data == NULL && custom_data == NULL)
{
task = (Image_Entry_Task*) &dummy_task;
}
else
{
task = malloc(sizeof (Image_Entry_Task));
if (!task)
{
free(tg);
return 0;
}
task->cb = func;
task->engine_data = engine_data;
task->custom_data = custom_data;
}
ie->targets = (Evas_Cache_Target *) ie->targets = (Evas_Cache_Target *)
eina_inlist_append(EINA_INLIST_GET(ie->targets), EINA_INLIST_GET(tg)); eina_inlist_append(EINA_INLIST_GET(ie->targets), EINA_INLIST_GET(tg));
LKL(ie->lock_task);
ie->tasks = eina_list_append(ie->tasks, task);
LKU(ie->lock_task);
if (!ie->preload) if (!ie->preload)
{ {
ie->cache->preload = eina_list_append(ie->cache->preload, ie); ie->cache->preload = eina_list_append(ie->cache->preload, ie);
@ -437,10 +485,14 @@ _evas_cache_image_entry_preload_add(Image_Entry *ie, const void *target)
static void static void
_evas_cache_image_entry_preload_remove(Image_Entry *ie, const void *target) _evas_cache_image_entry_preload_remove(Image_Entry *ie, const void *target)
{ {
Evas_Cache_Target *tg;
Eina_List *l;
Image_Entry_Task *task;
if (target) if (target)
{ {
Evas_Cache_Target *tg; LKL(ie->lock_task);
l = ie->tasks;
EINA_INLIST_FOREACH(ie->targets, tg) EINA_INLIST_FOREACH(ie->targets, tg)
{ {
if (tg->target == target) if (tg->target == target)
@ -449,15 +501,22 @@ _evas_cache_image_entry_preload_remove(Image_Entry *ie, const void *target)
ie->targets = (Evas_Cache_Target *) ie->targets = (Evas_Cache_Target *)
eina_inlist_remove(EINA_INLIST_GET(ie->targets), eina_inlist_remove(EINA_INLIST_GET(ie->targets),
EINA_INLIST_GET(tg)); EINA_INLIST_GET(tg));
task = eina_list_data_get(l);
ie->tasks = eina_list_remove_list(ie->tasks, l);
if (task != &dummy_task) free(task);
LKU(ie->lock_task);
free(tg); free(tg);
break; break;
} }
l = eina_list_next(l);
} }
LKU(ie->lock_task);
} }
else else
{ {
Evas_Cache_Target *tg;
while (ie->targets) while (ie->targets)
{ {
tg = ie->targets; tg = ie->targets;
@ -466,6 +525,11 @@ _evas_cache_image_entry_preload_remove(Image_Entry *ie, const void *target)
EINA_INLIST_GET(tg)); EINA_INLIST_GET(tg));
free(tg); free(tg);
} }
LKL(ie->lock_task);
EINA_LIST_FREE(ie->tasks, task)
if (task != &dummy_task) free(task);
LKU(ie->lock_task);
} }
if ((!ie->targets) && (ie->preload) && (!ie->flags.pending)) if ((!ie->targets) && (ie->preload) && (!ie->flags.pending))
@ -1180,7 +1244,8 @@ evas_cache_image_is_loaded(Image_Entry *im)
} }
EAPI void EAPI void
evas_cache_image_preload_data(Image_Entry *im, const void *target) evas_cache_image_preload_data(Image_Entry *im, const void *target,
Evas_Engine_Thread_Task_Cb func, const void *engine_data, const void *custom_data)
{ {
RGBA_Image *img = (RGBA_Image *)im; RGBA_Image *img = (RGBA_Image *)im;
@ -1190,7 +1255,7 @@ evas_cache_image_preload_data(Image_Entry *im, const void *target)
return; return;
} }
im->flags.loaded = 0; im->flags.loaded = 0;
if (!_evas_cache_image_entry_preload_add(im, target)) if (!_evas_cache_image_entry_preload_add(im, target, func, engine_data, custom_data))
evas_object_inform_call_image_preloaded((Evas_Object *)target); evas_object_inform_call_image_preloaded((Evas_Object *)target);
} }

View File

@ -353,6 +353,7 @@ typedef unsigned short DATA16;
typedef unsigned char DATA8; typedef unsigned char DATA8;
typedef struct _Image_Entry Image_Entry; typedef struct _Image_Entry Image_Entry;
typedef struct _Image_Entry_Task Image_Entry_Task;
typedef struct _Image_Entry_Flags Image_Entry_Flags; typedef struct _Image_Entry_Flags Image_Entry_Flags;
typedef struct _Image_Entry_Frame Image_Entry_Frame; typedef struct _Image_Entry_Frame Image_Entry_Frame;
typedef struct _Image_Timestamp Image_Timestamp; typedef struct _Image_Timestamp Image_Timestamp;
@ -414,6 +415,8 @@ typedef void (*Gfx_Func_Convert) (DATA32 *src, DATA8 *dst, int src_jump, int dst
typedef void (*Evas_Render_Done_Cb)(void *); typedef void (*Evas_Render_Done_Cb)(void *);
typedef void (*Evas_Engine_Thread_Task_Cb)(void *engine_data, Image_Entry *ie, void *custom_data);
#include "../cache/evas_cache.h" #include "../cache/evas_cache.h"
#ifdef EVAS_CSERVE2 #ifdef EVAS_CSERVE2
#include "../cache2/evas_cache2.h" #include "../cache2/evas_cache2.h"
@ -541,6 +544,13 @@ struct _Image_Timestamp
#endif #endif
}; };
struct _Image_Entry_Task
{
Evas_Engine_Thread_Task_Cb cb;
const void *engine_data;
const void *custom_data;
};
struct _Image_Entry struct _Image_Entry
{ {
EINA_INLIST; EINA_INLIST;
@ -557,13 +567,14 @@ struct _Image_Entry
Evas_Cache_Target *targets; Evas_Cache_Target *targets;
Evas_Preload_Pthread *preload; Evas_Preload_Pthread *preload;
Eina_List *tasks;
Image_Timestamp tstamp; Image_Timestamp tstamp;
int references; int references;
#ifdef BUILD_PIPE_RENDER #ifdef BUILD_PIPE_RENDER
RGBA_Pipe *pipe; RGBA_Pipe *pipe;
#endif #endif
Evas_Image_Load_Opts load_opts; Evas_Image_Load_Opts load_opts;
@ -588,6 +599,7 @@ struct _Image_Entry
LK(lock); LK(lock);
LK(lock_cancel); LK(lock_cancel);
LK(lock_task);
/* for animation feature */ /* for animation feature */
Evas_Image_Animated animated; Evas_Image_Animated animated;

View File

@ -864,7 +864,7 @@ eng_image_data_preload_request(void *data EINA_UNUSED, void *image, const void *
if (gim->native.data) return; if (gim->native.data) return;
im = (RGBA_Image *)gim->im; im = (RGBA_Image *)gim->im;
if (!im) return; if (!im) return;
evas_cache_image_preload_data(&im->cache_entry, target); evas_cache_image_preload_data(&im->cache_entry, target, NULL, NULL, NULL);
} }
static void static void

View File

@ -720,7 +720,7 @@ eng_image_data_preload_request(void *data EINA_UNUSED, void *image, const void *
if (gim->native.data) return; if (gim->native.data) return;
im = (RGBA_Image *)gim->im; im = (RGBA_Image *)gim->im;
if (!im) return; if (!im) return;
evas_cache_image_preload_data(&im->cache_entry, target); evas_cache_image_preload_data(&im->cache_entry, target, NULL, NULL, NULL);
} }
static void static void

View File

@ -2784,7 +2784,7 @@ eng_image_data_preload_request(void *data EINA_UNUSED, void *image, const void *
if (gim->native.data) return; if (gim->native.data) return;
im = (RGBA_Image *)gim->im; im = (RGBA_Image *)gim->im;
if (!im) return; if (!im) return;
evas_cache_image_preload_data(&im->cache_entry, target); evas_cache_image_preload_data(&im->cache_entry, target, NULL, NULL, NULL);
} }
static void static void

View File

@ -1167,7 +1167,7 @@ eng_image_data_preload_request(void *data EINA_UNUSED, void *image, const void *
return; return;
} }
#endif #endif
evas_cache_image_preload_data(&im->cache_entry, target); evas_cache_image_preload_data(&im->cache_entry, target, NULL, NULL, NULL);
} }
static void static void

View File

@ -1810,7 +1810,7 @@ eng_image_data_preload_request(void *data EINA_UNUSED, void *image, const void *
if (gim->native.data) return; if (gim->native.data) return;
im = (RGBA_Image *)gim->im; im = (RGBA_Image *)gim->im;
if (!im) return; if (!im) return;
evas_cache_image_preload_data(&im->cache_entry, target); evas_cache_image_preload_data(&im->cache_entry, target, NULL, NULL, NULL);
} }
static void static void