From d8b2bce148e56809abb0a0982c29ed3f3c33e57f Mon Sep 17 00:00:00 2001 From: Ulisses Furquim Date: Wed, 16 Jan 2013 22:32:39 +0000 Subject: [PATCH] evas/async_render: fix scalecache integration Note: scalecache is really crazy stuff, we should rewrite it or get rid of it. SVN revision: 82912 --- src/lib/evas/canvas/evas_object_image.c | 4 ++ src/lib/evas/canvas/evas_render.c | 9 ++- src/lib/evas/common/evas_image.h | 1 + src/lib/evas/common/evas_image_main.c | 12 ++-- src/lib/evas/common/evas_image_private.h | 3 + src/lib/evas/common/evas_image_scalecache.c | 61 ++++++++++++++++++++- 6 files changed, 84 insertions(+), 6 deletions(-) diff --git a/src/lib/evas/canvas/evas_object_image.c b/src/lib/evas/canvas/evas_object_image.c index 136b725e71..54d57bcac5 100644 --- a/src/lib/evas/canvas/evas_object_image.c +++ b/src/lib/evas/canvas/evas_object_image.c @@ -2584,6 +2584,7 @@ void _canvas_image_cache_flush(Eo *eo_e EINA_UNUSED, void *_pd, va_list *list EINA_UNUSED) { Evas_Public_Data *e = _pd; + evas_render_rendering_wait(e); e->engine.func->image_cache_flush(e->engine.data.output); } @@ -2647,6 +2648,7 @@ _canvas_image_cache_set(Eo *eo_e EINA_UNUSED, void *_pd, va_list *list) int size = va_arg(*list, int); Evas_Public_Data *e = _pd; if (size < 0) size = 0; + evas_render_rendering_wait(e); e->engine.func->image_cache_set(e->engine.data.output, size); } @@ -3160,6 +3162,8 @@ _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); } } diff --git a/src/lib/evas/canvas/evas_render.c b/src/lib/evas/canvas/evas_render.c index 0136f736a9..09ca0dfe99 100644 --- a/src/lib/evas/canvas/evas_render.c +++ b/src/lib/evas/canvas/evas_render.c @@ -1309,6 +1309,8 @@ evas_render_rendering_wait(Evas_Public_Data *evas) 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); @@ -1893,8 +1895,11 @@ evas_render_wakeup(Evas *eo_e) /* unref queues */ 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); + eina_array_foreach(&e->texts_unref_queue, _drop_texts_ref, NULL); eina_array_clean(&e->texts_unref_queue); @@ -2111,9 +2116,11 @@ evas_render_dump(Evas *eo_e) void _canvas_render_dump(Eo *eo_e EINA_UNUSED, void *_pd, va_list *list EINA_UNUSED) { + Evas_Public_Data *e = _pd; Evas_Layer *lay; - Evas_Public_Data *e = _pd; + evas_render_rendering_wait(e); + EINA_INLIST_FOREACH(e->layers, lay) { Evas_Object_Protected_Data *obj; diff --git a/src/lib/evas/common/evas_image.h b/src/lib/evas/common/evas_image.h index 804019afc1..d9ca581818 100644 --- a/src/lib/evas/common/evas_image.h +++ b/src/lib/evas/common/evas_image.h @@ -41,6 +41,7 @@ EAPI void evas_common_rgba_image_scalecache_size_set(unsigned int size); EAPI unsigned int evas_common_rgba_image_scalecache_size_get(void); EAPI void evas_common_rgba_image_scalecache_flush(void); EAPI void evas_common_rgba_image_scalecache_dump(void); +EAPI void evas_common_rgba_image_scalecache_prune(void); EAPI void evas_common_rgba_image_scalecache_prepare(Image_Entry *ie, RGBA_Image *dst, RGBA_Draw_Context *dc, int smooth, diff --git a/src/lib/evas/common/evas_image_main.c b/src/lib/evas/common/evas_image_main.c index 0677bfae31..684e28bb7c 100644 --- a/src/lib/evas/common/evas_image_main.c +++ b/src/lib/evas/common/evas_image_main.c @@ -184,6 +184,8 @@ _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 @@ -400,14 +402,16 @@ _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 +# ifdef PIXMAN_IMAGE if (im->pixman.im) { pixman_image_unref(im->pixman.im); im->pixman.im = NULL; } -# endif +# endif #endif if (ie->file) DBG("unload: [%p] %s %s", ie, ie->file, ie->key); @@ -429,7 +433,7 @@ _evas_common_rgba_image_surface_delete(Image_Entry *ie) free(im->image.data); #ifdef SURFDBG surfs = eina_list_remove(surfs, ie); -#endif +#endif } // #ifdef EVAS_CSERVE2 // else if (ie->data1) @@ -445,7 +449,7 @@ _evas_common_rgba_image_surface_delete(Image_Entry *ie) evas_common_rgba_image_scalecache_dirty(&im->cache_entry); #ifdef SURFDBG surf_debug(); -#endif +#endif } static void diff --git a/src/lib/evas/common/evas_image_private.h b/src/lib/evas/common/evas_image_private.h index f40866cfd8..4223412743 100644 --- a/src/lib/evas/common/evas_image_private.h +++ b/src/lib/evas/common/evas_image_private.h @@ -12,4 +12,7 @@ void evas_common_rgba_image_scalecache_dirty(Image_Entry *ie); void evas_common_rgba_image_scalecache_orig_use(Image_Entry *ie); int evas_common_rgba_image_scalecache_usage_get(Image_Entry *ie); +void evas_common_rgba_image_scalecache_items_ref(Image_Entry *ie); +void evas_common_rgba_image_scalecache_items_unref(Image_Entry *ie); + #endif /* _EVAS_IMAGE_PRIVATE_H */ diff --git a/src/lib/evas/common/evas_image_scalecache.c b/src/lib/evas/common/evas_image_scalecache.c index 41c0b82fdb..475aa0244b 100644 --- a/src/lib/evas/common/evas_image_scalecache.c +++ b/src/lib/evas/common/evas_image_scalecache.c @@ -178,6 +178,46 @@ evas_common_rgba_image_scalecache_usage_get(Image_Entry *ie) #endif } +void +evas_common_rgba_image_scalecache_items_ref(Image_Entry *ie) +{ +#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); +#endif +} + +void +evas_common_rgba_image_scalecache_items_unref(Image_Entry *ie) +{ +#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); +#endif +} + #ifdef SCALECACHE static void _sci_fix_newest(RGBA_Image *im) @@ -278,8 +318,10 @@ _cache_prune(Scaleitem *notsci, Eina_Bool copies_only) Scaleitem *sci; while (cache_size > max_cache_size) { + Image_Entry *scie; if (!cache_list) break; sci = (Scaleitem *)(cache_list); +repeat: if (copies_only) { while ((sci) && (!sci->parent_im->image.data)) @@ -287,8 +329,15 @@ _cache_prune(Scaleitem *notsci, Eina_Bool copies_only) if (!sci) return; } 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; @@ -335,6 +384,16 @@ evas_common_rgba_image_scalecache_size_get(void) #endif } +EAPI void +evas_common_rgba_image_scalecache_prune(void) +{ +#ifdef SCALECACHE + LKL(cache_lock); + _cache_prune(NULL, 0); + LKU(cache_lock); +#endif +} + EAPI void evas_common_rgba_image_scalecache_dump(void) { @@ -711,7 +770,6 @@ evas_common_rgba_image_scalecache_do_cbs(Image_Entry *ie, RGBA_Image *dst, // sci->dst_w * sci->dst_h * 4, sci->flop, // sci->dst_w, sci->dst_h); cache_list = eina_inlist_append(cache_list, (Eina_Inlist *)sci); - _cache_prune(sci, 0); LKU(cache_lock); didpop = 1; } @@ -858,4 +916,5 @@ evas_common_rgba_image_scalecache_do(Image_Entry *ie, RGBA_Image *dst, dst_region_x, dst_region_y, dst_region_w, dst_region_h, evas_common_scale_rgba_in_to_out_clip_sample, evas_common_scale_rgba_in_to_out_clip_smooth); + evas_common_rgba_image_scalecache_prune(); }