move around - flatter.
[profile/ivi/evas.git] / src / modules / engines / buffer / evas_engine.c
1 #include "evas_common.h"
2 #include "evas_private.h"
3 #include "evas_engine.h"
4 #include "Evas_Engine_Buffer.h"
5
6 /* function tables - filled in later (func and parent func) */
7 static Evas_Func func, pfunc;
8
9 /* engine struct data */
10 typedef struct _Render_Engine Render_Engine;
11
12 struct _Render_Engine
13 {
14    Tilebuf          *tb;
15    Outbuf           *ob;
16    Tilebuf_Rect     *rects;
17    Evas_Object_List *cur_rect;
18    int               end : 1;
19 };
20
21 /* prototypes we will use here */
22 static void *_output_setup(int w, int h, void *dest_buffer, int dest_buffer_row_bytes, int depth_type, int use_color_key, int alpha_threshold, int color_key_r, int color_key_g, int color_key_b, void *(*new_update_region) (int x, int y, int w, int h, int *row_bytes), void (*free_update_region) (int x, int y, int w, int h, void *data));
23
24 static void *eng_info(Evas *e);
25 static void eng_info_free(Evas *e, void *info);
26 static void eng_setup(Evas *e, void *info);
27 static void eng_output_free(void *data);
28 static void eng_output_resize(void *data, int w, int h);
29 static void eng_output_tile_size_set(void *data, int w, int h);
30 static void eng_output_redraws_rect_add(void *data, int x, int y, int w, int h);
31 static void eng_output_redraws_rect_del(void *data, int x, int y, int w, int h);
32 static void eng_output_redraws_clear(void *data);
33 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);
34 static void eng_output_redraws_next_update_push(void *data, void *surface, int x, int y, int w, int h);
35 static void eng_output_flush(void *data);
36 static void eng_output_idle_flush(void *data);
37
38 /* internal engine routines */
39 static void *
40 _output_setup(int w,
41               int h,
42               void *dest_buffer,
43               int dest_buffer_row_bytes,
44               int depth_type,
45               int use_color_key,
46               int alpha_threshold,
47               int color_key_r,
48               int color_key_g,
49               int color_key_b,
50               void *(*new_update_region) (int x, int y, int w, int h, int *row_bytes),
51               void (*free_update_region) (int x, int y, int w, int h, void *data)
52               )
53 {
54    Render_Engine *re;
55
56    re = calloc(1, sizeof(Render_Engine));
57    /* if we haven't initialized - init (automatic abort if already done) */
58    evas_common_cpu_init();
59
60    evas_common_blend_init();
61    evas_common_image_init();
62    evas_common_convert_init();
63    evas_common_scale_init();
64    evas_common_rectangle_init();
65    evas_common_gradient_init();
66    evas_common_polygon_init();
67    evas_common_line_init();
68    evas_common_font_init();
69    evas_common_draw_init();
70    evas_common_tilebuf_init();
71
72    evas_buffer_outbuf_buf_init();
73
74      {
75         Outbuf_Depth dep;
76         DATA32 color_key;
77
78         dep = OUTBUF_DEPTH_BGR_24BPP_888_888;
79         if      (depth_type == EVAS_ENGINE_BUFFER_DEPTH_ARGB32)
80           dep = OUTBUF_DEPTH_ARGB_32BPP_8888_8888;
81         else if (depth_type == EVAS_ENGINE_BUFFER_DEPTH_RGB32)
82           dep = OUTBUF_DEPTH_RGB_32BPP_888_8888;
83         else if (depth_type == EVAS_ENGINE_BUFFER_DEPTH_BGRA32)
84           dep = OUTBUF_DEPTH_BGRA_32BPP_8888_8888;
85         else if (depth_type == EVAS_ENGINE_BUFFER_DEPTH_RGB24)
86           dep = OUTBUF_DEPTH_RGB_24BPP_888_888;
87         else if (depth_type == EVAS_ENGINE_BUFFER_DEPTH_BGR24)
88           dep = OUTBUF_DEPTH_BGR_24BPP_888_888;
89         R_VAL(&color_key) = color_key_r;
90         G_VAL(&color_key) = color_key_g;
91         B_VAL(&color_key) = color_key_b;
92         A_VAL(&color_key) = 0;
93         re->ob = evas_buffer_outbuf_buf_setup_fb(w,
94                                                  h,
95                                                  dep,
96                                                  dest_buffer,
97                                                  dest_buffer_row_bytes,
98                                                  use_color_key,
99                                                  color_key,
100                                                  alpha_threshold,
101                                                  new_update_region,
102                                                  free_update_region);
103      }
104    re->tb = evas_common_tilebuf_new(w, h);
105    evas_common_tilebuf_set_tile_size(re->tb, TILESIZE, TILESIZE);
106    return re;
107 }
108
109 /* engine api this module provides */
110 static void *
111 eng_info(Evas *e)
112 {
113    Evas_Engine_Info_Buffer *info;
114
115    info = calloc(1, sizeof(Evas_Engine_Info_Buffer));
116    if (!info) return NULL;
117    info->magic.magic = rand();
118    return info;
119    e = NULL;
120 }
121
122 static void
123 eng_info_free(Evas *e, void *info)
124 {
125    Evas_Engine_Info_Buffer *in;
126
127    in = (Evas_Engine_Info_Buffer *)info;
128    free(in);
129 }
130
131 static void
132 eng_setup(Evas *e, void *in)
133 {
134    Render_Engine *re;
135    Evas_Engine_Info_Buffer *info;
136
137    info = (Evas_Engine_Info_Buffer *)in;
138    if (e->engine.data.output)
139      eng_output_free(e->engine.data.output);
140    re = _output_setup(e->output.w,
141                       e->output.h,
142                       info->info.dest_buffer,
143                       info->info.dest_buffer_row_bytes,
144                       info->info.depth_type,
145                       info->info.use_color_key,
146                       info->info.alpha_threshold,
147                       info->info.color_key_r,
148                       info->info.color_key_g,
149                       info->info.color_key_b,
150                       info->info.func.new_update_region,
151                       info->info.func.free_update_region);
152    e->engine.data.output = re;
153    if (!e->engine.data.output) return;
154    if (!e->engine.data.context)
155      e->engine.data.context = e->engine.func->context_new(e->engine.data.output);
156 }
157
158 static void
159 eng_output_free(void *data)
160 {
161    Render_Engine *re;
162
163    re = (Render_Engine *)data;
164    evas_buffer_outbuf_buf_free(re->ob);
165    evas_common_tilebuf_free(re->tb);
166    if (re->rects) evas_common_tilebuf_free_render_rects(re->rects);
167    free(re);
168
169    evas_common_font_shutdown();
170    evas_common_image_shutdown();
171 }
172
173 static void
174 eng_output_resize(void *data, int w, int h)
175 {
176    Render_Engine *re;
177
178    re = (Render_Engine *)data;
179      {
180         int      depth;
181         void    *dest;
182         int      dest_row_bytes;
183         int      alpha_level;
184         DATA32   color_key;
185         char     use_color_key;
186         void * (*new_update_region) (int x, int y, int w, int h, int *row_bytes);
187         void   (*free_update_region) (int x, int y, int w, int h, void *data);
188
189         depth = re->ob->depth;
190         dest = re->ob->dest;
191         dest_row_bytes = re->ob->dest_row_bytes;
192         alpha_level = re->ob->alpha_level;
193         color_key = re->ob->color_key;
194         use_color_key = re->ob->use_color_key;
195         new_update_region = re->ob->func.new_update_region;
196         free_update_region = re->ob->func.free_update_region;
197         evas_buffer_outbuf_buf_free(re->ob);
198         re->ob = evas_buffer_outbuf_buf_setup_fb(w,
199                                                  h,
200                                                  depth,
201                                                  dest,
202                                                  dest_row_bytes,
203                                                  use_color_key,
204                                                  color_key,
205                                                  alpha_level,
206                                                  new_update_region,
207                                                  free_update_region);
208      }
209    evas_common_tilebuf_free(re->tb);
210    re->tb = evas_common_tilebuf_new(w, h);
211    if (re->tb)
212      evas_common_tilebuf_set_tile_size(re->tb, TILESIZE, TILESIZE);
213 }
214
215 static void
216 eng_output_tile_size_set(void *data, int w, int h)
217 {
218    Render_Engine *re;
219
220    re = (Render_Engine *)data;
221    evas_common_tilebuf_set_tile_size(re->tb, w, h);
222 }
223
224 static void
225 eng_output_redraws_rect_add(void *data, int x, int y, int w, int h)
226 {
227    Render_Engine *re;
228
229    re = (Render_Engine *)data;
230    evas_common_tilebuf_add_redraw(re->tb, x, y, w, h);
231 }
232
233 static void
234 eng_output_redraws_rect_del(void *data, int x, int y, int w, int h)
235 {
236    Render_Engine *re;
237
238    re = (Render_Engine *)data;
239    evas_common_tilebuf_del_redraw(re->tb, x, y, w, h);
240 }
241
242 static void
243 eng_output_redraws_clear(void *data)
244 {
245    Render_Engine *re;
246
247    re = (Render_Engine *)data;
248    evas_common_tilebuf_clear(re->tb);
249 }
250
251 static void *
252 eng_output_redraws_next_update_get(void *data, int *x, int *y, int *w, int *h, int *cx, int *cy, int *cw, int *ch)
253 {
254    Render_Engine *re;
255    RGBA_Image *surface;
256    Tilebuf_Rect *rect;
257    int ux, uy, uw, uh;
258
259    re = (Render_Engine *)data;
260    if (re->end)
261      {
262         re->end = 0;
263         return NULL;
264      }
265    if (!re->rects)
266      {
267         re->rects = evas_common_tilebuf_get_render_rects(re->tb);
268         re->cur_rect = (Evas_Object_List *)re->rects;
269      }
270    if (!re->cur_rect) return NULL;
271    rect = (Tilebuf_Rect *)re->cur_rect;
272    ux = rect->x; uy = rect->y; uw = rect->w; uh = rect->h;
273    re->cur_rect = re->cur_rect->next;
274    if (!re->cur_rect)
275      {
276         evas_common_tilebuf_free_render_rects(re->rects);
277         re->rects = NULL;
278         re->end = 1;
279      }
280
281    if ((ux + uw) > re->ob->w) uw = re->ob->w - ux;
282    if ((uy + uh) > re->ob->h) uh = re->ob->h - uy;
283    if ((uw <= 0) || (uh <= 0)) return NULL;
284    surface = evas_buffer_outbuf_buf_new_region_for_update(re->ob,
285                                                           ux, uy, uw, uh,
286                                                           cx, cy, cw, ch);
287    *x = ux; *y = uy; *w = uw; *h = uh;
288    return surface;
289 }
290
291 static void
292 eng_output_redraws_next_update_push(void *data, void *surface, int x, int y, int w, int h)
293 {
294    Render_Engine *re;
295
296    re = (Render_Engine *)data;
297    evas_common_pipe_begin(surface);
298    evas_common_pipe_flush(surface);
299    evas_buffer_outbuf_buf_push_updated_region(re->ob, surface, x, y, w, h);
300    evas_buffer_outbuf_buf_free_region_for_update(re->ob, surface);
301    evas_common_cpu_end_opt();
302 }
303
304 static void
305 eng_output_flush(void *data)
306 {
307    Render_Engine *re;
308
309    re = (Render_Engine *)data;
310 }
311
312 static void
313 eng_output_idle_flush(void *data)
314 {
315    Render_Engine *re;
316
317    re = (Render_Engine *)data;
318 }
319
320 /* module advertising code */
321 EAPI int
322 module_open(Evas_Module *em)
323 {
324    if (!em) return 0;
325    /* get whatever engine module we inherit from */
326    if (!_evas_module_engine_inherit(&pfunc, "software_generic")) return 0;
327    /* store it for later use */
328    func = pfunc;
329    /* now to override methods */
330 #define ORD(f) EVAS_API_OVERRIDE(f, &func, eng_)
331    ORD(info);
332    ORD(info_free);
333    ORD(setup);
334    ORD(output_free);
335    ORD(output_resize);
336    ORD(output_tile_size_set);
337    ORD(output_redraws_rect_add);
338    ORD(output_redraws_rect_del);
339    ORD(output_redraws_clear);
340    ORD(output_redraws_next_update_get);
341    ORD(output_redraws_next_update_push);
342    ORD(output_flush);
343    ORD(output_idle_flush);
344    /* now advertise out own api */
345    em->functions = (void *)(&func);
346    return 1;
347 }
348
349 EAPI void
350 module_close(void)
351 {
352 }
353
354 EAPI Evas_Module_Api evas_modapi = 
355 {
356    EVAS_MODULE_API_VERSION, 
357      EVAS_MODULE_TYPE_ENGINE,
358      "buffer",
359      "none"
360 };