evas: add support for engine specific extention during thread task.
authorCedric Bail <cedric.bail@samsung.com>
Fri, 31 May 2013 03:55:14 +0000 (12:55 +0900)
committerCedric Bail <cedric.bail@samsung.com>
Tue, 4 Jun 2013 02:20:25 +0000 (11:20 +0900)
src/lib/evas/cache/evas_cache.h
src/lib/evas/cache/evas_cache_image.c
src/lib/evas/include/evas_common.h
src/modules/evas/engines/gl_cocoa/evas_engine.c
src/modules/evas/engines/gl_sdl/evas_engine.c
src/modules/evas/engines/gl_x11/evas_engine.c
src/modules/evas/engines/software_generic/evas_engine.c
src/modules/evas/engines/wayland_egl/evas_engine.c

index b7756ae..3f3c9c0 100644 (file)
@@ -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);
index 5236592..377e0fa 100644 (file)
@@ -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);
 }
 
index 5e7bd34..611529b 100644 (file)
@@ -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;
index b5fc778..b567227 100644 (file)
@@ -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
index f055306..bd7ba06 100644 (file)
@@ -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
index 0d1b0f9..6b6f164 100644 (file)
@@ -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
index bb2d4b8..ba6810d 100644 (file)
@@ -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
index ae4c037..e110c49 100644 (file)
@@ -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