vg_json: Set multiple mask from json 08/203808/2
authorJunsuChoi <jsuya.choi@samsung.com>
Thu, 18 Apr 2019 01:22:34 +0000 (10:22 +0900)
committerjunsu choi <jsuya.choi@samsung.com>
Thu, 18 Apr 2019 01:49:07 +0000 (01:49 +0000)
Summary:
This patch supports multiple masks for multiple attributes on a layer.
Make main_mask_layer and make each mask EFL_CANVAS_VG_CONTAINER_CLASS and connect them.
main_mask_layer is made for masks
The masks are composited into main_mask_layer in order.
main_mask_layer exists for the intersect option in last order
This can be optimized later, and is created and used temporarily in this patch.

Test Plan:
If there are three masks, they can be created as below.
mask_set(clayer, main_mask);
mask_set(main_mask, mask_1);
mask_set(mask_1, mask_2);
mask_set(mask_2, mask_3);

Reviewers: Hermet

Reviewed By: Hermet

Subscribers: cedric, kimcinoo, #reviewers, smohanty, #committers

Tags: #efl

Differential Revision: https://phab.enlightenment.org/D8507

Change-Id: I5a75640308a69e8e7e50800ff2444d6078c4fe4d

src/static_libs/vg_common/vg_common_json.c

index cabeade..764db87 100644 (file)
@@ -9,10 +9,25 @@
 
 #include <rlottie_capi.h>
 
+//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.
+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 char*
 _get_key_val(void *key)
 {
-   static char buf[20];
+   static char buf[30];
    snprintf(buf, sizeof(buf), "%ld", (size_t) key);
    return buf;
 }
@@ -193,65 +208,56 @@ _construct_drawable_nodes(Efl_Canvas_Vg_Container *parent, const LOTLayerNode *l
 }
 
 static void
-_construct_mask_nodes(Efl_Canvas_Vg_Container *parent, const LOTLayerNode *layer, int depth EINA_UNUSED)
+_construct_mask_nodes(Efl_Canvas_Vg_Container *parent, LOTMask *mask, int depth EINA_UNUSED)
 {
-   if (!parent) return;
+   const float *data = mask->mPath.ptPtr;
+   if (!data) return;
 
-   for (unsigned int i = 0; i < layer->mMaskList.size; i++)
+   char *key = _get_key_val(mask);
+   Efl_Canvas_Vg_Shape *shape = efl_key_data_get(parent, key);
+   if (!shape)
      {
-        LOTMask *mask = &layer->mMaskList.ptr[i];
-        if (!mask) continue;
-
-        const float *data = mask->mPath.ptPtr;
-        if (!data) continue;
-
-        char *key = _get_key_val(mask);
-        Efl_Canvas_Vg_Shape *shape = efl_key_data_get(parent, key);
-        if (!shape)
-          {
-             shape = efl_add(EFL_CANVAS_VG_SHAPE_CLASS, parent);
-             efl_key_data_set(parent, key, shape);
-          }
-        else
-          efl_gfx_path_reset(shape);
+        shape = efl_add(EFL_CANVAS_VG_SHAPE_CLASS, parent);
+        efl_key_data_set(parent, key, shape);
+     }
+   else
+     efl_gfx_path_reset(shape);
 
-        efl_gfx_entity_visible_set(shape, EINA_TRUE);
+   efl_gfx_entity_visible_set(shape, EINA_TRUE);
 
-        efl_gfx_path_reserve(shape, mask->mPath.elmCount, mask->mPath.ptCount);
+   efl_gfx_path_reserve(shape, mask->mPath.elmCount, mask->mPath.ptCount);
 
-        for (int i = 0; i < mask->mPath.elmCount; i++)
+   for (int i = 0; i < mask->mPath.elmCount; i++)
+     {
+        switch (mask->mPath.elmPtr[i])
           {
-             switch (mask->mPath.elmPtr[i])
-               {
-                case 0:
-                   efl_gfx_path_append_move_to(shape, data[0], data[1]);
-                   data += 2;
-                   break;
-                case 1:
-                   efl_gfx_path_append_line_to(shape, data[0], data[1]);
-                   data += 2;
-                   break;
-                case 2:
-                   efl_gfx_path_append_cubic_to(shape, data[0], data[1], data[2], data[3], data[4], data[5]);
-                   data += 6;
-                   break;
-                case 3:
-                   efl_gfx_path_append_close(shape);
-                   break;
-                default:
-                   ERR("No reserved path type = %d", mask->mPath.elmPtr[i]);
-                   break;
-               }
+           case 0:
+              efl_gfx_path_append_move_to(shape, data[0], data[1]);
+              data += 2;
+              break;
+           case 1:
+              efl_gfx_path_append_line_to(shape, data[0], data[1]);
+              data += 2;
+              break;
+           case 2:
+              efl_gfx_path_append_cubic_to(shape, data[0], data[1], data[2], data[3], data[4], data[5]);
+              data += 6;
+              break;
+           case 3:
+              efl_gfx_path_append_close(shape);
+              break;
+           default:
+              ERR("No reserved path type = %d", mask->mPath.elmPtr[i]);
+              break;
           }
-
-        //Temporary solid type setting.
-        float pa = ((float)mask->mAlpha) / 255;
-        int r = (int)(((float) 255) * pa);
-        int g = (int)(((float) 255) * pa);
-        int b = (int)(((float) 255) * pa);
-        int a = (int)(((float) 255) * pa);
-        efl_gfx_color_set(shape, r, g, b, a);
      }
+   //White color and alpha setting
+   float pa = ((float)mask->mAlpha) / 255;
+   int r = (int) (255.0f * pa);
+   int g = (int) (255.0f * pa);
+   int b = (int) (255.0f * pa);
+   int a = mask->mAlpha;
+   efl_gfx_color_set(shape, r, g, b, a);
 }
 
 static void
@@ -288,6 +294,62 @@ _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)
+          {
+             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;
+               }
+          }
+
         if (matte_mode != 0)
            efl_canvas_vg_node_mask_set(ptree, ctree, matte_mode);
 
@@ -301,10 +363,10 @@ _update_vg_tree(Efl_Canvas_Vg_Container *root, const LOTLayerNode *layer, int de
               matte_mode = 0;
               break;
            case MatteAlpha:
-              matte_mode = 1;
+              matte_mode = EFL_CANVAS_VG_NODE_BLEND_TYPE_ALPHA;
               break;
            case MatteAlphaInv:
-              matte_mode = 2;
+              matte_mode = EFL_CANVAS_VG_NODE_BLEND_TYPE_ALPHA_INV;
               break;
            case MatteLuma:
               matte_mode = 0;
@@ -319,43 +381,6 @@ _update_vg_tree(Efl_Canvas_Vg_Container *root, const LOTLayerNode *layer, int de
               break;
           }
 
-        //This layer has a mask
-        if (clayer->mMaskList.size > 0)
-          {
-             key = _get_key_val(clayer->mMaskList.ptr);
-             Efl_Canvas_Vg_Container *mtree = efl_key_data_get(ctree, key);
-             if (!mtree)
-               {
-                  mtree = efl_add(EFL_CANVAS_VG_CONTAINER_CLASS, ctree);
-                  efl_key_data_set(ctree, key, mtree);
-               }
-             _construct_mask_nodes(mtree, clayer, depth);
-
-             int mask_mode = 0;
-
-             //Remap Mask Mode
-             switch (clayer->mMaskList.ptr->mMode)
-               {
-                case MaskAdd:
-                   mask_mode = 1;
-                   break;
-                case MaskSubstract:
-                   mask_mode = 2;
-                   break;
-                case MaskIntersect:
-                   ERR("TODO: MaskIntersect");
-                   mask_mode = 3;
-                   break;
-                case MaskDifference:
-                   ERR("TODO: MaskDifference");
-                   mask_mode = 0;
-                   break;
-                default:
-                   mask_mode = 0;
-                   break;
-               }
-             efl_canvas_vg_node_mask_set(ctree, mtree, mask_mode);
-          }
      }
    //Construct drawable nodes.
    if (layer->mNodeList.size > 0)