From c94ae99c008fe387af98352f85719693e72a5340 Mon Sep 17 00:00:00 2001 From: Hermet Park Date: Thu, 8 Nov 2018 18:37:57 +0900 Subject: [PATCH] evas vg: free ector surface if they are not cached. Ector surfaces which not gonna cached should be destroyed immediately. Those surfaces was introduced for animation frames. Here patch decides which one is cacheable or not. This is a regresion bug by 7dff71295c3c99ea136955625ba0ebbfa4beee32 Change-Id: Iebde8ae0f29104b49cca1665778c404f3eba0278 --- src/lib/evas/canvas/efl_canvas_vg.c | 48 ++++++++++++++++++++++------------- src/lib/evas/canvas/evas_vg_private.h | 2 +- 2 files changed, 31 insertions(+), 19 deletions(-) diff --git a/src/lib/evas/canvas/efl_canvas_vg.c b/src/lib/evas/canvas/efl_canvas_vg.c index 4058ae0..f5e9698 100644 --- a/src/lib/evas/canvas/efl_canvas_vg.c +++ b/src/lib/evas/canvas/efl_canvas_vg.c @@ -507,7 +507,7 @@ static void * _render_to_buffer(Evas_Object_Protected_Data *obj, Efl_Canvas_Vg_Data *pd, void *engine, void *surface, Efl_VG *root, int w, int h, void *key, - void *buffer, Eina_Bool do_async) + void *buffer, Eina_Bool do_async, Eina_Bool cacheable) { Ector_Surface *ector; RGBA_Draw_Context *context; @@ -553,12 +553,8 @@ _render_to_buffer(Evas_Object_Protected_Data *obj, Efl_Canvas_Vg_Data *pd, evas_common_draw_context_free(context); //caching buffer only for first and last frames. - if (buffer_created) - { - if (pd->frame_index == 0 || - (pd->frame_index == (int) evas_cache_vg_anim_frame_count_get(pd->vg_entry) - 1)) - obj->layer->evas->engine.func->ector_surface_cache_set(engine, key, buffer); - } + if (buffer_created && cacheable) + obj->layer->evas->engine.func->ector_surface_cache_set(engine, key, buffer); return buffer; } @@ -568,11 +564,11 @@ _render_buffer_to_screen(Evas_Object_Protected_Data *obj, void *engine, void *output, void *context, void *surface, void *buffer, int x, int y, int w, int h, - Eina_Bool do_async) + Eina_Bool do_async, Eina_Bool cacheable) { Eina_Bool async_unref; - // draw the buffer as image to canvas + //Draw the buffer as image to canvas async_unref = obj->layer->evas->engine.func->image_draw(engine, output, context, surface, buffer, 0, 0, w, h, @@ -580,16 +576,22 @@ _render_buffer_to_screen(Evas_Object_Protected_Data *obj, EINA_TRUE, do_async); if (do_async && async_unref) { + //Free buffer after drawing. evas_cache_image_ref((Image_Entry *)buffer); evas_unref_queue_image_put(obj->layer->evas, buffer); } + + //TODO: Reuse buffer if size is same? + if (!cacheable) + obj->layer->evas->engine.func->ector_surface_destroy(engine, buffer); } static void _cache_vg_entry_render(Evas_Object_Protected_Data *obj, Efl_Canvas_Vg_Data *pd, void *engine, void *output, void *context, void *surface, - int x, int y, int w, int h, Eina_Bool do_async) + int x, int y, int w, int h, Eina_Bool do_async, + Eina_Bool cacheable) { Vg_Cache_Entry *vg_entry = pd->vg_entry; Efl_VG *root; @@ -609,7 +611,8 @@ _cache_vg_entry_render(Evas_Object_Protected_Data *obj, void *buffer = obj->layer->evas->engine.func->ector_surface_cache_get(engine, root); if (!buffer) - buffer = _render_to_buffer(obj, pd, engine, surface, root, w, h, root, NULL, do_async); + buffer = _render_to_buffer(obj, pd, engine, surface, root, w, h, root, NULL, + do_async, cacheable); else //cache reference was increased when we get the cache. obj->layer->evas->engine.func->ector_surface_cache_drop(engine, root); @@ -618,14 +621,15 @@ _cache_vg_entry_render(Evas_Object_Protected_Data *obj, engine, output, context, surface, buffer, x, y, w, h, - do_async); + do_async, cacheable); } static void _user_vg_entry_render(Evas_Object_Protected_Data *obj, Efl_Canvas_Vg_Data *pd, void *engine, void *output, void *context, void *surface, - int x, int y, int w, int h, Eina_Bool do_async) + int x, int y, int w, int h, Eina_Bool do_async, + Eina_Bool cacheable) { Vg_User_Entry *user_entry = pd->user_entry; @@ -650,7 +654,7 @@ _user_vg_entry_render(Evas_Object_Protected_Data *obj, w, h, user_entry, buffer, - do_async); + do_async, cacheable); } else { @@ -662,7 +666,7 @@ _user_vg_entry_render(Evas_Object_Protected_Data *obj, w, h, user_entry, buffer, - do_async); + do_async, EINA_FALSE); //cache reference was increased when we get the cache. obj->layer->evas->engine.func->ector_surface_cache_drop(engine, user_entry->root); } @@ -671,7 +675,7 @@ _user_vg_entry_render(Evas_Object_Protected_Data *obj, engine, output, context, surface, buffer, x, y, w, h, - do_async); + do_async, cacheable); } static void @@ -696,19 +700,27 @@ _efl_canvas_vg_render(Evas_Object *eo_obj EINA_UNUSED, obj->cur->anti_alias); obj->layer->evas->engine.func->context_render_op_set(engine, context, obj->cur->render_op); + + //Cache surface? + Eina_Bool cacheable = EINA_FALSE; + + if (pd->frame_index == 0 || + (pd->frame_index == (int) evas_cache_vg_anim_frame_count_get(pd->vg_entry) - 1)) + cacheable = EINA_TRUE; + if (pd->vg_entry) { _cache_vg_entry_render(obj, pd, engine, output, context, surface, obj->cur->geometry.x + x, obj->cur->geometry.y + y, - obj->cur->geometry.w, obj->cur->geometry.h, do_async); + obj->cur->geometry.w, obj->cur->geometry.h, do_async, cacheable); } if (pd->user_entry) { _user_vg_entry_render(obj, pd, engine, output, context, surface, obj->cur->geometry.x + x, obj->cur->geometry.y + y, - obj->cur->geometry.w, obj->cur->geometry.h, do_async); + obj->cur->geometry.w, obj->cur->geometry.h, do_async, cacheable); } pd->changed = EINA_FALSE; } diff --git a/src/lib/evas/canvas/evas_vg_private.h b/src/lib/evas/canvas/evas_vg_private.h index 8e60fc0..23590a9 100644 --- a/src/lib/evas/canvas/evas_vg_private.h +++ b/src/lib/evas/canvas/evas_vg_private.h @@ -43,7 +43,7 @@ struct _Efl_Canvas_Vg_Data void *engine_data; Efl_VG *root; Vg_Cache_Entry *vg_entry; - Vg_User_Entry *user_entry; // holds the user set vg tree + Vg_User_Entry *user_entry; //holds the user set vg tree Eina_Rect fill; Eina_Rect viewbox; unsigned int width, height; -- 2.7.4