From 68a6ccb8c9b00902ef4ee8a5d119d03d18a45d80 Mon Sep 17 00:00:00 2001 From: JunsuChoi Date: Fri, 26 Apr 2019 10:46:06 +0900 Subject: [PATCH] vg_common_json: Support mask with matte case. Summary: The layer can have both a mask node and a matte node. In this case, one of them may be missing because it uses one mask_set api. If there is a matte, the mask is to be child of the matte. Test Plan: .._mask_set(layer, matte); .._mask_set(layer, mask); Reviewers: Hermet, kimcinoo Reviewed By: Hermet Subscribers: cedric, #reviewers, smohanty, #committers Tags: #efl Differential Revision: https://phab.enlightenment.org/D8709 Change-Id: I2a617cbaf087ae9839befa40b94d6e40e2d859ce --- src/lib/evas/canvas/efl_canvas_vg_container.c | 8 +- src/static_libs/vg_common/vg_common_json.c | 131 +++++++++++++++----------- 2 files changed, 80 insertions(+), 59 deletions(-) diff --git a/src/lib/evas/canvas/efl_canvas_vg_container.c b/src/lib/evas/canvas/efl_canvas_vg_container.c index 7623401..1660884 100644 --- a/src/lib/evas/canvas/efl_canvas_vg_container.c +++ b/src/lib/evas/canvas/efl_canvas_vg_container.c @@ -124,7 +124,7 @@ _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) + if (pd->mask.option >= EFL_CANVAS_VG_NODE_BLEND_TYPE_MASK_ADD) { Efl_Canvas_Vg_Container_Data *src_pd = pd; mask = pd->mask.buffer; @@ -178,7 +178,11 @@ _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 && !pd->mask.target) + //FIXME : _prepare_mask() should only work in cases with matte or main mask. + // This condition is valid because the main mask use same type as matte alpha. + if (pd->mask_src && + (pd->mask.option == EFL_CANVAS_VG_NODE_BLEND_TYPE_ALPHA || + pd->mask.option == EFL_CANVAS_VG_NODE_BLEND_TYPE_ALPHA_INV)) { mask_op = pd->mask.option; mask = _prepare_mask(vg_pd, pd->mask_src, diff --git a/src/static_libs/vg_common/vg_common_json.c b/src/static_libs/vg_common/vg_common_json.c index 764db87..c97bfea 100644 --- a/src/static_libs/vg_common/vg_common_json.c +++ b/src/static_libs/vg_common/vg_common_json.c @@ -261,6 +261,64 @@ _construct_mask_nodes(Efl_Canvas_Vg_Container *parent, LOTMask *mask, int depth } static void +_construct_masks(Efl_Canvas_Vg_Container *mtarget, LOTMask *masks, unsigned int mask_cnt, int depth) +{ + char *key = NULL; + + Efl_Canvas_Vg_Container *msource = NULL; + + key = _get_key_val(mtarget); + msource = efl_key_data_get(mtarget, key); + if (!msource) + { + msource = efl_add(EFL_CANVAS_VG_CONTAINER_CLASS, mtarget); + efl_key_data_set(mtarget, key, msource); + } + + //FIXME : EFL_CANVAS_VG_NODE_BLEND_TYPE_ALPHA option is temporary + //Currently matte alpha implemtnes is same the mask intersect impletment. + //It has been implemented as a multiplication calculation. + efl_canvas_vg_node_mask_set(mtarget, msource, EFL_CANVAS_VG_NODE_BLEND_TYPE_ALPHA); + + mtarget = msource; + + //Make mask layers + for (unsigned int i = 0; i < mask_cnt; i++) + { + LOTMask *mask = &masks[i];; + key = _get_key_val(mask); + msource = efl_key_data_get(mtarget, key); + + if (!msource) + { + msource = efl_add(EFL_CANVAS_VG_CONTAINER_CLASS, mtarget); + efl_key_data_set(mtarget, key, msource); + } + _construct_mask_nodes(msource, mask, depth + 1); + + EFL_CANVAS_VG_NODE_BLEND_TYPE mask_mode; + switch (mask->mMode) + { + case MaskSubstract: + mask_mode = EFL_CANVAS_VG_NODE_BLEND_TYPE_MASK_SUBSTRACT; + break; + case MaskIntersect: + mask_mode = EFL_CANVAS_VG_NODE_BLEND_TYPE_MASK_INTERSECT; + break; + case MaskDifference: + mask_mode = EFL_CANVAS_VG_NODE_BLEND_TYPE_MASK_DIFFERENCE; + break; + case MaskAdd: + default: + mask_mode = EFL_CANVAS_VG_NODE_BLEND_TYPE_MASK_ADD; + break; + } + efl_canvas_vg_node_mask_set(mtarget, msource, mask_mode); + mtarget = msource; + } +} + +static void _update_vg_tree(Efl_Canvas_Vg_Container *root, const LOTLayerNode *layer, int depth EINA_UNUSED) { if (!layer->mVisible) @@ -274,6 +332,8 @@ _update_vg_tree(Efl_Canvas_Vg_Container *root, const LOTLayerNode *layer, int de //Note: We assume that if matte is valid, next layer must be a matte source. int matte_mode = 0; + Efl_Canvas_Vg_Container *mtarget = NULL; + LOTLayerNode *mlayer = NULL; //Is this layer a container layer? for (unsigned int i = 0; i < layer->mLayerList.size; i++) @@ -294,66 +354,19 @@ _update_vg_tree(Efl_Canvas_Vg_Container *root, const LOTLayerNode *layer, int de #endif _update_vg_tree(ctree, clayer, depth+1); - if (clayer->mMaskList.size > 0) + if (matte_mode != 0) { - Efl_Canvas_Vg_Container *mtarget = ctree; - Efl_Canvas_Vg_Container *msource = NULL; - - key = _get_key_val(clayer); - msource = efl_key_data_get(mtarget, key); - if (!msource) - { - msource = efl_add(EFL_CANVAS_VG_CONTAINER_CLASS, ctree); - efl_key_data_set(mtarget, key, msource); - } - - //FIXME : EFL_CANVAS_VG_NODE_BLEND_TYPE_ALPHA option is temporary - //Currently matte alpha implemtnes is same the mask intersect impletment. - //It has been implemented as a multiplication calculation. - efl_canvas_vg_node_mask_set(mtarget, msource, EFL_CANVAS_VG_NODE_BLEND_TYPE_ALPHA); - - mtarget = msource; - - //Make mask layers - for (unsigned int i = 0; i < clayer->mMaskList.size; i++) - { - LOTMask *mask = &clayer->mMaskList.ptr[i]; - key = _get_key_val(mask); - msource = efl_key_data_get(mtarget, key); - - if (!msource) - { - msource = efl_add(EFL_CANVAS_VG_CONTAINER_CLASS, mtarget); - efl_key_data_set(mtarget, key, msource); - } - _construct_mask_nodes(msource, mask, depth + 1); - - EFL_CANVAS_VG_NODE_BLEND_TYPE mask_mode; - switch (mask->mMode) - { - case MaskSubstract: - mask_mode = EFL_CANVAS_VG_NODE_BLEND_TYPE_MASK_SUBSTRACT; - break; - case MaskIntersect: - mask_mode = EFL_CANVAS_VG_NODE_BLEND_TYPE_MASK_INTERSECT; - break; - case MaskDifference: - mask_mode = EFL_CANVAS_VG_NODE_BLEND_TYPE_MASK_DIFFERENCE; - break; - case MaskAdd: - default: - mask_mode = EFL_CANVAS_VG_NODE_BLEND_TYPE_MASK_ADD; - break; - } - efl_canvas_vg_node_mask_set(mtarget, msource, mask_mode); - mtarget = msource; - } + efl_canvas_vg_node_mask_set(ptree, ctree, matte_mode); + mtarget = ctree; } + matte_mode = (int) clayer->mMatte; - if (matte_mode != 0) - efl_canvas_vg_node_mask_set(ptree, ctree, matte_mode); + if (clayer->mMaskList.size > 0) + { + mlayer = clayer; + if (!mtarget) mtarget = ctree; + } - matte_mode = (int) clayer->mMatte; ptree = ctree; //Remap Matte Mode @@ -380,11 +393,15 @@ _update_vg_tree(Efl_Canvas_Vg_Container *root, const LOTLayerNode *layer, int de matte_mode = 0; break; } - } + //Construct drawable nodes. if (layer->mNodeList.size > 0) _construct_drawable_nodes(root, layer, depth); + + //Construct node that have mask. + if (mlayer) + _construct_masks(mtarget, mlayer->mMaskList.ptr, mlayer->mMaskList.size, depth); } #endif -- 2.7.4