From ad5d75dfcdda13a1136b8f850dab6235b42c5c0e Mon Sep 17 00:00:00 2001 From: Cedric Bail Date: Fri, 31 May 2013 12:55:14 +0900 Subject: [PATCH] evas: add support for engine specific extention during thread task. --- src/lib/evas/cache/evas_cache.h | 5 +- src/lib/evas/cache/evas_cache_image.c | 83 +++++++++++++++++++--- src/lib/evas/include/evas_common.h | 14 +++- src/modules/evas/engines/gl_cocoa/evas_engine.c | 2 +- src/modules/evas/engines/gl_sdl/evas_engine.c | 2 +- src/modules/evas/engines/gl_x11/evas_engine.c | 2 +- .../evas/engines/software_generic/evas_engine.c | 2 +- src/modules/evas/engines/wayland_egl/evas_engine.c | 2 +- 8 files changed, 94 insertions(+), 18 deletions(-) diff --git a/src/lib/evas/cache/evas_cache.h b/src/lib/evas/cache/evas_cache.h index b7756ae..3f3c9c0 100644 --- a/src/lib/evas/cache/evas_cache.h +++ b/src/lib/evas/cache/evas_cache.h @@ -1,13 +1,11 @@ #ifndef _EVAS_CACHE_H #define _EVAS_CACHE_H - typedef struct _Evas_Cache_Image Evas_Cache_Image; 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_Func Evas_Cache_Engine_Image_Func; - struct _Evas_Cache_Image_Func { 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_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_wakeup(void); diff --git a/src/lib/evas/cache/evas_cache_image.c b/src/lib/evas/cache/evas_cache_image.c index 5236592..377e0fa 100644 --- a/src/lib/evas/cache/evas_cache_image.c +++ b/src/lib/evas/cache/evas_cache_image.c @@ -31,6 +31,8 @@ static int _evas_cache_mutex_init = 0; 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); #define FREESTRC(Var) \ @@ -177,6 +179,8 @@ _evas_cache_image_lru_nodata_del(Image_Entry *im) static void _evas_cache_image_entry_delete(Evas_Cache_Image *cache, Image_Entry *ie) { + Image_Entry_Task *task; + if (!ie) return; if (cache->func.debug) cache->func.debug("deleting", ie); if (ie->flags.delete_me == 1) return; @@ -187,6 +191,9 @@ _evas_cache_image_entry_delete(Evas_Cache_Image *cache, Image_Entry *ie) return; } + EINA_LIST_FREE(ie->tasks, task) + if (task != &dummy_task) free(task); + _evas_cache_image_dirty_del(ie); _evas_cache_image_activ_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_cancel); + LKD(ie->lock_task); 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)); LKI(ie->lock); - LKI(ie->lock_cancel); + LKI(ie->lock_cancel); + LKI(ie->lock_task); if (lo) ie->load_opts = *lo; if (ie->file || ie->f) @@ -323,6 +332,7 @@ _evas_cache_image_async_heavy(void *data) { Evas_Cache_Image *cache; Image_Entry *current; + Image_Entry_Task *task; int error; int pchannel; @@ -348,6 +358,17 @@ _evas_cache_image_async_heavy(void *data) else { 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; @@ -368,6 +389,7 @@ static void _evas_cache_image_async_end(void *data) { Image_Entry *ie = (Image_Entry *)data; + Image_Entry_Task *task; Evas_Cache_Target *tmp; 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)); free(tmp); } + + EINA_LIST_FREE(ie->tasks, task) + if (task != &dummy_task) free(task); } 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 // entry. make sure you only add once, or remove first, then add 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; + Image_Entry_Task *task; if (ie->flags.preload_done) return 0; tg = malloc(sizeof (Evas_Cache_Target)); if (!tg) return 0; - 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 *) 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) { 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 _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) { - Evas_Cache_Target *tg; - + LKL(ie->lock_task); + l = ie->tasks; EINA_INLIST_FOREACH(ie->targets, tg) { 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 *) eina_inlist_remove(EINA_INLIST_GET(ie->targets), 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); break; } + + l = eina_list_next(l); } + LKU(ie->lock_task); } else { - Evas_Cache_Target *tg; - while (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)); 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)) @@ -1180,7 +1244,8 @@ evas_cache_image_is_loaded(Image_Entry *im) } 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; @@ -1190,7 +1255,7 @@ evas_cache_image_preload_data(Image_Entry *im, const void *target) return; } 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); } diff --git a/src/lib/evas/include/evas_common.h b/src/lib/evas/include/evas_common.h index 5e7bd34..611529b 100644 --- a/src/lib/evas/include/evas_common.h +++ b/src/lib/evas/include/evas_common.h @@ -353,6 +353,7 @@ typedef unsigned short DATA16; typedef unsigned char DATA8; 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_Frame Image_Entry_Frame; 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_Engine_Thread_Task_Cb)(void *engine_data, Image_Entry *ie, void *custom_data); + #include "../cache/evas_cache.h" #ifdef EVAS_CSERVE2 #include "../cache2/evas_cache2.h" @@ -541,6 +544,13 @@ struct _Image_Timestamp #endif }; +struct _Image_Entry_Task +{ + Evas_Engine_Thread_Task_Cb cb; + const void *engine_data; + const void *custom_data; +}; + struct _Image_Entry { EINA_INLIST; @@ -557,13 +567,14 @@ struct _Image_Entry Evas_Cache_Target *targets; Evas_Preload_Pthread *preload; + Eina_List *tasks; Image_Timestamp tstamp; int references; #ifdef BUILD_PIPE_RENDER - RGBA_Pipe *pipe; + RGBA_Pipe *pipe; #endif Evas_Image_Load_Opts load_opts; @@ -588,6 +599,7 @@ struct _Image_Entry LK(lock); LK(lock_cancel); + LK(lock_task); /* for animation feature */ Evas_Image_Animated animated; diff --git a/src/modules/evas/engines/gl_cocoa/evas_engine.c b/src/modules/evas/engines/gl_cocoa/evas_engine.c index b5fc778..b567227 100644 --- a/src/modules/evas/engines/gl_cocoa/evas_engine.c +++ b/src/modules/evas/engines/gl_cocoa/evas_engine.c @@ -864,7 +864,7 @@ eng_image_data_preload_request(void *data EINA_UNUSED, void *image, const void * if (gim->native.data) return; im = (RGBA_Image *)gim->im; 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 diff --git a/src/modules/evas/engines/gl_sdl/evas_engine.c b/src/modules/evas/engines/gl_sdl/evas_engine.c index f055306..bd7ba06 100644 --- a/src/modules/evas/engines/gl_sdl/evas_engine.c +++ b/src/modules/evas/engines/gl_sdl/evas_engine.c @@ -720,7 +720,7 @@ eng_image_data_preload_request(void *data EINA_UNUSED, void *image, const void * if (gim->native.data) return; im = (RGBA_Image *)gim->im; 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 diff --git a/src/modules/evas/engines/gl_x11/evas_engine.c b/src/modules/evas/engines/gl_x11/evas_engine.c index 0d1b0f9..6b6f164 100644 --- a/src/modules/evas/engines/gl_x11/evas_engine.c +++ b/src/modules/evas/engines/gl_x11/evas_engine.c @@ -2784,7 +2784,7 @@ eng_image_data_preload_request(void *data EINA_UNUSED, void *image, const void * if (gim->native.data) return; im = (RGBA_Image *)gim->im; 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 diff --git a/src/modules/evas/engines/software_generic/evas_engine.c b/src/modules/evas/engines/software_generic/evas_engine.c index bb2d4b8..ba6810d 100644 --- a/src/modules/evas/engines/software_generic/evas_engine.c +++ b/src/modules/evas/engines/software_generic/evas_engine.c @@ -1167,7 +1167,7 @@ eng_image_data_preload_request(void *data EINA_UNUSED, void *image, const void * return; } #endif - evas_cache_image_preload_data(&im->cache_entry, target); + evas_cache_image_preload_data(&im->cache_entry, target, NULL, NULL, NULL); } static void diff --git a/src/modules/evas/engines/wayland_egl/evas_engine.c b/src/modules/evas/engines/wayland_egl/evas_engine.c index ae4c037..e110c49 100644 --- a/src/modules/evas/engines/wayland_egl/evas_engine.c +++ b/src/modules/evas/engines/wayland_egl/evas_engine.c @@ -1810,7 +1810,7 @@ eng_image_data_preload_request(void *data EINA_UNUSED, void *image, const void * if (gim->native.data) return; im = (RGBA_Image *)gim->im; 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 -- 2.7.4