efl_canvas_vg_container : Support mask tree for multiple mask.
Summary: If another mask is set in the mask source, the rendering of the mask is performed in order. The mask will render one buffer in order. And depending on some types, the initial values of the buffers may be different. (alpha zero or 255). If the implementation for masking is efl_canvas_vg_node_mask_set(layer, mask1, MASKADD); efl_canvas_vg_node_mask_set(mask1, mask2, MASKSUBSTRACT); efl_canvas_vg_node_mask_set(mask3, mask4, MASKINTERSECT); Supports rendering for consecutive masks. Reviewers: Hermet, cedric Reviewed By: Hermet Subscribers: #reviewers, #committers, smohanty, kimcinoo Tags: #efl Differential Revision: https://phab.enlightenment.org/D8517
This commit is contained in:
parent
83d5ea1a42
commit
b849ad9022
|
@ -5,6 +5,23 @@
|
|||
|
||||
#define MY_CLASS EFL_CANVAS_VG_CONTAINER_CLASS
|
||||
|
||||
|
||||
//FIXME: This enum add temporarily to help understanding of additional code
|
||||
//related to masking in prepare_mask.
|
||||
//This needs to be formally declared through the eo class.
|
||||
//This is a list of blending supported via efl_canvas_vg_node_mask_set().
|
||||
typedef enum _EFL_CANVAS_VG_NODE_BLEND_TYPE
|
||||
{
|
||||
EFL_CANVAS_VG_NODE_BLEND_TYPE_NONE = 0,
|
||||
EFL_CANVAS_VG_NODE_BLEND_TYPE_ALPHA,
|
||||
EFL_CANVAS_VG_NODE_BLEND_TYPE_ALPHA_INV,
|
||||
EFL_CANVAS_VG_NODE_BLEND_TYPE_MASK_ADD,
|
||||
EFL_CANVAS_VG_NODE_BLEND_TYPE_MASK_SUBSTRACT,
|
||||
EFL_CANVAS_VG_NODE_BLEND_TYPE_MASK_INTERSECT,
|
||||
EFL_CANVAS_VG_NODE_BLEND_TYPE_MASK_DIFFERENCE
|
||||
}EFL_CANVAS_VG_NODE_BLEND_TYPE;
|
||||
//
|
||||
|
||||
static void
|
||||
_invalidate_cb(void *data EINA_UNUSED, const Efl_Event *event)
|
||||
{
|
||||
|
@ -53,6 +70,7 @@ _prepare_mask(Evas_Object_Protected_Data *obj, //vector object
|
|||
void *engine, void *output, void *context,
|
||||
Ector_Surface *surface,
|
||||
Eina_Matrix3 *ptransform,
|
||||
Eina_Matrix3 *ctransform,
|
||||
Ector_Buffer *mask,
|
||||
int mask_op)
|
||||
{
|
||||
|
@ -60,6 +78,7 @@ _prepare_mask(Evas_Object_Protected_Data *obj, //vector object
|
|||
Efl_Canvas_Vg_Node_Data *nd =
|
||||
efl_data_scope_get(mask_obj, EFL_CANVAS_VG_NODE_CLASS);
|
||||
if (nd->flags == EFL_GFX_CHANGE_FLAG_NONE) return pd->mask.buffer;
|
||||
uint32_t init_buffer = 0x0;
|
||||
|
||||
//1. Mask Size
|
||||
Eina_Rect mbound;
|
||||
|
@ -68,7 +87,9 @@ _prepare_mask(Evas_Object_Protected_Data *obj, //vector object
|
|||
mbound.w = obj->cur->geometry.w;
|
||||
mbound.h = obj->cur->geometry.h;
|
||||
|
||||
// efl_gfx_path_bounds_get(mask, &mbound);
|
||||
//FIXME: If mask typs is SUBSTRACT or INTERSECT, buffer fills in white color(Full alpha color).
|
||||
if (pd->mask.option == EFL_CANVAS_VG_NODE_BLEND_TYPE_MASK_SUBSTRACT || pd->mask.option == EFL_CANVAS_VG_NODE_BLEND_TYPE_MASK_INTERSECT)
|
||||
init_buffer = 0xFFFFFFFF;
|
||||
|
||||
//2. Reusable ector buffer?
|
||||
if (!pd->mask.buffer || (pd->mask.bound.w != mbound.w) ||
|
||||
|
@ -76,7 +97,8 @@ _prepare_mask(Evas_Object_Protected_Data *obj, //vector object
|
|||
{
|
||||
if (pd->mask.pixels) free(pd->mask.pixels);
|
||||
if (pd->mask.buffer) efl_unref(pd->mask.buffer);
|
||||
pd->mask.pixels = calloc(sizeof(uint32_t), mbound.w * mbound.h);
|
||||
pd->mask.pixels = malloc(sizeof(uint32_t) * (mbound.w * mbound.h));
|
||||
memset(pd->mask.pixels, init_buffer, sizeof(uint32_t) * (mbound.w * mbound.h));
|
||||
pd->mask.buffer = ENFN->ector_buffer_new(ENC, obj->layer->evas->evas,
|
||||
mbound.w, mbound.h,
|
||||
EFL_GFX_COLORSPACE_ARGB8888,
|
||||
|
@ -93,7 +115,7 @@ _prepare_mask(Evas_Object_Protected_Data *obj, //vector object
|
|||
else
|
||||
{
|
||||
if (pd->mask.pixels)
|
||||
memset(pd->mask.pixels, 0x0, sizeof(uint32_t) * mbound.w * mbound.h);
|
||||
memset(pd->mask.pixels, init_buffer, sizeof(uint32_t) * mbound.w * mbound.h);
|
||||
}
|
||||
|
||||
pd->mask.bound.x = mbound.x;
|
||||
|
@ -101,6 +123,22 @@ _prepare_mask(Evas_Object_Protected_Data *obj, //vector object
|
|||
|
||||
if (!pd->mask.buffer) ERR("Mask Buffer is invalid");
|
||||
|
||||
//FIXME: This code means that there is another masking container.
|
||||
if (pd->mask.option != EFL_CANVAS_VG_NODE_BLEND_TYPE_NONE)
|
||||
{
|
||||
Efl_Canvas_Vg_Container_Data *src_pd = pd;
|
||||
mask = pd->mask.buffer;
|
||||
for (Efl_VG *mask_src = pd->mask_src; mask_src; mask_src = src_pd->mask_src)
|
||||
{
|
||||
Efl_Canvas_Vg_Container_Data *target_pd = NULL;
|
||||
src_pd = efl_data_scope_get(mask_src, MY_CLASS);
|
||||
target_pd = efl_data_scope_get(eina_list_nth(src_pd->mask.target, 0), MY_CLASS);
|
||||
_evas_vg_render_pre(obj, mask_src,
|
||||
engine, output, context, surface,
|
||||
ctransform, mask, target_pd->mask.option);
|
||||
}
|
||||
}
|
||||
|
||||
//3. Prepare Drawing shapes.
|
||||
_evas_vg_render_pre(obj, mask_obj,
|
||||
engine, output, context,
|
||||
|
@ -140,12 +178,12 @@ _efl_canvas_vg_container_render_pre(Evas_Object_Protected_Data *vg_pd,
|
|||
EFL_CANVAS_VG_COMPUTE_MATRIX(ctransform, ptransform, nd);
|
||||
|
||||
//Container may have mask source.
|
||||
if (pd->mask_src)
|
||||
if (pd->mask_src && !pd->mask.target)
|
||||
{
|
||||
mask_op = pd->mask.option;
|
||||
mask = _prepare_mask(vg_pd, pd->mask_src,
|
||||
engine, output, context, surface,
|
||||
ptransform, mask, mask_op);
|
||||
mask_op = pd->mask.option;
|
||||
ptransform, ctransform, mask, mask_op);
|
||||
}
|
||||
|
||||
EINA_LIST_FOREACH(pd->children, l, child)
|
||||
|
|
Loading…
Reference in New Issue