evas vg: optimize memory in layer blending.

Same method to 321035d1e7

By far, with previous memory optimization,

The memory usage is reduced to half of composition buffer size.
This commit is contained in:
Hermet Park 2019-09-11 15:12:35 +09:00
parent 321035d1e7
commit 1c1f9b8623
3 changed files with 64 additions and 54 deletions

View File

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

View File

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

View File

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