summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCedric BAIL <cedric@osg.samsung.com>2014-09-27 12:55:03 +0200
committerCedric BAIL <cedric@osg.samsung.com>2014-09-27 12:55:03 +0200
commitafea9e94bb99e0c342c3ba46bd0e281937702b4f (patch)
tree36d4c4168d803f3f10bdb4252f1acf626db6d316
parentfc40591f1195da03766e0e97f3a6559648c80824 (diff)
evas: add logic to do limit output tile to fit in L1 cache.devs/cedric/evas_tiling
This code is not turned on by default at the moment as it expose the cost of walking over and over again Evas_Object stack. We need to seriously optimize this or maybe i should do it another way. Instead we could replay the command list in the asynchronous pipe by adding cliping and replay as many time as needed. Worth exploring that option to.
-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
80 unsigned char end : 1; 80 unsigned char end : 1;
81 unsigned char lost_back : 1; 81 unsigned char lost_back : 1;
82 unsigned char tile_strict : 1; 82 unsigned char tile_strict : 1;
83 unsigned char tiling : 1;
83}; 84};
84 85
85static inline Eina_Bool 86static inline Eina_Bool
@@ -124,6 +125,9 @@ evas_render_engine_software_generic_init(Render_Engine_Software_Generic *re,
124 re->lost_back = 0; 125 re->lost_back = 0;
125 re->tile_strict = 0; 126 re->tile_strict = 0;
126 127
128 if (getenv("EVAS_TILING_ENABLE"))
129 re->tiling = 1;
130
127 re->tb = evas_common_tilebuf_new(w, h); 131 re->tb = evas_common_tilebuf_new(w, h);
128 if (!re->tb) return EINA_FALSE; 132 if (!re->tb) return EINA_FALSE;
129 133
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,
2701 return rects; 2701 return rects;
2702} 2702}
2703 2703
2704static inline Tilebuf_Rect *
2705_split_rect_horizontaly(Tilebuf_Rect *it)
2706{
2707 Tilebuf_Rect *tmp;
2708
2709 tmp = calloc(1, sizeof(Tilebuf_Rect));
2710 if (!tmp) return NULL;
2711 tmp->x = it->x + it->w / 2;
2712 tmp->w = it->w / 2 + it->w % 2;
2713 tmp->y = it->y;
2714 tmp->h = it->h;
2715 it->w = it->w / 2;
2716
2717 return tmp;
2718}
2719
2720static inline Tilebuf_Rect *
2721_split_rect_verticaly(Tilebuf_Rect *it)
2722{
2723 Tilebuf_Rect *tmp;
2724
2725 tmp = calloc(1, sizeof(Tilebuf_Rect));
2726 if (!tmp) return NULL;
2727 tmp->y = it->y + it->h / 2;
2728 tmp->h = it->h / 2 + it->h % 2;
2729 tmp->x = it->x;
2730 tmp->w = it->w;
2731 it->h = it->h / 2;
2732
2733 return tmp;
2734}
2704 2735
2705static void * 2736static void *
2706eng_output_redraws_next_update_get(void *data, int *x, int *y, int *w, int *h, int *cx, int *cy, int *cw, int *ch) 2737eng_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
2775 } 2806 }
2776 evas_common_tilebuf_clear(re->tb); 2807 evas_common_tilebuf_clear(re->tb);
2777 re->cur_rect = EINA_INLIST_GET(re->rects); 2808 re->cur_rect = EINA_INLIST_GET(re->rects);
2809
2810 if (re->tiling)
2811 {
2812 /* We will limit each rect to be fiting inside 16KB */
2813 Tilebuf_Rect *it;
2814
2815 EINA_INLIST_FOREACH(re->cur_rect, it)
2816 {
2817 while ((it->w * it->h * sizeof (int)) > (16 * 1024))
2818 {
2819 Tilebuf_Rect *tmp;
2820
2821 /* Split the largest side first */
2822 if (it->w > it->h)
2823 {
2824 /* Let's try to divide it horizontaly */
2825 tmp = _split_rect_horizontaly(it);
2826 if (!tmp) break;
2827 re->cur_rect = eina_inlist_append(re->cur_rect, EINA_INLIST_GET(tmp));
2828
2829 if ((it->w * it->h * sizeof (int)) <= (16 * 1024))
2830 break;
2831
2832 /* Let's try to divide it verticaly */
2833 tmp = _split_rect_verticaly(it);
2834 if (!tmp) break;
2835 re->cur_rect = eina_inlist_append(re->cur_rect, EINA_INLIST_GET(tmp));
2836 }
2837 else
2838 {
2839 /* Let's try to divide it verticaly */
2840 tmp = _split_rect_verticaly(it);
2841 if (!tmp) break;
2842 re->cur_rect = eina_inlist_append(re->cur_rect, EINA_INLIST_GET(tmp));
2843
2844 if ((it->w * it->h * sizeof (int)) <= (16 * 1024))
2845 break;
2846
2847 /* Let's try to divide it horizontaly */
2848 tmp = _split_rect_horizontaly(it);
2849 if (!tmp) break;
2850 re->cur_rect = eina_inlist_append(re->cur_rect, EINA_INLIST_GET(tmp));
2851 }
2852 }
2853 }
2854 }
2778 } 2855 }
2779 if (!re->cur_rect) return NULL; 2856 if (!re->cur_rect) return NULL;
2780 rect = (Tilebuf_Rect *)re->cur_rect; 2857 rect = (Tilebuf_Rect *)re->cur_rect;