Revert "Rollback to previous package. evas_1.0.0.001+svn.62695slp2+build31"
[framework/uifw/evas.git] / src / lib / canvas / evas_render.c
index 5e85214..12f5f2c 100644 (file)
@@ -2,8 +2,8 @@
 #include "evas_private.h"
 
 // debug rendering
-//#define REND_DGB 1
-//#define STDOUT_DBG 1
+/* #define REND_DGB 1 */
+/* #define STDOUT_DBG 1 */
 
 #ifdef REND_DGB
 static FILE *dbf = NULL;
@@ -15,9 +15,9 @@ rend_dbg(const char *txt)
      {
 #ifdef STDOUT_DBG
         dbf = stdout;
-#else           
+#else
         dbf = fopen("EVAS-RENDER-DEBUG.log", "w");
-#endif        
+#endif
         if (!dbf) return;
      }
    fputs(txt, dbf);
@@ -46,20 +46,6 @@ rend_dbg(const char *txt)
 static Eina_List *
 evas_render_updates_internal(Evas *e, unsigned char make_updates, unsigned char do_draw);
 
-/**
- * Add a damage rectangle.
- *
- * @param e The given canvas pointer.
- * @param x The rectangle's left position.
- * @param y The rectangle's top position.
- * @param w The rectangle's width.
- * @param h The rectangle's height.
- *
- * This is the function by which one tells evas that a part of the
- * canvas has to be repainted.
- *
- * @ingroup Evas_Canvas
- */
 EAPI void
 evas_damage_rectangle_add(Evas *e, int x, int y, int w, int h)
 {
@@ -74,23 +60,6 @@ evas_damage_rectangle_add(Evas *e, int x, int y, int w, int h)
    e->changed = 1;
 }
 
-/**
- * Add an obscured region.
- *
- * @param e The given canvas pointer.
- * @param x The rectangle's left position.
- * @param y The rectangle's top position
- * @param w The rectangle's width.
- * @param h The rectangle's height.
- *
- * This is the function by which one tells evas that a part of the
- * canvas has not to be repainted. To make this region one that have
- * to be repainted, call the function evas_obscured_clear().
- *
- * @see evas_obscured_clear().
- *
- * @ingroup Evas_Canvas
- */
 EAPI void
 evas_obscured_rectangle_add(Evas *e, int x, int y, int w, int h)
 {
@@ -104,18 +73,6 @@ evas_obscured_rectangle_add(Evas *e, int x, int y, int w, int h)
    e->obscures = eina_list_append(e->obscures, r);
 }
 
-/**
- * Remove all obscured region rectangles from the canvas.
- *
- * @param e The given canvas pointer.
- *
- * This function removes all the rectangles from the obscured list of
- * the canvas. It takes obscured areas added with
- * evas_obscured_rectangle_add() and makes it a region that have to be
- * repainted.
- *
- * @ingroup Evas_Canvas
- */
 EAPI void
 evas_obscured_clear(Evas *e)
 {
@@ -135,14 +92,14 @@ _evas_render_has_map(Evas_Object *obj)
 {
    return ((!((obj->func->can_map) && (obj->func->can_map(obj)))) &&
            ((obj->cur.map) && (obj->cur.usemap)));
-//   return ((obj->cur.map) && (obj->cur.usemap));
+   //   return ((obj->cur.map) && (obj->cur.usemap));
 }
 
 static Eina_Bool
 _evas_render_had_map(Evas_Object *obj)
 {
    return ((obj->prev.map) && (obj->prev.usemap));
-//   return ((!obj->cur.map) && (obj->prev.usemap));
+   //   return ((!obj->cur.map) && (obj->prev.usemap));
 }
 
 static Eina_Bool
@@ -185,34 +142,66 @@ _evas_render_cur_clip_cache_del(Evas *e, Evas_Object *obj)
 
 static void
 _evas_render_phase1_direct(Evas *e,
-                           Eina_Array *active_objects __UNUSED__,
+                           Eina_Array *active_objects,
                            Eina_Array *restack_objects __UNUSED__,
                            Eina_Array *delete_objects __UNUSED__,
                            Eina_Array *render_objects)
 {
    unsigned int i;
+   Eina_List *l;
+   Evas_Object *proxy;
 
    RD("  [--- PHASE 1 DIRECT\n");
+   for (i = 0; i < active_objects->count; i++)
+     {
+        Evas_Object *obj;
+
+        obj = eina_array_data_get(active_objects, i);
+        if (obj->changed)
+          {
+             /* Flag need redraw on proxy too */
+             evas_object_clip_recalc(obj);
+             if (obj->proxy.proxies)
+               {
+                  EINA_LIST_FOREACH(obj->proxy.proxies, l, proxy)
+                    proxy->proxy.redraw = 1;
+               }
+          }
+     }
    for (i = 0; i < render_objects->count; i++)
      {
-       Evas_Object *obj;
+        Evas_Object *obj;
 
-       obj = eina_array_data_get(render_objects, i);
+        obj = eina_array_data_get(render_objects, i);
         RD("    OBJ [%p] changed %i\n", obj, obj->changed);
-       if (obj->changed)
+        if (obj->changed)
           {
+             /* Flag need redraw on proxy too */
              evas_object_clip_recalc(obj);
              obj->func->render_pre(obj);
+             if (obj->proxy.proxies)
+               {
+                  obj->proxy.redraw = 1;
+                  EINA_LIST_FOREACH(obj->proxy.proxies, l, proxy)
+                    {
+                       proxy->func->render_pre(proxy);
+                       _evas_render_prev_cur_clip_cache_add(e, proxy);
+                    }
+               }
+             else if (obj->proxy.redraw)
+               {
+                  _evas_render_prev_cur_clip_cache_add(e, obj);
+               }
              if (obj->pre_render_done)
                {
                   RD("      pre-render-done smart:%p|%p  [%p, %i] | [%p, %i] has_map:%i had_map:%i\n",
-                     obj->smart.smart, 
+                     obj->smart.smart,
                      evas_object_smart_members_get_direct(obj),
                      obj->cur.map, obj->cur.usemap,
                      obj->prev.map, obj->prev.usemap,
                      _evas_render_has_map(obj),
                      _evas_render_had_map(obj));
-                  if ((obj->smart.smart) && 
+                  if ((obj->smart.smart) &&
                       (_evas_render_has_map(obj)))
                     {
                        RD("      has map + smart\n");
@@ -225,18 +214,18 @@ _evas_render_phase1_direct(Evas *e,
                   _evas_render_prev_cur_clip_cache_add(e, obj);
                }
           }
-       else
-         {
-            if (obj->smart.smart)
+        else
+          {
+             if (obj->smart.smart)
                {
-//                  obj->func->render_pre(obj);
+                  //                  obj->func->render_pre(obj);
                }
-            else if (obj->rect_del)
+             else if (obj->rect_del)
                {
                   RD("    rect del\n");
                   _evas_render_cur_clip_cache_del(e, obj);
                }
-         }
+          }
      }
    RD("  ---]\n");
 }
@@ -252,13 +241,13 @@ _evas_render_phase1_object_process(Evas *e, Evas_Object *obj,
 #ifdef REND_DGB
                                    , int level
 #endif
-                                   )
+                                  )
 {
    Eina_Bool clean_them = EINA_FALSE;
    Evas_Object *obj2;
    int is_active;
    Eina_Bool hmap;
-   
+
    obj->rect_del = 0;
    obj->render_pre = 0;
 
@@ -266,10 +255,10 @@ _evas_render_phase1_object_process(Evas *e, Evas_Object *obj,
    /* because of clip objects - delete 2 cycles later */
    if (obj->delete_me == 2)
 #else
-   if (obj->delete_me == evas_common_frameq_get_frameq_sz() + 2)
+     if (obj->delete_me == evas_common_frameq_get_frameq_sz() + 2)
 #endif
-        eina_array_push(delete_objects, obj);
-   else if (obj->delete_me != 0) obj->delete_me++;
+       eina_array_push(delete_objects, obj);
+     else if (obj->delete_me != 0) obj->delete_me++;
    /* If the object will be removed, we should not cache anything during this run. */
    if (obj->delete_me != 0) clean_them = EINA_TRUE;
 
@@ -296,13 +285,13 @@ _evas_render_phase1_object_process(Evas *e, Evas_Object *obj,
 
    if ((restack) && (!map))
      {
-       if (!obj->changed)
+        if (!obj->changed)
           {
              eina_array_push(&e->pending_objects, obj);
              obj->changed = 1;
           }
-       obj->restack = 1;
-       clean_them = EINA_TRUE;
+        obj->restack = 1;
+        clean_them = EINA_TRUE;
      }
 
    if (map)
@@ -340,7 +329,7 @@ _evas_render_phase1_object_process(Evas *e, Evas_Object *obj,
      {
         RDI(level);
         RD("      had map - restack objs\n");
-//        eina_array_push(restack_objects, obj);
+        //        eina_array_push(restack_objects, obj);
         _evas_render_prev_cur_clip_cache_add(e, obj);
         if (obj->changed)
           {
@@ -361,31 +350,31 @@ _evas_render_phase1_object_process(Evas *e, Evas_Object *obj,
    /* handle normal rendering. this object knows how to handle maps */
    if (obj->changed)
      {
-       if (obj->smart.smart)
-         {
+        if (obj->smart.smart)
+          {
              RDI(level);
              RD("      changed + smart - render ok\n");
-            eina_array_push(render_objects, obj);
-            obj->render_pre = 1;
-            EINA_INLIST_FOREACH(evas_object_smart_members_get_direct(obj), obj2)
-              {
-                 _evas_render_phase1_object_process(e, obj2,
-                                                    active_objects,
-                                                    restack_objects,
-                                                    delete_objects,
-                                                    render_objects,
-                                                    obj->restack,
+             eina_array_push(render_objects, obj);
+             obj->render_pre = 1;
+             EINA_INLIST_FOREACH(evas_object_smart_members_get_direct(obj), obj2)
+               {
+                  _evas_render_phase1_object_process(e, obj2,
+                                                     active_objects,
+                                                     restack_objects,
+                                                     delete_objects,
+                                                     render_objects,
+                                                     obj->restack,
                                                      map,
                                                      redraw_all
 #ifdef REND_DGB
                                                      , level + 1
 #endif
-                                                     );
-              }
-         }
-       else
-         {
-            if ((is_active) && (!obj->clip.clipees) &&
+                                                    );
+               }
+          }
+        else
+          {
+             if ((is_active) && (!obj->clip.clipees) &&
                  _evas_render_is_relevant(obj))
                {
                   RDI(level);
@@ -403,7 +392,7 @@ _evas_render_phase1_object_process(Evas *e, Evas_Object *obj,
                   RDI(level);
                   RD("      skip - not smart, not active or clippees or not relevant\n");
                }
-         }
+          }
      }
    else
      {
@@ -411,42 +400,42 @@ _evas_render_phase1_object_process(Evas *e, Evas_Object *obj,
            evas_object_is_visible(obj),
            obj->cur.visible, obj->cur.cache.clip.visible, obj->smart.smart, obj->cur.cache.clip.a,
            evas_object_was_visible(obj));
-       if ((!obj->clip.clipees) && (obj->delete_me == 0) &&
-           (_evas_render_can_render(obj) ||
-            (evas_object_was_visible(obj) && (!obj->prev.have_clipees))))
-         {
-            if (obj->smart.smart)
-              {
+        if ((!obj->clip.clipees) && (obj->delete_me == 0) &&
+            (_evas_render_can_render(obj) ||
+             (evas_object_was_visible(obj) && (!obj->prev.have_clipees))))
+          {
+             if (obj->smart.smart)
+               {
                   RDI(level);
                   RD("      smart + visible/was visible + not clip\n");
-                 eina_array_push(render_objects, obj);
-                 obj->render_pre = 1;
-                 EINA_INLIST_FOREACH
-                    (evas_object_smart_members_get_direct(obj), obj2)
-                   {
-                      _evas_render_phase1_object_process(e, obj2,
-                                                         active_objects,
-                                                         restack_objects,
-                                                         delete_objects,
-                                                         render_objects,
-                                                         restack, map,
-                                                          redraw_all
+                  eina_array_push(render_objects, obj);
+                  obj->render_pre = 1;
+                  EINA_INLIST_FOREACH
+                     (evas_object_smart_members_get_direct(obj), obj2)
+                       {
+                          _evas_render_phase1_object_process(e, obj2,
+                                                             active_objects,
+                                                             restack_objects,
+                                                             delete_objects,
+                                                             render_objects,
+                                                             restack, map,
+                                                             redraw_all
 #ifdef REND_DGB
-                                                          , level + 1
+                                                             , level + 1
 #endif
-                                                          );
-                   }
-              }
-            else
-              {
-                 if (evas_object_is_opaque(obj) &&
+                                                            );
+                       }
+               }
+             else
+               {
+                  if (evas_object_is_opaque(obj) &&
                       evas_object_is_visible(obj))
-                   {
+                    {
                        RDI(level);
                        RD("      opaque + visible\n");
-                      eina_array_push(render_objects, obj);
-                      obj->rect_del = 1;
-                   }
+                       eina_array_push(render_objects, obj);
+                       obj->rect_del = 1;
+                    }
                   else if (evas_object_is_visible(obj))
                     {
                        RDI(level);
@@ -459,37 +448,37 @@ _evas_render_phase1_object_process(Evas *e, Evas_Object *obj,
                        RDI(level);
                        RD("      skip\n");
                     }
-              }
-         }
-/*
-        else if (obj->smart.smart)
-          {
-             RDI(level);
-             RD("      smart + mot visible/was visible\n");
-             eina_array_push(render_objects, obj);
-             obj->render_pre = 1;
-             EINA_INLIST_FOREACH
-               (evas_object_smart_members_get_direct(obj), obj2)
-               {
-                  _evas_render_phase1_object_process(e, obj2,
-                                                     active_objects,
-                                                     restack_objects,
-                                                     delete_objects,
-                                                     render_objects,
-                                                     restack, map,
-                                                     redraw_all
-#ifdef REND_DGB
-                                                     , level + 1
-#endif
-                                                     );
                }
           }
- */
-     }
-   if (!is_active) obj->restack = 0;
-   RDI(level);
-   RD("    ---]\n");
-   return clean_them;
+        /*
+           else if (obj->smart.smart)
+           {
+           RDI(level);
+           RD("      smart + mot visible/was visible\n");
+           eina_array_push(render_objects, obj);
+           obj->render_pre = 1;
+           EINA_INLIST_FOREACH
+           (evas_object_smart_members_get_direct(obj), obj2)
+           {
+           _evas_render_phase1_object_process(e, obj2,
+           active_objects,
+           restack_objects,
+           delete_objects,
+           render_objects,
+           restack, map,
+           redraw_all
+#ifdef REND_DGB
+, level + 1
+#endif
+);
+}
+}
+         */
+}
+if (!is_active) obj->restack = 0;
+RDI(level);
+RD("    ---]\n");
+return clean_them;
 }
 
 static Eina_Bool
@@ -506,18 +495,18 @@ _evas_render_phase1_process(Evas *e,
    RD("  [--- PHASE 1\n");
    EINA_INLIST_FOREACH(e->layers, lay)
      {
-       Evas_Object *obj;
+        Evas_Object *obj;
 
-       EINA_INLIST_FOREACH(lay->objects, obj)
-         {
-            clean_them |= _evas_render_phase1_object_process
-               (e, obj, active_objects, restack_objects, delete_objects,
-                render_objects, 0, 0, redraw_all
+        EINA_INLIST_FOREACH(lay->objects, obj)
+          {
+             clean_them |= _evas_render_phase1_object_process
+                (e, obj, active_objects, restack_objects, delete_objects,
+                 render_objects, 0, 0, redraw_all
 #ifdef REND_DGB
-                , 1
+                 , 1
 #endif
                 );
-         }
+          }
      }
    RD("  ---]\n");
    return clean_them;
@@ -530,67 +519,67 @@ _evas_render_check_pending_objects(Eina_Array *pending_objects, Evas *e)
 
    for (i = 0; i < pending_objects->count; ++i)
      {
-       Evas_Object *obj;
-       int is_active, ok = 0;
+        Evas_Object *obj;
+        int is_active, ok = 0;
 
-       obj = eina_array_data_get(pending_objects, i);
+        obj = eina_array_data_get(pending_objects, i);
 
-       if (!obj->layer) goto clean_stuff;
+        if (!obj->layer) goto clean_stuff;
 
-       evas_object_clip_recalc(obj);
-       is_active = evas_object_is_active(obj);
+        evas_object_clip_recalc(obj);
+        is_active = evas_object_is_active(obj);
 
-       if ((!is_active) && (!obj->is_active) && (!obj->render_pre) &&
+        if ((!is_active) && (!obj->is_active) && (!obj->render_pre) &&
             (!obj->rect_del))
-         {
-            ok = 1;
-            goto clean_stuff;
-         }
-
-       if (obj->is_active == is_active)
-         {
-            if (obj->changed)
-              {
-                 if (obj->smart.smart)
-                   {
-                      if (obj->render_pre || obj->rect_del) ok = 1;
-                   }
-                 else
-                   if ((is_active) && (obj->restack) && (!obj->clip.clipees) &&
-                       (_evas_render_can_render(obj) ||
-                        (evas_object_was_visible(obj) && (!obj->prev.have_clipees))))
-                     {
-                        if (!(obj->render_pre || obj->rect_del)) ok = 1;
-                     }
+          {
+             ok = 1;
+             goto clean_stuff;
+          }
+
+        if (obj->is_active == is_active)
+          {
+             if (obj->changed)
+               {
+                  if (obj->smart.smart)
+                    {
+                       if (obj->render_pre || obj->rect_del) ok = 1;
+                    }
                   else
-                    if (is_active && (!obj->clip.clipees) &&
+                    if ((is_active) && (obj->restack) && (!obj->clip.clipees) &&
                         (_evas_render_can_render(obj) ||
                          (evas_object_was_visible(obj) && (!obj->prev.have_clipees))))
                       {
-                         if (obj->render_pre || obj->rect_del) ok = 1;
+                         if (!(obj->render_pre || obj->rect_del)) ok = 1;
                       }
-              }
-            else
-              {
-                 if ((!obj->clip.clipees) && (obj->delete_me == 0) &&
-                     (!obj->cur.have_clipees || (evas_object_was_visible(obj) && (!obj->prev.have_clipees)))
-                     && evas_object_is_opaque(obj) && evas_object_is_visible(obj))
+                    else
+                      if (is_active && (!obj->clip.clipees) &&
+                          (_evas_render_can_render(obj) ||
+                           (evas_object_was_visible(obj) && (!obj->prev.have_clipees))))
+                        {
+                           if (obj->render_pre || obj->rect_del) ok = 1;
+                        }
+               }
+             else
+               {
+                  if ((!obj->clip.clipees) && (obj->delete_me == 0) &&
+                      (!obj->cur.have_clipees || (evas_object_was_visible(obj) && (!obj->prev.have_clipees)))
+                      && evas_object_is_opaque(obj) && evas_object_is_visible(obj))
                     {
                        if (obj->rect_del || obj->smart.smart) ok = 1;
                     }
-              }
-         }
-
-     clean_stuff:
-       if (!ok)
-         {
-            eina_array_clean(&e->active_objects);
-            eina_array_clean(&e->render_objects);
-            eina_array_clean(&e->restack_objects);
-            eina_array_clean(&e->delete_objects);
-            e->invalidate = 1;
-            return ;
-         }
+               }
+          }
+
+clean_stuff:
+        if (!ok)
+          {
+             eina_array_clean(&e->active_objects);
+             eina_array_clean(&e->render_objects);
+             eina_array_clean(&e->restack_objects);
+             eina_array_clean(&e->delete_objects);
+             e->invalidate = 1;
+             return ;
+          }
      }
 }
 
@@ -605,7 +594,7 @@ pending_change(void *data, void *gdata __UNUSED__)
      {
         RD("  OBJ [%p] pending change %i -> 0, pre %i\n", obj, obj->changed, obj->pre_render_done);
         obj->pre_render_done = 0;
-//// FIXME: this wipes out changes
+        //// FIXME: this wipes out changes
         obj->changed = 0;
         obj->changed_move_only = 0;
         obj->changed_nomove = 0;
@@ -614,9 +603,9 @@ pending_change(void *data, void *gdata __UNUSED__)
    return obj->changed ? EINA_TRUE : EINA_FALSE;
 }
 /*
-static void
-unchange(Evas_Object *obj)
-{
+   static void
+   unchange(Evas_Object *obj)
+   {
    Evas_Object *obj2;
 
    if (!obj->changed) return;
@@ -625,46 +614,240 @@ unchange(Evas_Object *obj)
    obj->changed_nomove = 0;
    obj->changed_move = 0;
    EINA_INLIST_FOREACH(evas_object_smart_members_get_direct(obj), obj2)
-     {
-        unchange(obj2);
-     }
-}
+   {
+   unchange(obj2);
+   }
+   }
 
-static int
-chlist(Evas_Object *obj, int i)
-{
+   static int
+   chlist(Evas_Object *obj, int i)
+   {
    Evas_Object *obj2;
    int j;
    int ret = 0;
 
    if (!obj->changed) return 0;
    for (j = 0; j < i; j++) printf(" ");
-   printf("ch2 %p %s %i [%i %i %ix%i] v %i/%i [r%i] %p\n", obj, 
-          obj->type, 
-          obj->changed_move_only,
-          obj->cur.geometry.x,
-          obj->cur.geometry.y,
-          obj->cur.geometry.w,
-          obj->cur.geometry.h,
-          obj->cur.visible,
-          obj->prev.visible,
-          obj->restack,
-          obj->clip.clipees);
+   printf("ch2 %p %s %i [%i %i %ix%i] v %i/%i [r%i] %p\n", obj,
+   obj->type,
+   obj->changed_move_only,
+   obj->cur.geometry.x,
+   obj->cur.geometry.y,
+   obj->cur.geometry.w,
+   obj->cur.geometry.h,
+   obj->cur.visible,
+   obj->prev.visible,
+   obj->restack,
+   obj->clip.clipees);
    EINA_INLIST_FOREACH(evas_object_smart_members_get_direct(obj), obj2)
+   {
+   if (obj2->changed)
+   ret |= chlist(obj2, i + 1);
+   }
+   }
+ */
+static Eina_Bool
+_evas_render_can_use_overlay(Evas *e, Evas_Object *obj)
+{
+   Eina_Rectangle *r;
+   Evas_Object *tmp;
+   Eina_List *alphas = NULL;
+   Eina_List *opaques = NULL;
+   Evas_Object *video_parent = NULL;
+   Eina_Rectangle zone;
+   Evas_Coord xc1, yc1, xc2, yc2;
+   unsigned int i;
+   Eina_Bool nooverlay;
+
+   video_parent = _evas_object_image_video_parent_get(obj);
+
+   /* Check if any one is the stack make this object mapped */
+   tmp = obj;
+   while (tmp && !_evas_render_has_map(tmp))
+     tmp = tmp->smart.parent;
+
+   if (tmp && _evas_render_has_map(tmp)) return EINA_FALSE; /* we are mapped, we can't be an overlay */
+
+   if (!evas_object_is_visible(obj)) return EINA_FALSE; /* no need to update the overlay if it's not visible */
+
+   /* If any recoloring of the surface is needed, n overlay to */
+   if ((obj->cur.cache.clip.r != 255) ||
+       (obj->cur.cache.clip.g != 255) ||
+       (obj->cur.cache.clip.b != 255) ||
+       (obj->cur.cache.clip.a != 255))
+     return EINA_FALSE;
+
+   /* Check presence of transparent object on top of the video object */
+   EINA_RECTANGLE_SET(&zone,
+                      obj->cur.cache.clip.x,
+                      obj->cur.cache.clip.y,
+                      obj->cur.cache.clip.w,
+                      obj->cur.cache.clip.h);
+
+   for (i = e->active_objects.count - 1; i > 0; i--)
      {
-        if (obj2->changed)
-           ret |= chlist(obj2, i + 1);
+        Eina_Rectangle self;
+        Eina_Rectangle *match;
+        Evas_Object *current;
+        Eina_List *l;
+        int xm1, ym1, xm2, ym2;
+
+        current = eina_array_data_get(&e->active_objects, i);
+
+        /* Did we find the video object in the stack ? */
+        if (current == video_parent || current == obj)
+          break;
+
+        EINA_RECTANGLE_SET(&self,
+                           current->cur.cache.clip.x,
+                           current->cur.cache.clip.y,
+                           current->cur.cache.clip.w,
+                           current->cur.cache.clip.h);
+
+        /* This doesn't cover the area of the video object, so don't bother with that object */
+        if (!eina_rectangles_intersect(&zone, &self))
+          continue ;
+
+        xc1 = current->cur.cache.clip.x;
+        yc1 = current->cur.cache.clip.y;
+        xc2 = current->cur.cache.clip.x + current->cur.cache.clip.w;
+        yc2 = current->cur.cache.clip.y + current->cur.cache.clip.h;
+
+        if (evas_object_is_visible(current) &&
+            (!current->clip.clipees) &&
+            (current->cur.visible) &&
+            (!current->delete_me) &&
+            (current->cur.cache.clip.visible) &&
+            (!current->smart.smart))
+          {
+             Eina_Bool included = EINA_FALSE;
+
+             if (evas_object_is_opaque(current) ||
+                 ((current->func->has_opaque_rect) &&
+                  (current->func->has_opaque_rect(current))))
+               {
+                  /* The object is opaque */
+
+                  /* Check if the opaque object is inside another opaque object */
+                  EINA_LIST_FOREACH(opaques, l, match)
+                    {
+                       xm1 = match->x;
+                       ym1 = match->y;
+                       xm2 = match->x + match->w;
+                       ym2 = match->y + match->h;
+
+                       /* Both object are included */
+                       if (xc1 >= xm1 && yc1 >= ym1 && xc2 <= xm2 && yc2 <= ym2)
+                         {
+                            included = EINA_TRUE;
+                            break;
+                         }
+                    }
+
+                  /* Not included yet */
+                  if (!included)
+                    {
+                       Eina_List *ln;
+                       Evas_Coord xn2, yn2;
+
+                       r = eina_rectangle_new(current->cur.cache.clip.x, current->cur.cache.clip.y,
+                                              current->cur.cache.clip.w, current->cur.cache.clip.h);
+
+                       opaques = eina_list_append(opaques, r);
+
+                       xn2 = r->x + r->w;
+                       yn2 = r->y + r->h;
+
+                       /* Remove all the transparent object that are covered by the new opaque object */
+                       EINA_LIST_FOREACH_SAFE(alphas, l, ln, match)
+                         {
+                            xm1 = match->x;
+                            ym1 = match->y;
+                            xm2 = match->x + match->w;
+                            ym2 = match->y + match->h;
+
+                            if (xm1 >= r->x && ym1 >= r->y && xm2 <= xn2 && ym2 <= yn2)
+                              {
+                                 /* The new rectangle is over some transparent object,
+                                    so remove the transparent object */
+                                 alphas = eina_list_remove_list(alphas, l);
+                              }
+                         }
+                    }
+               }
+             else
+               {
+                  /* The object has some transparency */
+
+                  /* Check if the transparent object is inside any other transparent object */
+                  EINA_LIST_FOREACH(alphas, l, match)
+                    {
+                       xm1 = match->x;
+                       ym1 = match->y;
+                       xm2 = match->x + match->w;
+                       ym2 = match->y + match->h;
+
+                       /* Both object are included */
+                       if (xc1 >= xm1 && yc1 >= ym1 && xc2 <= xm2 && yc2 <= ym2)
+                         {
+                            included = EINA_TRUE;
+                            break;
+                         }
+                    }
+
+                  /* If not check if it is inside any opaque one */
+                  if (!included)
+                    {
+                       EINA_LIST_FOREACH(opaques, l, match)
+                         {
+                            xm1 = match->x;
+                            ym1 = match->y;
+                            xm2 = match->x + match->w;
+                            ym2 = match->y + match->h;
+
+                            /* Both object are included */
+                            if (xc1 >= xm1 && yc1 >= ym1 && xc2 <= xm2 && yc2 <= ym2)
+                              {
+                                 included = EINA_TRUE;
+                                 break;
+                              }
+                         }
+                    }
+
+                  /* No inclusion at all, so add it */
+                  if (!included)
+                    {
+                       r = eina_rectangle_new(current->cur.cache.clip.x, current->cur.cache.clip.y,
+                                              current->cur.cache.clip.w, current->cur.cache.clip.h);
+
+                       alphas = eina_list_append(alphas, r);
+                    }
+               }
+          }
      }
+
+   /* If there is any pending transparent object, then no overlay */
+   nooverlay = !!eina_list_count(alphas);
+
+   EINA_LIST_FREE(alphas, r)
+     eina_rectangle_free(r);
+   EINA_LIST_FREE(opaques, r)
+     eina_rectangle_free(r);
+
+   if (nooverlay)
+     return EINA_FALSE;
+
+   return EINA_TRUE;
 }
-*/
 
-static Eina_Bool
+Eina_Bool
 evas_render_mapped(Evas *e, Evas_Object *obj, void *context, void *surface,
-                   int off_x, int off_y, int mapped
+                   int off_x, int off_y, int mapped,
+                   int ecx, int ecy, int ecw, int ech
 #ifdef REND_DGB
                    , int level
 #endif
-                   )
+                  )
 {
    void *ctx;
    Evas_Object *obj2;
@@ -685,7 +868,7 @@ evas_render_mapped(Evas *e, Evas_Object *obj, void *context, void *surface,
      }
    else if (!(((evas_object_is_active(obj) && (!obj->clip.clipees) &&
                 (_evas_render_can_render(obj))))
-              ))
+             ))
      {
         RDI(level);
         RD("      }\n");
@@ -694,7 +877,10 @@ evas_render_mapped(Evas *e, Evas_Object *obj, void *context, void *surface,
 
    // set render_pre - for child objs that may not have gotten it.
    obj->pre_render_done = 1;
-
+   RD("          Hasmap: %p (%d) %p %d -> %d\n",obj->func->can_map,
+      obj->func->can_map ? obj->func->can_map(obj): -1,
+      obj->cur.map, obj->cur.usemap,
+      _evas_render_has_map(obj));
    if (_evas_render_has_map(obj))
      {
         const Evas_Map_Point *p, *p_end;
@@ -702,7 +888,7 @@ evas_render_mapped(Evas *e, Evas_Object *obj, void *context, void *surface,
         int sw, sh;
         int changed = 0, rendered = 0;
 
-       clean_them = EINA_TRUE;
+        clean_them = EINA_TRUE;
 
         sw = obj->cur.geometry.w;
         sh = obj->cur.geometry.h;
@@ -719,9 +905,9 @@ evas_render_mapped(Evas *e, Evas_Object *obj, void *context, void *surface,
         pts[0].py = obj->cur.map->persp.py << FP;
         pts[0].foc = obj->cur.map->persp.foc << FP;
         pts[0].z0 = obj->cur.map->persp.z0 << FP;
-        
+
         p = obj->cur.map->points;
-        p_end = p + 4;
+        p_end = p + obj->cur.map->count;
         pt = pts;
         for (; p < p_end; p++, pt++)
           {
@@ -739,6 +925,12 @@ evas_render_mapped(Evas *e, Evas_Object *obj, void *context, void *surface,
              else if (pt->v > (sh * FP1)) pt->v = (sh * FP1);
              pt->col = ARGB_JOIN(p->a, p->r, p->g, p->b);
           }
+        /* Copy last for software engine */
+        if (obj->cur.map->count & 0x1)
+          {
+             pts[obj->cur.map->count] = pts[obj->cur.map->count - 1];
+          }
+
 
         if (obj->cur.map->surface)
           {
@@ -748,7 +940,7 @@ evas_render_mapped(Evas *e, Evas_Object *obj, void *context, void *surface,
                   RDI(level);
                   RD("        new surf: %ix%i\n", sw, sh);
                   obj->layer->evas->engine.func->image_map_surface_free
-                    (e->engine.data.output, obj->cur.map->surface);
+                     (e->engine.data.output, obj->cur.map->surface);
                   obj->cur.map->surface = NULL;
                }
           }
@@ -758,41 +950,41 @@ evas_render_mapped(Evas *e, Evas_Object *obj, void *context, void *surface,
              obj->cur.map->surface_h = sh;
 
              obj->cur.map->surface =
-               obj->layer->evas->engine.func->image_map_surface_new
-               (e->engine.data.output, obj->cur.map->surface_w,
-                obj->cur.map->surface_h,
-                obj->cur.map->alpha);
+                obj->layer->evas->engine.func->image_map_surface_new
+                (e->engine.data.output, obj->cur.map->surface_w,
+                 obj->cur.map->surface_h,
+                 obj->cur.map->alpha);
              RDI(level);
              RD("        fisrt surf: %ix%i\n", sw, sh);
              changed = 1;
           }
         if (obj->smart.smart)
           {
-             Evas_Object *obj2;
-             
-             EINA_INLIST_FOREACH(evas_object_smart_members_get_direct(obj), obj2)
+             Evas_Object *o2;
+
+             EINA_INLIST_FOREACH(evas_object_smart_members_get_direct(obj), o2)
                {
-                  if (!evas_object_is_visible(obj2) &&
-                      !evas_object_was_visible(obj2))
+                  if (!evas_object_is_visible(o2) &&
+                      !evas_object_was_visible(o2))
                     {
-                       obj2->changed = 0;
-                       obj2->changed_move_only = 0;
-                       obj2->changed_nomove = 0;
-                       obj2->changed_move = 0;
+                       o2->changed = 0;
+                       o2->changed_move_only = 0;
+                       o2->changed_nomove = 0;
+                       o2->changed_move = 0;
                        continue;
                     }
-                  if (obj2->changed)
+                  if (o2->changed)
                     {
-//                       chlist(obj2, 0);
+                       //                       chlist(o2, 0);
                        changed = 1;
-                       obj2->changed = 0;
-                       obj2->changed_move_only = 0;
-                       obj2->changed_nomove = 0;
-                       obj2->changed_move = 0;
+                       o2->changed = 0;
+                       o2->changed_move_only = 0;
+                       o2->changed_nomove = 0;
+                       o2->changed_move = 0;
                        break;
                     }
                }
-//             unchange(obj);
+             //             unchange(obj);
              obj->changed = 0;
              obj->changed_move_only = 0;
              obj->changed_nomove = 0;
@@ -814,7 +1006,7 @@ evas_render_mapped(Evas *e, Evas_Object *obj, void *context, void *surface,
         if ((changed) && (obj->cur.map->surface))
           {
              int off_x2, off_y2;
-             
+
              RDI(level);
              RD("        children redraw\n");
              // FIXME: calculate "changes" within map surface and only clear
@@ -823,9 +1015,9 @@ evas_render_mapped(Evas *e, Evas_Object *obj, void *context, void *surface,
                {
                   ctx = e->engine.func->context_new(e->engine.data.output);
                   e->engine.func->context_color_set
-                    (e->engine.data.output, ctx, 0, 0, 0, 0);
+                     (e->engine.data.output, ctx, 0, 0, 0, 0);
                   e->engine.func->context_render_op_set
-                    (e->engine.data.output, ctx, EVAS_RENDER_COPY);
+                     (e->engine.data.output, ctx, EVAS_RENDER_COPY);
                   e->engine.func->rectangle_draw(e->engine.data.output,
                                                  ctx,
                                                  obj->cur.map->surface,
@@ -840,16 +1032,17 @@ evas_render_mapped(Evas *e, Evas_Object *obj, void *context, void *surface,
              if (obj->smart.smart)
                {
                   EINA_INLIST_FOREACH
-                    (evas_object_smart_members_get_direct(obj), obj2)
-                    {
-                       clean_them |= evas_render_mapped(e, obj2, ctx,
-                                                       obj->cur.map->surface,
-                                                       off_x2, off_y2, 1
+                     (evas_object_smart_members_get_direct(obj), obj2)
+                       {
+                          clean_them |= evas_render_mapped(e, obj2, ctx,
+                                                           obj->cur.map->surface,
+                                                           off_x2, off_y2, 1,
+                                                           ecx, ecy, ecw, ech
 #ifdef REND_DGB
-                                                       , level + 1
+                                                           , level + 1
 #endif
-                                                       );
-                    }
+                                                          );
+                       }
                }
              else
                {
@@ -862,6 +1055,7 @@ evas_render_mapped(Evas *e, Evas_Object *obj, void *context, void *surface,
                                      obj->cur.geometry.y + off_y2,
                                      obj->cur.geometry.w,
                                      obj->cur.geometry.h);
+
                   e->engine.func->context_clip_set(e->engine.data.output,
                                                    ctx, x, y, w, h);
                   obj->func->render(obj, e->engine.data.output, ctx,
@@ -872,17 +1066,17 @@ evas_render_mapped(Evas *e, Evas_Object *obj, void *context, void *surface,
           }
 
         RDI(level);
-        RD("        draw map4\n");
+        RD("        draw map\n");
 
         if (rendered)
           {
              obj->cur.map->surface = e->engine.func->image_dirty_region
-               (e->engine.data.output, obj->cur.map->surface,
-                0, 0, obj->cur.map->surface_w, obj->cur.map->surface_h);
+                (e->engine.data.output, obj->cur.map->surface,
+                 0, 0, obj->cur.map->surface_w, obj->cur.map->surface_h);
           }
         e->engine.func->context_clip_unset(e->engine.data.output,
                                            e->engine.data.context);
-        if (obj->cur.map->surface) 
+        if (obj->cur.map->surface)
           {
              if (obj->smart.smart)
                {
@@ -890,7 +1084,7 @@ evas_render_mapped(Evas *e, Evas_Object *obj, void *context, void *surface,
                     {
                        int x, y, w, h;
                        Evas_Object *tobj;
-                       
+
                        obj->cur.cache.clip.dirty = 1;
                        tobj = obj->cur.map_parent;
                        obj->cur.map_parent = obj->cur.clipper->cur.map_parent;
@@ -900,6 +1094,11 @@ evas_render_mapped(Evas *e, Evas_Object *obj, void *context, void *surface,
                        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);
                        e->engine.func->context_clip_set(e->engine.data.output,
                                                         e->engine.data.context,
                                                         x + off_x, y + off_y, w, h);
@@ -910,32 +1109,37 @@ evas_render_mapped(Evas *e, Evas_Object *obj, void *context, void *surface,
                   if (obj->cur.clipper)
                     {
                        int x, y, w, h;
-                       
+
                        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);
+                                          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);
                        e->engine.func->context_clip_set(e->engine.data.output,
                                                         e->engine.data.context,
                                                         x + off_x, y + off_y, w, h);
                     }
                }
           }
+        if (surface == e->engine.data.output)
+          e->engine.func->context_clip_clip(e->engine.data.output,
+                                            e->engine.data.context,
+                                            ecx, ecy, ecw, ech);
         if (obj->cur.cache.clip.visible)
-           obj->layer->evas->engine.func->image_map4_draw
-           (e->engine.data.output, e->engine.data.context, surface,
-            obj->cur.map->surface, pts, obj->cur.map->smooth, 0);
+          obj->layer->evas->engine.func->image_map_draw
+             (e->engine.data.output, e->engine.data.context, surface,
+              obj->cur.map->surface, obj->cur.map->count, pts,
+              obj->cur.map->smooth, 0);
         // FIXME: needs to cache these maps and
         // keep them only rendering updates
-//        obj->layer->evas->engine.func->image_map_surface_free
-//          (e->engine.data.output, obj->cur.map->surface);
-//        obj->cur.map->surface = NULL;
+        //        obj->layer->evas->engine.func->image_map_surface_free
+        //          (e->engine.data.output, obj->cur.map->surface);
+        //        obj->cur.map->surface = NULL;
      }
    else
      {
@@ -947,25 +1151,52 @@ evas_render_mapped(Evas *e, Evas_Object *obj, void *context, void *surface,
              if (obj->smart.smart)
                {
                   EINA_INLIST_FOREACH
-                    (evas_object_smart_members_get_direct(obj), obj2)
-                    {
-                       clean_them |= evas_render_mapped(e, obj2, ctx,
-                                                       surface,
-                                                       off_x, off_y, 1
+                     (evas_object_smart_members_get_direct(obj), obj2)
+                       {
+                          clean_them |= evas_render_mapped(e, obj2, ctx,
+                                                           surface,
+                                                           off_x, off_y, 1,
+                                                           ecx, ecy, ecw, ech
 #ifdef REND_DGB
-                                                       , level + 1
+                                                           , level + 1
 #endif
-                                                       );
-                    }
+                                                          );
+                       }
                }
              else
                {
                   if (!obj->cur.map)
                     {
+                       int x, y, w, h;
+
                        RDI(level);
+
+                       x = obj->cur.cache.clip.x + off_x;
+                       y = obj->cur.cache.clip.y + off_y;
+                       w = obj->cur.cache.clip.w;
+                       h = obj->cur.cache.clip.h;
+
+                       if (obj->cur.clipper)
+                         {
+                            if (_evas_render_has_map(obj))
+                              evas_object_clip_recalc(obj);
+
+                            RD("        clipper: %i %i %ix%i\n",
+                               obj->cur.clipper->cur.cache.clip.x + off_x,
+                               obj->cur.clipper->cur.cache.clip.y + off_y,
+                               obj->cur.clipper->cur.cache.clip.w,
+                               obj->cur.clipper->cur.cache.clip.h);
+
+                            RECTS_CLIP_TO_RECT(x, y, w, h,
+                                               obj->cur.clipper->cur.cache.clip.x + off_x,
+                                               obj->cur.clipper->cur.cache.clip.y + off_y,
+                                               obj->cur.clipper->cur.cache.clip.w,
+                                               obj->cur.clipper->cur.cache.clip.h);
+                         }
+
                        RD("        clip: %i %i %ix%i [%i %i %ix%i]\n",
                           obj->cur.cache.clip.x + off_x,
-                          obj->cur.cache.clip.y + off_y, 
+                          obj->cur.cache.clip.y + off_y,
                           obj->cur.cache.clip.w,
                           obj->cur.cache.clip.h,
                           obj->cur.geometry.x + off_x,
@@ -973,11 +1204,7 @@ evas_render_mapped(Evas *e, Evas_Object *obj, void *context, void *surface,
                           obj->cur.geometry.w,
                           obj->cur.geometry.h);
                        e->engine.func->context_clip_set(e->engine.data.output,
-                                                        ctx,
-                                                        obj->cur.cache.clip.x + off_x,
-                                                        obj->cur.cache.clip.y + off_y, 
-                                                        obj->cur.cache.clip.w,
-                                                        obj->cur.cache.clip.h);
+                                                        ctx, x, y, w, h);
                     }
                   else
                     {
@@ -986,20 +1213,43 @@ evas_render_mapped(Evas *e, Evas_Object *obj, void *context, void *surface,
                     }
                   obj->func->render(obj, e->engine.data.output, ctx,
                                     surface, off_x, off_y);
-/*                  
-                  obj->layer->evas->engine.func->context_color_set(e->engine.data.output,
-                                                                   ctx,
-                                                                   0, 30, 0, 30);
-                  obj->layer->evas->engine.func->rectangle_draw(e->engine.data.output,
-                                                                ctx,
-                                                                surface,
-                                                                0, 0, 9999, 9999);
- */
+                  /*
+                                      obj->layer->evas->engine.func->context_color_set(e->engine.data.output,
+                                      ctx,
+                                      0, 30, 0, 30);
+                                      obj->layer->evas->engine.func->rectangle_draw(e->engine.data.output,
+                                      ctx,
+                                      surface,
+                                      0, 0, 9999, 9999);
                  */
                }
              e->engine.func->context_free(e->engine.data.output, ctx);
           }
         else
           {
+             if (obj->cur.clipper)
+               {
+                  int x, y, w, h;
+
+                  if (_evas_render_has_map(obj))
+                    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);
+                  e->engine.func->context_clip_set(e->engine.data.output,
+                                                   e->engine.data.context,
+                                                   x + off_x, y + off_y, w, h);
+                  e->engine.func->context_clip_clip(e->engine.data.output,
+                                                    e->engine.data.context,
+                                                    ecx, ecy, ecw, ech);
+               }
+
              RDI(level);
              RD("        draw normal obj\n");
              obj->func->render(obj, e->engine.data.output, context, surface,
@@ -1017,6 +1267,7 @@ evas_render_updates_internal(Evas *e,
                              unsigned char make_updates,
                              unsigned char do_draw)
 {
+   Evas_Object *obj;
    Eina_List *updates = NULL;
    Eina_List *ll;
    void *surface;
@@ -1044,23 +1295,34 @@ evas_render_updates_internal(Evas *e,
 
    /* phase 1. add extra updates for changed objects */
    if (e->invalidate || e->render_objects.count <= 0)
-     clean_them = _evas_render_phase1_process(e, 
-                                              &e->active_objects, 
-                                              &e->restack_objects, 
-                                              &e->delete_objects, 
+     clean_them = _evas_render_phase1_process(e,
+                                              &e->active_objects,
+                                              &e->restack_objects,
+                                              &e->delete_objects,
                                               &e->render_objects,
                                               &redraw_all);
 
    _evas_render_phase1_direct(e, &e->active_objects, &e->restack_objects,
                               &e->delete_objects, &e->render_objects);
 
+   /* phase 1.5. check if the video should be inlined or stay in their overlay */
+   alpha = e->engine.func->canvas_alpha_get(e->engine.data.output,
+                                           e->engine.data.context);
+
+   EINA_LIST_FOREACH(e->video_objects, ll, obj)
+     {
+        /* we need the surface to be transparent to display the underlying overlay */
+        if (alpha && _evas_render_can_use_overlay(e, obj))
+         _evas_object_image_video_overlay_show(obj);
+        else
+         _evas_object_image_video_overlay_hide(obj);
+     }
+
    /* phase 2. force updates for restacks */
    for (i = 0; i < e->restack_objects.count; ++i)
      {
-       Evas_Object *obj;
-
-       obj = eina_array_data_get(&e->restack_objects, i);
-       obj->func->render_pre(obj);
+        obj = eina_array_data_get(&e->restack_objects, i);
+        obj->func->render_pre(obj);
         _evas_render_prev_cur_clip_cache_add(e, obj);
      }
    eina_array_clean(&e->restack_objects);
@@ -1088,27 +1350,25 @@ evas_render_updates_internal(Evas *e,
      }
    if ((e->output.w != e->viewport.w) || (e->output.h != e->viewport.h))
      {
-       ERR("viewport size != output size!");
+        ERR("viewport size != output size!");
      }
    if (redraw_all)
      {
         e->engine.func->output_redraws_rect_add(e->engine.data.output,
-                                                0, 0, 
+                                                0, 0,
                                                 e->output.w, e->output.h);
      }
    /* phase 5. add obscures */
    EINA_LIST_FOREACH(e->obscures, ll, r)
      {
         e->engine.func->output_redraws_rect_del(e->engine.data.output,
-                                              r->x, r->y, r->w, r->h);
+                                                r->x, r->y, r->w, r->h);
      }
    /* build obscure objects list of active objects that obscure */
    for (i = 0; i < e->active_objects.count; ++i)
      {
-       Evas_Object *obj;
-
-       obj = eina_array_data_get(&e->active_objects, i);
-       if (UNLIKELY((evas_object_is_opaque(obj) ||
+        obj = eina_array_data_get(&e->active_objects, i);
+        if (UNLIKELY((evas_object_is_opaque(obj) ||
                       ((obj->func->has_opaque_rect) &&
                        (obj->func->has_opaque_rect(obj)))) &&
                      evas_object_is_visible(obj) &&
@@ -1117,160 +1377,134 @@ evas_render_updates_internal(Evas *e,
                      (!obj->delete_me) &&
                      (obj->cur.cache.clip.visible) &&
                      (!obj->smart.smart)))
-/*       obscuring_objects = eina_list_append(obscuring_objects, obj); */
-         eina_array_push(&e->obscuring_objects, obj);
+          /*     obscuring_objects = eina_list_append(obscuring_objects, obj); */
+          eina_array_push(&e->obscuring_objects, obj);
      }
+
    /* save this list */
-/*    obscuring_objects_orig = obscuring_objects; */
-/*    obscuring_objects = NULL; */
+   /*    obscuring_objects_orig = obscuring_objects; */
+   /*    obscuring_objects = NULL; */
    /* phase 6. go thru each update rect and render objects in it*/
    if (do_draw)
      {
-       unsigned int offset = 0;
+        unsigned int offset = 0;
 
-       alpha = e->engine.func->canvas_alpha_get(e->engine.data.output, 
-                                                 e->engine.data.context);
-
-       while ((surface =
-               e->engine.func->output_redraws_next_update_get
+        while ((surface =
+                e->engine.func->output_redraws_next_update_get
                 (e->engine.data.output,
-                    &ux, &uy, &uw, &uh,
-                    &cx, &cy, &cw, &ch)))
-         {
-            int off_x, off_y;
+                 &ux, &uy, &uw, &uh,
+                 &cx, &cy, &cw, &ch)))
+          {
+             int off_x, off_y;
 
              RD("  [--- UPDATE %i %i %ix%i\n", ux, uy, uw, uh);
-            if (make_updates)
-              {
-                 Eina_Rectangle *rect;
-
-                 NEW_RECT(rect, ux, uy, uw, uh);
-                 if (rect)
-                   updates = eina_list_append(updates, rect);
-              }
+             if (make_updates)
+               {
+                  Eina_Rectangle *rect;
+
+                  NEW_RECT(rect, ux, uy, uw, uh);
+                  if (rect)
+                    updates = eina_list_append(updates, rect);
+               }
              haveup = 1;
-            off_x = cx - ux;
-            off_y = cy - uy;
-            /* build obscuring objects list (in order from bottom to top) */
-            for (i = 0; i < e->obscuring_objects.count; ++i)
-              {
-                 Evas_Object *obj;
-
-                 obj = (Evas_Object *)eina_array_data_get
+             off_x = cx - ux;
+             off_y = cy - uy;
+             /* build obscuring objects list (in order from bottom to top) */
+             for (i = 0; i < e->obscuring_objects.count; ++i)
+               {
+                  obj = (Evas_Object *)eina_array_data_get
                      (&e->obscuring_objects, i);
-                 if (evas_object_is_in_output_rect(obj, ux, uy, uw, uh))
-                   {
-                      eina_array_push(&e->temporary_objects, obj);
-                       
-                      /* reset the background of the area if needed (using cutout and engine alpha flag to help) */
+                  if (evas_object_is_in_output_rect(obj, ux, uy, uw, uh))
+                    {
+                       eina_array_push(&e->temporary_objects, obj);
+
+                       /* reset the background of the area if needed (using cutout and engine alpha flag to help) */
                        if (alpha)
                          {
                             if (evas_object_is_opaque(obj))
-                               e->engine.func->context_cutout_add
-                               (e->engine.data.output,
-                                   e->engine.data.context,
-                                   obj->cur.cache.clip.x + off_x,
-                                   obj->cur.cache.clip.y + off_y,
-                                   obj->cur.cache.clip.w,
-                                   obj->cur.cache.clip.h);
-                           else
-                             {
-                                if (obj->func->get_opaque_rect)
-                                  {
-                                     Evas_Coord obx, oby, obw, obh;
-
-                                     obj->func->get_opaque_rect
+                              e->engine.func->context_cutout_add
+                                 (e->engine.data.output,
+                                  e->engine.data.context,
+                                  obj->cur.cache.clip.x + off_x,
+                                  obj->cur.cache.clip.y + off_y,
+                                  obj->cur.cache.clip.w,
+                                  obj->cur.cache.clip.h);
+                            else
+                              {
+                                 if (obj->func->get_opaque_rect)
+                                   {
+                                      Evas_Coord obx, oby, obw, obh;
+
+                                      obj->func->get_opaque_rect
                                          (obj, &obx, &oby, &obw, &obh);
-                                     if ((obw > 0) && (obh > 0))
-                                       {
-                                          obx += off_x;
-                                          oby += off_y;
-                                          RECTS_CLIP_TO_RECT
+                                      if ((obw > 0) && (obh > 0))
+                                        {
+                                           obx += off_x;
+                                           oby += off_y;
+                                           RECTS_CLIP_TO_RECT
                                               (obx, oby, obw, obh,
-                                                  obj->cur.cache.clip.x + off_x,
-                                                  obj->cur.cache.clip.y + off_y,
-                                                  obj->cur.cache.clip.w,
-                                                  obj->cur.cache.clip.h);
-                                          e->engine.func->context_cutout_add
+                                               obj->cur.cache.clip.x + off_x,
+                                               obj->cur.cache.clip.y + off_y,
+                                               obj->cur.cache.clip.w,
+                                               obj->cur.cache.clip.h);
+                                           e->engine.func->context_cutout_add
                                               (e->engine.data.output,
-                                                  e->engine.data.context,
-                                                  obx, oby,
-                                                  obw, obh);
-                                       }
-                                  }
-                             }
-                        }
-                   }
-              }
-            if (alpha)
-              {
-                 e->engine.func->context_clip_set(e->engine.data.output,
-                                                  e->engine.data.context,
-                                                  ux, uy, uw, uh);
-                 e->engine.func->context_color_set(e->engine.data.output, 
-                                                    e->engine.data.context, 
+                                               e->engine.data.context,
+                                               obx, oby,
+                                               obw, obh);
+                                        }
+                                   }
+                              }
+                         }
+                    }
+               }
+             if (alpha)
+               {
+                  e->engine.func->context_clip_set(e->engine.data.output,
+                                                   e->engine.data.context,
+                                                   ux + off_x, uy + off_y, uw, uh);
+                  e->engine.func->context_color_set(e->engine.data.output,
+                                                    e->engine.data.context,
                                                     0, 0, 0, 0);
-                 e->engine.func->context_multiplier_unset
+                  e->engine.func->context_multiplier_unset
                      (e->engine.data.output, e->engine.data.context);
-                 e->engine.func->context_render_op_set(e->engine.data.output, 
+                  e->engine.func->context_render_op_set(e->engine.data.output,
                                                         e->engine.data.context,
                                                         EVAS_RENDER_COPY);
-                 e->engine.func->rectangle_draw(e->engine.data.output,
-                                                e->engine.data.context,
-                                                surface,
-                                                cx, cy, cw, ch);
-                 e->engine.func->context_cutout_clear(e->engine.data.output,
-                                                      e->engine.data.context);
-                 e->engine.func->context_clip_unset(e->engine.data.output,
+                  e->engine.func->rectangle_draw(e->engine.data.output,
+                                                 e->engine.data.context,
+                                                 surface,
+                                                 cx, cy, cw, ch);
+                  e->engine.func->context_cutout_clear(e->engine.data.output,
+                                                       e->engine.data.context);
+                  e->engine.func->context_clip_unset(e->engine.data.output,
                                                      e->engine.data.context);
-              }
-            /* render all object that intersect with rect */
+               }
+             /* render all object that intersect with rect */
              for (i = 0; i < e->active_objects.count; ++i)
-              {
-                 Evas_Object *obj;
-
-                 obj = eina_array_data_get(&e->active_objects, i);
+               {
+                  obj = eina_array_data_get(&e->active_objects, i);
 
-                 /* if it's in our outpout rect and it doesn't clip anything */
+                  /* if it's in our outpout rect and it doesn't clip anything */
                   RD("    OBJ: [%p] '%s' %i %i %ix%i\n", obj, obj->type, obj->cur.geometry.x, obj->cur.geometry.y, obj->cur.geometry.w, obj->cur.geometry.h);
-                 if ((evas_object_is_in_output_rect(obj, ux, uy, uw, uh) ||
+                  if ((evas_object_is_in_output_rect(obj, ux, uy, uw, uh) ||
                        (obj->smart.smart)) &&
-                     (!obj->clip.clipees) &&
-                     (obj->cur.visible) &&
-                     (!obj->delete_me) &&
-                     (obj->cur.cache.clip.visible) &&
-//                   (!obj->smart.smart) &&
-                     ((obj->cur.color.a > 0 || obj->cur.render_op != EVAS_RENDER_BLEND)))
-                   {
-                      int x, y, w, h;
+                      (!obj->clip.clipees) &&
+                      (obj->cur.visible) &&
+                      (!obj->delete_me) &&
+                      (obj->cur.cache.clip.visible) &&
+                      //                     (!obj->smart.smart) &&
+                      ((obj->cur.color.a > 0 || obj->cur.render_op != EVAS_RENDER_BLEND)))
+                    {
+                       int x, y, w, h;
 
                        RD("      DRAW (vis: %i, a: %i, clipees: %p\n", obj->cur.visible, obj->cur.color.a, obj->clip.clipees);
-                      if ((e->temporary_objects.count > offset) &&
-                          (eina_array_data_get(&e->temporary_objects, offset) == obj))
-                        offset++;
-                      x = cx; y = cy; w = cw; h = ch;
-                       if (obj->cur.clipper)
+                       if ((e->temporary_objects.count > offset) &&
+                           (eina_array_data_get(&e->temporary_objects, offset) == obj))
+                         offset++;
+                       x = cx; y = cy; w = cw; h = ch;
+                       if (((w > 0) && (h > 0)) || (obj->smart.smart))
                          {
-                            if (_evas_render_has_map(obj))
-                              {
-                                 evas_object_clip_recalc(obj);
-                              }
-/* hmmmm clip seems to kill eweather in elm-test
-                            printf("clip: %4i %4i %4ix%4i to %4i %4i %4ix%4i\n",
-                                   x, y, w, h,
-                                   obj->cur.cache.clip.x + off_x,
-                                   obj->cur.cache.clip.y + off_y,
-                                   obj->cur.cache.clip.w,
-                                   obj->cur.cache.clip.h);
- */
-                            RECTS_CLIP_TO_RECT(x, y, w, h,
-                                               obj->cur.cache.clip.x + off_x,
-                                               obj->cur.cache.clip.y + off_y,
-                                               obj->cur.cache.clip.w,
-                                               obj->cur.cache.clip.h);
-                         }
-                      if (((w > 0) && (h > 0)) || (obj->smart.smart))
-                        {
                             if (!obj->smart.smart)
                               {
                                  RECTS_CLIP_TO_RECT(x, y, w, h,
@@ -1279,19 +1513,30 @@ evas_render_updates_internal(Evas *e,
                                                     obj->cur.cache.clip.w,
                                                     obj->cur.cache.clip.h);
                               }
+                            if (obj->cur.mask)
+                              e->engine.func->context_mask_set(e->engine.data.output,
+                                                               e->engine.data.context,
+                                                               obj->cur.mask->func->engine_data_get(obj->cur.mask),
+                                                               obj->cur.mask->cur.geometry.x + off_x,
+                                                               obj->cur.mask->cur.geometry.y + off_y,
+                                                               obj->cur.mask->cur.geometry.w,
+                                                               obj->cur.mask->cur.geometry.h);
+                            else
+                              e->engine.func->context_mask_unset(e->engine.data.output,
+                                                                 e->engine.data.context);
                             if (obj->cur.clipper)
-                               e->engine.func->context_clip_set(e->engine.data.output,
-                                                                e->engine.data.context,
-                                                                x, y, w, h);
+                              e->engine.func->context_clip_set(e->engine.data.output,
+                                                               e->engine.data.context,
+                                                               x, y, w, h);
                             else
-                               e->engine.func->context_clip_unset(e->engine.data.output,
-                                                                  e->engine.data.context);
+                              e->engine.func->context_clip_unset(e->engine.data.output,
+                                                                 e->engine.data.context);
 #if 1 /* FIXME: this can slow things down... figure out optimum... coverage */
-                           for (j = offset; j < e->temporary_objects.count; ++j)
-                             {
-                                Evas_Object *obj2;
+                            for (j = offset; j < e->temporary_objects.count; ++j)
+                              {
+                                 Evas_Object *obj2;
 
-                                obj2 = (Evas_Object *) eina_array_data_get(&e->temporary_objects, j);
+                                 obj2 = (Evas_Object *) eina_array_data_get(&e->temporary_objects, j);
                                  if (evas_object_is_opaque(obj2))
                                    e->engine.func->context_cutout_add(e->engine.data.output,
                                                                       e->engine.data.context,
@@ -1306,7 +1551,7 @@ evas_render_updates_internal(Evas *e,
                                            Evas_Coord obx, oby, obw, obh;
 
                                            obj2->func->get_opaque_rect
-                                             (obj2, &obx, &oby, &obw, &obh);
+                                              (obj2, &obx, &oby, &obw, &obh);
                                            if ((obw > 0) && (obh > 0))
                                              {
                                                 obx += off_x;
@@ -1323,31 +1568,32 @@ evas_render_updates_internal(Evas *e,
                                              }
                                         }
                                    }
-                             }
+                              }
 #endif
                             e->engine.func->context_clip_set(e->engine.data.output,
                                                              e->engine.data.context,
                                                              x, y, w, h);
                             clean_them |= evas_render_mapped(e, obj, e->engine.data.context,
-                                                            surface, off_x, off_y, 0
+                                                             surface, off_x, off_y, 0,
+                                                             cx, cy, cw, ch
 #ifdef REND_DGB
-                                                            , 1
+                                                             , 1
 #endif
-                                                            );
-                           e->engine.func->context_cutout_clear(e->engine.data.output,
-                                                                e->engine.data.context);
-                        }
-                   }
-              }
-            /* punch rect out */
-            e->engine.func->output_redraws_next_update_push(e->engine.data.output,
-                                                            surface,
-                                                            ux, uy, uw, uh);
-            /* free obscuring objects list */
-            eina_array_clean(&e->temporary_objects);
+                                                            );
+                            e->engine.func->context_cutout_clear(e->engine.data.output,
+                                                                 e->engine.data.context);
+                         }
+                    }
+               }
+             /* punch rect out */
+             e->engine.func->output_redraws_next_update_push(e->engine.data.output,
+                                                             surface,
+                                                             ux, uy, uw, uh);
+             /* free obscuring objects list */
+             eina_array_clean(&e->temporary_objects);
              RD("  ---]\n");
-         }
-       /* flush redraws */
+          }
+        /* flush redraws */
         if (haveup)
           {
              evas_event_callback_call(e, EVAS_CALLBACK_RENDER_FLUSH_PRE, NULL);
@@ -1360,39 +1606,37 @@ evas_render_updates_internal(Evas *e,
    /* and do a post render pass */
    for (i = 0; i < e->active_objects.count; ++i)
      {
-       Evas_Object *obj;
-
-       obj = eina_array_data_get(&e->active_objects, i);
-       obj->pre_render_done = 0;
+        obj = eina_array_data_get(&e->active_objects, i);
+        obj->pre_render_done = 0;
         RD("    OBJ [%p] post... %i %i\n", obj, obj->changed, do_draw);
-       if ((obj->changed) && (do_draw))
-         {
+        if ((obj->changed) && (do_draw))
+          {
              RD("    OBJ [%p] post... func1\n", obj);
-            obj->func->render_post(obj);
-            obj->restack = 0;
-            obj->changed = 0;
+             obj->func->render_post(obj);
+             obj->restack = 0;
+             obj->changed = 0;
              obj->changed_move_only = 0;
              obj->changed_nomove = 0;
              obj->changed_move = 0;
-         }
+          }
         else if ((obj->cur.map != obj->prev.map) ||
                  (obj->cur.usemap != obj->prev.usemap))
           {
              RD("    OBJ [%p] post... func2\n", obj);
-            obj->func->render_post(obj);
-            obj->restack = 0;
-            obj->changed = 0;
+             obj->func->render_post(obj);
+             obj->restack = 0;
+             obj->changed = 0;
              obj->changed_move_only = 0;
              obj->changed_nomove = 0;
              obj->changed_move = 0;
           }
-/* moved to other pre-process phase 1
-       if (obj->delete_me == 2)
-         {
-            delete_objects = eina_list_append(delete_objects, obj);
-         }
-       else if (obj->delete_me != 0) obj->delete_me++;
- */
+        /* moved to other pre-process phase 1
+           if (obj->delete_me == 2)
+           {
+           delete_objects = eina_list_append(delete_objects, obj);
+           }
+           else if (obj->delete_me != 0) obj->delete_me++;
        */
      }
    /* free our obscuring object list */
    eina_array_clean(&e->obscuring_objects);
@@ -1401,13 +1645,17 @@ evas_render_updates_internal(Evas *e,
       them from the pending list. */
    eina_array_remove(&e->pending_objects, pending_change, NULL);
 
+   for (i = 0; i < e->render_objects.count; ++i)
+     {
+        obj = eina_array_data_get(&e->render_objects, i);
+        obj->pre_render_done = 0;
+     }
+
    /* delete all objects flagged for deletion now */
    for (i = 0; i < e->delete_objects.count; ++i)
      {
-       Evas_Object *obj;
-
-       obj = eina_array_data_get(&e->delete_objects, i);
-       evas_object_free(obj, 1);
+        obj = eina_array_data_get(&e->delete_objects, i);
+        evas_object_free(obj, 1);
      }
    eina_array_clean(&e->delete_objects);
 
@@ -1416,24 +1664,16 @@ evas_render_updates_internal(Evas *e,
    e->output.changed = 0;
    e->invalidate = 0;
 
-   for (i = 0; i < e->render_objects.count; ++i)
-     {
-        Evas_Object *obj;
-
-        obj = eina_array_data_get(&e->render_objects, i);
-        obj->pre_render_done = 0;
-     }
-
    /* If their are some object to restack or some object to delete,
     * it's useless to keep the render object list around. */
    if (clean_them)
      {
-       eina_array_clean(&e->active_objects);
-       eina_array_clean(&e->render_objects);
-       eina_array_clean(&e->restack_objects);
-       eina_array_clean(&e->delete_objects);
+        eina_array_clean(&e->active_objects);
+        eina_array_clean(&e->render_objects);
+        eina_array_clean(&e->restack_objects);
+        eina_array_clean(&e->delete_objects);
         eina_array_clean(&e->obscuring_objects);
-       e->invalidate = 1;
+        e->invalidate = 1;
      }
 
    evas_module_clean();
@@ -1443,37 +1683,15 @@ evas_render_updates_internal(Evas *e,
    return updates;
 }
 
-/**
- * Free the rectangles returned by evas_render_updates().
- *
- * @param updates The list of updated rectangles of the canvas.
- *
- * This function removes the region from the render updates list. It
- * makes the region doesn't be render updated anymore.
- *
- * @ingroup Evas_Canvas
- */
 EAPI void
 evas_render_updates_free(Eina_List *updates)
 {
    Eina_Rectangle *r;
 
    EINA_LIST_FREE(updates, r)
-     eina_rectangle_free(r);
+      eina_rectangle_free(r);
 }
 
-/**
- * Force immediate renderization of the given canvas.
- *
- * @param e The given canvas pointer.
- * @return A newly allocated list of updated rectangles of the canvas.
- *         Free this list with evas_render_updates_free().
- *
- * This function forces an immediate renderization update of the given
- * given canvas.
- *
- * @ingroup Evas_Canvas
- */
 EAPI Eina_List *
 evas_render_updates(Evas *e)
 {
@@ -1489,13 +1707,6 @@ evas_render_updates(Evas *e)
    return evas_render_updates_internal(e, 1, 1);
 }
 
-/**
- * Force renderization of the given canvas.
- *
- * @param e The given canvas pointer.
- *
- * @ingroup Evas_Canvas
- */
 EAPI void
 evas_render(Evas *e)
 {
@@ -1511,20 +1722,6 @@ evas_render(Evas *e)
    evas_render_updates_internal(e, 0, 1);
 }
 
-/**
- * Update the canvas internal objects but not triggering immediate
- * renderization.
- *
- * @param e The given canvas pointer.
- *
- * This function updates the canvas internal objects not triggering
- * renderization. To force renderization function evas_render() should
- * be used.
- *
- * @see evas_render.
- *
- * @ingroup Evas_Canvas
- */
 EAPI void
 evas_norender(Evas *e)
 {
@@ -1532,21 +1729,10 @@ evas_norender(Evas *e)
    return;
    MAGIC_CHECK_END();
 
-//   if (!e->changed) return;
+   //   if (!e->changed) return;
    evas_render_updates_internal(e, 0, 0);
 }
 
-/**
- * Make the canvas discard internally cached data used for rendering.
- *
- * @param e The given canvas pointer.
- *
- * This function flushes the arrays of delete, active and render objects.
- * Other things it may also discard are: shared memory segments,
- * temporary scratch buffers, cached data to avoid re-compute of that data etc.
- *
- * @ingroup Evas_Canvas
- */
 EAPI void
 evas_render_idle_flush(Evas *e)
 {
@@ -1577,33 +1763,19 @@ evas_sync(Evas *e)
    return;
    MAGIC_CHECK_END();
 
-   evas_common_frameq_flush ();
+   evas_common_frameq_flush();
 #else
    (void) e;
 #endif
 }
 
-/**
- * Make the canvas discard as much data as possible used by the engine at
- * runtime.
- *
- * @param e The given canvas pointer.
- *
- * This function will unload images, delete textures and much more, where
- * possible. You may also want to call evas_render_idle_flush() immediately
- * prior to this to perhaps discard a little more, though evas_render_dump()
- * should implicitly delete most of what evas_render_idle_flush() might
- * discard too.
- *
- * @ingroup Evas_Canvas
- */
 static void
 _evas_render_dump_map_surfaces(Evas_Object *obj)
 {
    if ((obj->cur.map) && obj->cur.map->surface)
      {
         obj->layer->evas->engine.func->image_map_surface_free
-          (obj->layer->evas->engine.data.output, obj->cur.map->surface);
+           (obj->layer->evas->engine.data.output, obj->cur.map->surface);
         obj->cur.map->surface = NULL;
      }
 
@@ -1612,7 +1784,7 @@ _evas_render_dump_map_surfaces(Evas_Object *obj)
         Evas_Object *obj2;
 
         EINA_INLIST_FOREACH(evas_object_smart_members_get_direct(obj), obj2)
-          _evas_render_dump_map_surfaces(obj2);
+           _evas_render_dump_map_surfaces(obj2);
      }
 }
 
@@ -1632,7 +1804,7 @@ evas_render_dump(Evas *e)
         EINA_INLIST_FOREACH(lay->objects, obj)
           {
              if ((obj->type) && (!strcmp(obj->type, "image")))
-                evas_object_inform_call_image_unloaded(obj);
+               evas_object_inform_call_image_unloaded(obj);
              _evas_render_dump_map_surfaces(obj);
           }
      }
@@ -1667,17 +1839,19 @@ evas_render_object_recalc(Evas_Object *obj)
 #ifndef EVAS_FRAME_QUEUING
    if ((!obj->changed) && (obj->delete_me < 2))
 #else
-   if ((!obj->changed))
+     if ((!obj->changed))
 #endif
-     {
-       Evas *e;
+       {
+          Evas *e;
 
-       e = obj->layer->evas;
-       if ((!e) || (e->cleanup)) return;
+          e = obj->layer->evas;
+          if ((!e) || (e->cleanup)) return;
 #ifdef EVAS_FRAME_QUEUING
-        if (obj->delete_me >= evas_common_frameq_get_frameq_sz() + 2) return;
+          if (obj->delete_me >= evas_common_frameq_get_frameq_sz() + 2) return;
 #endif
-        eina_array_push(&e->pending_objects, obj);
-       obj->changed = 1;
-     }
+          eina_array_push(&e->pending_objects, obj);
+          obj->changed = 1;
+       }
 }
+
+/* vim:set ts=8 sw=3 sts=3 expandtab cino=>5n-2f0^-2{2(0W1st0 :*/