Time to wake up dead old patch :-)

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:
>>   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.

So updated the patch (It's against the root svn as it also patch
expedite) and added the lock around the surface allocation.

Deleting the image should not be a problem as it is handle right now
by evas_cache_image_drop. It will remove, with wait if needed, the
image from the queue when the reference goes down to zero. Their is no
need to lock anything around the image in the engine, every thing is
done in evas_cache_image.c.

I am using since few month and I didn't see any crach with it nor slow
down, so if people don't really mind I can put it in svn (It's
possible to deactivate it at compile time, in which case preload will
act as a synchronous load).

-- 
Cedric BAIL
diff --git a/evas/configure.in b/evas/configure.in
index f2027bd..60781a8 100644
--- a/evas/configure.in
+++ b/evas/configure.in
@@ -1136,16 +1136,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" ]
             )
           ],
@@ -1166,8 +1174,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))
@@ -1184,8 +1191,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
   ]
 )
@@ -1205,12 +1211,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
@@ -1818,6 +1857,7 @@ echo "  Thread Support..........: $build_pthreads"
 echo "  MAGIC_DEBUG.............: $want_evas_magic_debug"
 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/evas/src/lib/Evas.h b/evas/src/lib/Evas.h
index 32334ed..905ee08 100644
--- a/evas/src/lib/Evas.h
+++ b/evas/src/lib/Evas.h
@@ -54,7 +54,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
@@ -518,6 +519,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);
@@ -838,7 +840,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/evas/src/lib/cache/evas_cache_image.c b/evas/src/lib/cache/evas_cache_image.c
index 4ec0356..fb41f41 100644
--- a/evas/src/lib/cache/evas_cache_image.c
+++ b/evas/src/lib/cache/evas_cache_image.c
@@ -8,6 +8,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)                         \
     {                              \
@@ -227,17 +243,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)
 {
@@ -470,6 +557,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);
@@ -731,6 +822,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);
@@ -749,12 +846,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;
 
@@ -851,3 +983,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/evas/src/lib/canvas/evas_async_events.c b/evas/src/lib/canvas/evas_async_events.c
index e038450..e928d74 100644
--- a/evas/src/lib/canvas/evas_async_events.c
+++ b/evas/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/evas/src/lib/canvas/evas_main.c b/evas/src/lib/canvas/evas_main.c
index 1a9b34c..e11368c 100644
--- a/evas/src/lib/canvas/evas_main.c
+++ b/evas/src/lib/canvas/evas_main.c
@@ -8,7 +8,10 @@ EAPI int
 evas_init(void)
 {
    if (initcount == 0)
-     evas_module_init();
+     {
+	evas_module_init();
+	evas_async_events_init();
+     }
    return ++initcount;
 }
 
@@ -18,6 +21,7 @@ evas_shutdown(void)
    initcount--;
    if (initcount == 0)
      {
+	evas_async_events_shutdown();
 	evas_font_dir_cache_free();
 	evas_common_shutdown();
 	evas_module_shutdown();
diff --git a/evas/src/lib/canvas/evas_object_image.c b/evas/src/lib/canvas/evas_object_image.c
index 59acbcb..c003a7a 100644
--- a/evas/src/lib/canvas/evas_object_image.c
+++ b/evas/src/lib/canvas/evas_object_image.c
@@ -998,6 +998,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/evas/src/lib/include/evas_common.h b/evas/src/lib/include/evas_common.h
index 7c8f1aa..91043dd 100644
--- a/evas/src/lib/include/evas_common.h
+++ b/evas/src/lib/include/evas_common.h
@@ -259,6 +259,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
@@ -272,6 +275,8 @@ struct _Image_Entry
   const char            *file;
   const char            *key;
 
+  const void            *target;
+
   time_t                 timestamp;
   time_t                 laststat;
 
diff --git a/evas/src/lib/include/evas_private.h b/evas/src/lib/include/evas_private.h
index a4d0c35..bed9703 100644
--- a/evas/src/lib/include/evas_private.h
+++ b/evas/src/lib/include/evas_private.h
@@ -614,6 +614,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/evas/src/modules/engines/cairo_x11/evas_engine.c b/evas/src/modules/engines/cairo_x11/evas_engine.c
index c100d21..74aa4ca 100644
--- a/evas/src/modules/engines/cairo_x11/evas_engine.c
+++ b/evas/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/evas/src/modules/engines/directfb/evas_engine.c b/evas/src/modules/engines/directfb/evas_engine.c
index 79b5d0b..c8244d9 100644
--- a/evas/src/modules/engines/directfb/evas_engine.c
+++ b/evas/src/modules/engines/directfb/evas_engine.c
@@ -1413,6 +1413,30 @@ evas_engine_dfb_image_data_put(void *data, void *image, DATA32* image_data)
    return deie;
 }
 
+static void
+evas_engine_dfb_image_data_preload_request(void *data, void *image, void *target)
+{
+   DirectFB_Engine_Image_Entry *deie = image;
+   RGBA_Image *im;
+
+   if (!deie) return ;
+   im = (RGBA_Image*) deie->cache_entry.src;
+   if (!im) return ;
+   evas_cache_image_preload_data(&im->cache_entry, target);
+}
+
+static void
+evas_engine_dfb_image_data_preload_cancel(void *data, void *image)
+{
+   DirectFB_Engine_Image_Entry *deie = image;
+   RGBA_Image *im;
+
+   if (!deie) return ;
+   im = (RGBA_Image*) deie->cache_entry.src;
+   if (!im) return ;
+   evas_cache_image_preload_cancel(&im->cache_entry);
+}
+
 static void *
 evas_engine_dfb_image_alpha_set(void *data, void *image, int has_alpha)
 {
@@ -1608,6 +1632,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_draw);
diff --git a/evas/src/modules/engines/gl_glew/evas_engine.c b/evas/src/modules/engines/gl_glew/evas_engine.c
index 33f790e..de8c599 100644
--- a/evas/src/modules/engines/gl_glew/evas_engine.c
+++ b/evas/src/modules/engines/gl_glew/evas_engine.c
@@ -837,6 +837,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;
@@ -938,6 +962,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/evas/src/modules/engines/gl_x11/evas_engine.c b/evas/src/modules/engines/gl_x11/evas_engine.c
index 4b2450f..1c56809 100644
--- a/evas/src/modules/engines/gl_x11/evas_engine.c
+++ b/evas/src/modules/engines/gl_x11/evas_engine.c
@@ -967,6 +967,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;
@@ -1123,6 +1147,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/evas/src/modules/engines/software_16/evas_engine.c b/evas/src/modules/engines/software_16/evas_engine.c
index 0381185..af3ac10 100644
--- a/evas/src/modules/engines/software_16/evas_engine.c
+++ b/evas/src/modules/engines/software_16/evas_engine.c
@@ -614,7 +614,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)
@@ -902,6 +918,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/evas/src/modules/engines/software_16_sdl/evas_engine.c b/evas/src/modules/engines/software_16_sdl/evas_engine.c
index ea4911e..4914395 100644
--- a/evas/src/modules/engines/software_16_sdl/evas_engine.c
+++ b/evas/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/evas/src/modules/engines/software_generic/evas_engine.c b/evas/src/modules/engines/software_generic/evas_engine.c
index 4242b2a..9108c4b 100644
--- a/evas/src/modules/engines/software_generic/evas_engine.c
+++ b/evas/src/modules/engines/software_generic/evas_engine.c
@@ -714,6 +714,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;
@@ -1011,6 +1029,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/evas/src/modules/engines/software_sdl/evas_engine.c b/evas/src/modules/engines/software_sdl/evas_engine.c
index 69d47ad..f2a9f19 100644
--- a/evas/src/modules/engines/software_sdl/evas_engine.c
+++ b/evas/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/evas/src/modules/engines/xrender_x11/evas_engine.c b/evas/src/modules/engines/xrender_x11/evas_engine.c
index 31a96fe..0b73742 100644
--- a/evas/src/modules/engines/xrender_x11/evas_engine.c
+++ b/evas/src/modules/engines/xrender_x11/evas_engine.c
@@ -900,6 +900,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;
@@ -1045,6 +1069,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/evas/src/modules/engines/xrender_xcb/evas_engine.c b/evas/src/modules/engines/xrender_xcb/evas_engine.c
index 84049bf..ea0bb73 100644
--- a/evas/src/modules/engines/xrender_xcb/evas_engine.c
+++ b/evas/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/expedite/src/bin/main.c b/expedite/src/bin/main.c
index 736e249..87ccc4a 100644
--- a/expedite/src/bin/main.c
+++ b/expedite/src/bin/main.c
@@ -1,5 +1,12 @@
 #include "main.h"
 
+typedef struct _Evas_Object_Image_Preload Evas_Object_Image_Preload;
+struct _Evas_Object_Image_Preload
+{
+   Evas_Object *obj;
+   const char *name;
+};
+
 Evas *evas = NULL;
 int win_w = 720, win_h = 420;
 
@@ -1040,6 +1047,17 @@ static const unsigned short r[65536] =
 7968, 2599, 8735, 29790, 6290, 30746, 32702, 4455, 16084, 13228, 29890, 28634, 5614, 3659, 22541, 13680, 13544, 6990, 4032, 29236, 23846, 12513, 28685, 12501, 1470, 25253, 25536, 8868, 10340, 1045, 27154, 18308, 3644, 3122, 15330, 9934, 1100, 15264, 14389, 17184, 28493, 11512, 13050, 1339, 15171, 2823, 15020, 28715, 9814, 19052, 25184, 892, 31565, 21101, 13394, 267, 13586, 6162, 9135, 23926, 7207, 3522, 9466, 10852
 };
 
+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" }
+};
+
 void
 srnd(void)
 {
@@ -1324,6 +1342,8 @@ _engine_args(int argc, char **argv)
 int
 main(int argc, char **argv)
 {
+   int i;
+
    evas_init();
    evas = evas_new();
 
@@ -1332,12 +1352,28 @@ main(int argc, char **argv)
 
    evas_font_hinting_set(evas, EVAS_FONT_HINTING_AUTO);
 
+   /* Preloading every image. */
+   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);
+     }
+
    while (_engine_go())
      {
 	ui_loop();
 	engine_loop();
 	evas_render(evas);
      }
+
+   /* Delete object, just to be clean. */
+   for (i = 0; i < sizeof (preloading) / sizeof (Evas_Object_Image_Preload); ++i)
+     {
+	evas_object_del(preloading[i].obj);
+	preloading[i].obj = NULL;
+     }
+
    evas_free(evas);
 
    evas_shutdown();
-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
enlightenment-devel mailing list
enlightenment-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/enlightenment-devel

Reply via email to