diff options
-rw-r--r-- | src/modules/evas/engines/software_generic/Evas_Engine_Software_Generic.h | 4 | ||||
-rw-r--r-- | src/modules/evas/engines/software_generic/evas_engine.c | 77 |
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; |