From 1c1f9b862369d20adcde2a7937a927a537316b0f Mon Sep 17 00:00:00 2001 From: Hermet Park Date: Wed, 11 Sep 2019 15:12:35 +0900 Subject: [PATCH] evas vg: optimize memory in layer blending. Same method to 321035d1e7d58fb9165b7ee55c1962d39c859caa By far, with previous memory optimization, The memory usage is reduced to half of composition buffer size. --- src/lib/evas/canvas/efl_canvas_vg_container.c | 37 +++++++--- src/lib/evas/canvas/efl_canvas_vg_object.c | 69 ++++++++----------- src/lib/evas/canvas/evas_vg_private.h | 12 +++- 3 files changed, 64 insertions(+), 54 deletions(-) diff --git a/src/lib/evas/canvas/efl_canvas_vg_container.c b/src/lib/evas/canvas/efl_canvas_vg_container.c index d53d5624c3..a78dec8fc5 100644 --- a/src/lib/evas/canvas/efl_canvas_vg_container.c +++ b/src/lib/evas/canvas/efl_canvas_vg_container.c @@ -76,15 +76,19 @@ _prepare_comp(Evas_Object_Protected_Data *obj, //vector object init_buffer = 0xFFFFFFFF; //2. Reusable ector buffer? - if (!pd->comp.buffer || (pd->comp.bound.w != mbound.w) || - (pd->comp.bound.h != mbound.h)) + if (pd->comp.buffer && + ((pd->comp.bound.w != mbound.w) || + (pd->comp.bound.h != mbound.h))) + + { + if (pd->comp.pixels) + ector_buffer_unmap(pd->comp.buffer, pd->comp.pixels, pd->comp.length); + efl_unref(pd->comp.buffer); + pd->comp.buffer = NULL; + } + + if (!pd->comp.buffer) { - if (pd->comp.buffer) - { - if (pd->comp.pixels) - ector_buffer_unmap(pd->comp.buffer, pd->comp.pixels, pd->comp.length); - efl_unref(pd->comp.buffer); - } pd->comp.buffer = ENFN->ector_buffer_new(ENC, obj->layer->evas->evas, mbound.w, mbound.h, EFL_GFX_COLORSPACE_ARGB8888, @@ -233,8 +237,7 @@ static void _efl_canvas_vg_container_efl_object_destructor(Eo *obj, Efl_Canvas_Vg_Container_Data *pd) { - if (pd->blend_pixels) free(pd->blend_pixels); - if (pd->blend_buffer) efl_unref(pd->blend_buffer); + efl_canvas_vg_container_blend_buffer_clear(obj, pd); //Destroy comp surface if (pd->comp.buffer) @@ -441,6 +444,20 @@ efl_canvas_vg_container_vg_obj_update(Efl_VG *obj, Efl_Canvas_Vg_Node_Data *nd) } } +void +efl_canvas_vg_container_blend_buffer_clear(Efl_VG *obj EINA_UNUSED, Efl_Canvas_Vg_Container_Data *cd) +{ + if (!cd->blend.buffer) return; + + if (cd->blend.pixels) + { + ector_buffer_unmap(cd->blend.buffer, cd->blend.pixels, cd->blend.length); + cd->blend.pixels = NULL; + } + if (cd->blend.buffer) efl_unref(cd->blend.buffer); + cd->blend.buffer = NULL; +} + EAPI Efl_VG* evas_vg_container_add(Efl_VG *parent) { diff --git a/src/lib/evas/canvas/efl_canvas_vg_object.c b/src/lib/evas/canvas/efl_canvas_vg_object.c index 6fc21e1de7..1f8e05189b 100644 --- a/src/lib/evas/canvas/efl_canvas_vg_object.c +++ b/src/lib/evas/canvas/efl_canvas_vg_object.c @@ -405,45 +405,40 @@ _evas_vg_render(Evas_Object_Protected_Data *obj, Efl_Canvas_Vg_Object_Data *pd, if (alpha < 255) { //Replace with a new size. - if (cd->blend_buffer) + if (cd->blend.buffer) { int w2, h2; - ector_buffer_size_get(cd->blend_buffer, &w2, &h2); - + ector_buffer_size_get(cd->blend.buffer, &w2, &h2); if (w2 != w || h2 != h) - { - if (cd->blend_pixels) - { - free(cd->blend_pixels); - cd->blend_pixels = NULL; - } - efl_unref(cd->blend_buffer); - cd->blend_buffer = NULL; - } + efl_canvas_vg_container_blend_buffer_clear(node, cd); } - // Reuse buffer - if (!cd->blend_pixels) - cd->blend_pixels = calloc(w * h, sizeof(uint32_t*)); - else - memset(cd->blend_pixels, 0, sizeof(uint32_t) * (w * h)); - - if (!cd->blend_buffer) + if (!cd->blend.buffer) { - cd->blend_buffer = ENFN->ector_buffer_new(ENC, obj->layer->evas->evas, - w, h, - EFL_GFX_COLORSPACE_ARGB8888, - ECTOR_BUFFER_FLAG_DRAWABLE | - ECTOR_BUFFER_FLAG_CPU_READABLE | - ECTOR_BUFFER_FLAG_CPU_WRITABLE); - ector_buffer_pixels_set(cd->blend_buffer, cd->blend_pixels, - w, h, 0, - EFL_GFX_COLORSPACE_ARGB8888, EINA_TRUE); + cd->blend.buffer = ENFN->ector_buffer_new(ENC, obj->layer->evas->evas, + w, h, + EFL_GFX_COLORSPACE_ARGB8888, + ECTOR_BUFFER_FLAG_DRAWABLE | + ECTOR_BUFFER_FLAG_CPU_READABLE | + ECTOR_BUFFER_FLAG_CPU_WRITABLE); + cd->blend.pixels = ector_buffer_map(cd->blend.buffer, &cd->blend.length, + (ECTOR_BUFFER_FLAG_DRAWABLE | + ECTOR_BUFFER_FLAG_CPU_READABLE | + ECTOR_BUFFER_FLAG_CPU_WRITABLE), + 0, 0, w, h, + EFL_GFX_COLORSPACE_ARGB8888, + &cd->blend.stride); + if (!cd->blend.pixels) ERR("Failed to map VG blend bufffer"); + } + else + { + if (cd->blend.pixels) + memset(cd->blend.pixels, 0, cd->blend.length); } // Buffer change - ector_buffer_pixels_set(ector, cd->blend_pixels, - w, h, 0, + ector_buffer_pixels_set(ector, cd->blend.pixels, + w, h, cd->blend.stride, EFL_GFX_COLORSPACE_ARGB8888, EINA_TRUE); ector_surface_reference_point_set(ector, 0,0); @@ -455,21 +450,13 @@ _evas_vg_render(Evas_Object_Protected_Data *obj, Efl_Canvas_Vg_Object_Data *pd, ENFN->ector_begin(engine, output, context, ector, 0, 0, EINA_FALSE, do_async); // Draw buffer to original surface.(Ector_Surface) - ector_surface_draw_image(ector, cd->blend_buffer, 0, 0, alpha); + ector_surface_draw_image(ector, cd->blend.buffer, 0, 0, alpha); } else { - if (cd->blend_pixels) - { - free(cd->blend_pixels); - cd->blend_pixels = NULL; - } - if (cd->blend_buffer) - { - efl_unref(cd->blend_buffer); - cd->blend_buffer = NULL; - } + efl_canvas_vg_container_blend_buffer_clear(node, cd); + EINA_LIST_FOREACH(cd->children, l, child) _evas_vg_render(obj, pd, engine, output, context, child, clips, w, h, ector, do_async); } diff --git a/src/lib/evas/canvas/evas_vg_private.h b/src/lib/evas/canvas/evas_vg_private.h index c87753778b..d5eb04f1cc 100644 --- a/src/lib/evas/canvas/evas_vg_private.h +++ b/src/lib/evas/canvas/evas_vg_private.h @@ -100,9 +100,14 @@ struct _Efl_Canvas_Vg_Container_Data Efl_Canvas_Vg_Node *comp_target; //Composite target Vg_Comp comp; //Composite target data - //Layer transparency feature. This buffer is only valid when the layer has transparency. - Ector_Buffer *blend_buffer; - void *blend_pixels; + /* Layer transparency feature. + This buffer is only valid when the layer has transparency. */ + struct { + Ector_Buffer *buffer; + void *pixels; + unsigned int length; //blend buffer data size + unsigned int stride; //blend buffer stride + } blend; }; struct _Efl_Canvas_Vg_Gradient_Data @@ -139,6 +144,7 @@ Eina_Size2D evas_cache_vg_entry_default_size_get(const Vg_Cache_ void efl_canvas_vg_node_vg_obj_set(Efl_VG *node, Efl_VG *vg_obj, Efl_Canvas_Vg_Object_Data *vd); void efl_canvas_vg_node_change(Efl_VG *node); void efl_canvas_vg_container_vg_obj_update(Efl_VG *obj, Efl_Canvas_Vg_Node_Data *nd); +void efl_canvas_vg_container_blend_buffer_clear(Efl_VG *obj, Efl_Canvas_Vg_Container_Data *cd); static inline void efl_canvas_vg_object_change(Efl_Canvas_Vg_Object_Data *vd)