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