evas/async_render: fix refcount handling of scaled image entries

SVN revision: 82961
This commit is contained in:
Ulisses Furquim 2013-01-17 22:14:05 +00:00
parent de6fa1ea64
commit 34cc6a1b15
7 changed files with 81 additions and 63 deletions

View File

@ -145,6 +145,7 @@ _constructor(Eo *eo_obj, void *class_data, va_list *list EINA_UNUSED)
EVAS_ARRAY_SET(e, temporary_objects);
EVAS_ARRAY_SET(e, calculate_objects);
EVAS_ARRAY_SET(e, clip_changes);
EVAS_ARRAY_SET(e, scie_unref_queue);
EVAS_ARRAY_SET(e, image_unref_queue);
EVAS_ARRAY_SET(e, glyph_unref_queue);
EVAS_ARRAY_SET(e, texts_unref_queue);
@ -253,6 +254,7 @@ _destructor(Eo *eo_e, void *_pd, va_list *list EINA_UNUSED)
eina_array_flush(&e->temporary_objects);
eina_array_flush(&e->calculate_objects);
eina_array_flush(&e->clip_changes);
eina_array_flush(&e->scie_unref_queue);
eina_array_flush(&e->image_unref_queue);
eina_array_flush(&e->glyph_unref_queue);
eina_array_flush(&e->texts_unref_queue);

View File

@ -3222,8 +3222,6 @@ _draw_image(Evas_Object_Protected_Data *obj,
#endif
evas_cache_image_ref((Image_Entry *)image);
evas_common_rgba_image_scalecache_items_ref(image);
evas_unref_queue_image_put(obj->layer->evas, image);
}
}

View File

@ -1380,11 +1380,16 @@ evas_render_rendering_wait(Evas_Public_Data *evas)
while (evas->rendering) evas_async_events_process_blocking();
}
static Eina_Bool
_drop_scie_ref(const void *container EINA_UNUSED, void *data, void *fdata EINA_UNUSED)
{
evas_common_rgba_image_scalecache_item_unref(data);
return EINA_TRUE;
}
static Eina_Bool
_drop_image_cache_ref(const void *container EINA_UNUSED, void *data, void *fdata EINA_UNUSED)
{
evas_common_rgba_image_scalecache_items_unref(data);
#ifdef EVAS_CSERVE2
if (evas_cserve2_use_get())
evas_cache2_image_close((Image_Entry *)data);
@ -1974,9 +1979,12 @@ evas_render_wakeup(Evas *eo_e)
e->engine.func->output_redraws_clear(e->engine.data.output);
/* unref queues */
eina_array_foreach(&e->scie_unref_queue, _drop_scie_ref, NULL);
eina_array_clean(&e->scie_unref_queue);
evas_common_rgba_image_scalecache_prune();
eina_array_foreach(&e->image_unref_queue, _drop_image_cache_ref, NULL);
eina_array_clean(&e->image_unref_queue);
evas_common_rgba_image_scalecache_prune();
eina_array_foreach(&e->glyph_unref_queue, _drop_glyph_ref, NULL);
eina_array_clean(&e->glyph_unref_queue);
@ -1984,6 +1992,7 @@ evas_render_wakeup(Evas *eo_e)
eina_array_foreach(&e->texts_unref_queue, _drop_texts_ref, NULL);
eina_array_clean(&e->texts_unref_queue);
/* post rendering */
up_cb = e->render.updates_cb;
up_data = e->render.data;
e->render.updates_cb = NULL;
@ -2264,6 +2273,7 @@ void
evas_unref_queue_image_put(Evas_Public_Data *pd, void *image)
{
eina_array_push(&pd->image_unref_queue, image);
evas_common_rgba_image_scalecache_items_ref(image, &pd->scie_unref_queue);
}
void

View File

@ -184,8 +184,6 @@ _evas_common_rgba_image_delete(Image_Entry *ie)
{
RGBA_Image *im = (RGBA_Image *)ie;
if (ie->references > 0) return;
#ifdef BUILD_PIPE_RENDER
evas_common_pipe_free(im);
#endif
@ -225,6 +223,8 @@ _evas_common_rgba_image_delete(Image_Entry *ie)
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);
}
@ -402,8 +402,6 @@ _evas_common_rgba_image_surface_delete(Image_Entry *ie)
{
RGBA_Image *im = (RGBA_Image *) ie;
if (ie->references > 0) return;
#ifdef HAVE_PIXMAN
# ifdef PIXMAN_IMAGE
if (im->pixman.im)

View File

@ -119,25 +119,31 @@ evas_common_rgba_image_scalecache_dirty(Image_Entry *ie)
{
#ifdef SCALECACHE
RGBA_Image *im = (RGBA_Image *)ie;
LKL(im->cache.lock);
while (im->cache.list)
{
Scaleitem *sci;
sci = im->cache.list->data;
Scaleitem *sci = im->cache.list->data;
im->cache.list = eina_list_remove(im->cache.list, sci);
if (sci->im)
if ((sci->im) && (sci->im->cache_entry.references == 0))
{
// INF(" 0- %i", sci->dst_w * sci->dst_h * 4);
LKL(cache_lock);
evas_common_rgba_image_free(&sci->im->cache_entry);
sci->im = NULL;
if (!sci->forced_unload)
cache_size -= sci->dst_w * sci->dst_h * 4;
else
cache_size -= sci->size_adjust;
cache_list = eina_inlist_remove(cache_list, (Eina_Inlist *)sci);
LKU(cache_lock);
}
free(sci);
if (!sci->im)
free(sci);
}
LKU(im->cache.lock);
#endif
@ -178,43 +184,37 @@ evas_common_rgba_image_scalecache_usage_get(Image_Entry *ie)
#endif
}
/* receives original Image_Entry */
void
evas_common_rgba_image_scalecache_items_ref(Image_Entry *ie)
evas_common_rgba_image_scalecache_items_ref(Image_Entry *ie, Eina_Array *ret)
{
#ifdef SCALECACHE
RGBA_Image *im = (RGBA_Image *)ie;
Eina_List *l;
Scaleitem *sci;
LKL(im->cache.lock);
EINA_LIST_FOREACH(im->cache.list, l, sci)
{
if (sci->im)
{
Image_Entry *scie = (Image_Entry *)sci->im;
assert(scie->references >= 0);
scie->references++;
eina_array_push(ret, scie);
}
}
LKU(im->cache.lock);
#endif
}
/* receives scaled Image_Entry */
void
evas_common_rgba_image_scalecache_items_unref(Image_Entry *ie)
evas_common_rgba_image_scalecache_item_unref(Image_Entry *scie)
{
#ifdef SCALECACHE
RGBA_Image *im = (RGBA_Image *)ie;
Eina_List *l;
Scaleitem *sci;
LKL(im->cache.lock);
EINA_LIST_FOREACH(im->cache.list, l, sci)
{
if (sci->im)
{
Image_Entry *scie = (Image_Entry *)sci->im;
scie->references--;
}
}
LKU(im->cache.lock);
scie->references--;
assert(scie->references >= 0);
#endif
}
@ -274,8 +274,11 @@ _sci_find(RGBA_Image *im,
if ((sci->usage == im->cache.newest_usage) ||
(sci->usage_count == im->cache.newest_usage_count))
_sci_fix_newest(im);
if (sci->im)
{
if (sci->im->cache_entry.references > 0) goto try_alloc;
evas_common_rgba_image_free(&sci->im->cache_entry);
if (!sci->forced_unload)
cache_size -= sci->dst_w * sci->dst_h * 4;
@ -288,10 +291,11 @@ _sci_find(RGBA_Image *im,
}
else
{
try_alloc:
if (max_scale_items < 1) return NULL;
if (eina_list_count(im->cache.list) > (max_scale_items - 1))
return NULL;
sci = calloc(1, sizeof(Scaleitem));
sci->parent_im = im;
}
@ -315,44 +319,48 @@ _sci_find(RGBA_Image *im,
static void
_cache_prune(Scaleitem *notsci, Eina_Bool copies_only)
{
Scaleitem *sci;
while (cache_size > max_cache_size)
Eina_Inlist *next;
if (!cache_list) return;
next = cache_list;
while ((next) && (cache_size > max_cache_size))
{
Scaleitem *sci;
Image_Entry *scie;
if (!cache_list) break;
sci = (Scaleitem *)(cache_list);
repeat:
sci = EINA_INLIST_CONTAINER_GET(next, Scaleitem);
if (copies_only)
{
while ((sci) && (!sci->parent_im->image.data))
sci = (Scaleitem *)(((Eina_Inlist *)sci)->next);
if (!sci) return;
while (!sci->parent_im->image.data)
{
next = EINA_INLIST_GET(sci)->next;
if (!next) return;
sci = EINA_INLIST_CONTAINER_GET(next, Scaleitem);
}
}
if (sci == notsci) return;
scie = (Image_Entry *)sci->im;
if (sci->im)
{
if (scie->references > 0)
{
sci = (Scaleitem *)(((Eina_Inlist *)sci)->next);
goto repeat;
}
evas_common_rgba_image_free(&sci->im->cache_entry);
sci->im = NULL;
sci->usage = 0;
sci->usage_count = 0;
sci->flop += FLOP_ADD;
if (!sci->forced_unload)
cache_size -= sci->dst_w * sci->dst_h * 4;
else
cache_size -= sci->size_adjust;
// INF(" 2- %i", sci->dst_w * sci->dst_h * 4);
cache_list = eina_inlist_remove(cache_list, (Eina_Inlist *)sci);
memset(sci, 0, sizeof(Eina_Inlist));
}
// INF("FLUSH %i > %i", cache_size, max_cache_size);
}
next = EINA_INLIST_GET(sci)->next;
if (sci == notsci) continue;
if ((!scie) || (scie->references > 0)) continue;
evas_common_rgba_image_free(scie);
sci->im = NULL;
sci->usage = 0;
sci->usage_count = 0;
sci->flop += FLOP_ADD;
if (!sci->forced_unload)
cache_size -= sci->dst_w * sci->dst_h * 4;
else
cache_size -= sci->size_adjust;
cache_list = eina_inlist_remove(cache_list, EINA_INLIST_GET(sci));
memset(sci, 0, sizeof(Eina_Inlist));
}
}
#endif
@ -829,6 +837,7 @@ evas_common_rgba_image_scalecache_do_cbs(Image_Entry *ie, RGBA_Image *dst,
evas_cache2_image_unload_data(&im->cache_entry);
else
#endif
/* FIXME: must be the _cache version, no? */
evas_common_rgba_image_unload(&im->cache_entry);
}
}

View File

@ -1267,8 +1267,8 @@ typedef enum _Evas_Render_Mode
/****/
void evas_common_rgba_image_scalecache_items_ref(Image_Entry *ie);
void evas_common_rgba_image_scalecache_items_unref(Image_Entry *ie);
void evas_common_rgba_image_scalecache_items_ref(Image_Entry *ie, Eina_Array *ret);
void evas_common_rgba_image_scalecache_item_unref(Image_Entry *ie);
/*****************************************************************************/

View File

@ -387,6 +387,7 @@ struct _Evas_Public_Data
Eina_Array temporary_objects;
Eina_Array calculate_objects;
Eina_Array clip_changes;
Eina_Array scie_unref_queue;
Eina_Array image_unref_queue;
Eina_Array glyph_unref_queue;
Eina_Array texts_unref_queue;