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