raster pushed a commit to branch master.

http://git.enlightenment.org/core/efl.git/commit/?id=ec6ddf59e221b1a35543c0be9d09122567c1d4f7

commit ec6ddf59e221b1a35543c0be9d09122567c1d4f7
Author: Carsten Haitzler (Rasterman) <ras...@rasterman.com>
Date:   Tue Jul 7 21:29:31 2015 +0900

    evas - image core - fix unloading of images to work again
    
    i think this has been disabled for a while. image unloading is broken
    - esp with gl enigne as due to async move it was effectively disabled.
    
    this re-enables it. unloading is deferred with a managed list of things
    needing unloading and then when any async sw renders are not busy any
    more - do the unload then in the mainloop of all pending/flagged
    images to unload
    
    @fix
---
 src/lib/evas/cache/evas_cache_image.c      |   1 +
 src/lib/evas/canvas/evas_render.c          |  25 ++++++
 src/lib/evas/common/evas_image.h           |   5 +-
 src/lib/evas/common/evas_image_main.c      | 117 +++++++++++++++++++----------
 src/lib/evas/include/evas_common_private.h |   2 +
 5 files changed, 109 insertions(+), 41 deletions(-)

diff --git a/src/lib/evas/cache/evas_cache_image.c 
b/src/lib/evas/cache/evas_cache_image.c
index 979d299..6220fbc 100644
--- a/src/lib/evas/cache/evas_cache_image.c
+++ b/src/lib/evas/cache/evas_cache_image.c
@@ -1142,6 +1142,7 @@ evas_cache_image_load_data(Image_Entry *im)
    int error = EVAS_LOAD_ERROR_NONE;
 
    if ((im->flags.loaded) && (!im->animated.animated)) return error;
+   evas_common_rgba_pending_unloads_remove(im);
    if (im->preload)
      {
         preload = EINA_TRUE;
diff --git a/src/lib/evas/canvas/evas_render.c 
b/src/lib/evas/canvas/evas_render.c
index dc15572..e820288 100644
--- a/src/lib/evas/canvas/evas_render.c
+++ b/src/lib/evas/canvas/evas_render.c
@@ -167,6 +167,28 @@ _accumulate_time(double before, Eina_Bool async)
 }
 #endif
 
+static int _render_busy = 0;
+
+static void
+_evas_render_cleanup(void)
+{
+   if (_render_busy != 0) return;
+   evas_common_rgba_pending_unloads_cleanup();
+}
+
+static void
+_evas_render_busy_begin(void)
+{
+   _render_busy++;
+}
+
+static void
+_evas_render_busy_end(void)
+{
+   _render_busy--;
+   _evas_render_cleanup();
+}
+
 EOLIAN void
 _evas_canvas_damage_rectangle_add(Eo *eo_e EINA_UNUSED, Evas_Public_Data *e, 
int x, int y, int w, int h)
 {
@@ -2335,6 +2357,7 @@ evas_render_updates_internal(Evas *eo_e,
         int fx = e->framespace.x;
         int fy = e->framespace.y;
 
+        if (do_async) _evas_render_busy_begin();
         eina_evlog("+render_surface", eo_e, 0.0, NULL);
         while ((surface =
                 e->engine.func->output_redraws_next_update_get
@@ -2699,6 +2722,7 @@ evas_render_updates_internal(Evas *eo_e,
    _accumulate_time(start_time, do_async);
 #endif
 
+   if (!do_async) _evas_render_cleanup();
    return EINA_TRUE;
 }
 
@@ -2793,6 +2817,7 @@ evas_render_async_wakeup(void *target, Evas_Callback_Type 
type EINA_UNUSED, void
 {
    Evas_Public_Data *e = target;
    evas_render_wakeup(e->evas);
+   _evas_render_busy_end();
 }
 
 static void
diff --git a/src/lib/evas/common/evas_image.h b/src/lib/evas/common/evas_image.h
index 3eecfee..a625bba 100644
--- a/src/lib/evas/common/evas_image.h
+++ b/src/lib/evas/common/evas_image.h
@@ -6,7 +6,10 @@ EAPI void              evas_common_image_init                  
    (void);
 EAPI void              evas_common_image_shutdown                  (void);
 
 EAPI void              evas_common_image_image_all_unload          (void);
-    
+
+EAPI void              evas_common_rgba_pending_unloads_cleanup    (void);
+EAPI void              evas_common_rgba_pending_unloads_remove     
(Image_Entry *ie);
+
 EAPI void              evas_common_rgba_image_free                 
(Image_Entry *ie);
 EAPI void              evas_common_rgba_image_unload               
(Image_Entry *ie);
 EAPI void              evas_common_image_colorspace_normalize      (RGBA_Image 
*im);
diff --git a/src/lib/evas/common/evas_image_main.c 
b/src/lib/evas/common/evas_image_main.c
index 3cb2044..eb0d509 100644
--- a/src/lib/evas/common/evas_image_main.c
+++ b/src/lib/evas/common/evas_image_main.c
@@ -332,50 +332,11 @@ _evas_common_rgba_image_delete(Image_Entry *ie)
    free(im);
 }
 
-EAPI void
-evas_common_rgba_image_free(Image_Entry *ie)
-{
-   if (ie->references > 0) return;
-
-   _evas_common_rgba_image_surface_delete(ie);
-   _evas_common_rgba_image_delete(ie);
-}
-
-#ifdef SURFDBG
-static Eina_List *surfs = NULL;
-
 static void
-surf_debug(void)
-{
-   Eina_List *l;
-   Image_Entry *ie;
-   RGBA_Image *im;
-   int i = 0;
-   
-   printf("----SURFS----\n");
-   EINA_LIST_FOREACH(surfs, l, ie)
-     {
-        im = ie;
-        printf("%i - %p - %ix%i  [%s][%s]\n", 
-               i, im->image.data, ie->allocated.w, ie->allocated.h,
-               ie->file, ie->key
-              );
-        i++;
-     }
-}
-#endif
-
-EAPI void
-evas_common_rgba_image_unload(Image_Entry *ie)
+evas_common_rgba_image_unload_real(Image_Entry *ie)
 {
    RGBA_Image   *im = (RGBA_Image *) ie;
 
-   if (!ie->flags.loaded) return;
-   if ((!ie->info.module) && (!ie->data1)) return;
-   if (!ie->file && !ie->f) return;
-   if ((evas_cache_async_frozen_get() == 0) &&
-       (ie->references > 0)) return;
-
    ie->flags.loaded = 0;
 
    if ((im->cs.data) && (im->image.data))
@@ -424,6 +385,82 @@ evas_common_rgba_image_unload(Image_Entry *ie)
 #endif   
 }
 
+static Eina_List *pending_unloads = NULL;
+
+EAPI void
+evas_common_rgba_pending_unloads_cleanup(void)
+{
+   Image_Entry *ie;
+
+   EINA_LIST_FREE(pending_unloads, ie)
+     {
+        if ((ie->need_unload) && (!ie->preload))
+          evas_common_rgba_image_unload_real(ie);
+     }
+}
+
+EAPI void
+evas_common_rgba_pending_unloads_remove(Image_Entry *ie)
+{
+   if (!ie->preload) return;
+   ie->preload = 0;
+   pending_unloads = eina_list_remove(pending_unloads, ie);
+}
+
+EAPI void
+evas_common_rgba_image_free(Image_Entry *ie)
+{
+   if (ie->references > 0) return;
+   evas_common_rgba_pending_unloads_remove(ie);
+   _evas_common_rgba_image_surface_delete(ie);
+   _evas_common_rgba_image_delete(ie);
+}
+
+#ifdef SURFDBG
+static Eina_List *surfs = NULL;
+
+static void
+surf_debug(void)
+{
+   Eina_List *l;
+   Image_Entry *ie;
+   RGBA_Image *im;
+   int i = 0;
+   
+   printf("----SURFS----\n");
+   EINA_LIST_FOREACH(surfs, l, ie)
+     {
+        im = ie;
+        printf("%i - %p - %ix%i  [%s][%s]\n", 
+               i, im->image.data, ie->allocated.w, ie->allocated.h,
+               ie->file, ie->key
+              );
+        i++;
+     }
+}
+#endif
+
+EAPI void
+evas_common_rgba_image_unload(Image_Entry *ie)
+{
+   RGBA_Image   *im = (RGBA_Image *) ie;
+
+   if (!ie->flags.loaded) return;
+   if ((!ie->info.module) && (!ie->data1)) return;
+   if (!ie->file && !ie->f) return;
+   if ((evas_cache_async_frozen_get() == 0) &&
+       (ie->references > 0))
+     {
+        if (!ie->need_unload)
+          {
+             pending_unloads = eina_list_append(pending_unloads, ie);
+             ie->need_unload = 1;
+          }
+        return;
+     }
+   evas_common_rgba_image_unload_real(ie);
+}
+
 void
 _evas_common_rgba_image_post_surface(Image_Entry *ie)
 {
diff --git a/src/lib/evas/include/evas_common_private.h 
b/src/lib/evas/include/evas_common_private.h
index 17a08bd..934daa8 100644
--- a/src/lib/evas/include/evas_common_private.h
+++ b/src/lib/evas/include/evas_common_private.h
@@ -638,6 +638,8 @@ struct _Image_Entry
 
    unsigned char          scale;
 
+   unsigned char          need_unload : 1;
+
    struct
      {
         unsigned int w;

-- 


Reply via email to