more map work. now only re-render map surface if size changed or any contents
authorCarsten Haitzler <raster@rasterman.com>
Sat, 31 Oct 2009 09:08:01 +0000 (09:08 +0000)
committerCarsten Haitzler <raster@rasterman.com>
Sat, 31 Oct 2009 09:08:01 +0000 (09:08 +0000)
changed. still renders all, but better now. keeps map surfacer around for
shits and giggles until map unset or object deleted. als be able to set
smooth map and disable alpha (for smart objects)

SVN revision: 43362

legacy/evas/src/lib/Evas.h
legacy/evas/src/lib/canvas/evas_map.c
legacy/evas/src/lib/canvas/evas_object_image.c
legacy/evas/src/lib/canvas/evas_render.c
legacy/evas/src/lib/include/evas_private.h
legacy/evas/src/modules/engines/software_generic/evas_engine.c

index 05dd2b7..9c3f17e 100644 (file)
@@ -858,6 +858,10 @@ extern "C" {
    EAPI void              evas_map_util_zoom                (Evas_Map *m, double zoomx, double zoomy, Evas_Coord cx, Evas_Coord cy);
 
    EAPI Evas_Map         *evas_map_new                      (int count);
+   EAPI void              evas_map_smooth_set               (Evas_Map *m, Eina_Bool enabled);
+   EAPI Eina_Bool         evas_map_smooth_get               (const Evas_Map *m);
+   EAPI void              evas_map_alpha_set                (Evas_Map *m, Eina_Bool enabled);
+   EAPI Eina_Bool         evas_map_alpha_get                (const Evas_Map *m);
    EAPI Evas_Map         *evas_map_dup                      (const Evas_Map *m);
    EAPI void              evas_map_free                     (Evas_Map *m);
    EAPI void              evas_map_point_coord_set          (Evas_Map *m, int idx, Evas_Coord x, Evas_Coord y, Evas_Coord z);
index 22f5634..0d31e1b 100644 (file)
@@ -66,6 +66,8 @@ _evas_map_new(int count)
    Evas_Map *m = calloc(1, sizeof(Evas_Map) + count * sizeof(Evas_Map_Point));
    if (!m) return NULL;
    m->count = count;
+   m->alpha = 1;
+   m->smooth = 1;
    return m;
 }
 
@@ -83,11 +85,12 @@ _evas_map_copy(Evas_Map *dst, const Evas_Map *src)
 {
    if (dst->count != src->count)
      {
-       ERR("cannot copy map of different sizes: dst=%lu, src=%lu",
-           dst->count, src->count);
+       ERR("cannot copy map of different sizes: dst=%i, src=%i", dst->count, src->count);
        return EINA_FALSE;
      }
    memcpy(dst->points, src->points, src->count * sizeof(Evas_Map_Point));
+   dst->smooth = src->smooth;
+   dst->alpha = src->alpha;
    return EINA_TRUE;
 }
 
@@ -204,6 +207,13 @@ evas_object_map_set(Evas_Object *obj, const Evas_Map *map)
      {
         if (obj->cur.map)
           {
+             if (obj->cur.map->surface)
+               {
+                  obj->layer->evas->engine.func->image_map_surface_free
+                    (obj->layer->evas->engine.data.output,
+                     obj->cur.map->surface);
+                  obj->cur.map->surface = NULL;
+               }
              obj->cur.geometry = obj->cur.map->normal_geometry;
              if (!obj->prev.map)
                {
@@ -284,13 +294,76 @@ evas_map_new(int count)
 {
    if (count != 4)
      {
-       ERR("num (%lu) != 4 is unsupported!", count);
+       ERR("num (%i) != 4 is unsupported!", count);
        return NULL;
      }
    return _evas_map_new(count);
 }
 
 /**
+ * Set the smoothing for map rendering
+ * 
+ * This sets smoothing for map rendering. If the object is a type that has
+ * its own smoothing settings, then both the smooth settings for this object
+ * and the map must be turned off. By default smooth maps are enabled.
+ * 
+ * @param m map to modify. Must not be NULL.
+ * @param enabled enable or disable smooth map rendering
+ */
+EAPI void
+evas_map_smooth_set(Evas_Map *m, Eina_Bool enabled)
+{
+   if (!m) return;
+   m->smooth = enabled;
+}
+
+/**
+ * get the smoothing for map rendering
+ * 
+ * This gets smoothing for map rendering.
+ * 
+ * @param m map to get the smooth from. Must not be NULL.
+ */
+EAPI Eina_Bool
+evas_map_smooth_get(const Evas_Map *m)
+{
+   if (!m) return 0;
+   return m->smooth;
+}
+
+/**
+ * Set the alpha flag for map rendering
+ * 
+ * This sets alpha flag for map rendering. If the object is a type that has
+ * its own alpha settings, then this will take precedence. Only image objects
+ * have this currently. Fits stops alpha blending of the map area, and is
+ * useful if you know the object and/or all sub-objects is 100% solid.
+ * 
+ * @param m map to modify. Must not be NULL.
+ * @param enabled enable or disable alpha map rendering
+ */
+EAPI void
+evas_map_alpha_set(Evas_Map *m, Eina_Bool enabled)
+{
+   if (!m) return;
+   m->alpha = enabled;
+}
+
+/**
+ * get the alpha flag for map rendering
+ * 
+ * This gets the alph flag for map rendering.
+ * 
+ * @param m map to get the alpha from. Must not be NULL.
+ */
+EAPI Eina_Bool
+evas_map_alpha_get(const Evas_Map *m)
+{
+   if (!m) return 0;
+   return m->alpha;
+}
+
+/**
  * Copy a previously allocated map.
  * 
  * This makes a duplicate of the @p m object and returns it.
index 0e49ca1..1754068 100644 (file)
@@ -2347,13 +2347,9 @@ evas_object_image_render(Evas_Object *obj, void *output, void *context, void *su
                   pt->u = p->u * FP1;
                   pt->v = p->v * FP1;
                }
-             obj->layer->evas->engine.func->image_map4_draw(output,
-                                                            context,
-                                                            surface,
-                                                            o->engine_data,
-                                                            pts,
-                                                            o->cur.smooth_scale,
-                                                            0);
+             obj->layer->evas->engine.func->image_map4_draw
+               (output, context, surface, o->engine_data, pts,
+                o->cur.smooth_scale | obj->cur.map->smooth, 0);
           }
         else
           {
index a0ea94b..77b4b09 100644 (file)
@@ -128,7 +128,7 @@ _evas_child_changed_propagate(Evas_Object *obj)
                  (obj2->changed))
                {
                   obj->changed = 1;
-                  return 1;
+                  return;
                }
              else if (obj2->smart.smart)
                {
@@ -182,42 +182,21 @@ _evas_render_phase1_object_process(Evas *e, Evas_Object *obj, Eina_Array *active
    if (!((obj->func->can_map) && (obj->func->can_map(obj))) &&
        ((obj->cur.map) && (obj->cur.map->count == 4) && (obj->cur.usemap)))
      {
-        if (obj->smart.smart)
-          {
-             _evas_child_changed_propagate(obj);
-//             printf("%p changed\n", obj);
-          }
+        if (obj->smart.smart) _evas_child_changed_propagate(obj);
         if (obj->changed)
           {
              if ((is_active) && (obj->restack) && (!obj->clip.clipees) &&
                  ((evas_object_is_visible(obj) && (!obj->cur.have_clipees)) ||
                   (evas_object_was_visible(obj) && (!obj->prev.have_clipees))))
-               {
-//                  printf("a\n");
-                  eina_array_push(restack_objects, obj);
-               }
+               eina_array_push(restack_objects, obj);
              else if ((is_active) && (!obj->clip.clipees) &&
                       ((evas_object_is_visible(obj) && (!obj->cur.have_clipees)) ||
                        (evas_object_was_visible(obj) && (!obj->prev.have_clipees))))
                {
-//                  printf("b\n");
                   eina_array_push(restack_objects, obj);
-//                  eina_array_push(render_objects, obj);
                   obj->render_pre = 1;
                }
           }
-//        printf("---\n");
-        /* for now all mapped objects are no logner opaque        
-        else
-          {
-             if (evas_object_is_opaque(obj) &&
-                 evas_object_is_visible(obj))
-               {
-                  eina_array_push(render_objects, obj);
-                  obj->rect_del = 1;
-               }
-          }
-         */
         return;
      }
    
@@ -229,7 +208,6 @@ _evas_render_phase1_object_process(Evas *e, Evas_Object *obj, Eina_Array *active
          {
             Evas_Object *obj2;
 
-//             printf("_evas_render_phase1_object_process smart1 %p\n", obj);
             eina_array_push(render_objects, obj);
             obj->render_pre = 1;
             EINA_INLIST_FOREACH(evas_object_smart_members_get_direct(obj), obj2)
@@ -267,7 +245,6 @@ _evas_render_phase1_object_process(Evas *e, Evas_Object *obj, Eina_Array *active
               {
                  Evas_Object *obj2;
 
-//             printf("_evas_render_phase1_object_process smart2 %p\n", obj);
                  eina_array_push(render_objects, obj);
                  obj->render_pre = 1;
                  EINA_INLIST_FOREACH(evas_object_smart_members_get_direct(obj), obj2)
@@ -406,16 +383,14 @@ evas_render_mapped(Evas *e, Evas_Object *obj, void *context, void *surface, int
      {
         const Evas_Map_Point *p, *p_end;
         RGBA_Map_Point pts[4], *pt;
-        void *ctx;
+        void *ctx, *ctx2;
+        int sw, sh;
+        int changed = 0;
         
-        if ((obj->cur.map->normal_geometry.w <= 0) || 
-            (obj->cur.map->normal_geometry.h <= 0))
-          return;
+        sw = obj->cur.map->normal_geometry.w;
+        sh = obj->cur.map->normal_geometry.h;
+        if ((sw <= 0) || (sh <= 0)) return;
              
-        static int level = 0;
-        
-        level++;
-//        printf("+-- mapped draw lv %i\n", level);
         p = obj->cur.map->points;
         p_end = p + 4;
         pt = pts;
@@ -428,60 +403,104 @@ evas_render_mapped(Evas *e, Evas_Object *obj, void *context, void *surface, int
              pt->v = p->v * FP1;
           }
         
-        
-        ctx = e->engine.func->context_new(e->engine.data.output);
+        if (obj->cur.map->surface)
+          {
+             if ((obj->cur.map->surface_w != sw) ||
+                 (obj->cur.map->surface_h != sh))
+               {
+                  obj->layer->evas->engine.func->image_map_surface_free
+                    (e->engine.data.output, obj->cur.map->surface);
+                  obj->cur.map->surface = NULL;
+               }
+          }
         if (!obj->cur.map->surface)
-          obj->cur.map->surface =
-          obj->layer->evas->engine.func->image_map_surface_new
-          (e->engine.data.output, obj->cur.map->normal_geometry.w,
-           obj->cur.map->normal_geometry.h, 1);
-        
-        // FIXME: only re-render if obj changed or smart children or size changed etc.
+          {
+             obj->cur.map->surface_w = sw;
+             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);
+             changed = 1;
+          }
         if (obj->smart.smart)
           {
              Evas_Object *obj2;
              
-             off_x = -obj->cur.map->normal_geometry.x;
-             off_y = -obj->cur.map->normal_geometry.y;
-/*             
-             printf("draw mapped smart obj %p, %ix%i, off %i %i [%i %i]\n",
-                    obj,
-                    obj->cur.map->normal_geometry.w, 
-                    obj->cur.map->normal_geometry.h,
-                    off_x, off_y,
-                    obj->cur.map->normal_geometry.x,
-                    obj->cur.map->normal_geometry.y);
- */
-             EINA_INLIST_FOREACH
-               (evas_object_smart_members_get_direct(obj), obj2)
+             EINA_INLIST_FOREACH(evas_object_smart_members_get_direct(obj), obj2)
                {
-                  if (evas_object_is_active(obj2) && 
-                      (!obj2->clip.clipees) &&
-                      ((evas_object_is_visible(obj2) && 
-                        (!obj2->cur.have_clipees))))
-                    evas_render_mapped(e, obj2, ctx, obj->cur.map->surface, 
-                                       off_x, off_y);
+                  if (!obj2->smart.smart)
+                    {
+                       if (obj2->changed)
+                         {
+                            obj2->changed = 0;
+                            changed = 1;
+                         }
+                    }
                }
+             obj->changed = 0;
           }
         else
+          changed = obj->changed;
+        
+        // clear surface before re-render
+        if ((changed) && (obj->cur.map->surface))
           {
-             off_x = -obj->cur.cache.clip.x;
-             off_y = -obj->cur.cache.clip.y;
-             obj->func->render(obj, e->engine.data.output, ctx,
-                               obj->cur.map->surface, off_x, off_y);
-          }
-        e->engine.func->context_free(e->engine.data.output, ctx);
+             ctx2 = e->engine.func->context_new(e->engine.data.output);
+             e->engine.func->context_color_set
+               (e->engine.data.output, ctx2, 0, 0, 0, 0);
+             e->engine.func->context_render_op_set
+               (e->engine.data.output, ctx2, EVAS_RENDER_COPY);
+             e->engine.func->rectangle_draw(e->engine.data.output,
+                                            ctx2,
+                                            obj->cur.map->surface,
+                                            0, 0, 
+                                            obj->cur.map->surface_w,
+                                            obj->cur.map->surface_h);
+             e->engine.func->context_free(e->engine.data.output, ctx2);
+             
+             ctx = e->engine.func->context_new(e->engine.data.output);
         
+             // FIXME: only re-render if obj changed or smart children or size changed etc.
+             if (obj->smart.smart)
+               {
+                  Evas_Object *obj2;
+                  
+                  off_x = -obj->cur.map->normal_geometry.x;
+                  off_y = -obj->cur.map->normal_geometry.y;
+                  EINA_INLIST_FOREACH
+                    (evas_object_smart_members_get_direct(obj), obj2)
+                    {
+                       if (evas_object_is_active(obj2) && 
+                           (!obj2->clip.clipees) &&
+                           ((evas_object_is_visible(obj2) && 
+                             (!obj2->cur.have_clipees))))
+                         evas_render_mapped(e, obj2, ctx, 
+                                            obj->cur.map->surface, 
+                                            off_x, off_y);
+                    }
+               }
+             else
+               {
+                  off_x = -obj->cur.cache.clip.x;
+                  off_y = -obj->cur.cache.clip.y;
+                  obj->func->render(obj, e->engine.data.output, ctx,
+                                    obj->cur.map->surface, off_x, off_y);
+               }
+             e->engine.func->context_free(e->engine.data.output, ctx);
+          }
+
         obj->layer->evas->engine.func->image_map4_draw
           (e->engine.data.output, e->engine.data.context, surface, 
-           obj->cur.map->surface, pts, 1, /*smooth? (on for now)*/ 0);
+           obj->cur.map->surface, 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;
-        level--;
-//        printf("+-- done\n");
+//        obj->layer->evas->engine.func->image_map_surface_free
+//          (e->engine.data.output, obj->cur.map->surface);
+//        obj->cur.map->surface = NULL;
      }
    else
      obj->func->render(obj, e->engine.data.output, context, surface, 
index 3b19aab..2ff66fe 100644 (file)
@@ -369,6 +369,9 @@ struct _Evas_Map
    int count;
    Evas_Coord_Rectangle normal_geometry;
    void *surface;
+   int surface_w, surface_h;
+   Eina_Bool alpha : 1;
+   Eina_Bool smooth : 1;
    Evas_Map_Point points[];
 };
 
index e4af6fa..fc2c9af 100644 (file)
@@ -796,8 +796,6 @@ eng_image_map_surface_new(void *data __UNUSED__, int w, int h, int alpha)
                                           w, h, NULL, alpha, 
                                           EVAS_COLORSPACE_ARGB8888);
    pixels = evas_cache_image_pixels(surface);
-   // FIXME: need a clear call
-   memset(pixels, 0, (w *h * sizeof(DATA32)));
    return surface;
 }