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
This commit is contained in:
Carsten Haitzler 2015-07-07 21:29:31 +09:00
parent 9183ba9546
commit ec6ddf59e2
5 changed files with 109 additions and 41 deletions

View File

@ -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;

View File

@ -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

View File

@ -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);

View File

@ -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)
{

View File

@ -638,6 +638,8 @@ struct _Image_Entry
unsigned char scale;
unsigned char need_unload : 1;
struct
{
unsigned int w;