diff --git a/src/lib/evas/cache/evas_cache_image.c b/src/lib/evas/cache/evas_cache_image.c index 979d299759..6220fbc345 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 dc15572c4c..e8202889c5 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 3eecfeee8a..a625bbaf3f 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 3cb2044518..eb0d50922a 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 17a08bdd20..934daa8f57 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;