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.
-- 
Cedric BAIL
diff --git a/configure.in b/configure.in
index 8f63c17..b07ee1f 100644
--- a/configure.in
+++ b/configure.in
@@ -1207,6 +1207,26 @@ else
 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$has_pthreads" = "xyes"; then
+  AC_MSG_RESULT(yes)
+  AC_DEFINE(BUILD_ASYNC_PRELOAD, 1, [Build async image preload support])
+  build_async_preload="yes"
+else
+  AC_MSG_RESULT(no)
+  build_async_preload="no"
+fi
+
+#######################################
 ## MMX
 build_cpu_mmx="no"
 case $host_cpu in
@@ -1792,6 +1812,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..fb33696 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
@@ -870,7 +871,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..ec9d4d3 100644
--- a/src/lib/cache/evas_cache_image.c
+++ b/src/lib/cache/evas_cache_image.c
@@ -4,6 +4,21 @@
 #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_t tid;
+
+static Evas_Bool running = 0;
+
+static void* _evas_cache_background_load(void *);
+#endif
+
 #define FREESTRC(Var)              \
   if (Var)                         \
     {                              \
@@ -234,6 +249,68 @@ _evas_cache_image_entry_surface_alloc(Evas_Cache_Image *cache,
    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 +543,8 @@ evas_cache_image_drop(Image_Entry *im)
 
    if (im->references == 0)
      {
+	_evas_cache_image_entry_preload_remove(cache, im);
+
 	if (im->flags.dirty)
 	  {
 	     _evas_cache_image_entry_delete(cache, im);
@@ -727,6 +806,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 +830,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 +967,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);
diff --git a/src/bin/ui.c b/src/bin/ui.c
index 07dd97c..8801451 100644
--- a/src/bin/ui.c
+++ b/src/bin/ui.c
@@ -22,6 +22,13 @@ struct _Menu_Item
    void (*func) (void);
 };
 
+typedef struct _Evas_Object_Image_Preload Evas_Object_Image_Preload;
+struct _Evas_Object_Image_Preload
+{
+   Evas_Object *obj;
+   const char *name;
+};
+
 static Evas_Object *o_bg = NULL;
 static Evas_Object *o_wallpaper = NULL;
 static Evas_Object *o_title = NULL;
@@ -52,12 +59,31 @@ _ui_exit(void)
    engine_abort();
 }
 
+static Evas_Object_Image_Preload preloading[] = {
+  { NULL, "logo.png" },
+  { NULL, "image.png" },
+  { NULL, "bar.png" },
+  { NULL, "pan.png" },
+  { NULL, "frame.png" },
+  { NULL, "im1.png" },
+  { NULL, "im2.png" },
+  { NULL, "tp.png" }
+};
+
 static void
 _ui_all(void)
 {
    Evas_List *l;
    double fps = 0.0;
    int t_count = 0;
+   int i;
+
+   for (i = 0; i < sizeof (preloading) / sizeof (Evas_Object_Image_Preload); ++i)
+     {
+	preloading[i].obj = evas_object_image_add(evas);
+	evas_object_image_file_set(preloading[i].obj, build_path(preloading[i].name), NULL);
+	evas_object_image_preload(preloading[i].obj, 0);
+     }
 
    for (l = menu; l; l = l->next)
      {
@@ -75,11 +101,18 @@ _ui_all(void)
 	     engine_loop();
 	     evas_render(evas);
 	  }
+	evas_render(evas);
 	t_count++;
 	fps += p_fps;
 	key_func("Escape");
      }
    if (t_count > 0) printf("%4.2f , EVAS SPEED\n", fps / t_count);
+
+   for (i = 0; i < sizeof (preloading) / sizeof (Evas_Object_Image_Preload); ++i)
+     {
+	evas_object_del(preloading[i].obj);
+	preloading[i].obj = NULL;
+     }
 }
 
 static void
-------------------------------------------------------------------------
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
[email protected]
https://lists.sourceforge.net/lists/listinfo/enlightenment-devel

Reply via email to