jpeg pushed a commit to branch master.

http://git.enlightenment.org/core/efl.git/commit/?id=73919ea43708b4caa980ca59c3d4a2fa8864aef2

commit 73919ea43708b4caa980ca59c3d4a2fa8864aef2
Author: Jean-Philippe Andre <jp.an...@samsung.com>
Date:   Thu Nov 13 10:47:29 2014 +0900

    Evas masking: Implement mask support in evas_render
    
    This implements supports for masking inside evas_render, which
    means:
    - Render the mask itself into a surface (ALPHA if possible)
    - Pass this mask surface to the draw context
    - Apply mask recursively in case a masked object is contained
      by another masked object.
    
    @feature
---
 src/lib/evas/canvas/evas_render.c  | 343 +++++++++++++++++++++++++++++++++++--
 src/lib/evas/include/evas_inline.x |  39 ++++-
 2 files changed, 362 insertions(+), 20 deletions(-)

diff --git a/src/lib/evas/canvas/evas_render.c 
b/src/lib/evas/canvas/evas_render.c
index 4a340ee..896a330 100644
--- a/src/lib/evas/canvas/evas_render.c
+++ b/src/lib/evas/canvas/evas_render.c
@@ -255,6 +255,7 @@ _evas_render_cur_clip_cache_del(Evas_Public_Data *e, 
Evas_Object_Protected_Data
                                            y + e->framespace.y, w, h);
 }
 
+/* sets the redraw flag for all the proxies depending on this obj as a source 
*/
 static void
 _evas_proxy_redraw_set(Evas_Public_Data *e, Evas_Object_Protected_Data *obj,
                        Eina_Bool render)
@@ -293,6 +294,59 @@ _evas_proxy_redraw_set(Evas_Public_Data *e, 
Evas_Object_Protected_Data *obj,
      }
 }
 
+/* sets the mask redraw flag for all the objects clipped by this mask */
+static void
+_evas_mask_redraw_set(Evas_Public_Data *e EINA_UNUSED,
+                      Evas_Object_Protected_Data *obj)
+{
+   Evas_Object_Protected_Data *clippee;
+   Eina_List *l;
+
+   if (!(obj->mask->redraw &&
+         obj->mask->x == obj->cur->geometry.x &&
+         obj->mask->y == obj->cur->geometry.y &&
+         obj->mask->w == obj->cur->geometry.w &&
+         obj->mask->h == obj->cur->geometry.h))
+     {
+        EINA_COW_WRITE_BEGIN(evas_object_mask_cow, obj->mask,
+                             Evas_Object_Mask_Data, mask)
+          mask->redraw = EINA_TRUE;
+          mask->x = obj->cur->geometry.x;
+          mask->y = obj->cur->geometry.y;
+          mask->w = obj->cur->geometry.w;
+          mask->h = obj->cur->geometry.h;
+        EINA_COW_WRITE_END(evas_object_mask_cow, obj->mask, mask);
+     }
+
+   if (!obj->cur->cache.clip.dirty)
+     {
+        EINA_COW_STATE_WRITE_BEGIN(obj, state_write, cur)
+          state_write->cache.clip.dirty = EINA_TRUE;
+        EINA_COW_STATE_WRITE_END(obj, state_write, cur);
+     }
+
+   EINA_LIST_FOREACH(obj->clip.clipees, l, clippee)
+     {
+        evas_object_clip_recalc(clippee);
+     }
+}
+
+static inline Eina_Bool
+_evas_render_object_changed_get(Evas_Object_Protected_Data *obj)
+{
+   if (obj->smart.smart)
+     return evas_object_smart_changed_get(obj->object);
+   else
+     return obj->changed;
+}
+
+static inline Eina_Bool
+_evas_render_object_is_mask(Evas_Object_Protected_Data *obj)
+{
+   if (!obj) return EINA_FALSE;
+   return (obj->mask->is_mask && obj->clip.clipees);
+}
+
 static void
 _evas_render_phase1_direct(Evas_Public_Data *e,
                            Eina_Array *active_objects,
@@ -302,7 +356,6 @@ _evas_render_phase1_direct(Evas_Public_Data *e,
 {
    unsigned int i;
    Evas_Object *eo_obj;
-   Eina_Bool changed;
 
    RD("  [--- PHASE 1 DIRECT\n");
    for (i = 0; i < active_objects->count; i++)
@@ -311,13 +364,19 @@ _evas_render_phase1_direct(Evas_Public_Data *e,
            eina_array_data_get(active_objects, i);
 
         if (obj->changed) evas_object_clip_recalc(obj);
-        if (!obj->proxy->proxies && !obj->proxy->proxy_textures) continue;
-
-        if (obj->smart.smart)
-          changed = evas_object_smart_changed_get(obj->object);
-        else changed = obj->changed;
 
-        if (changed) _evas_proxy_redraw_set(e, obj, EINA_FALSE);
+        if (obj->proxy->proxies || obj->proxy->proxy_textures)
+          {
+             /* is proxy source */
+             if (_evas_render_object_changed_get(obj))
+               _evas_proxy_redraw_set(e, obj, EINA_FALSE);
+          }
+        if (_evas_render_object_is_mask(obj))
+          {
+             /* is image clipper */
+             if (_evas_render_object_changed_get(obj))
+               _evas_mask_redraw_set(e, obj);
+          }
      }
    for (i = 0; i < render_objects->count; i++)
      {
@@ -336,11 +395,14 @@ _evas_render_phase1_direct(Evas_Public_Data *e,
           {
              evas_object_clip_recalc(obj);
              obj->func->render_pre(eo_obj, obj, obj->private_data);
-             if (obj->proxy->redraw)
+
+             if (obj->proxy->redraw || obj->mask->redraw)
                _evas_render_prev_cur_clip_cache_add(e, obj);
-             if (obj->proxy->proxies || obj->proxy->proxy_textures)
+
+             if (!obj->smart.smart || evas_object_smart_changed_get(eo_obj))
                {
-                  if (!obj->smart.smart || 
evas_object_smart_changed_get(eo_obj))
+                  /* proxy sources */
+                  if (obj->proxy->proxies || obj->proxy->proxy_textures)
                     {
                        EINA_COW_WRITE_BEGIN(evas_object_proxy_cow, obj->proxy,
                                             Evas_Object_Proxy_Data, 
proxy_write)
@@ -349,6 +411,10 @@ _evas_render_phase1_direct(Evas_Public_Data *e,
                                           proxy_write);
                        _evas_proxy_redraw_set(e, obj, EINA_TRUE);
                     }
+
+                  /* clipper objects (image masks) */
+                  if (_evas_render_object_is_mask(obj))
+                    _evas_mask_redraw_set(e, obj);
                }
 
              RD("      pre-render-done smart:%p|%p  [%p, %i] | [%p, %i] 
has_map:%i had_map:%i\n",
@@ -547,6 +613,7 @@ _evas_render_phase1_object_process(Evas_Public_Data *e, 
Evas_Object *eo_obj,
           }
         else
           {
+             /* non smart object */
              if ((!obj->clip.clipees) && _evas_render_is_relevant(eo_obj))
                {
                   if (is_active)
@@ -573,6 +640,20 @@ _evas_render_phase1_object_process(Evas_Public_Data *e, 
Evas_Object *eo_obj,
                        RD("      skip - not smart, not active or clippees or 
not relevant\n");
                     }
                }
+             else if (is_active && _evas_render_object_is_mask(obj) &&
+                      (evas_object_is_visible(eo_obj, obj) || 
evas_object_was_visible(eo_obj, obj)))
+               {
+                  if (obj->restack)
+                    OBJ_ARRAY_PUSH(restack_objects, obj);
+                  else
+                    {
+                       OBJ_ARRAY_PUSH(render_objects, obj);
+                       obj->render_pre = EINA_TRUE;
+                    }
+
+                  RDI(level);
+                  RD("      relevant + active: clipper image\n");
+               }
              else
                {
                   RDI(level);
@@ -582,6 +663,7 @@ _evas_render_phase1_object_process(Evas_Public_Data *e, 
Evas_Object *eo_obj,
      }
    else
      {
+        /* not changed */
         RD("      not changed... [%i] -> (%i %i %p %i) [%i]\n",
            evas_object_is_visible(eo_obj, obj),
            obj->cur->visible, obj->cur->cache.clip.visible, obj->smart.smart,
@@ -615,6 +697,7 @@ _evas_render_phase1_object_process(Evas_Public_Data *e, 
Evas_Object *eo_obj,
                }
              else
                {
+                  /* not smart */
                   if (evas_object_is_opaque(eo_obj, obj) &&
                       evas_object_is_visible(eo_obj, obj))
                     {
@@ -637,6 +720,14 @@ _evas_render_phase1_object_process(Evas_Public_Data *e, 
Evas_Object *eo_obj,
                     }
                }
           }
+        else if (is_active && _evas_render_object_is_mask(obj) &&
+                 evas_object_is_visible(eo_obj, obj))
+          {
+             RDI(level);
+             RD("      visible clipper image\n");
+             OBJ_ARRAY_PUSH(render_objects, obj);
+             obj->render_pre = EINA_TRUE;
+          }
  /*       else if (obj->smart.smart)
           {
              RDI(level);
@@ -1139,7 +1230,11 @@ evas_render_mapped(Evas_Public_Data *e, Evas_Object 
*eo_obj,
 
    if (mapped)
      {
-        if (proxy_src_clip)
+        if (_evas_render_object_is_mask(obj))
+          {
+             // don't return;
+          }
+        else if (proxy_src_clip)
           {
              if ((!evas_object_is_visible(eo_obj, obj)) || (obj->clip.clipees)
                  || (obj->cur->have_clipees))
@@ -1395,6 +1490,7 @@ evas_render_mapped(Evas_Public_Data *e, Evas_Object 
*eo_obj,
                   obj->cur->bounding_box.x, obj->cur->bounding_box.x,
                   obj->cur->bounding_box.w, obj->cur->bounding_box.h);
 #endif
+
         if (mapped)
           {
              RDI(level);
@@ -1431,11 +1527,31 @@ evas_render_mapped(Evas_Public_Data *e, Evas_Object 
*eo_obj,
 
                   if (obj->cur->clipper)
                     {
-                       if (_evas_render_has_map(eo_obj, obj))
+                       if (_evas_render_has_map(eo_obj, obj) ||
+                           _evas_render_object_is_mask(obj->cur->clipper))
                          evas_object_clip_recalc(obj);
                        _evas_render_mapped_context_clip_set(e, eo_obj, obj, 
ctx,
                                                             proxy_render_data,
-                                                           off_x, off_y);
+                                                            off_x, off_y);
+
+                       /* Clipper masks */
+                       if (_evas_render_object_is_mask(obj->cur->clipper))
+                         {
+                            // This path can be hit when we're multiplying 
masks on top of each other...
+                            Evas_Object_Protected_Data *mask =
+                                  (Evas_Object_Protected_Data *) 
obj->cur->clipper;
+                            if (mask->mask->redraw || !mask->mask->surface)
+                              evas_render_mask_subrender(obj->layer->evas, 
mask, NULL);
+
+                            if (mask->mask->surface)
+                              {
+                                 e->engine.func->context_clip_image_set
+                                       (e->engine.data.output, ctx,
+                                        mask->mask->surface,
+                                        mask->mask->x + off_x,
+                                        mask->mask->y + off_y);
+                              }
+                         }
                     }
                   obj->func->render(eo_obj, obj, obj->private_data,
                                    e->engine.data.output, ctx,
@@ -1448,19 +1564,21 @@ evas_render_mapped(Evas_Public_Data *e, Evas_Object 
*eo_obj,
           {
              if (obj->cur->clipper)
                {
+                  Evas_Object_Protected_Data *clipper = obj->cur->clipper;
                   int x, y, w, h;
 
-                  if (_evas_render_has_map(eo_obj, obj))
+                  if (_evas_render_has_map(eo_obj, obj) ||
+                      _evas_render_object_is_mask(obj->cur->clipper))
                     evas_object_clip_recalc(obj);
                   x = obj->cur->cache.clip.x;
                   y = obj->cur->cache.clip.y;
                   w = obj->cur->cache.clip.w;
                   h = obj->cur->cache.clip.h;
                   RECTS_CLIP_TO_RECT(x, y, w, h,
-                                     obj->cur->clipper->cur->cache.clip.x,
-                                     obj->cur->clipper->cur->cache.clip.y,
-                                     obj->cur->clipper->cur->cache.clip.w,
-                                     obj->cur->clipper->cur->cache.clip.h);
+                                     clipper->cur->cache.clip.x,
+                                     clipper->cur->cache.clip.y,
+                                     clipper->cur->cache.clip.w,
+                                     clipper->cur->cache.clip.h);
                   e->engine.func->context_clip_set(e->engine.data.output,
                                                    context,
                                                    x + off_x, y + off_y, w, h);
@@ -1558,6 +1676,161 @@ evas_render_proxy_subrender(Evas *eo_e, Evas_Object 
*eo_source, Evas_Object *eo_
    EINA_COW_WRITE_END(evas_object_proxy_cow, source->proxy, proxy_write);
 }
 
+/* @internal
+ * Synchronously render a mask image (or smart object) into a surface.
+ * In SW the target surface will be ALPHA only (GRY8), after conversion.
+ * In GL the target surface will be RGBA for now. TODO: Find out how to
+ *   render GL to alpha, if that's possible.
+ */
+void
+evas_render_mask_subrender(Evas_Public_Data *evas,
+                           Evas_Object_Protected_Data *mask,
+                           Evas_Object_Protected_Data *prev_mask)
+{
+   int x, y, w, h, r, g, b, a;
+   void *ctx;
+
+   if (!mask) return;
+   if (!mask->mask->redraw && mask->mask->surface)
+     {
+        DBG("Requested mask redraw but the redraw flag is off.");
+        return;
+     }
+
+   x = mask->cur->geometry.x;
+   y = mask->cur->geometry.y;
+   w = mask->cur->geometry.w;
+   h = mask->cur->geometry.h;
+
+   r = mask->cur->color.r;
+   g = mask->cur->color.g;
+   b = mask->cur->color.b;
+   a = mask->cur->color.a;
+   if ((r != 255) || (g != 255) || (b != 255) || (a != 255))
+     {
+        EINA_COW_STATE_WRITE_BEGIN(mask, state_write, cur)
+          {
+             state_write->color.r = 255;
+             state_write->color.g = 255;
+             state_write->color.b = 255;
+             state_write->color.a = 255;
+        }
+        EINA_COW_STATE_WRITE_END(mask, state_write, cur);
+     }
+
+   if (prev_mask == mask)
+     prev_mask = NULL;
+
+   if (prev_mask)
+     {
+        if (!prev_mask->mask->is_mask)
+          {
+             ERR("Passed invalid mask that is not a mask");
+             prev_mask = NULL;
+          }
+        else if (!prev_mask->mask->surface)
+          {
+             // FIXME?
+             WRN("Mask render order may be invalid");
+             evas_render_mask_subrender(evas, prev_mask, NULL);
+          }
+     }
+
+   EINA_COW_WRITE_BEGIN(evas_object_mask_cow, mask->mask, 
Evas_Object_Mask_Data, mdata)
+     mdata->redraw = EINA_FALSE;
+
+     /* delete render surface if changed or if already alpha
+      * (we don't know how to render objects to alpha) */
+     if (mdata->surface && ((w != mdata->w) || (h != mdata->h) || 
mdata->is_alpha))
+       {
+          ENFN->image_map_surface_free(ENDT, mdata->surface);
+          mdata->surface = NULL;
+       }
+
+     /* create new RGBA render surface if needed */
+     if (!mdata->surface)
+       {
+          mdata->surface = ENFN->image_map_surface_new(ENDT, w, h, EINA_TRUE);
+          if (!mdata->surface) goto end;
+          mdata->w = w;
+          mdata->h = h;
+       }
+
+     mdata->x = x;
+     mdata->y = y;
+     mdata->is_alpha = EINA_FALSE;
+
+     /* Clear surface with transparency */
+     ctx = ENFN->context_new(ENDT);
+     ENFN->context_color_set(ENDT, ctx, 0, 0, 0, 0);
+     ENFN->context_render_op_set(ENDT, ctx, EVAS_RENDER_COPY);
+     ENFN->rectangle_draw(ENDT, ctx, mdata->surface, 0, 0, w, h, EINA_FALSE);
+     ENFN->context_free(ENDT, ctx);
+
+     /* Render mask to RGBA surface */
+     ctx = ENFN->context_new(ENDT);
+     if (prev_mask)
+       {
+          ENFN->context_clip_image_set(ENDT, ctx,
+                                       prev_mask->mask->surface,
+                                       prev_mask->mask->x - x,
+                                       prev_mask->mask->y - y);
+       }
+     evas_render_mapped(evas, mask->object, mask, ctx, mdata->surface,
+                        -x, -y, 1, 0, 0, evas->output.w, evas->output.h,
+                        NULL, 1, EINA_TRUE, EINA_FALSE);
+     ENFN->context_free(ENDT, ctx);
+
+     /* BEGIN HACK */
+
+     /* Now we want to convert this RGBA surface to Alpha.
+      * NOTE: So, this is not going to work with the GL engine but only with
+      *       the SW engine. Here's the detection hack:
+      * FIXME: If you know of a way to support rendering to GL_ALPHA in GL,
+      *        then we should render directly to an ALPHA surface. A priori,
+      *        GLES FBO does not support this.
+      */
+     if (!ENFN->gl_surface_read_pixels)
+       {
+          RGBA_Image *alpha_surface;
+          DATA32 *rgba;
+          DATA8* alpha;
+
+          alpha_surface = ENFN->image_new_from_copied_data
+                (ENDT, w, h, NULL, EINA_TRUE, EVAS_COLORSPACE_GRY8);
+          if (!alpha_surface) goto end;
+
+          /* Copy alpha channel */
+          rgba = ((RGBA_Image *) mdata->surface)->image.data;
+          alpha = alpha_surface->image.data8;
+          for (y = h; y; --y)
+            for (x = w; x; --x, alpha++, rgba++)
+              *alpha = (DATA8) A_VAL(rgba);
+
+          /* Now we can drop the original surface */
+          ENFN->image_map_surface_free(ENDT, mdata->surface);
+          mdata->surface = alpha_surface;
+          mdata->is_alpha = EINA_TRUE;
+       }
+
+     /* END OF HACK */
+
+end:
+   EINA_COW_WRITE_END(evas_object_mask_cow, mask->mask, mdata);
+
+   if ((r != 255) || (g != 255) || (b != 255) || (a != 255))
+     {
+        EINA_COW_STATE_WRITE_BEGIN(mask, state_write, cur)
+          {
+             state_write->color.r = r;
+             state_write->color.g = g;
+             state_write->color.b = b;
+             state_write->color.a = a;
+          }
+        EINA_COW_STATE_WRITE_END(mask, state_write, cur);
+     }
+}
+
 static void
 _evas_render_cutout_add(Evas_Public_Data *e, Evas_Object_Protected_Data *obj, 
int off_x, int off_y)
 {
@@ -1878,6 +2151,7 @@ evas_render_updates_internal(Evas *eo_e,
         if (UNLIKELY((evas_object_is_opaque(eo_obj, obj) ||
                       ((obj->func->has_opaque_rect) &&
                        (obj->func->has_opaque_rect(eo_obj, obj, 
obj->private_data)))) &&
+                     (!obj->mask->is_mask) &&
                      evas_object_is_visible(eo_obj, obj) &&
                      (!obj->clip.clipees) &&
                      (obj->cur->visible) &&
@@ -1999,6 +2273,9 @@ evas_render_updates_internal(Evas *eo_e,
                        x = cx; y = cy; w = cw; h = ch;
                        if (((w > 0) && (h > 0)) || (obj->is_smart))
                          {
+                            Evas_Object_Protected_Data *prev_mask = NULL;
+                            Evas_Object_Protected_Data *mask = NULL;
+
                             if (!obj->is_smart)
                               {
                                  RECTS_CLIP_TO_RECT(x, y, w, h,
@@ -2011,6 +2288,30 @@ evas_render_updates_internal(Evas *eo_e,
                             
e->engine.func->context_clip_set(e->engine.data.output,
                                                              
e->engine.data.context,
                                                              x, y, w, h);
+
+                            /* Clipper masks */
+                            if (_evas_render_object_is_mask(obj->cur->clipper))
+                              mask = (Evas_Object_Protected_Data *) 
obj->cur->clipper; // main object clipped by this mask
+                            else if (obj->cur->cache.clip.mask)
+                              mask = (Evas_Object_Protected_Data *) 
obj->cur->cache.clip.mask; // propagated clip
+                            prev_mask = (Evas_Object_Protected_Data *) 
obj->cur->cache.clip.prev_mask;
+
+                            if (mask)
+                              {
+                                 if (mask->mask->redraw || 
!mask->mask->surface)
+                                   
evas_render_mask_subrender(obj->layer->evas, mask, prev_mask);
+
+                                 if (mask->mask->surface)
+                                   {
+                                      e->engine.func->context_clip_image_set
+                                            (e->engine.data.output,
+                                             e->engine.data.context,
+                                             mask->mask->surface,
+                                             mask->mask->x + off_x,
+                                             mask->mask->y + off_y);
+                                   }
+                              }
+
 #if 1 /* FIXME: this can slow things down... figure out optimum... coverage */
                             for (j = offset; j < e->temporary_objects.count; 
++j)
                               {
@@ -2030,6 +2331,12 @@ evas_render_updates_internal(Evas *eo_e,
                                                              do_async);
                             
e->engine.func->context_cutout_clear(e->engine.data.output,
                                                                  
e->engine.data.context);
+
+                            if (mask)
+                              {
+                                  e->engine.func->context_clip_image_unset
+                                    (e->engine.data.output, 
e->engine.data.context);
+                              }
                          }
                     }
                }
diff --git a/src/lib/evas/include/evas_inline.x 
b/src/lib/evas/include/evas_inline.x
index 756a60f..0a86e9b 100644
--- a/src/lib/evas/include/evas_inline.x
+++ b/src/lib/evas/include/evas_inline.x
@@ -1,6 +1,8 @@
 #ifndef EVAS_INLINE_H
 #define EVAS_INLINE_H
 
+#include "evas_private.h"
+
 static inline Eina_Bool
 _evas_render_has_map(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj)
 {
@@ -65,9 +67,13 @@ static inline int
 evas_object_is_opaque(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj)
 {
    if (obj->is_smart) return 0;
-   /* If a mask: Assume alpha */
+   /* If clipped: Assume alpha */
    if (obj->cur->cache.clip.a == 255)
      {
+        /* If has mask image: Always assume non opaque */
+        if ((obj->cur->clipper && obj->cur->clipper->mask->is_mask) ||
+            (obj->cur->cache.clip.mask))
+          return 0;
         if (obj->func->is_opaque)
           return obj->func->is_opaque(eo_obj, obj, obj->private_data);
         return 1;
@@ -240,6 +246,7 @@ evas_object_clip_recalc(Evas_Object_Protected_Data *obj)
    Evas_Object_Protected_Data *clipper = NULL;
    int cx, cy, cw, ch, cr, cg, cb, ca;
    int nx, ny, nw, nh, nr, ng, nb, na;
+   const Evas_Object_Protected_Data *mask = NULL, *prev_mask = NULL;
    Eina_Bool cvis, nvis;
    Evas_Object *eo_obj;
 
@@ -293,6 +300,29 @@ evas_object_clip_recalc(Evas_Object_Protected_Data *obj)
              RECTS_CLIP_TO_RECT(cx, cy, cw, ch, nx, ny, nw, nh);
           }
 
+        if (clipper->mask->is_mask)
+          {
+             // Set complex masks the object being clipped (parent)
+             mask = clipper;
+
+             // Forward any mask from the parents
+             if (EINA_LIKELY(obj->smart.parent != NULL))
+               {
+                  Evas_Object_Protected_Data *parent =
+                        eo_data_scope_get(obj->smart.parent, 
EVAS_OBJECT_CLASS);
+                  if (parent->cur->cache.clip.mask)
+                    {
+                       if (parent->cur->cache.clip.mask != mask)
+                         prev_mask = parent->cur->cache.clip.mask;
+                    }
+               }
+          }
+        else if (clipper->cur->cache.clip.mask)
+          {
+             // Pass complex masks to children
+             mask = clipper->cur->cache.clip.mask;
+          }
+
         nvis = clipper->cur->cache.clip.visible;
         nr = clipper->cur->cache.clip.r;
         ng = clipper->cur->cache.clip.g;
@@ -304,6 +334,7 @@ evas_object_clip_recalc(Evas_Object_Protected_Data *obj)
         cb = (cb * (nb + 1)) >> 8;
         ca = (ca * (na + 1)) >> 8;
      }
+
    if ((ca == 0 && obj->cur->render_op == EVAS_RENDER_BLEND) ||
        (cw <= 0) || (ch <= 0)) cvis = EINA_FALSE;
 
@@ -316,7 +347,9 @@ evas_object_clip_recalc(Evas_Object_Protected_Data *obj)
        obj->cur->cache.clip.g == cg &&
        obj->cur->cache.clip.b == cb &&
        obj->cur->cache.clip.a == ca &&
-       obj->cur->cache.clip.dirty == EINA_FALSE)
+       obj->cur->cache.clip.dirty == EINA_FALSE &&
+       obj->cur->cache.clip.mask == mask &&
+       obj->cur->cache.clip.prev_mask == prev_mask)
      return ;
 
    EINA_COW_STATE_WRITE_BEGIN(obj, state_write, cur)
@@ -331,6 +364,8 @@ evas_object_clip_recalc(Evas_Object_Protected_Data *obj)
         state_write->cache.clip.b = cb;
         state_write->cache.clip.a = ca;
         state_write->cache.clip.dirty = EINA_FALSE;
+        state_write->cache.clip.mask = mask;
+        state_write->cache.clip.prev_mask = prev_mask;
      }
    EINA_COW_STATE_WRITE_END(obj, state_write, cur);
 }

-- 


Reply via email to