big patch from Samsung SAIT (Advanced research group) for async multi-frame
[framework/uifw/evas.git] / src / modules / engines / software_ddraw / evas_engine.c
1 #include "evas_common.h"
2 #include "evas_private.h"
3 #include "evas_engine.h"
4 #include "Evas_Engine_Software_DDraw.h"
5
6 int _evas_engine_soft_ddraw_log_dom = -1;
7 /* function tables - filled in later (func and parent func) */
8 static Evas_Func func, pfunc;
9
10 /* engine struct data */
11 typedef struct _Render_Engine Render_Engine;
12
13 struct _Render_Engine
14 {
15    Tilebuf          *tb;
16    Outbuf           *ob;
17    Tilebuf_Rect     *rects;
18    Eina_Inlist      *cur_rect;
19    int               end : 1;
20 };
21
22
23 /* log domain variable */
24 int _evas_log_dom_module = -1;
25
26
27 static void *
28 _output_setup(int  width,
29               int  height,
30               int  rot,
31               HWND window,
32               int  depth,
33               int  fullscreen)
34 {
35    Render_Engine *re;
36
37    re = calloc(1, sizeof(Render_Engine));
38    if (!re)
39      return NULL;
40
41    /* if we haven't initialized - init (automatic abort if already done) */
42    evas_common_cpu_init();
43
44    evas_common_blend_init();
45    evas_common_image_init();
46    evas_common_convert_init();
47    evas_common_scale_init();
48    evas_common_rectangle_init();
49    evas_common_gradient_init();
50    evas_common_polygon_init();
51    evas_common_line_init();
52    evas_common_font_init();
53    evas_common_draw_init();
54    evas_common_tilebuf_init();
55
56    evas_software_ddraw_outbuf_init();
57
58    re->ob = evas_software_ddraw_outbuf_setup(width, height, rot,
59                                              OUTBUF_DEPTH_INHERIT,
60                                              window, depth, fullscreen);
61    if (!re->ob)
62      {
63         free(re);
64         return NULL;
65      }
66
67    /* for updates return 1 big buffer, but only use portions of it, also cache
68     it and keep it around until an idle_flush */
69    /* disable for now - i am hunting down why some expedite tests are slower,
70     * as well as shaped stuff is broken and probable non-32bpp is broken as
71     * convert funcs dont do the right thing
72     *
73    re->ob->onebuf = 1;
74     */
75
76    re->tb = evas_common_tilebuf_new(width, height);
77    if (!re->tb)
78      {
79         evas_software_ddraw_outbuf_free(re->ob);
80         free(re);
81         return NULL;
82      }
83    /* in preliminary tests 16x16 gave highest framerates */
84    evas_common_tilebuf_set_tile_size(re->tb, TILESIZE, TILESIZE);
85
86    return re;
87 }
88
89
90 /* engine api this module provides */
91
92 static void *
93 eng_info(Evas *e)
94 {
95    Evas_Engine_Info_Software_DDraw *info;
96
97    info = calloc(1, sizeof(Evas_Engine_Info_Software_DDraw));
98    if (!info) return NULL;
99    info->magic.magic = rand();
100    info->render_mode = EVAS_RENDER_MODE_BLOCKING;
101    return info;
102    e = NULL;
103 }
104
105 static void
106 eng_info_free(Evas *e, void *info)
107 {
108    Evas_Engine_Info_Software_DDraw *in;
109    in = (Evas_Engine_Info_Software_DDraw *)info;
110    free(in);
111 }
112
113 static int
114 eng_setup(Evas *e, void *in)
115 {
116    Render_Engine                   *re;
117    Evas_Engine_Info_Software_DDraw *info;
118
119    info = (Evas_Engine_Info_Software_DDraw *)in;
120    if (!e->engine.data.output)
121      e->engine.data.output = _output_setup(e->output.w,
122                                            e->output.h,
123                                            info->info.rotation,
124                                            info->info.window,
125                                            info->info.depth,
126                                            info->info.fullscreen);
127    else
128      {
129         int ponebuf = 0;
130
131         re = e->engine.data.output;
132         ponebuf = re->ob->onebuf;
133         evas_software_ddraw_outbuf_free(re->ob);
134         re->ob = evas_software_ddraw_outbuf_setup(e->output.w,
135                                                   e->output.h,
136                                                   info->info.rotation,
137                                                   OUTBUF_DEPTH_INHERIT,
138                                                   info->info.window,
139                                                   info->info.depth,
140                                                   info->info.fullscreen);
141         re->ob->onebuf = ponebuf;
142      }
143    if (!e->engine.data.output) return 0;
144    if (!e->engine.data.context)
145      e->engine.data.context = e->engine.func->context_new(e->engine.data.output);
146
147    re = e->engine.data.output;
148
149    return 1;
150 }
151
152 static void
153 eng_output_free(void *data)
154 {
155    Render_Engine *re;
156
157    if (!data) return;
158
159    re = (Render_Engine *)data;
160    evas_software_ddraw_outbuf_free(re->ob);
161    evas_common_tilebuf_free(re->tb);
162    if (re->rects) evas_common_tilebuf_free_render_rects(re->rects);
163    free(re);
164
165    evas_common_font_shutdown();
166    evas_common_image_shutdown();
167 }
168
169 static void
170 eng_output_resize(void *data, int width, int height)
171 {
172    Render_Engine *re;
173
174    re = (Render_Engine *)data;
175    evas_software_ddraw_outbuf_reconfigure(re->ob,
176                                           width,
177                                           height,
178                                           evas_software_ddraw_outbuf_rot_get(re->ob),
179                                           OUTBUF_DEPTH_INHERIT);
180    evas_common_tilebuf_free(re->tb);
181    re->tb = evas_common_tilebuf_new(width, height);
182    if (re->tb)
183      evas_common_tilebuf_set_tile_size(re->tb, TILESIZE, TILESIZE);
184 }
185
186 static void
187 eng_output_tile_size_set(void *data, int w, int h)
188 {
189    Render_Engine *re;
190
191    re = (Render_Engine *)data;
192    evas_common_tilebuf_set_tile_size(re->tb, w, h);
193 }
194
195 static void
196 eng_output_redraws_rect_add(void *data, int x, int y, int w, int h)
197 {
198    Render_Engine *re;
199
200    re = (Render_Engine *)data;
201    evas_common_tilebuf_add_redraw(re->tb, x, y, w, h);
202 }
203
204 static void
205 eng_output_redraws_rect_del(void *data, int x, int y, int w, int h)
206 {
207    Render_Engine *re;
208
209    re = (Render_Engine *)data;
210    evas_common_tilebuf_del_redraw(re->tb, x, y, w, h);
211 }
212
213 static void
214 eng_output_redraws_clear(void *data)
215 {
216    Render_Engine *re;
217
218    re = (Render_Engine *)data;
219    evas_common_tilebuf_clear(re->tb);
220 }
221
222 static void *
223 eng_output_redraws_next_update_get(void *data,
224                                    int  *x,
225                                    int  *y,
226                                    int  *w,
227                                    int  *h,
228                                    int  *cx,
229                                    int  *cy,
230                                    int  *cw,
231                                    int  *ch)
232 {
233    Render_Engine *re;
234    RGBA_Image    *surface;
235    Tilebuf_Rect  *rect;
236    int            ux;
237    int            uy;
238    int            uw;
239    int            uh;
240
241    re = (Render_Engine *)data;
242    if (re->end)
243      {
244         re->end = 0;
245         return NULL;
246      }
247    if (!re->rects)
248      {
249         re->rects = evas_common_tilebuf_get_render_rects(re->tb);
250         re->cur_rect = EINA_INLIST_GET(re->rects);
251      }
252    if (!re->cur_rect) return NULL;
253    rect = (Tilebuf_Rect *)re->cur_rect;
254    ux = rect->x;
255    uy = rect->y;
256    uw = rect->w;
257    uh = rect->h;
258    re->cur_rect = re->cur_rect->next;
259    if (!re->cur_rect)
260      {
261         evas_common_tilebuf_free_render_rects(re->rects);
262         re->rects = NULL;
263         re->end = 1;
264      }
265
266    surface = evas_software_ddraw_outbuf_new_region_for_update(re->ob,
267                                                               ux,
268                                                               uy,
269                                                               uw,
270                                                               uh,
271                                                               cx,
272                                                               cy,
273                                                               cw,
274                                                               ch);
275
276    *x = ux;
277    *y = uy;
278    *w = uw;
279    *h = uh;
280
281    return surface;
282 }
283
284 static void
285 eng_output_redraws_next_update_push(void *data, void *surface, int x, int y, int w, int h)
286 {
287    Render_Engine *re;
288
289    re = (Render_Engine *)data;
290 #ifdef BUILD_PIPE_RENDER
291    evas_common_pipe_map4_begin(surface);
292 #endif   
293    evas_software_ddraw_outbuf_push_updated_region(re->ob, surface, x, y, w, h);
294    evas_software_ddraw_outbuf_free_region_for_update(re->ob, surface);
295    evas_common_cpu_end_opt();
296 }
297
298 static void
299 eng_output_flush(void *data)
300 {
301    Render_Engine *re;
302
303    re = (Render_Engine *)data;
304    evas_software_ddraw_outbuf_flush(re->ob);
305 }
306
307 static void
308 eng_output_idle_flush(void *data)
309 {
310    Render_Engine *re;
311
312    re = (Render_Engine *)data;
313    evas_software_ddraw_outbuf_idle_flush(re->ob);
314 }
315
316 static Eina_Bool
317 eng_canvas_alpha_get(void *data, void *context)
318 {
319    return EINA_FALSE;
320 }
321
322 /* module advertising code */
323 static int
324 module_open(Evas_Module *em)
325 {
326    if (!em) return 0;
327    /* get whatever engine module we inherit from */
328    if (!_evas_module_engine_inherit(&pfunc, "software_generic")) return 0;
329    _evas_log_dom_module = eina_log_domain_register("Software_DDraw", EVAS_DEFAULT_LOG_COLOR);
330    if(_evas_log_dom_module < 0)
331      {
332        EINA_LOG_ERR("Can not create a module log domain.");
333        return 0;
334      }
335    /* store it for later use */
336    func = pfunc;
337    /* now to override methods */
338 #define ORD(f) EVAS_API_OVERRIDE(f, &func, eng_)
339    ORD(info);
340    ORD(info_free);
341    ORD(setup);
342    ORD(canvas_alpha_get);
343    ORD(output_free);
344    ORD(output_resize);
345    ORD(output_tile_size_set);
346    ORD(output_redraws_rect_add);
347    ORD(output_redraws_rect_del);
348    ORD(output_redraws_clear);
349    ORD(output_redraws_next_update_get);
350    ORD(output_redraws_next_update_push);
351    ORD(output_flush);
352    ORD(output_idle_flush);
353    /* now advertise out own api */
354    em->functions = (void *)(&func);
355    return 1;
356 }
357
358 static void
359 module_close(Evas_Module *em)
360 {
361   eina_log_domain_unregister(_evas_log_dom_module);
362 }
363
364 static Evas_Module_Api evas_modapi =
365 {
366    EVAS_MODULE_API_VERSION,
367    "software_ddraw",
368    "none",
369    {
370      module_open,
371      module_close
372    }
373 };
374
375 EVAS_MODULE_DEFINE(EVAS_MODULE_TYPE_ENGINE, engine, software_ddraw);
376
377 #ifndef EVAS_STATIC_BUILD_SOFTWARE_DDRAW
378 EVAS_EINA_MODULE_DEFINE(engine, software_ddraw);
379 #endif