move around - flatter.
[profile/ivi/evas.git] / src / modules / engines / fb / evas_engine.c
1 #include "evas_common.h"
2 #include "evas_private.h"
3 #include "evas_engine.h"
4 #include "Evas_Engine_FB.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, int rot, int vt, int dev, int refresh);
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, int h, int rot, int vt, int dev, int refresh)
41 {
42    Render_Engine *re;
43
44    re = calloc(1, sizeof(Render_Engine));
45    /* if we haven't initialized - init (automatic abort if already done) */
46    evas_common_cpu_init();
47
48    evas_common_blend_init();
49    evas_common_image_init();
50    evas_common_convert_init();
51    evas_common_scale_init();
52    evas_common_rectangle_init();
53    evas_common_gradient_init();
54    evas_common_polygon_init();
55    evas_common_line_init();
56    evas_common_font_init();
57    evas_common_draw_init();
58    evas_common_tilebuf_init();
59
60    evas_fb_outbuf_fb_init();
61
62    /* get any stored performance metrics from device (xserver) */
63    re->ob = evas_fb_outbuf_fb_setup_fb(w, h, rot, OUTBUF_DEPTH_INHERIT, vt, dev, refresh);
64    re->tb = evas_common_tilebuf_new(evas_fb_outbuf_fb_get_width(re->ob), evas_fb_outbuf_fb_get_height(re->ob));
65    /* no backbuf! */
66    evas_fb_outbuf_fb_set_have_backbuf(re->ob, 0);
67    /* in preliminary tests 16x16 gave highest framerates */
68    evas_common_tilebuf_set_tile_size(re->tb, TILESIZE, TILESIZE);
69    return re;
70 }
71
72 /* engine api this module provides */
73 static void *
74 eng_info(Evas *e)
75 {
76    Evas_Engine_Info_FB *info;
77
78    info = calloc(1, sizeof(Evas_Engine_Info_FB));
79    if (!info) return NULL;
80    info->magic.magic = rand();
81    return info;
82    e = NULL;
83 }
84
85 static void
86 eng_info_free(Evas *e, void *info)
87 {
88    Evas_Engine_Info_FB *in;
89
90    in = (Evas_Engine_Info_FB *)info;
91    free(in);
92 }
93
94 static void
95 eng_setup(Evas *e, void *in)
96 {
97    Render_Engine *re;
98    Evas_Engine_Info_FB *info;
99
100    info = (Evas_Engine_Info_FB *)in;
101    re = _output_setup(e->output.w,
102                       e->output.h,
103                       info->info.rotation,
104                       info->info.virtual_terminal,
105                       info->info.device_number,
106                       info->info.refresh);
107    e->engine.data.output = re;
108    if (!e->engine.data.output) return;
109    e->engine.data.context = e->engine.func->context_new(e->engine.data.output);
110 }
111
112 static void
113 eng_output_free(void *data)
114 {
115    Render_Engine *re;
116
117    re = (Render_Engine *)data;
118    evas_fb_outbuf_fb_free(re->ob);
119    evas_common_tilebuf_free(re->tb);
120    if (re->rects) evas_common_tilebuf_free_render_rects(re->rects);
121    free(re);
122
123    evas_common_font_shutdown();
124    evas_common_image_shutdown();
125 }
126
127 static void
128 eng_output_resize(void *data, int w, int h)
129 {
130    Render_Engine *re;
131
132    re = (Render_Engine *)data;
133    evas_fb_outbuf_fb_reconfigure(re->ob, w, h,
134                                  evas_fb_outbuf_fb_get_rot(re->ob),
135                                  OUTBUF_DEPTH_INHERIT);
136    evas_common_tilebuf_free(re->tb);
137    re->tb = evas_common_tilebuf_new(w, h);
138    if (re->tb)
139      evas_common_tilebuf_set_tile_size(re->tb, TILESIZE, TILESIZE);
140 }
141
142 static void
143 eng_output_tile_size_set(void *data, int w, int h)
144 {
145    Render_Engine *re;
146
147    re = (Render_Engine *)data;
148    evas_common_tilebuf_set_tile_size(re->tb, w, h);
149 }
150
151 static void
152 eng_output_redraws_rect_add(void *data, int x, int y, int w, int h)
153 {
154    Render_Engine *re;
155
156    re = (Render_Engine *)data;
157    evas_common_tilebuf_add_redraw(re->tb, x, y, w, h);
158 }
159
160 static void
161 eng_output_redraws_rect_del(void *data, int x, int y, int w, int h)
162 {
163    Render_Engine *re;
164
165    re = (Render_Engine *)data;
166    evas_common_tilebuf_del_redraw(re->tb, x, y, w, h);
167 }
168
169 static void
170 eng_output_redraws_clear(void *data)
171 {
172    Render_Engine *re;
173
174    re = (Render_Engine *)data;
175    evas_common_tilebuf_clear(re->tb);
176 }
177
178 static void *
179 eng_output_redraws_next_update_get(void *data, int *x, int *y, int *w, int *h, int *cx, int *cy, int *cw, int *ch)
180 {
181    Render_Engine *re;
182    RGBA_Image *surface;
183    Tilebuf_Rect *rect;
184    int ux, uy, uw, uh;
185
186    re = (Render_Engine *)data;
187    if (re->end)
188      {
189         re->end = 0;
190         return NULL;
191      }
192    if (!re->rects)
193      {
194         re->rects = evas_common_tilebuf_get_render_rects(re->tb);
195         re->cur_rect = (Evas_Object_List *)re->rects;
196      }
197    if (!re->cur_rect) return NULL;
198    rect = (Tilebuf_Rect *)re->cur_rect;
199    ux = rect->x; uy = rect->y; uw = rect->w; uh = rect->h;
200    re->cur_rect = re->cur_rect->next;
201    if (!re->cur_rect)
202      {
203         evas_common_tilebuf_free_render_rects(re->rects);
204         re->rects = NULL;
205         re->end = 1;
206      }
207
208    surface = evas_fb_outbuf_fb_new_region_for_update(re->ob,
209                                           ux, uy, uw, uh,
210                                           cx, cy, cw, ch);
211    *x = ux; *y = uy; *w = uw; *h = uh;
212    return surface;
213 }
214
215 static void
216 eng_output_redraws_next_update_push(void *data, void *surface, int x, int y, int w, int h)
217 {
218    Render_Engine *re;
219
220    re = (Render_Engine *)data;
221    evas_common_pipe_begin(surface);
222    evas_common_pipe_flush(surface);
223    evas_fb_outbuf_fb_push_updated_region(re->ob, surface, x, y, w, h);
224    evas_fb_outbuf_fb_free_region_for_update(re->ob, surface);
225    evas_common_cpu_end_opt();
226 }
227
228 static void
229 eng_output_flush(void *data)
230 {
231    Render_Engine *re;
232
233    re = (Render_Engine *)data;
234 }
235
236 static void
237 eng_output_idle_flush(void *data)
238 {
239    Render_Engine *re;
240
241    re = (Render_Engine *)data;
242 }
243
244 /* module advertising code */
245 EAPI int
246 module_open(Evas_Module *em)
247 {
248    if (!em) return 0;
249    /* get whatever engine module we inherit from */
250    if (!_evas_module_engine_inherit(&pfunc, "software_generic")) return 0;
251    /* store it for later use */
252    func = pfunc;
253    /* now to override methods */
254 #define ORD(f) EVAS_API_OVERRIDE(f, &func, eng_)
255    ORD(info);
256    ORD(info_free);
257    ORD(setup);
258    ORD(output_free);
259    ORD(output_resize);
260    ORD(output_tile_size_set);
261    ORD(output_redraws_rect_add);
262    ORD(output_redraws_rect_del);
263    ORD(output_redraws_clear);
264    ORD(output_redraws_next_update_get);
265    ORD(output_redraws_next_update_push);
266    ORD(output_flush);
267    ORD(output_idle_flush);
268    /* now advertise out own api */
269    em->functions = (void *)(&func);
270    return 1;
271 }
272
273 EAPI void
274 module_close(void)
275 {
276 }
277
278 EAPI Evas_Module_Api evas_modapi = 
279 {
280    EVAS_MODULE_API_VERSION, 
281      EVAS_MODULE_TYPE_ENGINE,
282      "fb",
283      "none"
284 };