raster pushed a commit to branch master.

http://git.enlightenment.org/core/efl.git/commit/?id=49adf8aa47f37c41ee1fed288c828737104f1c5f

commit 49adf8aa47f37c41ee1fed288c828737104f1c5f
Author: Carsten Haitzler (Rasterman) <ras...@rasterman.com>
Date:   Wed Sep 23 22:22:27 2015 +0900

    evas tiler update handler - move to region code to be accurate and fast
    
    this move evas tiler that does update handling to use fully correct
    regions using region.[xh]. this also removed old unused regionbuf code
    and a bunch of commented out code no longer needed. much simpler now
    and easier to maintain.
---
 src/Makefile_Evas.am                       |   1 -
 src/lib/evas/common/evas_regionbuf.c       | 357 ------------
 src/lib/evas/common/evas_tiler.c           | 878 ++---------------------------
 src/lib/evas/include/evas_common_private.h |  93 +--
 4 files changed, 39 insertions(+), 1290 deletions(-)

diff --git a/src/Makefile_Evas.am b/src/Makefile_Evas.am
index 2fe051b..518c80a 100644
--- a/src/Makefile_Evas.am
+++ b/src/Makefile_Evas.am
@@ -298,7 +298,6 @@ lib/evas/common/evas_scale_smooth.c \
 lib/evas/common/evas_scale_span.c \
 lib/evas/common/evas_thread_render.c \
 lib/evas/common/evas_tiler.c \
-lib/evas/common/evas_regionbuf.c \
 lib/evas/common/evas_pipe.c \
 lib/evas/common/language/evas_bidi_utils.c \
 lib/evas/common/language/evas_language_utils.c \
diff --git a/src/lib/evas/common/evas_regionbuf.c 
b/src/lib/evas/common/evas_regionbuf.c
deleted file mode 100644
index 3b14af8..0000000
--- a/src/lib/evas/common/evas_regionbuf.c
+++ /dev/null
@@ -1,357 +0,0 @@
-#include "evas_common_private.h"
-
-#if 0
-Regionbuf *
-evas_common_regionbuf_new(int w, int h)
-{
-   Regionbuf *rb;
-
-   rb = calloc(1, sizeof(Regionbuf) + (h * sizeof(Regionspan)));
-   if (!rb) return NULL;
-   rb->spans = (Regionspan **)(rb + sizeof(Regionbuf));
-   rb->w = w;
-   rb->h = h;
-   return rb;
-}
-
-void
-evas_common_regionbuf_free(Regionbuf *rb)
-{
-   evas_common_regionbuf_clear(rb);
-   free(rb);
-}
-
-void
-evas_common_regionbuf_clear(Regionbuf *rb)
-{
-   int y;
-
-   for (y = 0; y < rb->h; y++)
-     {
-       while (rb->spans[y])
-         {
-            Regionspan *span;
-
-            span = rb->spans[y];
-            rb->spans[y] = eina_inlist_remove(rb->spans[y], rb->spans[y]);
-            free(span);
-         }
-     }
-}
-
-void
-evas_common_regionbuf_span_add(Regionbuf *rb, int x1, int x2, int y)
-{
-   Regionspan *span, *span2, *nspan, *sp_start, *sp_stop;
-
-   /* abort if outside */
-   if ((y < 0) ||
-       (y >= rb->h) ||
-       (x2 < 0) ||
-       (x1 >= rb->w)) return;
-   /* clip to horiz bounds */
-   if (x1 < 0) x1 = 0;
-   if (x2 < (rb->w - 1)) x2 = rb->w - 1;
-   sp_start = NULL;
-   sp_stop = NULL;
-   EINA_INLIST_FOREACH(rb->spans[y], span)
-     {
-       nspan = (Regionspan *)(EINA_INLIST_GET(span))->next;
-       /* we dont know what t do with the span yet */
-       if (!sp_start)
-         {
-            /* if new span starts before or on this span or just after
-             * with no gap */
-            if (x1 <= (span->x2 + 1))
-              sp_start = span;
-            /* if there is no next span */
-            if (!nspan)
-              {
-                 sp_stop = span;
-                 break;
-              }
-            /* if new span ends before the next span starts with a gap of
-             * 1 pixel (or more) */
-            else if (x2 < (nspan->x1 - 1))
-              {
-                 sp_stop = span;
-                 break;
-              }
-         }
-       /* we already know it already starts before or in sp_start */
-       else
-         {
-            /* there is no span after this one, so this has to be the stop */
-            if (!nspan)
-              {
-                 sp_stop = span;
-                 break;
-              }
-            /* if new span ends before the next span starts with a gap of
-             * 1 pixel (or more) */
-            else if (x2 < (nspan->x1 - 1))
-              {
-                 sp_stop = span;
-                 break;
-              }
-         }
-     }
-   /* sp_start is where the new span starts in or before */
-   /* sp_stop is where the new span stops in or after */
-   if ((sp_start) && (sp_stop))
-     {
-       /* same start and stop */
-       if (sp_start == sp_stop)
-         {
-            if (x2 < (sp_start->x1 - 1))
-              {
-                 span2 = calloc(1, sizeof(Regionspan));
-                 span2->x1 = x1;
-                 span2->x2 = x2;
-                 rb->spans[y] = eina_inlist_prepend_relative(rb->spans[y], 
span2, sp_start);
-                 return;
-              }
-            if (x1 < sp_start->x1)
-              sp_start->x1 = x1;
-            if (x2 > sp_start->x2)
-              sp_start->x2 = x2;
-            return;
-         }
-       else
-         {
-            Eina_Inlist *l;
-
-            /* remove all nodes after sp_start and before_sp_stop because
-             * the new  */
-            for (l = (EINA_INLIST_GET(sp_start))->next; l != 
EINA_INLIST_GET(sp_stop);)
-              {
-                 span = (Regionspan *)l;
-                 l = l->next;
-                 rb->spans[y] = eina_inlist_remove(rb->spans[y], span);
-                 free(span);
-              }
-            /* remove the end span */
-            rb->spans[y] = eina_inlist_remove(rb->spans[y], sp_stop);
-            /* if the new span is before the start span - extend */
-            if (x1 < sp_start->x1)
-              sp_start->x1 = x1;
-            /* if it goes beyond the stop span - extend stop span */
-            if (x2 > sp_stop->x2)
-              sp_stop->x2 = x2;
-            /* extend start span to stop span */
-            sp_start->x2 = sp_stop->x2;
-            /* don't need stop span anymore */
-            free(sp_stop);
-            return;
-         }
-     }
-   /* no start AND stop... just append */
-   span2 = calloc(1, sizeof(Regionspan));
-   span2->x1 = x1;
-   span2->x2 = x2;
-   rb->spans[y] = eina_inlist_append(rb->spans[y], span2);
-}
-
-void
-evas_common_regionbuf_span_del(Regionbuf *rb, int x1, int x2, int y)
-{
-   /* FIXME: del span */
-   Regionspan *span, *span2, *nspan, *sp_start, *sp_stop;
-
-   /* abort if outside */
-   if ((y < 0) ||
-       (y >= rb->h) ||
-       (x2 < 0) ||
-       (x1 >= rb->w)) return;
-   /* clip to horiz bounds */
-   if (x1 < 0) x1 = 0;
-   if (x2 < (rb->w - 1)) x2 = rb->w - 1;
-   sp_start = NULL;
-   sp_stop = NULL;
-   EINA_INLIST_FOREACH(rb->spans[y], span)
-     {
-       nspan = (Regionspan *)(EINA_INLIST_GET(l))->next;
-       /* we dont know what t do with the span yet */
-       if (!sp_start)
-         {
-            /* if new span starts before or on this span or just after
-             * with no gap */
-            if (x1 <= (span->x2))
-              sp_start = span;
-            /* if there is no next span */
-            if (!nspan)
-              {
-                 sp_stop = span;
-                 break;
-              }
-            /* if new span ends before the next span starts with a gap of
-             * 1 pixel (or more) */
-            else if (x2 < nspan->x1)
-              {
-                 sp_stop = span;
-                 break;
-              }
-         }
-       /* we already know it already starts before or in sp_start */
-       else
-         {
-            /* there is no span after this one, so this has to be the stop */
-            if (!nspan)
-              {
-                 sp_stop = span;
-                 break;
-              }
-            /* if new span ends before the next span starts with a gap of
-             * 1 pixel (or more) */
-            else if (x2 < nspan->x1)
-              {
-                 sp_stop = span;
-                 break;
-              }
-         }
-     }
-   /* sp_start is where the new span starts in or before */
-   /* sp_stop is where the new span stops in or after */
-   if ((sp_start) && (sp_stop))
-     {
-       /* same start and stop */
-       if (sp_start == sp_stop)
-         {
-            /* if it ends before this the span start starts... return */
-            if (x2 < sp_start->x1)
-              return;
-            /* it starts on or before this span */
-            else if (x1 <= sp_start->x1)
-              {
-                 /* right edge is within the span */
-                 if (x2 < sp_start->x2)
-                   {
-                      sp_start->x2 = x2;
-                      return;
-                   }
-                 else
-                   {
-                      rb->spans[y] = eina_inlist_remove(rb->spans[y], 
sp_start);
-                      return;
-                   }
-              }
-            /* it ends on or after the end of this span */
-            else if (x2 >= sp_start->x2)
-              {
-                 /* it starts after the start */
-                 if (x1 > sp_start->x1)
-                   {
-                      sp_start->x1 = x1;
-                      return;
-                   }
-                 /* remove it all */
-                 else
-                   {
-                      rb->spans[y] = eina_inlist_remove(rb->spans[y], 
sp_start);
-                      return;
-                   }
-                 return;
-              }
-            /* this breaks the span into 2 */
-            else
-              {
-                 span2 = calloc(1, sizeof(Regionspan));
-                 span2->x1 = sp_start->x1;
-                 span2->x2 = x1 - 1;
-                 rb->spans[y] = eina_inlist_prepend_relative(rb->spans[y], 
span2, sp_start);
-                 sp_start->x1 = x2 + 1;
-                 return;
-              }
-         }
-       else
-         {
-            Eina_Inlist *l;
-
-            /* remove all nodes after sp_start and before_sp_stop because
-             * the new  */
-            for (l = (EINA_INLIST_GET(sp_start))->next; l != 
EINA_INLIST_GET(sp_stop);)
-              {
-                 span = (Regionspan *)l;
-                 l = l->next;
-                 rb->spans[y] = eina_inlist_remove(rb->spans[y], span);
-                 free(span);
-              }
-            /* all of the start span is cut out */
-            if (x1 <= sp_start->x1)
-              {
-                 rb->spans[y] = eina_inlist_remove(rb->spans[y], sp_start);
-                 free(sp_start);
-              }
-            /* chup it off at the new span start */
-            else
-              sp_start->x2 = x1 - 1;
-            /* all of the end span is cut out */
-            if (x2 >= sp_stop->x2)
-              {
-                 rb->spans[y] = eina_inlist_remove(rb->spans[y], sp_stop);
-                 free(sp_stop);
-              }
-            /* chop it up at the end */
-            else
-              sp_stop->x1 = x2 + 1;
-            return;
-         }
-     }
-}
-
-Tilebuf_Rect *
-evas_common_regionbuf_rects_get(Regionbuf *rb)
-{
-   Tilebuf_Rect *rects = NULL, *r;
-   int y;
-
-   /* FIXME: take spans, make rects */
-   for (y = 0; y < rb->h; y++)
-     {
-       Regionspan *sp_start;
-       Eina_Inlist *l, *ll;
-
-       for (l = EINA_INLIST_GET(rb->spans[y]); l;)
-         {
-            Regionspan *span;
-            int yy;
-
-            sp_start = (Regionspan *)l;
-            l = l->next;
-            rb->spans[y] = eina_inlist_remove(rb->spans[y], sp_start);
-            for (yy = y + 1; yy < rb->h; yy++)
-              {
-                 int match = 0;
-
-                 for (ll = EINA_INLIST_GET(rb->spans[yy]); ll;)
-                   {
-                      span = (Regionspan *)ll;
-                      ll = ll->next;
-                      if (span->x1 == sp_start->x1)
-                        {
-                           if ((span->x1 != sp_start->x1) ||
-                               (span->x2 != sp_start->x2))
-                             {
-                                goto coallate;
-                             }
-                           match = 1;
-                           rb->spans[yy] = eina_inlist_remove(rb->spans[yy], 
span);
-                           free(span);
-                        }
-                   }
-                 if (!match) goto coallate;
-              }
-            coallate:
-            r = calloc(1, sizeof(Tilebuf_Rect));
-            r->x = sp_start->x1;
-            r->y = y;
-            r->w = sp_start->x2 - sp_start->x1 + 1;
-            r->h = yy - y;
-            rects = eina_inlist_append(rects, r);
-            free(sp_start);
-         }
-     }
-   evas_common_regionbuf_clear(rb);
-   return rects;
-}
-#endif
diff --git a/src/lib/evas/common/evas_tiler.c b/src/lib/evas/common/evas_tiler.c
index 2dbe9fd..74f5d18 100644
--- a/src/lib/evas/common/evas_tiler.c
+++ b/src/lib/evas/common/evas_tiler.c
@@ -1,684 +1,5 @@
 #include "evas_common_private.h"
-
-#define FUZZ 32
-#define MAXREG 24
-#define MAX_NODES 1024
-
-static inline void rect_list_node_pool_flush(void);
-static inline list_node_t *rect_list_node_pool_get(void);
-static inline void rect_list_node_pool_put(list_node_t *node);
-static inline void rect_init(rect_t *r, int x, int y, int w, int h);
-static inline void rect_list_append_node(list_t *rects, list_node_t *node);
-static inline void rect_list_append(list_t *rects, const rect_t r);
-static inline void rect_list_append_xywh(list_t *rects, int x, int y, int w, 
int h);
-static inline void rect_list_concat(list_t *rects, list_t *other);
-static inline list_node_t *rect_list_unlink_next(list_t *rects, list_node_t 
*parent_node);
-static inline void rect_list_del_next(list_t *rects, list_node_t *parent_node);
-static inline void rect_list_clear(list_t *rects);
-static inline void rect_list_del_split_strict(list_t *rects, const rect_t 
del_r);
-static inline list_node_t *rect_list_add_split_fuzzy(list_t *rects, 
list_node_t *node, int accepted_error);
-static inline void rect_list_merge_rects(list_t *rects, list_t *to_merge, int 
accepted_error);
-static inline void rect_list_add_split_fuzzy_and_merge(list_t *rects, 
list_node_t *node, int split_accepted_error, int merge_accepted_error);
-
-static const list_node_t list_node_zeroed = { NULL };
-static const list_t list_zeroed = { NULL, NULL };
-
-typedef struct list_node_pool
-{
-   list_node_t *node;
-   int len;
-   int max;
-} list_node_pool_t;
-
-static list_node_pool_t list_node_pool = { NULL, 0, MAX_NODES };
-
-static inline void
-rect_list_node_pool_flush(void)
-{
-   while (list_node_pool.node)
-     {
-        list_node_t *node = list_node_pool.node;
-        list_node_pool.node = node->next;
-        list_node_pool.len--;
-        free(node);
-     }
-}
-
-static inline list_node_t *
-rect_list_node_pool_get(void)
-{
-   if (list_node_pool.node)
-     {
-        list_node_t *node = list_node_pool.node;
-        list_node_pool.node = node->next;
-        list_node_pool.len--;
-        return node;
-     }
-   else return (list_node_t *)malloc(sizeof(rect_node_t));
-}
-
-static inline void
-rect_list_node_pool_put(list_node_t *node)
-{
-   if (list_node_pool.len < list_node_pool.max)
-     {
-        node->next = list_node_pool.node;
-        list_node_pool.node = node;
-        list_node_pool.len++;
-     }
-   else free(node);
-}
-
-static inline void
-rect_init(rect_t *r, int x, int y, int w, int h)
-{
-   r->area = w * h;
-   r->left = x;
-   r->top = y;
-   r->right = x + w;
-   r->bottom = y + h;
-   r->width = w;
-   r->height = h;
-}
-
-static inline void
-rect_list_append_node(list_t *rects, list_node_t *node)
-{
-   if (rects->tail)
-     {
-       rects->tail->next = node;
-       rects->tail = node;
-     }
-   else
-     {
-       rects->head = node;
-       rects->tail = node;
-     }
-}
-
-static inline void
-rect_list_append(list_t *rects, const rect_t r)
-{
-   rect_node_t *rect_node = (rect_node_t *)rect_list_node_pool_get();
-   rect_node->rect = r;
-   rect_node->_lst = list_node_zeroed;
-   rect_list_append_node(rects, (list_node_t *)rect_node);
-}
-
-static inline void
-rect_list_append_xywh(list_t *rects, int x, int y, int w, int h)
-{
-   rect_t r;
-   rect_init(&r, x, y, w, h);
-   rect_list_append(rects, r);
-}
-
-static inline void
-rect_list_concat(list_t *rects, list_t *other)
-{
-   if (!other->head) return;
-   if (rects->tail)
-     {
-       rects->tail->next = other->head;
-       rects->tail = other->tail;
-     }
-   else
-     {
-       rects->head = other->head;
-       rects->tail = other->tail;
-     }
-   *other = list_zeroed;
-}
-
-static inline list_node_t *
-rect_list_unlink_next(list_t *rects, list_node_t *parent_node)
-{
-   list_node_t *node;
-   
-   if (parent_node)
-     {
-        node = parent_node->next;
-        parent_node->next = node->next;
-     }
-   else
-     {
-        node = rects->head;
-        rects->head = node->next;
-     }
-   if (rects->tail == node) rects->tail = parent_node;
-   *node = list_node_zeroed;
-   return node;
-}
-
-static inline void
-rect_list_del_next(list_t *rects, list_node_t *parent_node)
-{
-    list_node_t *node = rect_list_unlink_next(rects, parent_node);
-    rect_list_node_pool_put(node);
-}
-
-static inline void
-rect_list_clear(list_t *rects)
-{
-   list_node_t *node = rects->head;
-   while (node)
-     {
-        list_node_t *aux;
-        
-        aux = node->next;
-        rect_list_node_pool_put(node);
-        node = aux;
-     }
-   *rects = list_zeroed;
-}
-
-static inline void
-_calc_intra_rect_area(const rect_t a, const rect_t b, int *width, int *height)
-{
-   int max_left, min_right, max_top, min_bottom;
-
-   if (a.left < b.left) max_left = b.left;
-   else max_left = a.left;
-   if (a.right < b.right) min_right = a.right;
-   else min_right = b.right;
-   *width = min_right - max_left;
-
-   if (a.top < b.top) max_top = b.top;
-   else max_top = a.top;
-   if (a.bottom < b.bottom) min_bottom = a.bottom;
-   else min_bottom = b.bottom;
-   *height = min_bottom - max_top;
-}
-
-static inline void
-_split_strict(list_t *dirty, const rect_t current, rect_t r)
-{
-   int h_1, h_2, w_1, w_2;
-
-   h_1 = current.top - r.top;
-   h_2 = r.bottom - current.bottom;
-   w_1 = current.left - r.left;
-   w_2 = r.right - current.right;
-   if (h_1 > 0)
-     {
-       /*    .--.r (b)                .---.r2
-         *    |  |                     |   |
-         *  .-------.cur (a) .---.r    '---'
-         *  | |  |  |     -> |   |   +
-         *  | `--'  |        `---'
-         *  `-------'
-         */
-        rect_list_append_xywh(dirty, r.left, r.top, r.width, h_1);
-        r.height -= h_1;
-        r.top = current.top;
-     }
-   if (h_2 > 0)
-     {
-        /*  .-------.cur (a)
-         *  | .---. |        .---.r
-         *  | |   | |    ->  |   |
-         *  `-------'        `---'   +  .---.r2
-         *    |   |                     |   |
-         *    `---'r (b)                `---'
-         */
-        rect_list_append_xywh(dirty, r.left, current.bottom, r.width, h_2);
-        r.height -= h_2;
-     }
-   if (w_1 > 0)
-     {
-        /* (b) r  .----.cur (a)
-         *     .--|-.  |      .--.r2   .-.r
-         *     |  | |  |  ->  |  |   + | |
-         *     `--|-'  |      `--'     `-'
-         *        `----'
-         */
-        rect_list_append_xywh(dirty, r.left, r.top, w_1, r.height);
-        /* not necessary to keep these, r (b) will be destroyed */
-        /* r.width -= w_1; */
-        /* r.left = current.left; */
-     }
-   if (w_2 > 0)
-     {
-        /*  .----.cur (a)
-         *  |    |
-         *  |  .-|--.r (b)  .-.r   .--.r2
-         *  |  | |  |    -> | |  + |  |
-         *  |  `-|--'       `-'    `--'
-         *  `----'
-         */
-        rect_list_append_xywh(dirty, current.right, r.top, w_2, r.height);
-        /* not necessary to keep this, r (b) will be destroyed */
-        /* r.width -= w_2; */
-     }
-}
-
-static inline void
-rect_list_del_split_strict(list_t *rects, const rect_t del_r)
-{
-   list_t modified = list_zeroed;
-   list_node_t *cur_node, *prev_node;
-   int intra_width, intra_height;
-   rect_t current;
-
-   prev_node = NULL;
-   cur_node = rects->head;
-   while (cur_node)
-     {
-        current = ((rect_node_t*)cur_node)->rect;
-        _calc_intra_rect_area(del_r, current, &intra_width, &intra_height);
-        if ((intra_width <= 0) || (intra_height <= 0))
-          {
-             /*  .---.current      .---.del_r
-              *  |   |             |   |
-              *  `---+---.del_r    `---+---.current
-              *      |   |             |   |
-              *      `---'             `---'
-              * no interception, nothing to do
-              */
-              prev_node = cur_node;
-              cur_node = cur_node->next;
-          }
-        else if ((intra_width == current.width) &&
-                 (intra_height == current.height))
-          {
-             /*  .-------.del_r
-              *  | .---. |
-              *  | |   | |
-              *  | `---'current
-              *  `-------'
-              * current is contained, remove from rects
-              */
-              cur_node = cur_node->next;
-              rect_list_del_next(rects, prev_node);
-          }
-        else
-          {
-              _split_strict(&modified, del_r, current);
-              cur_node = cur_node->next;
-              rect_list_del_next(rects, prev_node);
-          }
-     }
-
-   rect_list_concat(rects, &modified);
-}
-
-static inline void
-_calc_intra_outer_rect_area(const rect_t a, const rect_t b,
-                            rect_t *intra, rect_t *outer)
-{
-   int min_left, max_left, min_right, max_right;
-   int min_top, max_top, min_bottom, max_bottom;
-   
-   if (a.left < b.left)
-     {
-        max_left = b.left;
-        min_left = a.left;
-     }
-   else
-     {
-        max_left = a.left;
-        min_left = b.left;
-     }
-   if (a.right < b.right)
-     {
-        min_right = a.right;
-        max_right = b.right;
-     }
-   else
-     {
-        min_right = b.right;
-        max_right = a.right;
-     }
-   intra->left = max_left;
-   intra->right = min_right;
-   intra->width = min_right - max_left;
-   outer->left = min_left;
-   outer->right = max_right;
-   outer->width = max_right - min_left;
-   if (a.top < b.top)
-     {
-       max_top = b.top;
-        min_top = a.top;
-     }
-   else
-     {
-        max_top = a.top;
-        min_top = b.top;
-     }
-   if (a.bottom < b.bottom)
-     {
-        min_bottom = a.bottom;
-        max_bottom = b.bottom;
-     }
-   else
-     {
-        min_bottom = b.bottom;
-        max_bottom = a.bottom;
-     }
-   intra->top = max_top;
-   intra->bottom = min_bottom;
-   intra->height = min_bottom - max_top;
-   if ((intra->width > 0) && (intra->height > 0))
-     intra->area = intra->width * intra->height;
-   else
-     intra->area = 0;
-   outer->top = min_top;
-   outer->bottom = max_bottom;
-   outer->height = max_bottom - min_top;
-   outer->area = outer->width * outer->height;
-}
-
-enum
-{
-   SPLIT_FUZZY_ACTION_NONE,
-   SPLIT_FUZZY_ACTION_SPLIT,
-   SPLIT_FUZZY_ACTION_MERGE
-};
-
-static inline int
-_split_fuzzy(list_t *dirty, const rect_t a, rect_t *b)
-{
-   int h_1, h_2, w_1, w_2, action;
-
-   h_1 = a.top - b->top;
-   h_2 = b->bottom - a.bottom;
-   w_1 = a.left - b->left;
-   w_2 = b->right - a.right;
-
-   action = SPLIT_FUZZY_ACTION_NONE;
-   if (h_1 > 0)
-     {
-        /*    .--.r (b)                .---.r2
-         *    |  |                     |   |
-         *  .-------.cur (a) .---.r    '---'
-         *  | |  |  |     -> |   |   +
-         *  | `--'  |        `---'
-         *  `-------'
-         */
-        rect_list_append_xywh(dirty, b->left, b->top, b->width, h_1);
-        b->height -= h_1;
-        b->top = a.top;
-        action = SPLIT_FUZZY_ACTION_SPLIT;
-     }
-   if (h_2 > 0)
-     {
-        /*  .-------.cur (a)
-         *  | .---. |        .---.r
-         *  | |   | |    ->  |   |
-         *  `-------'        `---'   +  .---.r2
-         *    |   |                     |   |
-         *    `---'r (b)                `---'
-         */
-        rect_list_append_xywh(dirty, b->left, a.bottom, b->width, h_2);
-        b->height -= h_2;
-        action = SPLIT_FUZZY_ACTION_SPLIT;
-     }
-   if (((w_1 > 0) || (w_2 > 0)) && (a.height == b->height))
-     return SPLIT_FUZZY_ACTION_MERGE;
-   if (w_1 > 0)
-     {
-        /* (b)  r  .----.cur (a)
-         *      .--|-.  |      .--.r2   .-.r
-         *      |  | |  |  ->  |  |   + | |
-         *      `--|-'  |      `--'     `-'
-         *         `----'
-         */
-        rect_list_append_xywh(dirty, b->left, b->top, w_1, b->height);
-        /* not necessary to keep these, r (b) will be destroyed */
-        /* b->width -= w_1; */
-        /* b->left = a.left; */
-        action = SPLIT_FUZZY_ACTION_SPLIT;
-     }
-   if (w_2 > 0)
-     {
-        /* .----.cur (a)
-         * |    |
-         * |  .-|--.r (b)  .-.r   .--.r2
-         * |  | |  |    -> | |  + |  |
-         * |  `-|--'       `-'    `--'
-         * `----'
-         */
-        rect_list_append_xywh(dirty, a.right, b->top, w_2, b->height);
-        /* not necessary to keep these, r (b) will be destroyed */
-        /* b->width -= w_2; */
-        action = SPLIT_FUZZY_ACTION_SPLIT;
-     }
-   return action;
-}
-
-static inline list_node_t *
-rect_list_add_split_fuzzy(list_t *rects, list_node_t *node, int accepted_error)
-{
-   list_t dirty = list_zeroed;
-   list_node_t *old_last = rects->tail;
-
-   if (!rects->head)
-     {
-        rect_list_append_node(rects, node);
-        return old_last;
-     }
-   rect_list_append_node(&dirty, node);
-   while (dirty.head)
-     {
-       list_node_t *d_node, *cur_node, *prev_cur_node;
-        int keep_dirty;
-        rect_t r;
-
-        d_node = rect_list_unlink_next(&dirty, NULL);
-        r = ((rect_node_t *)d_node)->rect;
-        prev_cur_node = NULL;
-        cur_node = rects->head;
-        keep_dirty = 1;
-        while (cur_node)
-         {
-            int area, action;
-            rect_t current, intra, outer;
-
-            current = ((rect_node_t *)cur_node)->rect;
-            _calc_intra_outer_rect_area(r, current, &intra, &outer);
-            area = current.area + r.area - intra.area;
-            if ((intra.width == r.width) && (intra.height == r.height))
-              {
-                 /*  .-------.cur
-                  *  | .---.r|
-                  *  | |   | |
-                  *  | `---' |
-                  *  `-------'
-                  */
-                 keep_dirty = 0;
-                 break;
-              }
-            else if ((intra.width == current.width) &&
-                     (intra.height == current.height))
-              {
-                 /* .-------.r
-                  * | .---.cur
-                  * | |   | |
-                  * | `---' |
-                  * `-------'
-                  */
-                 if (old_last == cur_node)
-                    old_last = prev_cur_node;
-                 cur_node = cur_node->next;
-                 rect_list_del_next(rects, prev_cur_node);
-              }
-            else if ((outer.area - area) <= accepted_error)
-              {
-                 /* .-----------. bounding box (outer)
-                  * |.---. .---.|
-                  * ||cur| |r  ||
-                  * ||   | |   ||
-                  * |`---' `---'|
-                  * `-----------'
-                  * merge them, remove both and add merged
-                  */
-                 rect_node_t *n;
-
-                 if (old_last == cur_node)
-                    old_last = prev_cur_node;
-
-                 n = (rect_node_t *)rect_list_unlink_next(rects, 
prev_cur_node);
-                 n->rect = outer;
-                 rect_list_append_node(&dirty, (list_node_t *)n);
-
-                 keep_dirty = 0;
-                 break;
-              }
-            else if ((intra.area - area) <= accepted_error)
-              {
-                 /*  .---.cur     .---.r
-                  *  |   |        |   |
-                  *  `---+---.r   `---+---.cur
-                  *      |   |        |   |
-                  *      `---'        `---'
-                  *  no split, no merge
-                  */
-                 prev_cur_node = cur_node;
-                 cur_node = cur_node->next;
-              }
-            else
-              {
-                 /* split is required */
-                 action = _split_fuzzy(&dirty, current, &r);
-                 if (action == SPLIT_FUZZY_ACTION_MERGE)
-                   {
-                      /* horizontal merge is possible: remove both, add merged 
*/
-                      rect_node_t *n;
-
-                      if (old_last == cur_node)
-                        old_last = prev_cur_node;
-
-                      n = (rect_node_t *)
-                        rect_list_unlink_next(rects, prev_cur_node);
-
-                      n->rect.left = outer.left;
-                      n->rect.width = outer.width;
-                      n->rect.right = outer.right;
-                      n->rect.area = outer.width * r.height;
-                      rect_list_append_node(&dirty, (list_node_t *)n);
-                   }
-                 else if (action == SPLIT_FUZZY_ACTION_NONE)
-                   {
-                      /* this rect check was totally useless,
-                       * should never happen */
-                      /* prev_cur_node = cur_node; */
-                      /* cur_node = cur_node->next; */
-                      WRN("Should not get here!");
-                      abort();
-                   }
-                 keep_dirty = 0;
-                 break;
-              }
-         }
-        if (UNLIKELY(keep_dirty)) rect_list_append_node(rects, d_node);
-        else rect_list_node_pool_put(d_node);
-     }
-    return old_last;
-}
-
-static inline void
-_calc_outer_rect_area(const rect_t a, const rect_t b, rect_t *outer)
-{
-   int min_left, max_right;
-   int min_top, max_bottom;
-
-   if (a.left < b.left) min_left = a.left;
-   else min_left = b.left;
-   if (a.right < b.right) max_right = b.right;
-   else max_right = a.right;
-   outer->left = min_left;
-   outer->right = max_right;
-   outer->width = max_right - min_left;
-   if (a.top < b.top) min_top = a.top;
-   else min_top = b.top;
-   if (a.bottom < b.bottom) max_bottom = b.bottom;
-   else max_bottom = a.bottom;
-   outer->top = min_top;
-   outer->bottom = max_bottom;
-   outer->height = max_bottom - min_top;
-   outer->area = outer->width * outer->height;
-}
-
-static inline void
-rect_list_merge_rects(list_t *rects, list_t *to_merge, int accepted_error)
-{
-   while (to_merge->head)
-     {
-        list_node_t *node, *parent_node;
-        rect_t r1;
-        int merged;
-
-        r1 = ((rect_node_t *)to_merge->head)->rect;
-        merged = 0;
-        parent_node = NULL;
-        node = rects->head;
-        while (node)
-         {
-            rect_t r2, outer;
-            int area;
-
-            r2 = ((rect_node_t *)node)->rect;
-            _calc_outer_rect_area(r1, r2, &outer);
-            area = r1.area + r2.area; /* intra area is taken as 0 */
-            if (outer.area - area <= accepted_error)
-              {
-                 /* remove both r1 and r2, create r3
-                  * actually r3 uses r2 instance, saves memory */
-                 rect_node_t *n;
-
-                 n = (rect_node_t *)rect_list_unlink_next(rects, parent_node);
-                 n->rect = outer;
-                 rect_list_append_node(to_merge, (list_node_t *)n);
-                 merged = 1;
-                 break;
-              }
-            parent_node = node;
-            node = node->next;
-         }
-        if (!merged)
-         {
-            list_node_t *n;
-            n = rect_list_unlink_next(to_merge, NULL);
-            rect_list_append_node(rects, n);
-         }
-       else
-         rect_list_del_next(to_merge, NULL);
-    }
-}
-
-static inline void
-rect_list_add_split_fuzzy_and_merge(list_t *rects,
-                                    list_node_t *node,
-                                    int split_accepted_error,
-                                    int merge_accepted_error)
-{
-   list_node_t *n;
-
-   n = rect_list_add_split_fuzzy(rects, node, split_accepted_error);
-   if (n && n->next)
-     {
-        list_t to_merge;
-        /* split list into 2 segments, already merged and to merge */
-        to_merge.head = n->next;
-        to_merge.tail = rects->tail;
-        rects->tail = n;
-        n->next = NULL;
-        rect_list_merge_rects(rects, &to_merge, merge_accepted_error);
-     }
-}
-
-static inline int
-_add_redraw(list_t *rects, int x, int y, int w, int h, int fuzz)
-{
-   rect_node_t *rn;
-   rn = (rect_node_t *)rect_list_node_pool_get();
-   rn->_lst = list_node_zeroed;
-   rect_init(&rn->rect, x, y, w, h);
-   rect_list_add_split_fuzzy_and_merge(rects, (list_node_t *)rn, fuzz, fuzz);
-   return 1;
-}
-
-/////////////////////////////////////////////////////////////////
+#include "region.h"
 
 EAPI void
 evas_common_tilebuf_init(void)
@@ -688,79 +9,49 @@ evas_common_tilebuf_init(void)
 EAPI Tilebuf *
 evas_common_tilebuf_new(int w, int h)
 {
-   Tilebuf *tb;
-
-   tb = calloc(1, sizeof(Tilebuf));
-   if (!tb) return NULL;
-   tb->tile_size.w = 8;
-   tb->tile_size.h = 8;
+   Tilebuf *tb = malloc(sizeof(Tilebuf));
    tb->outbuf_w = w;
    tb->outbuf_h = h;
+   tb->region = region_new(tb->outbuf_w, tb->outbuf_h);
    return tb;
 }
 
 EAPI void
 evas_common_tilebuf_free(Tilebuf *tb)
 {
-   rect_list_clear(&tb->rects);
-   rect_list_node_pool_flush();
+   region_free(tb->region);
    free(tb);
 }
 
 EAPI void
-evas_common_tilebuf_set_tile_size(Tilebuf *tb, int tw, int th)
+evas_common_tilebuf_set_tile_size(Tilebuf *tb EINA_UNUSED, int tw EINA_UNUSED, 
int th EINA_UNUSED)
 {
-   tb->tile_size.w = tw;
-   tb->tile_size.h = th;
 }
 
 EAPI void
-evas_common_tilebuf_get_tile_size(Tilebuf *tb, int *tw, int *th)
+evas_common_tilebuf_get_tile_size(Tilebuf *tb EINA_UNUSED, int *tw, int *th)
 {
-   if (tw) *tw = tb->tile_size.w;
-   if (th) *th = tb->tile_size.h;
+   if (tw) *tw = 1;
+   if (th) *th = 1;
 }
 
 EAPI void
-evas_common_tilebuf_tile_strict_set(Tilebuf *tb, Eina_Bool strict)
+evas_common_tilebuf_tile_strict_set(Tilebuf *tb EINA_UNUSED, Eina_Bool strict 
EINA_UNUSED)
 {
-   tb->strict_tiles = strict;
 }
 
 EAPI int
 evas_common_tilebuf_add_redraw(Tilebuf *tb, int x, int y, int w, int h)
 {
-   if ((w <= 0) || (h <= 0)) return 0;
-   RECTS_CLIP_TO_RECT(x, y, w, h, 0, 0, tb->outbuf_w, tb->outbuf_h);
-   if ((w <= 0) || (h <= 0)) return 0;
-   // optimize a common case -> adding the exact same rect 2x in a row
-   if ((tb->prev_add.x == x) && (tb->prev_add.y == y) && 
-       (tb->prev_add.w == w) && (tb->prev_add.h == h)) return 1;
-   tb->prev_add.x = x; tb->prev_add.y = y;
-   tb->prev_add.w = w; tb->prev_add.h = h;
-   tb->prev_del.w = 0; tb->prev_del.h = 0;
-   return _add_redraw(&tb->rects, x, y, w, h, FUZZ * FUZZ);
+   region_rect_add(tb->region, x, y, w, h);
+   return 1;
 }
 
 EAPI int
 evas_common_tilebuf_del_redraw(Tilebuf *tb, int x, int y, int w, int h)
 {
-   rect_t r;
-
-   if (!tb->rects.head) return 0;
-   if ((w <= 0) || (h <= 0)) return 0;
-   RECTS_CLIP_TO_RECT(x, y, w, h, 0, 0, tb->outbuf_w, tb->outbuf_h);
-   if ((w <= 0) || (h <= 0)) return 0;
-   // optimize a common case -> deleting the exact same rect 2x in a row
-   if ((tb->prev_del.x == x) && (tb->prev_del.y == y) && 
-       (tb->prev_del.w == w) && (tb->prev_del.h == h)) return 1;
-   tb->prev_del.x = x; tb->prev_del.y = y;
-   tb->prev_del.w = w; tb->prev_del.h = h;
-   tb->prev_add.w = 0; tb->prev_add.h = 0;
-   rect_init(&r, x, y, w, h);
-   rect_list_del_split_strict(&tb->rects, r);
-   tb->need_merge = 1;
-   return 0;
+   region_rect_del(tb->region, x, y, w, h);
+   return 1;
 }
 
 EAPI int
@@ -772,134 +63,41 @@ evas_common_tilebuf_add_motion_vector(Tilebuf *tb 
EINA_UNUSED, int x EINA_UNUSED
 EAPI void
 evas_common_tilebuf_clear(Tilebuf *tb)
 {
-   tb->prev_add.x = tb->prev_add.y = tb->prev_add.w = tb->prev_add.h = 0;
-   tb->prev_del.x = tb->prev_del.y = tb->prev_del.w = tb->prev_del.h = 0;
-   rect_list_clear(&tb->rects);
-   tb->need_merge = 0;
+   region_free(tb->region);
+   tb->region = region_new(tb->outbuf_w, tb->outbuf_h);
 }
 
 EAPI Tilebuf_Rect *
 evas_common_tilebuf_get_render_rects(Tilebuf *tb)
 {
-   list_node_t *n;
-   list_t to_merge;
-   Tilebuf_Rect *rects = NULL, *rbuf, *r;
-   int bx1 = 0, bx2 = 0, by1 = 0, by2 = 0, num = 0, x1, x2, y1, y2, i;
+   Tilebuf_Rect *rects = NULL, *r, *rend, *rbuf;
+   Box *rects2, *rs;
+   int n;
 
-/* don't need this since the below is now always on
-   if (tb->need_merge)
-     {
-        to_merge = tb->rects;
-        tb->rects = list_zeroed;
-        rect_list_merge_rects(&tb->rects, &to_merge, 0);
-        tb->need_merge = 0;
-     }
- */
-   if (1)
-// always fuzz merge for optimal perf
-//   if (!tb->strict_tiles)
-     {
-        // round up rects to tb->tile_size.w and tb->tile_size.h
-        to_merge = list_zeroed;
-        for (n = tb->rects.head; n; n = n->next)
-          {
-             x1 = ((rect_node_t *)n)->rect.left;
-             x2 = x1 + ((rect_node_t *)n)->rect.width;
-             y1 = ((rect_node_t *)n)->rect.top;
-             y2 = y1 + ((rect_node_t *)n)->rect.height;
-             x1 = tb->tile_size.w * (x1 / tb->tile_size.w);
-             y1 = tb->tile_size.h * (y1 / tb->tile_size.h);
-             x2 = tb->tile_size.w * ((x2 + tb->tile_size.w - 1) / 
tb->tile_size.w);
-             y2 = tb->tile_size.h * ((y2 + tb->tile_size.h - 1) / 
tb->tile_size.h);
-             _add_redraw(&to_merge, x1, y1, x2 - x1, y2 - y1, 0);
-          }
-        rect_list_clear(&tb->rects);
-        rect_list_merge_rects(&tb->rects, &to_merge, 0);
-     }
-   n = tb->rects.head;
-   if (n)
-     {
-        RECTS_CLIP_TO_RECT(((rect_node_t *)n)->rect.left,
-                           ((rect_node_t *)n)->rect.top,
-                           ((rect_node_t *)n)->rect.width,
-                           ((rect_node_t *)n)->rect.height,
-                           0, 0, tb->outbuf_w, tb->outbuf_h);
-        num = 1;
-        bx1 = ((rect_node_t *)n)->rect.left;
-        bx2 = bx1 + ((rect_node_t *)n)->rect.width;
-        by1 = ((rect_node_t *)n)->rect.top;
-        by2 = by1 + ((rect_node_t *)n)->rect.height;
-        n = n->next;
-        for (; n; n = n->next)
-          {
-             RECTS_CLIP_TO_RECT(((rect_node_t *)n)->rect.left,
-                                ((rect_node_t *)n)->rect.top,
-                                ((rect_node_t *)n)->rect.width,
-                                ((rect_node_t *)n)->rect.height,
-                                0, 0, tb->outbuf_w, tb->outbuf_h);
-             x1 = ((rect_node_t *)n)->rect.left;
-             if (x1 < bx1) bx1 = x1;
-             x2 = x1 + ((rect_node_t *)n)->rect.width;
-             if (x2 > bx2) bx2 = x2;
-             
-             y1 = ((rect_node_t *)n)->rect.top;
-             if (y1 < by1) by1 = y1;
-             y2 = y1 + ((rect_node_t *)n)->rect.height;
-             if (y2 > by2) by2 = y2;
-             num++;
-          }
-     }
-   else
-     return NULL;
-   
-   /* magic number - if we have > MAXREG regions to update, take bounding */
-   if (num > MAXREG)
-     {
-        r = malloc(sizeof(Tilebuf_Rect));
-        if (r)
-          {
-             EINA_INLIST_GET(r)->next = NULL;
-             EINA_INLIST_GET(r)->prev = NULL;
-             EINA_INLIST_GET(r)->last = NULL;
-             r->x = bx1;
-             r->y = by1;
-             r->w = bx2 - bx1;
-             r->h = by2 - by1;
-             rects = (Tilebuf_Rect *)
-               eina_inlist_append(EINA_INLIST_GET(rects),
-                                  EINA_INLIST_GET(r));
-          }
-        return rects;
-     }
+   rects2 = region_rects(tb->region);
+   if (!rects2) return NULL;
+   n = region_rects_num(tb->region);
+   if (n <= 0) return NULL;
 
-   rbuf = malloc(sizeof(Tilebuf_Rect) * num);
+   rbuf = malloc(n * sizeof(Tilebuf_Rect));
    if (!rbuf) return NULL;
 
-   for (i = 0, n = tb->rects.head; n; n = n->next)
-     {
-        rect_t cur;
-
-        cur = ((rect_node_t *)n)->rect;
-        if ((cur.width > 0) && (cur.height > 0))
-          {
-             r = &(rbuf[i]);
-             EINA_INLIST_GET(r)->next = NULL;
-             EINA_INLIST_GET(r)->prev = NULL;
-             EINA_INLIST_GET(r)->last = NULL;
-             r->x = cur.left;
-             r->y = cur.top;
-             r->w = cur.width;
-             r->h = cur.height;
-             rects = (Tilebuf_Rect *)
-               eina_inlist_append(EINA_INLIST_GET(rects),
-                                  EINA_INLIST_GET(r));
-             i++;
-          }
+   rend = rbuf + n;
+   rs = rects2;
+   for (r = rbuf; r < rend; r++)
+     {
+        EINA_INLIST_GET(r)->next = NULL;
+        EINA_INLIST_GET(r)->prev = NULL;
+        EINA_INLIST_GET(r)->last = NULL;
+        r->x = rs->x1;
+        r->y = rs->y1;
+        r->w = rs->x2 - rs->x1;
+        r->h = rs->y2 - rs->y1;
+        rs++;
+        rects = (Tilebuf_Rect *)
+          eina_inlist_append(EINA_INLIST_GET(rects),
+                             EINA_INLIST_GET(r));
      }
-
-   // It is possible that due to the clipping we do not return any rectangle 
here.
-   if (!rects) free(rbuf);
-
    return rects;
 }
 
diff --git a/src/lib/evas/include/evas_common_private.h 
b/src/lib/evas/include/evas_common_private.h
index 52c6b26..c7ab1ba 100644
--- a/src/lib/evas/include/evas_common_private.h
+++ b/src/lib/evas/include/evas_common_private.h
@@ -433,7 +433,6 @@ typedef struct _Cutout_Rects            Cutout_Rects;
 typedef struct _Convert_Pal             Convert_Pal;
 
 typedef struct _Tilebuf                 Tilebuf;
-typedef struct _Tilebuf_Tile            Tilebuf_Tile;
 typedef struct _Tilebuf_Rect           Tilebuf_Rect;
 
 typedef struct _Evas_Common_Transform        Evas_Common_Transform;
@@ -449,11 +448,6 @@ typedef int FPc;
 // one fp unit
 #define FP1 (1 << (FP))
 
-/*
-typedef struct _Regionbuf             Regionbuf;
-typedef struct _Regionspan            Regionspan;
-*/
-
 typedef void (*RGBA_Gfx_Func)    (DATA32 *src, DATA8 *mask, DATA32 col, DATA32 
*dst, int len);
 typedef void (*RGBA_Gfx_Pt_Func) (DATA32 src, DATA8 mask, DATA32 col, DATA32 
*dst);
 typedef void (*Gfx_Func_Copy)    (DATA32 *src, DATA32 *dst, int len);
@@ -1078,82 +1072,10 @@ struct _RGBA_Gfx_Compositor
    RGBA_Gfx_Pt_Func  (*composite_pixel_mask_pt_get)(Eina_Bool src_alpha, 
Eina_Bool dst_alpha);
 };
 
-#define EVAS_RECT_SPLIT 1
-#ifdef EVAS_RECT_SPLIT
-typedef struct list_node list_node_t;
-typedef struct list list_t;
-typedef struct rect rect_t;
-typedef struct rect_node rect_node_t;
-
-struct list_node
-{
-    struct list_node *next;
-};
-
-struct list
-{
-    struct list_node *head;
-    struct list_node *tail;
-};
-
-struct rect
-{
-    int left;
-    int top;
-    int right;
-    int bottom;
-    int width;
-    int height;
-    int area;
-};
-
-struct rect_node
-{
-    struct list_node _lst;
-    struct rect rect;
-};
-#endif /* EVAS_RECT_SPLIT */
-
 struct _Tilebuf
 {
    int outbuf_w, outbuf_h;
-   struct {
-      short w, h;
-   } tile_size;
-#ifdef RECTUPDATE
-/*
-   Regionbuf *rb;
- */
-#elif defined(EVAS_RECT_SPLIT)
-   int need_merge;
-   list_t rects;
-#else
-/*
-   struct {
-      int           w, h;
-      Tilebuf_Tile *tiles;
-   } tiles;
- */
-#endif
-   struct {
-      int x, y, w, h;
-   } prev_add, prev_del;
-   Eina_Bool strict_tiles : 1;
-};
-
-struct _Tilebuf_Tile
-{
-   Eina_Bool redraw : 1;
-/* FIXME: need these flags later - but not now */
-/*
-   Eina_Bool done   : 1;
-   Eina_Bool edge   : 1;
-   Eina_Bool from   : 1;
-
-   struct {
-      int dx, dy;
-   } vector;
- */
+   void *region;
 };
 
 struct _Tilebuf_Rect
@@ -1161,19 +1083,6 @@ struct _Tilebuf_Rect
    EINA_INLIST;
    int               x, y, w, h;
 };
-/*
-struct _Regionbuf
-{
-   int w, h;
-   Regionspan **spans;
-};
-
-struct _Regionspan
-{
-  EINA_INLIST;
-   int x1, x2;
-};
-*/
 
 struct _Convert_Pal
 {

-- 


Reply via email to