1 #ifndef EVAS_ENGINE_SOFTWARE_GENERIC_H_
2 # define EVAS_ENGINE_SOFTWARE_GENERIC_H_
3 
4 #include "Evas_Engine_Software_Shared.h"
5 
6 typedef enum _Outbuf_Depth
7 {
8    OUTBUF_DEPTH_NONE,
9    OUTBUF_DEPTH_INHERIT,
10 
11    /* From X11 */
12    OUTBUF_DEPTH_RGB_16BPP_565_565_DITHERED,
13    OUTBUF_DEPTH_RGB_16BPP_555_555_DITHERED,
14    OUTBUF_DEPTH_RGB_16BPP_444_444_DITHERED,
15    OUTBUF_DEPTH_RGB_16BPP_565_444_DITHERED,
16    OUTBUF_DEPTH_RGB_32BPP_888_8888,
17 
18    /* From buffer */
19    OUTBUF_DEPTH_ARGB_32BPP_8888_8888,
20    OUTBUF_DEPTH_BGRA_32BPP_8888_8888,
21    OUTBUF_DEPTH_BGR_32BPP_888_8888,
22    OUTBUF_DEPTH_RGB_24BPP_888_888,
23    OUTBUF_DEPTH_BGR_24BPP_888_888,
24 
25    OUTBUF_DEPTH_LAST
26 } Outbuf_Depth;
27 
28 typedef enum
29 {
30    MERGE_BOUNDING = 1,
31    MERGE_FULL = 2,
32    MERGE_SMART = 4
33 } Render_Output_Merge_Mode;
34 
35 typedef struct _Render_Engine_Software_Generic Render_Engine_Software_Generic;
36 typedef struct _Render_Output_Software_Generic Render_Output_Software_Generic;
37 typedef struct _Outbuf Outbuf;
38 
39 typedef Render_Output_Swap_Mode (*Outbuf_Swap_Mode_Get)(Outbuf *ob);
40 typedef void (*Outbuf_Reconfigure)(Outbuf *ob, int w, int h, int rot, Outbuf_Depth depth);
41 typedef Eina_Bool (*Outbuf_Region_First_Rect)(Outbuf *ob);
42 typedef void (*Outbuf_Damage_Region_Set)(Outbuf *ob, Tilebuf_Rect *rects);
43 typedef void *(*Outbuf_New_Region_For_Update)(Outbuf *ob, int x, int y, int w, int h, int *cx, int *cy, int *cw, int *ch);
44 typedef void (*Outbuf_Push_Updated_Region)(Outbuf *ob, RGBA_Image *update, int x, int y, int w, int h);
45 typedef void (*Outbuf_Idle_Flush)(Outbuf *ob);
46 typedef void (*Outbuf_Free_Region_For_Update)(Outbuf *ob, RGBA_Image *update);
47 typedef void (*Outbuf_Free)(Outbuf *ob);
48 typedef int (*Outbuf_Get_Rot)(Outbuf *ob);
49 typedef void (*Outbuf_Flush)(Outbuf *ob, Tilebuf_Rect *surface_damage, Tilebuf_Rect *buffer_damage, Evas_Render_Mode render_mode);
50 typedef void (*Outbuf_Redraws_Clear)(Outbuf *ob);
51 
52 struct _Render_Output_Software_Generic
53 {
54    Outbuf *ob;
55    Tilebuf *tb;
56    Tilebuf_Rect *rects;
57    Tilebuf_Rect *rects_prev[4];
58    Eina_Inlist *cur_rect;
59 
60    Outbuf_Swap_Mode_Get outbuf_swap_mode_get;
61    Outbuf_Get_Rot outbuf_get_rot;
62    Outbuf_Reconfigure outbuf_reconfigure;
63    Outbuf_Region_First_Rect outbuf_region_first_rect;
64    Outbuf_Damage_Region_Set outbuf_damage_region_set;
65    Outbuf_New_Region_For_Update outbuf_new_region_for_update;
66    Outbuf_Push_Updated_Region outbuf_push_updated_region;
67    Outbuf_Idle_Flush outbuf_idle_flush;
68    Outbuf_Free_Region_For_Update outbuf_free_region_for_update;
69    Outbuf_Free outbuf_free;
70    Outbuf_Flush outbuf_flush;
71    Outbuf_Redraws_Clear outbuf_redraws_clear;
72 
73    unsigned int w, h;
74 
75    Render_Output_Swap_Mode swap_mode;
76    Render_Output_Merge_Mode merge_mode;
77 
78    unsigned char end : 1;
79    unsigned char lost_back : 1;
80    unsigned char tile_strict : 1;
81 };
82 
83 struct _Render_Engine_Software_Generic
84 {
85    Eina_List *outputs;
86    Generic_Cache  *surface_cache;
87    struct {
88       int w, h;
89       Eina_Bool strict;
90    } tile;
91 };
92 
93 static inline Eina_Bool
evas_render_engine_software_generic_init(Render_Engine_Software_Generic * engine,Render_Output_Software_Generic * re,Outbuf * ob,Outbuf_Swap_Mode_Get outbuf_swap_mode_get,Outbuf_Get_Rot outbuf_get_rot,Outbuf_Reconfigure outbuf_reconfigure,Outbuf_Region_First_Rect outbuf_region_first_rect,Outbuf_Damage_Region_Set outbuf_damage_region_set,Outbuf_New_Region_For_Update outbuf_new_region_for_update,Outbuf_Push_Updated_Region outbuf_push_updated_region,Outbuf_Free_Region_For_Update outbuf_free_region_for_update,Outbuf_Idle_Flush outbuf_idle_flush,Outbuf_Flush outbuf_flush,Outbuf_Redraws_Clear outbuf_redraws_clear,Outbuf_Free outbuf_free,int w,int h)94 evas_render_engine_software_generic_init(Render_Engine_Software_Generic *engine,
95                                          Render_Output_Software_Generic *re,
96                                          Outbuf *ob,
97                                          Outbuf_Swap_Mode_Get outbuf_swap_mode_get,
98                                          Outbuf_Get_Rot outbuf_get_rot,
99                                          Outbuf_Reconfigure outbuf_reconfigure,
100                                          Outbuf_Region_First_Rect outbuf_region_first_rect,
101                                          Outbuf_Damage_Region_Set outbuf_damage_region_set,
102                                          Outbuf_New_Region_For_Update outbuf_new_region_for_update,
103                                          Outbuf_Push_Updated_Region outbuf_push_updated_region,
104                                          Outbuf_Free_Region_For_Update outbuf_free_region_for_update,
105                                          Outbuf_Idle_Flush outbuf_idle_flush,
106                                          Outbuf_Flush outbuf_flush,
107                                          Outbuf_Redraws_Clear outbuf_redraws_clear,
108                                          Outbuf_Free outbuf_free,
109                                          int w, int h)
110 {
111    unsigned int i;
112 
113    re->ob = ob;
114    re->outbuf_swap_mode_get = outbuf_swap_mode_get;
115    re->outbuf_get_rot = outbuf_get_rot;
116    re->outbuf_reconfigure = outbuf_reconfigure;
117    re->outbuf_region_first_rect = outbuf_region_first_rect;
118    re->outbuf_damage_region_set = outbuf_damage_region_set;
119    re->outbuf_new_region_for_update = outbuf_new_region_for_update;
120    re->outbuf_push_updated_region = outbuf_push_updated_region;
121    re->outbuf_idle_flush = outbuf_idle_flush;
122    re->outbuf_free_region_for_update = outbuf_free_region_for_update;
123    re->outbuf_free = outbuf_free;
124    re->outbuf_flush = outbuf_flush;
125    re->outbuf_redraws_clear = outbuf_redraws_clear;
126 
127    re->rects = NULL;
128    for (i = 0; i < 4; i++)
129      re->rects_prev[i] = NULL;
130    re->cur_rect = NULL;
131 
132    re->w = w;
133    re->h = h;
134    re->swap_mode = MODE_FULL;
135    re->merge_mode = MERGE_FULL;
136    re->end = 0;
137    re->lost_back = 0;
138    re->tile_strict = 0;
139 
140    re->tb = evas_common_tilebuf_new(w, h);
141    if (!re->tb) return EINA_FALSE;
142 
143    /* in preliminary tests 16x16 gave highest framerates */
144    evas_common_tilebuf_set_tile_size(re->tb, TILESIZE, TILESIZE);
145 
146    engine->outputs = eina_list_append(engine->outputs, re);
147 
148    return EINA_TRUE;
149 }
150 
151 static inline void
evas_render_engine_software_generic_clean(Render_Engine_Software_Generic * engine,Render_Output_Software_Generic * re)152 evas_render_engine_software_generic_clean(Render_Engine_Software_Generic *engine,
153                                           Render_Output_Software_Generic *re)
154 {
155    if (re->tb) evas_common_tilebuf_free(re->tb);
156    if (re->ob) re->outbuf_free(re->ob);
157 
158    if (re->rects) evas_common_tilebuf_free_render_rects(re->rects);
159    if (re->rects_prev[0]) evas_common_tilebuf_free_render_rects(re->rects_prev[0]);
160    if (re->rects_prev[1]) evas_common_tilebuf_free_render_rects(re->rects_prev[1]);
161    if (re->rects_prev[2]) evas_common_tilebuf_free_render_rects(re->rects_prev[2]);
162    if (re->rects_prev[3]) evas_common_tilebuf_free_render_rects(re->rects_prev[3]);
163 
164    engine->outputs = eina_list_remove(engine->outputs, re);
165 
166    memset(re, 0, sizeof (Render_Output_Software_Generic));
167 }
168 
169 static inline void
evas_render_engine_software_generic_merge_mode_set(Render_Output_Software_Generic * re)170 evas_render_engine_software_generic_merge_mode_set(Render_Output_Software_Generic *re)
171 {
172    Render_Output_Merge_Mode merge_mode = MERGE_SMART;
173    const char *s;
174 
175    s = getenv("EVAS_GL_PARTIAL_MERGE");
176    if (s)
177      {
178         if ((!strcmp(s, "bounding")) || (!strcmp(s, "b")))
179           merge_mode = MERGE_BOUNDING;
180         else if ((!strcmp(s, "full")) || (!strcmp(s, "f")))
181           merge_mode = MERGE_FULL;
182         else if ((!strcmp(s, "smart")) || (!strcmp(s, "s")))
183           merge_mode = MERGE_SMART;
184      }
185 
186    re->merge_mode = merge_mode;
187 }
188 
189 static inline void
evas_render_engine_software_generic_tile_strict_set(Render_Output_Software_Generic * re,Eina_Bool tile_strict)190 evas_render_engine_software_generic_tile_strict_set(Render_Output_Software_Generic *re,
191                                                     Eina_Bool tile_strict)
192 {
193    re->tile_strict = !!tile_strict;
194    evas_common_tilebuf_tile_strict_set(re->tb, re->tile_strict);
195 }
196 
197 static inline Eina_Bool
evas_render_engine_software_generic_update(Render_Output_Software_Generic * re,Outbuf * ob,int w,int h)198 evas_render_engine_software_generic_update(Render_Output_Software_Generic *re,
199                                            Outbuf *ob,
200                                            int w, int h)
201 {
202    if ((re->ob) && (re->ob != ob)) re->outbuf_free(re->ob);
203    re->ob = ob;
204 
205    evas_common_tilebuf_free(re->tb);
206    re->tb = evas_common_tilebuf_new(w, h);
207    if (!re->tb) return EINA_FALSE;
208    evas_common_tilebuf_set_tile_size(re->tb, TILESIZE, TILESIZE);
209    evas_render_engine_software_generic_tile_strict_set(re, re->tile_strict);
210    return EINA_TRUE;
211 }
212 
213 #endif
214