summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/modules/evas/engines/software_generic/Evas_Engine_Software_Generic.h4
-rw-r--r--src/modules/evas/engines/software_generic/evas_engine.c77
2 files changed, 81 insertions, 0 deletions
diff --git a/src/modules/evas/engines/software_generic/Evas_Engine_Software_Generic.h b/src/modules/evas/engines/software_generic/Evas_Engine_Software_Generic.h
index 8369f02178..66566c1592 100644
--- a/src/modules/evas/engines/software_generic/Evas_Engine_Software_Generic.h
+++ b/src/modules/evas/engines/software_generic/Evas_Engine_Software_Generic.h
@@ -80,6 +80,7 @@ struct _Render_Engine_Software_Generic
unsigned char end : 1;
unsigned char lost_back : 1;
unsigned char tile_strict : 1;
+ unsigned char tiling : 1;
};
static inline Eina_Bool
@@ -124,6 +125,9 @@ evas_render_engine_software_generic_init(Render_Engine_Software_Generic *re,
re->lost_back = 0;
re->tile_strict = 0;
+ if (getenv("EVAS_TILING_ENABLE"))
+ re->tiling = 1;
+
re->tb = evas_common_tilebuf_new(w, h);
if (!re->tb) return EINA_FALSE;
diff --git a/src/modules/evas/engines/software_generic/evas_engine.c b/src/modules/evas/engines/software_generic/evas_engine.c
index a2f60213c6..610051c715 100644
--- a/src/modules/evas/engines/software_generic/evas_engine.c
+++ b/src/modules/evas/engines/software_generic/evas_engine.c
@@ -2701,6 +2701,37 @@ _merge_rects(Render_Engine_Merge_Mode merge_mode,
return rects;
}
+static inline Tilebuf_Rect *
+_split_rect_horizontaly(Tilebuf_Rect *it)
+{
+ Tilebuf_Rect *tmp;
+
+ tmp = calloc(1, sizeof(Tilebuf_Rect));
+ if (!tmp) return NULL;
+ tmp->x = it->x + it->w / 2;
+ tmp->w = it->w / 2 + it->w % 2;
+ tmp->y = it->y;
+ tmp->h = it->h;
+ it->w = it->w / 2;
+
+ return tmp;
+}
+
+static inline Tilebuf_Rect *
+_split_rect_verticaly(Tilebuf_Rect *it)
+{
+ Tilebuf_Rect *tmp;
+
+ tmp = calloc(1, sizeof(Tilebuf_Rect));
+ if (!tmp) return NULL;
+ tmp->y = it->y + it->h / 2;
+ tmp->h = it->h / 2 + it->h % 2;
+ tmp->x = it->x;
+ tmp->w = it->w;
+ it->h = it->h / 2;
+
+ return tmp;
+}
static void *
eng_output_redraws_next_update_get(void *data, int *x, int *y, int *w, int *h, int *cx, int *cy, int *cw, int *ch)
@@ -2775,6 +2806,52 @@ eng_output_redraws_next_update_get(void *data, int *x, int *y, int *w, int *h, i
}
evas_common_tilebuf_clear(re->tb);
re->cur_rect = EINA_INLIST_GET(re->rects);
+
+ if (re->tiling)
+ {
+ /* We will limit each rect to be fiting inside 16KB */
+ Tilebuf_Rect *it;
+
+ EINA_INLIST_FOREACH(re->cur_rect, it)
+ {
+ while ((it->w * it->h * sizeof (int)) > (16 * 1024))
+ {
+ Tilebuf_Rect *tmp;
+
+ /* Split the largest side first */
+ if (it->w > it->h)
+ {
+ /* Let's try to divide it horizontaly */
+ tmp = _split_rect_horizontaly(it);
+ if (!tmp) break;
+ re->cur_rect = eina_inlist_append(re->cur_rect, EINA_INLIST_GET(tmp));
+
+ if ((it->w * it->h * sizeof (int)) <= (16 * 1024))
+ break;
+
+ /* Let's try to divide it verticaly */
+ tmp = _split_rect_verticaly(it);
+ if (!tmp) break;
+ re->cur_rect = eina_inlist_append(re->cur_rect, EINA_INLIST_GET(tmp));
+ }
+ else
+ {
+ /* Let's try to divide it verticaly */
+ tmp = _split_rect_verticaly(it);
+ if (!tmp) break;
+ re->cur_rect = eina_inlist_append(re->cur_rect, EINA_INLIST_GET(tmp));
+
+ if ((it->w * it->h * sizeof (int)) <= (16 * 1024))
+ break;
+
+ /* Let's try to divide it horizontaly */
+ tmp = _split_rect_horizontaly(it);
+ if (!tmp) break;
+ re->cur_rect = eina_inlist_append(re->cur_rect, EINA_INLIST_GET(tmp));
+ }
+ }
+ }
+ }
}
if (!re->cur_rect) return NULL;
rect = (Tilebuf_Rect *)re->cur_rect;