On Mon, Jun 23, 2008 at 6:14 PM, The Rasterman Carsten Haitzler
<[EMAIL PROTECTED]> wrote:
> On Wed, 18 Jun 2008 18:53:06 +0200 "Cedric BAIL" <[EMAIL PROTECTED]> babbled:
>> Hi,
>>
>>   Here is a patch that add support for background preloading of a data
>> image. You can now, if you know what you do, ask evas to load the data
>> of an image in memory before it is displayed (look at the sample code
>> for expedite).
>>
>>   The code is quite simple, we have now a work queue where we add all
>> the Image_Entry we need to preload. They are processed one after the
>> other in another thread. When it's done, it notify evas main thread
>> with evas async API and work on the next Image_Entry.
>>
>>   This means that we now require that engine surface creation and
>> loader should be thread safe. It's currently the case for all the
>> engine I know something about, so this should not break anything.
>> Anyway this code is optionnal and could be completely unactivated in a
>> per engine basis or globally.
>>
>> As always have fun reviewing this patch.
>
> hmmm - i like the idea - yes. missing cache surface alloc mutex :( that should
> not be hard to add - a little bit of extra code. also missing Evas.h prototype
> for exporting the preload call. looks like most engines have the calls
> supported. the problem is what to do out fd'with the locks on alloc. as such 
> it
> is unlikely to cause problems as it stands in the patch - but may if the alloc
> happens while deleting/freeing an image. the images themselves all need locks
> now for anything accessing them.

I don't think so as the path that will generate the async load as only
one way to interfer with the other load path and this one is
protected. Their was just one possibility that the engine wasn't
thread safe during the surface allocation and that could be a problem.
So now I attached a patch with a mutex around the surface allocation
(it also as some more autofoo patch).

This is just an updated patch, I don't know if I want to apply it as
many people expressed interresting opinion in this thread and I need
to make my own opinion on the issues/ideas they raised. I will be
back.
-- 
Cedric BAIL
diff --git a/configure.in b/configure.in
index 78c67be..b78bbdc 100644
--- a/configure.in
+++ b/configure.in
@@ -1135,16 +1135,24 @@ pthread_cflags=""
 pthread_libs=""
 build_pthreads="no"
 has_pthreads="no"
+need_pthreads="no"
+# basic pthread support
+AC_CHECK_HEADER(pthread.h,
+  [
+   has_pthreads="yes"
+  ],
+  [
+   has_pthreads="no"
+  ]
+)
+
 # sched_getaffinity pthread_attr_setaffinity_np
 AC_CHECK_HEADERS(pthread.h sched.h,
       [
         AC_CHECK_LIB(pthread, pthread_attr_setaffinity_np,
           [
             AC_CHECK_LIB(pthread, pthread_barrier_wait,
-              [
-	        build_pthreads="yes"
-	      	has_pthreads="yes"
-	      ],
+              [ build_pthreads="yes" ],
               [ build_pthreads="no" ]
             )
           ],
@@ -1165,8 +1173,7 @@ AC_ARG_ENABLE(pthreads,
           AC_MSG_RESULT(yes)
           AC_DEFINE(BUILD_PTHREAD, 1, [Build Threaded Rendering])
           build_pthreads="yes"
-          pthread_cflags=""
-          pthread_libs="-lpthread"
+	  need_pthreads="yes"
         else
           if "x$use_strict" = "xyes"; then
             AC_MSG_ERROR(pthreads headers or functions not found (strict dependencies checking))
@@ -1183,8 +1190,7 @@ AC_ARG_ENABLE(pthreads,
     AC_MSG_RESULT($build_pthreads)
     if test "x$build_pthreads" = "xyes" ; then
       AC_DEFINE(BUILD_PTHREAD, 1, [Build Threaded Rendering])
-      pthread_cflags=""
-      pthread_libs="-lpthread"
+      need_pthreads="yes"
     fi
   ]
 )
@@ -1204,12 +1210,45 @@ if test \( "x$build_async_events" = "xyes" -o "x$build_async_events" = "xauto" \
   AC_MSG_RESULT(yes)
   AC_DEFINE(BUILD_ASYNC_EVENTS, 1, [Build async events support])
   build_async_events="yes"
+  need_pthreads="yes"
 else
   AC_MSG_RESULT(no)
   build_async_events="no"
 fi
 
 #######################################
+## Async image preload
+build_async_preload="auto"
+AC_MSG_CHECKING(whether to build Async Image Preload support)
+AC_ARG_ENABLE(async-preload,
+  AC_HELP_STRING([--enable-async-preload], [enable async image preloading support]),
+  [ build_async_preload=$enableval ]
+)
+AC_MSG_RESULT($build_async_preload)
+
+AC_MSG_CHECKING(whether we can build Async Image Preload support)
+if test \( "x$build_async_preload" = "xyes" -o "x$build_async_preload" = "xauto" \) -a "x$build_async_events" = "xyes"; then
+  AC_MSG_RESULT(yes)
+  AC_DEFINE(BUILD_ASYNC_PRELOAD, 1, [Build async image preload support])
+  build_async_preload="yes"
+  need_pthreads="yes"
+else
+  AC_MSG_RESULT(no)
+  build_async_preload="no"
+fi
+
+#######################################
+## Link with pthread if needed
+AC_MSG_CHECKING(whether we should link with pthread)
+if test "x$need_pthreads" = "xyes"; then
+  AC_MSG_RESULT(yes)
+  pthread_cflags=""
+  pthread_libs="-lpthread"
+else
+  AC_MSG_RESULT(no)
+fi
+
+#######################################
 ## MMX
 build_cpu_mmx="no"
 case $host_cpu in
@@ -1795,6 +1834,7 @@ echo "  ALTIVEC.................: $build_cpu_altivec"
 echo "  Thread Support..........: $build_pthreads"
 echo
 echo "Async Events..............: $build_async_events"
+echo "Async Image Preload.......: $build_async_preload"
 echo
 echo "ARGB Software Engine Options:"
 echo "  Sampling Scaler.........: $scaler_sample"
diff --git a/src/lib/Evas.h b/src/lib/Evas.h
index 2491643..60f9b08 100644
--- a/src/lib/Evas.h
+++ b/src/lib/Evas.h
@@ -52,7 +52,8 @@ typedef enum _Evas_Callback_Type
    EVAS_CALLBACK_RESTACK, /**< Restack Event */
    EVAS_CALLBACK_DEL, /**< Object Being Deleted (called before Free) */
    EVAS_CALLBACK_HOLD, /**< Events go on/off hold */
-   EVAS_CALLBACK_CHANGED_SIZE_HINTS /**< Size hints changed event */
+   EVAS_CALLBACK_CHANGED_SIZE_HINTS, /**< Size hints changed event */
+   EVAS_CALLBACK_IMAGE_PRELOADED /**< Image as been preloaded */
 } Evas_Callback_Type; /**< The type of event to trigger the callback */
 
 typedef enum _Evas_Button_Flags
@@ -558,6 +559,7 @@ extern "C" {
    EAPI Evas_Bool         evas_object_image_alpha_get       (const Evas_Object *obj);
    EAPI void              evas_object_image_smooth_scale_set(Evas_Object *obj, Evas_Bool smooth_scale);
    EAPI Evas_Bool         evas_object_image_smooth_scale_get(const Evas_Object *obj);
+   EAPI void              evas_object_image_preload         (const Evas_Object *obj, Evas_Bool cancel);
    EAPI void              evas_object_image_reload          (Evas_Object *obj);
    EAPI Evas_Bool         evas_object_image_save            (const Evas_Object *obj, const char *file, const char *key, const char *flags);
    EAPI Evas_Bool         evas_object_image_pixels_import          (Evas_Object *obj, Evas_Pixel_Import_Source *pixels);
@@ -870,7 +872,7 @@ extern "C" {
 
    EAPI int		  evas_async_events_fd_get          (void);
    EAPI int		  evas_async_events_process	    (void);
-   EAPI Evas_Bool	  evas_async_events_put             (void *target, Evas_Callback_Type type, void *event_info, void (*func)(void *target, Evas_Callback_Type type, void *event_info));
+   EAPI Evas_Bool	  evas_async_events_put             (const void *target, Evas_Callback_Type type, void *event_info, void (*func)(void *target, Evas_Callback_Type type, void *event_info));
 
    EAPI void              evas_object_intercept_show_callback_add        (Evas_Object *obj, void (*func) (void *data, Evas_Object *obj), const void *data);
    EAPI void             *evas_object_intercept_show_callback_del        (Evas_Object *obj, void (*func) (void *data, Evas_Object *obj));
diff --git a/src/lib/cache/evas_cache_image.c b/src/lib/cache/evas_cache_image.c
index 5b837d6..c4e1893 100644
--- a/src/lib/cache/evas_cache_image.c
+++ b/src/lib/cache/evas_cache_image.c
@@ -4,6 +4,22 @@
 #include "evas_common.h"
 #include "evas_private.h"
 
+#ifdef BUILD_ASYNC_PRELOAD
+#include <pthread.h>
+
+static Evas_List *preload = NULL;
+static Image_Entry *current = NULL;
+
+static pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
+static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
+static pthread_mutex_t mutex_surface_alloc = PTHREAD_MUTEX_INITIALIZER;
+static pthread_t tid;
+
+static Evas_Bool running = 0;
+
+static void* _evas_cache_background_load(void *);
+#endif
+
 #define FREESTRC(Var)              \
   if (Var)                         \
     {                              \
@@ -223,17 +239,88 @@ _evas_cache_image_entry_surface_alloc(Evas_Cache_Image *cache,
    if (ie->allocated.w == wmin && ie->allocated.h == hmin)
      return ;
 
+#ifdef BUILD_ASYNC_PRELOAD
+   pthread_mutex_lock(&mutex_surface_alloc);
+#endif
+
    if (cache->func.surface_alloc(ie, wmin, hmin))
      {
         wmin = 0;
         hmin = 0;
      }
+
+#ifdef BUILD_ASYNC_PRELOAD
+   pthread_mutex_unlock(&mutex_surface_alloc);
+#endif
+
    ie->w = wmin;
    ie->h = hmin;
    ie->allocated.w = wmin;
    ie->allocated.h = hmin;
 }
 
+#ifdef BUILD_ASYNC_PRELOAD
+static int
+_evas_cache_image_entry_preload_add(Evas_Cache_Image *cache,
+				    Image_Entry *ie,
+				    const void *target)
+{
+   int ret = 0;
+
+   pthread_mutex_lock(&mutex);
+
+   if (!ie->flags.preload)
+     {
+	preload = evas_list_append(preload, ie);
+	ie->flags.preload = 1;
+	ie->target = target;
+
+	if (!running)
+	  {
+	     if (pthread_create(&tid, NULL, _evas_cache_background_load, NULL) == 0)
+	       running = 1;
+	  }
+
+	ret = 1;
+     }
+
+   pthread_mutex_unlock(&mutex);
+
+   return ret;
+}
+
+static int
+_evas_cache_image_entry_preload_remove(Evas_Cache_Image *cache,
+				       Image_Entry *ie)
+{
+   int ret = 0;
+
+   if (running)
+     {
+	pthread_mutex_lock(&mutex);
+
+	if (ie->flags.preload)
+	  {
+	     if (current == ie)
+	       {
+		  /* Wait until ie is processed. */
+		  pthread_cond_wait(&cond, &mutex);
+	       }
+	     else
+	       {
+		  preload = evas_list_remove(preload, ie);
+		  ie->flags.preload = 0;
+		  ret = 1;
+	       }
+	  }
+
+	pthread_mutex_unlock(&mutex);
+     }
+
+   return ret;
+}
+#endif
+
 EAPI int
 evas_cache_image_usage_get(Evas_Cache_Image *cache)
 {
@@ -466,6 +553,10 @@ evas_cache_image_drop(Image_Entry *im)
 
    if (im->references == 0)
      {
+#ifdef BUILD_ASYNC_PRELOAD
+	_evas_cache_image_entry_preload_remove(cache, im);
+#endif
+
 	if (im->flags.dirty)
 	  {
 	     _evas_cache_image_entry_delete(cache, im);
@@ -727,6 +818,12 @@ evas_cache_image_load_data(Image_Entry *im)
 
    if (im->flags.loaded) return ;
 
+#ifdef BUILD_ASYNC_PRELOAD
+   /* We check a first time, to prevent useless lock. */
+   _evas_cache_image_entry_preload_remove(cache, im);
+   if (im->flags.loaded) return ;
+#endif
+
    cache = im->cache;
 
    error = cache->func.load(im);
@@ -745,12 +842,47 @@ evas_cache_image_load_data(Image_Entry *im)
    im->flags.loaded = 1;
 }
 
+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);
+
+   if (im->flags.loaded) return ;
+
+   cache = im->cache;
+
+   _evas_cache_image_entry_preload_add(cache, im, target);
+#else
+   evas_cache_image_load_data(im);
+
+   evas_async_events_put(target, EVAS_CALLBACK_IMAGE_PRELOADED, NULL, evas_object_event_callback_call);
+#endif
+}
+
+EAPI void
+evas_cache_image_preload_cancel(Image_Entry *im)
+{
+#ifdef BUILD_ASYNC_PRELOAD
+   Evas_Cache_Image    *cache;
+
+   assert(im);
+   assert(im->cache);
+
+   _evas_cache_image_entry_preload_remove(cache, im);
+#else
+   (void) im;
+#endif
+}
+
 EAPI int
 evas_cache_image_flush(Evas_Cache_Image *cache)
 {
    assert(cache);
 
-//   printf("cache->limit = %i (used = %i)\n", cache->limit, cache->usage);
    if (cache->limit == -1)
      return -1;
 
@@ -847,3 +979,64 @@ evas_cache_image_pixels(Image_Entry *im)
 
    return cache->func.surface_pixels(im);
 }
+
+#ifdef BUILD_ASYNC_PRELOAD
+static void*
+_evas_cache_background_load(void *data)
+{
+   (void) data;
+
+ restart:
+   while (preload)
+     {
+	pthread_mutex_lock(&mutex);
+
+	current = evas_list_data(preload);
+	preload = evas_list_remove(preload, current);
+
+	pthread_mutex_unlock(&mutex);
+
+	if (current)
+	  {
+	     Evas_Cache_Image *cache;
+	     int error;
+
+	     cache = current->cache;
+
+	     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;
+	       }
+
+	     current->flags.preload = 0;
+	  }
+
+	evas_async_events_put(current->target, EVAS_CALLBACK_IMAGE_PRELOADED, NULL, evas_object_event_callback_call);
+
+	current = NULL;
+	pthread_cond_signal(&cond);
+     }
+
+   pthread_mutex_lock(&mutex);
+   if (preload)
+     {
+	pthread_mutex_unlock(&mutex);
+	goto restart;
+     }
+
+   running = 0;
+   pthread_mutex_unlock(&mutex);
+
+   return NULL;
+}
+#endif
diff --git a/src/lib/canvas/evas_async_events.c b/src/lib/canvas/evas_async_events.c
index e038450..e928d74 100644
--- a/src/lib/canvas/evas_async_events.c
+++ b/src/lib/canvas/evas_async_events.c
@@ -18,7 +18,7 @@ typedef struct _Evas_Event_Async	Evas_Event_Async;
 struct _Evas_Event_Async
 {
    void			(*func)(void *target, Evas_Callback_Type type, void *event_info);
-   void			 *target;
+   const void		 *target;
    Evas_Callback_Type	  type;
    void			 *event_info;
 };
@@ -99,7 +99,7 @@ evas_async_events_process(void)
 	     size += check;
 	     if (size == sizeof(current))
 	       {
-		  if (current.func) current.func(current.target, current.type, current.event_info);
+		  if (current.func) current.func((void*) current.target, current.type, current.event_info);
 		  size = 0;
 		  count++;
 	       }
@@ -124,7 +124,7 @@ evas_async_events_process(void)
 }
 
 EAPI Evas_Bool
-evas_async_events_put(void *target, Evas_Callback_Type type, void *event_info, void (*func)(void *target, Evas_Callback_Type type, void *event_info))
+evas_async_events_put(const void *target, Evas_Callback_Type type, void *event_info, void (*func)(void *target, Evas_Callback_Type type, void *event_info))
 {
 #ifdef BUILD_ASYNC_EVENTS
    Evas_Event_Async new;
@@ -163,7 +163,9 @@ evas_async_events_put(void *target, Evas_Callback_Type type, void *event_info, v
 
    return result;
 #else
-   return 0;
+   func(target, type, event_info);
+
+   return 1;
 #endif
 }
 
diff --git a/src/lib/canvas/evas_object_image.c b/src/lib/canvas/evas_object_image.c
index de34734..d090159 100644
--- a/src/lib/canvas/evas_object_image.c
+++ b/src/lib/canvas/evas_object_image.c
@@ -856,6 +856,41 @@ evas_object_image_data_get(const Evas_Object *obj, Evas_Bool for_writing)
 }
 
 /**
+ * Preload image in the background
+ *
+ * This function request the preload of the data image in the background. The
+ * worked is queued before being processed.
+ *
+ * If cancel is set, it will remove the image from the workqueue.
+ *
+ * @param obj The given image object.
+ * @param cancel 0 means add to the workqueue, 1 remove it.
+ * @ingroup Evas_Object_Image_Data
+ */
+EAPI void
+evas_object_image_preload(const Evas_Object *obj, Evas_Bool cancel)
+{
+   Evas_Object_Image *o;
+   DATA32 *data;
+
+   MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
+   return ;
+   MAGIC_CHECK_END();
+   o = (Evas_Object_Image *)(obj->object_data);
+   MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
+   return ;
+   MAGIC_CHECK_END();
+   if (!o->engine_data) return ;
+   if (cancel)
+     obj->layer->evas->engine.func->image_data_preload_cancel(obj->layer->evas->engine.data.output,
+							      o->engine_data);
+   else
+     obj->layer->evas->engine.func->image_data_preload_request(obj->layer->evas->engine.data.output,
+							       o->engine_data,
+							       obj);
+}
+
+/**
  * Replaces the raw image data of the given image object.
  *
  * This function lets the application replace an image object's internal pixel
diff --git a/src/lib/include/evas_common.h b/src/lib/include/evas_common.h
index 2893cee..209892b 100644
--- a/src/lib/include/evas_common.h
+++ b/src/lib/include/evas_common.h
@@ -278,6 +278,9 @@ struct _Image_Entry_Flags
    Evas_Bool cached       : 1;
    Evas_Bool alpha        : 1;
    Evas_Bool alpha_sparse : 1;
+#ifdef BUILD_ASYNC_PRELOAD
+   Evas_Bool preload      : 1;
+#endif
 };
 
 struct _Image_Entry
@@ -291,6 +294,8 @@ struct _Image_Entry
   const char            *file;
   const char            *key;
 
+  const void            *target;
+
   time_t                 timestamp;
   time_t                 laststat;
 
@@ -1308,6 +1313,9 @@ EAPI int                             evas_cache_image_usage_get(Evas_Cache_Image
 EAPI int                             evas_cache_image_get(Evas_Cache_Image *cache);
 EAPI void                            evas_cache_image_set(Evas_Cache_Image *cache, int size);
 
+EAPI void                            evas_cache_image_preload_data(Image_Entry *im, const void *target);
+EAPI void                            evas_cache_image_preload_cancel(Image_Entry *im);
+
 EAPI Image_Entry*                    evas_cache_image_alone(Image_Entry *im);
 EAPI Image_Entry*                    evas_cache_image_dirty(Image_Entry *im, int x, int y, int w, int h);
 EAPI void                            evas_cache_image_load_data(Image_Entry *im);
diff --git a/src/lib/include/evas_private.h b/src/lib/include/evas_private.h
index 0cf7675..e5fb025 100644
--- a/src/lib/include/evas_private.h
+++ b/src/lib/include/evas_private.h
@@ -634,6 +634,8 @@ struct _Evas_Func
    void *(*image_dirty_region)             (void *data, void *image, int x, int y, int w, int h);
    void *(*image_data_get)                 (void *data, void *image, int to_write, DATA32 **image_data);
    void *(*image_data_put)                 (void *data, void *image, DATA32 *image_data);
+   void  (*image_data_preload_request)     (void *data, void *image, const void *target);
+   void  (*image_data_preload_cancel)      (void *data, void *image);
    void *(*image_alpha_set)                (void *data, void *image, int has_alpha);
    int  (*image_alpha_get)                 (void *data, void *image);
    void *(*image_border_set)               (void *data, void *image, int l, int r, int t, int b);
diff --git a/src/modules/engines/cairo_x11/evas_engine.c b/src/modules/engines/cairo_x11/evas_engine.c
index c100d21..74aa4ca 100644
--- a/src/modules/engines/cairo_x11/evas_engine.c
+++ b/src/modules/engines/cairo_x11/evas_engine.c
@@ -79,6 +79,8 @@ static void *eng_image_size_set(void *data, void *image, int w, int h);
 static void *eng_image_dirty_region(void *data, void *image, int x, int y, int w, int h);
 static void *eng_image_data_get(void *data, void *image, int to_write, DATA32 **image_data);
 static void *eng_image_data_put(void *data, void *image, DATA32 *image_data);
+static void eng_image_data_preload_request(void *data, void *image, void *target);
+static void eng_image_data_preload_cancel(void *data, void *image);
 static void *eng_image_alpha_set(void *data, void *image, int has_alpha);
 static int eng_image_alpha_get(void *data, void *image);
 static void *eng_image_border_set(void *data, void *image, int l, int r, int t, int b);
@@ -197,6 +199,8 @@ static Evas_Func eng_func =
      eng_image_dirty_region,
      eng_image_data_get,
      eng_image_data_put,
+     eng_image_data_preload_request,
+     eng_image_data_preload_cancel,
      eng_image_alpha_set,
      eng_image_alpha_get,
      eng_image_border_set,
@@ -1045,6 +1049,26 @@ eng_image_data_put(void *data, void *image, DATA32 *image_data)
    return image;
 }
 
+static void
+eng_image_data_preload_request(void *data, void *image, void *target)
+{
+   Render_Engine *re;
+
+   /* FIXME */
+   re = (Render_Engine *)data;
+   return image;
+}
+
+static void
+eng_image_data_preload_cancel(void *data, void *image)
+{
+   Render_Engine *re;
+
+   /* FIXME */
+   re = (Render_Engine *)data;
+   return image;
+}
+
 static void *
 eng_image_alpha_set(void *data, void *image, int has_alpha)
 {
diff --git a/src/modules/engines/gl_glew/evas_engine.c b/src/modules/engines/gl_glew/evas_engine.c
index f640cd3..0508a1e 100644
--- a/src/modules/engines/gl_glew/evas_engine.c
+++ b/src/modules/engines/gl_glew/evas_engine.c
@@ -814,6 +814,30 @@ eng_image_data_put(void *data, void *image, DATA32 *image_data)
 }
 
 static void
+eng_image_data_preload_request(void *data, void *image, void *target)
+{
+   Evas_GL_Image *gim = image;
+   RGBA_Image *im;
+
+   if (!gim) return ;
+   im = (RGBA_Image*) gim->im;
+   if (!im) return ;
+   evas_cache_image_preload_data(&im->cache_entry, target);
+}
+
+static void
+eng_image_data_preload_cancel(void *data, void *image)
+{
+   Evas_GL_Image *gim = image;
+   RGBA_Image *im;
+
+   if (!gim) return ;
+   im = (RGBA_Image*) gim->im;
+   if (!im) return ;
+   evas_cache_image_preload_cancel(&im->cache_entry);
+}
+
+static void
 eng_image_draw(void *data, void *context, void *surface, void *image, int src_x, int src_y, int src_w, int src_h, int dst_x, int dst_y, int dst_w, int dst_h, int smooth)
 {
    Render_Engine *re;
@@ -915,6 +939,8 @@ module_open(Evas_Module *em)
    ORD(image_dirty_region);
    ORD(image_data_get);
    ORD(image_data_put);
+   ORD(image_data_preload_request);
+   ORD(image_data_preload_cancel);
    ORD(image_alpha_set);
    ORD(image_alpha_get);
    ORD(image_border_set);
diff --git a/src/modules/engines/gl_x11/evas_engine.c b/src/modules/engines/gl_x11/evas_engine.c
index a236a53..4d77321 100644
--- a/src/modules/engines/gl_x11/evas_engine.c
+++ b/src/modules/engines/gl_x11/evas_engine.c
@@ -860,6 +860,30 @@ eng_image_data_put(void *data, void *image, DATA32 *image_data)
 }
 
 static void
+eng_image_data_preload_request(void *data, void *image, void *target)
+{
+   Evas_GL_Image *gim = image;
+   RGBA_Image *im;
+
+   if (!gim) return ;
+   im = (RGBA_Image*) gim->im;
+   if (!im) return ;
+   evas_cache_image_preload_data(&im->cache_entry, target);
+}
+
+static void
+eng_image_data_preload_cancel(void *data, void *image)
+{
+   Evas_GL_Image *gim = image;
+   RGBA_Image *im;
+
+   if (!gim) return ;
+   im = (RGBA_Image*) gim->im;
+   if (!im) return ;
+   evas_cache_image_preload_cancel(&im->cache_entry);
+}
+
+static void
 eng_image_draw(void *data, void *context, void *surface, void *image, int src_x, int src_y, int src_w, int src_h, int dst_x, int dst_y, int dst_w, int dst_h, int smooth)
 {
    Render_Engine *re;
@@ -994,6 +1018,8 @@ module_open(Evas_Module *em)
    ORD(image_dirty_region);
    ORD(image_data_get);
    ORD(image_data_put);
+   ORD(image_data_preload_request);
+   ORD(image_data_preload_cancel);
    ORD(image_alpha_set);
    ORD(image_alpha_get);
    ORD(image_border_set);
diff --git a/src/modules/engines/software_16/evas_engine.c b/src/modules/engines/software_16/evas_engine.c
index 76b591b..71e0a3a 100644
--- a/src/modules/engines/software_16/evas_engine.c
+++ b/src/modules/engines/software_16/evas_engine.c
@@ -508,7 +508,23 @@ eng_image_data_put(void *data, void *image, DATA32 *image_data)
    return new_im;
 }
 
-#include <assert.h>
+static void
+eng_image_data_preload_request(void *data, void *image, void *target)
+{
+   Soft16_Image *im = image;
+
+   if (!im) return ;
+   evas_cache_image_preload_data(&im->cache_entry, target);
+}
+
+static void
+eng_image_data_preload_cancel(void *data, void *image)
+{
+   Soft16_Image *im = image;
+
+   if (!im) return ;
+   evas_cache_image_preload_cancel(&im->cache_entry);
+}
 
 static void
 eng_image_draw(void *data, void *context, void *surface, void *image, int src_x, int src_y, int src_w, int src_h, int dst_x, int dst_y, int dst_w, int dst_h, int smooth)
@@ -773,6 +789,8 @@ static Evas_Func func =
      eng_image_dirty_region,
      eng_image_data_get,
      eng_image_data_put,
+     eng_image_data_preload_request,
+     eng_image_data_preload_cancel,
      eng_image_alpha_set,
      eng_image_alpha_get,
      eng_image_border_set,
diff --git a/src/modules/engines/software_16_sdl/evas_engine.c b/src/modules/engines/software_16_sdl/evas_engine.c
index ea4911e..4914395 100644
--- a/src/modules/engines/software_16_sdl/evas_engine.c
+++ b/src/modules/engines/software_16_sdl/evas_engine.c
@@ -729,6 +729,30 @@ evas_engine_sdl16_image_data_put(void *data, void *image, DATA32* image_data)
    return eim_new;
 }
 
+static void
+evas_engine_sdl16_image_data_preload_request(void *data, void *image, const void *target)
+{
+   SDL_Engine_Image_Entry       *eim = image;
+   Soft16_Image                 *im;
+
+   if (!eim) return ;
+   im = (Soft16_Image *) eim->cache_entry.src;
+   if (!im) return ;
+   evas_cache_image_preload_data(&im->cache_entry, target);
+}
+
+static void
+evas_engine_sdl16_image_data_preload_cancel(void *data, void *image)
+{
+   SDL_Engine_Image_Entry       *eim = image;
+   Soft16_Image                 *im;
+
+   if (!eim) return ;
+   im = (Soft16_Image *) eim->cache_entry.src;
+   if (!im) return ;
+   evas_cache_image_preload_cancel(&im->cache_entry);
+}
+
 static void*
 evas_engine_sdl16_image_alpha_set(void *data, void *image, int has_alpha)
 {
@@ -1035,6 +1059,8 @@ module_open(Evas_Module *em)
    ORD(image_dirty_region);
    ORD(image_data_get);
    ORD(image_data_put);
+   ORD(image_data_preload_request);
+   ORD(image_data_preload_cancel);
    ORD(image_alpha_set);
    ORD(image_border_set);
    ORD(image_border_get);
diff --git a/src/modules/engines/software_generic/evas_engine.c b/src/modules/engines/software_generic/evas_engine.c
index 49749b8..b166e30 100644
--- a/src/modules/engines/software_generic/evas_engine.c
+++ b/src/modules/engines/software_generic/evas_engine.c
@@ -555,6 +555,24 @@ eng_image_data_put(void *data, void *image, DATA32 *image_data)
 }
 
 static void
+eng_image_data_preload_request(void *data, void *image, void *target)
+{
+   RGBA_Image *im = image;
+
+   if (!im) return ;
+   evas_cache_image_preload_data(&im->cache_entry, target);
+}
+
+static void
+eng_image_data_preload_cancel(void *data, void *image)
+{
+   RGBA_Image *im = image;
+
+   if (!im) return ;
+   evas_cache_image_preload_cancel(&im->cache_entry);
+}
+
+static void
 eng_image_draw(void *data, void *context, void *surface, void *image, int src_x, int src_y, int src_w, int src_h, int dst_x, int dst_y, int dst_w, int dst_h, int smooth)
 {
    RGBA_Image *im;
@@ -829,6 +847,8 @@ static Evas_Func func =
      eng_image_dirty_region,
      eng_image_data_get,
      eng_image_data_put,
+     eng_image_data_preload_request,
+     eng_image_data_preload_cancel,
      eng_image_alpha_set,
      eng_image_alpha_get,
      eng_image_border_set,
diff --git a/src/modules/engines/software_sdl/evas_engine.c b/src/modules/engines/software_sdl/evas_engine.c
index 69d47ad..f2a9f19 100644
--- a/src/modules/engines/software_sdl/evas_engine.c
+++ b/src/modules/engines/software_sdl/evas_engine.c
@@ -502,6 +502,30 @@ evas_engine_sdl_image_data_put(void *data, void *image, DATA32* image_data)
    return eim;
 }
 
+static void
+evas_engine_sdl_image_data_preload_request(void *data, void *image, const void *target)
+{
+   SDL_Engine_Image_Entry       *eim = image;
+   RGBA_Image                   *im;
+
+   if (!eim) return ;
+   im = (RGBA_Image*) eim->cache_entry.src;
+   if (!im) return ;
+   evas_cache_image_preload_data(&im->cache_entry, target);
+}
+
+static void
+evas_engine_sdl_image_data_preload_cancel(void *data, void *image)
+{
+   SDL_Engine_Image_Entry       *eim = image;
+   RGBA_Image                   *im;
+
+   if (!eim) return ;
+   im = (RGBA_Image*) eim->cache_entry.src;
+   if (!im) return ;
+   evas_cache_image_preload_cancel(&im->cache_entry);
+}
+
 static void*
 evas_engine_sdl_image_alpha_set(void *data, void *image, int has_alpha)
 {
@@ -812,6 +836,8 @@ EAPI int module_open(Evas_Module *em)
    ORD(image_dirty_region);
    ORD(image_data_get);
    ORD(image_data_put);
+   ORD(image_data_preload_request);
+   ORD(image_data_preload_cancel);
    ORD(image_alpha_set);
    ORD(image_alpha_get);
    ORD(image_border_set);
diff --git a/src/modules/engines/xrender_x11/evas_engine.c b/src/modules/engines/xrender_x11/evas_engine.c
index 9c50db3..1522e5d 100644
--- a/src/modules/engines/xrender_x11/evas_engine.c
+++ b/src/modules/engines/xrender_x11/evas_engine.c
@@ -792,6 +792,30 @@ eng_image_data_put(void *data, void *image, DATA32 *image_data)
 }
 
 static void
+eng_image_data_preload_request(void *data, void *image, const void *target)
+{
+   XR_Image *xim = image;
+   RGBA_Image *im;
+
+   if (!xim) return ;
+   im = (RGBA_Image*) xim->im;
+   if (!im) return ;
+   evas_cache_image_preload_data(&im->cache_entry, target);
+}
+
+static void
+eng_image_data_preload_cancel(void *data, void *image)
+{
+   XR_Image *xim = image;
+   RGBA_Image *im;
+
+   if (!xim) return ;
+   im = (RGBA_Image*) xim->im;
+   if (!im) return ;
+   evas_cache_image_preload_cancel(&im->cache_entry);
+}
+
+static void
 eng_image_draw(void *data, void *context, void *surface, void *image, int src_x, int src_y, int src_w, int src_h, int dst_x, int dst_y, int dst_w, int dst_h, int smooth)
 {
    if ((!image) || (!surface)) return;
@@ -915,6 +939,8 @@ module_open(Evas_Module *em)
    ORD(image_dirty_region);
    ORD(image_data_get);
    ORD(image_data_put);
+   ORD(image_data_preload_request);
+   ORD(image_data_preload_cancel);
    ORD(image_alpha_set);
    ORD(image_alpha_get);
    ORD(image_border_set);
diff --git a/src/modules/engines/xrender_xcb/evas_engine.c b/src/modules/engines/xrender_xcb/evas_engine.c
index 84049bf..ea0bb73 100644
--- a/src/modules/engines/xrender_xcb/evas_engine.c
+++ b/src/modules/engines/xrender_xcb/evas_engine.c
@@ -635,6 +635,30 @@ eng_image_data_put(void *data, void *image, DATA32 *image_data)
    return image;
 }
 
+static void
+eng_image_data_preload_request(void *data, void *image, void *target)
+{
+   XR_Image *xim = image;
+   RGBA_Image *im;
+
+   if (!xim) return ;
+   im = (RGBA_Image*) xim->im;
+   if (!im) return ;
+   evas_cache_image_preload_data(&im->cache_entry, target);
+}
+
+static void
+eng_image_data_preload_cancel(void *data, void *image)
+{
+   XR_Image *xim = image;
+   RGBA_Image *im;
+
+   if (!xim) return ;
+   im = (RGBA_Image*) xim->im;
+   if (!im) return ;
+   evas_cache_image_preload_data(&im->cache_entry, target);
+}
+
 static void *
 eng_image_alpha_set(void *data, void *image, int has_alpha)
 {
@@ -843,6 +867,8 @@ module_open(Evas_Module *em)
    ORD(image_dirty_region);
    ORD(image_data_get);
    ORD(image_data_put);
+   ORD(image_data_preload_request);
+   ORD(image_data_preload_cancel);
    ORD(image_alpha_set);
    ORD(image_alpha_get);
    ORD(image_border_set);
-------------------------------------------------------------------------
Check out the new SourceForge.net Marketplace.
It's the best place to buy or sell services for
just about anything Open Source.
http://sourceforge.net/services/buy/index.php
_______________________________________________
enlightenment-devel mailing list
enlightenment-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/enlightenment-devel

Reply via email to