move around - flatter.
[profile/ivi/evas.git] / src / modules / engines / fb / evas_outbuf.c
1 #include "evas_common.h"
2 #include "evas_engine.h"
3 #include <sys/time.h>
4 #include <sys/utsname.h>
5
6 void
7 evas_fb_outbuf_fb_init(void)
8 {
9 }
10
11 void
12 evas_fb_outbuf_fb_free(Outbuf *buf)
13 {
14    /* FIXME: impliment */
15    printf("destroying fb info.. not implemented!!!! WARNING. LEAK!\n");
16    if (buf->priv.back_buf)
17      evas_cache_image_drop(&buf->priv.back_buf->cache_entry);
18    free(buf);
19 }
20
21 Outbuf *
22 evas_fb_outbuf_fb_setup_fb(int w, int h, int rot, Outbuf_Depth depth, int vt_no, int dev_no, int refresh)
23 {
24    /* create outbuf struct */
25    /* setup window and/or fb */
26    /* if (dithered) create backbuf */
27    Outbuf *buf;
28    int fb_fd = -1;
29    int fb_depth;
30
31    fb_depth = -1;
32    if (depth == OUTBUF_DEPTH_RGB_16BPP_565_565_DITHERED) fb_depth = 16;
33    else if (depth == OUTBUF_DEPTH_RGB_16BPP_555_555_DITHERED) fb_depth = 15;
34    else if (depth == OUTBUF_DEPTH_RGB_16BPP_565_444_DITHERED) fb_depth = 16;
35    else if (depth == OUTBUF_DEPTH_RGB_16BPP_444_444_DITHERED) fb_depth = 12;
36    else if (depth == OUTBUF_DEPTH_RGB_32BPP_888_8888) fb_depth = 32;
37    else if (depth == OUTBUF_DEPTH_INHERIT) fb_depth = 0;
38    buf = calloc(1, sizeof(Outbuf));
39    if (!buf)
40      return NULL;
41
42    fb_init(vt_no, dev_no);
43    if (rot == 0 || rot == 180)
44      buf->priv.fb.fb = fb_setmode(w, h, fb_depth, refresh);
45    else if (rot == 90 || rot == 270)
46      buf->priv.fb.fb = fb_setmode(h, w, fb_depth, refresh);
47    if (!buf->priv.fb.fb) buf->priv.fb.fb = fb_getmode();
48    if (!buf->priv.fb.fb)
49      {
50         free(buf);
51         return NULL;
52      }
53    fb_fd = fb_postinit(buf->priv.fb.fb);
54
55    if (rot == 0 || rot == 180)
56      {
57         buf->w = buf->priv.fb.fb->width;
58         buf->h = buf->priv.fb.fb->height;
59      }
60    else if (rot == 90 || rot == 270)
61      {
62         buf->w = buf->priv.fb.fb->height;
63         buf->h = buf->priv.fb.fb->width;
64      }
65
66    buf->depth = depth;
67    buf->rot = rot;
68
69      {
70         Gfx_Func_Convert conv_func;
71         int i;
72
73         buf->priv.mask.r = 0;
74         for (i = 0; i < (int)buf->priv.fb.fb->fb_var.red.length; i++)
75           buf->priv.mask.r |= (1 << (buf->priv.fb.fb->fb_var.red.offset + i));
76         buf->priv.mask.g = 0;
77         for (i = 0; i < (int)buf->priv.fb.fb->fb_var.green.length; i++)
78           buf->priv.mask.g |= (1 << (buf->priv.fb.fb->fb_var.green.offset + i));
79         buf->priv.mask.b = 0;
80         for (i = 0; i < (int)buf->priv.fb.fb->fb_var.blue.length; i++)
81           buf->priv.mask.b |= (1 << (buf->priv.fb.fb->fb_var.blue.offset + i));
82
83         conv_func = NULL;
84         if (buf->rot == 0 || buf->rot == 180)
85           conv_func = evas_common_convert_func_get(0, buf->w, buf->h,
86                                        buf->priv.fb.fb->fb_var.bits_per_pixel,
87                                        buf->priv.mask.r,
88                                        buf->priv.mask.g,
89                                        buf->priv.mask.b,
90                                        PAL_MODE_NONE,
91                                        buf->rot);
92         else if (buf->rot == 90 || buf->rot == 270)
93           conv_func = evas_common_convert_func_get(0, buf->h, buf->w,
94                                        buf->priv.fb.fb->fb_var.bits_per_pixel,
95                                        buf->priv.mask.r,
96                                        buf->priv.mask.g,
97                                        buf->priv.mask.b,
98                                        PAL_MODE_NONE,
99                                        buf->rot);
100        if (!conv_func)
101           {
102              free(buf);
103              return NULL;
104           }
105      }
106 //   if (buf->priv.fb.fb->fb_var.bits_per_pixel < 24)
107 //     buf->priv.back_buf = evas_common_image_create(buf->w, buf->h);
108
109    return buf;
110 }
111
112 void
113 evas_fb_outbuf_fb_blit(Outbuf *buf, int src_x, int src_y, int w, int h, int dst_x, int dst_y)
114 {
115    if (buf->priv.back_buf)
116      {
117         evas_common_blit_rectangle(buf->priv.back_buf, buf->priv.back_buf,
118                        src_x, src_y, w, h, dst_x, dst_y);
119         evas_fb_outbuf_fb_update(buf, dst_x, dst_y, w, h);
120      }
121    else
122      {
123         if (buf->priv.fb.fb)
124           {
125              /* FIXME: need to impliment an fb call for "copy area" */
126           }
127      }
128 }
129
130 void
131 evas_fb_outbuf_fb_update(Outbuf *buf, int x, int y, int w, int h)
132 {
133    if (!(buf->priv.back_buf)) return;
134    if (buf->priv.fb.fb)
135      {
136         Gfx_Func_Convert conv_func;
137         DATA8 *data;
138
139         data = NULL;
140         conv_func = NULL;
141         if (buf->rot == 0)
142           {
143              data = (DATA8 *)buf->priv.fb.fb->mem + buf->priv.fb.fb->mem_offset +
144                buf->priv.fb.fb->bpp *
145                (x + (y * buf->priv.fb.fb->width));
146              conv_func = evas_common_convert_func_get(data, w, h, buf->priv.fb.fb->fb_var.bits_per_pixel,
147                                           buf->priv.mask.r, buf->priv.mask.g,
148                                           buf->priv.mask.b, PAL_MODE_NONE,
149                                           buf->rot);
150           }
151         else if (buf->rot == 180)
152           {
153              data = (DATA8 *)buf->priv.fb.fb->mem + buf->priv.fb.fb->mem_offset +
154                buf->priv.fb.fb->bpp *
155                (buf->w - x - w + ((buf->h - y - h) * buf->priv.fb.fb->width));
156              conv_func = evas_common_convert_func_get(data, w, h, buf->priv.fb.fb->fb_var.bits_per_pixel,
157                                           buf->priv.mask.r, buf->priv.mask.g,
158                                           buf->priv.mask.b, PAL_MODE_NONE,
159                                           buf->rot);
160           }
161         else if (buf->rot == 270)
162           {
163              data = (DATA8 *)buf->priv.fb.fb->mem + buf->priv.fb.fb->mem_offset +
164                buf->priv.fb.fb->bpp *
165                (buf->h - y - h + (x * buf->priv.fb.fb->width));
166              conv_func = evas_common_convert_func_get(data, h, w, buf->priv.fb.fb->fb_var.bits_per_pixel,
167                                           buf->priv.mask.r, buf->priv.mask.g,
168                                           buf->priv.mask.b, PAL_MODE_NONE,
169                                           buf->rot);
170           }
171         else if (buf->rot == 90)
172           {
173              data = (DATA8 *)buf->priv.fb.fb->mem + buf->priv.fb.fb->mem_offset +
174                buf->priv.fb.fb->bpp *
175                (y + ((buf->w - x - w) * buf->priv.fb.fb->width));
176              conv_func = evas_common_convert_func_get(data, h, w, buf->priv.fb.fb->fb_var.bits_per_pixel,
177                                           buf->priv.mask.r, buf->priv.mask.g,
178                                           buf->priv.mask.b, PAL_MODE_NONE,
179                                           buf->rot);
180           }
181         if (conv_func)
182           {
183              DATA32 *src_data;
184
185              src_data = buf->priv.back_buf->image.data + (y * buf->w) + x;
186              if (buf->rot == 0 || buf->rot == 180)
187                {
188                   conv_func(src_data, data,
189                             buf->w - w,
190                             buf->priv.fb.fb->width - w,
191                             w, h,
192                             x, y, NULL);
193                }
194              else if (buf->rot == 90 || buf->rot == 270)
195                {
196                   conv_func(src_data, data,
197                             buf->w - w,
198                             buf->priv.fb.fb->width - h,
199                             h, w,
200                             x, y, NULL);
201                }
202           }
203      }
204 }
205
206 RGBA_Image *
207 evas_fb_outbuf_fb_new_region_for_update(Outbuf *buf, int x, int y, int w, int h, int *cx, int *cy, int *cw, int *ch)
208 {
209    if (buf->priv.back_buf)
210      {
211         *cx = x; *cy = y; *cw = w; *ch = h;
212         return buf->priv.back_buf;
213      }
214    else
215      {
216         RGBA_Image *im;
217
218         *cx = 0; *cy = 0; *cw = w; *ch = h;
219         im = (RGBA_Image *) evas_cache_image_empty(evas_common_image_cache_get());
220         im->cache_entry.flags.alpha = 1;
221         im = (RGBA_Image *) evas_cache_image_size_set(&im->cache_entry, w, h);
222
223         /* handle framebuffers with alpha channel */
224         if (buf->priv.fb.fb->fb_var.transp.length > 0) {
225            memset(im->image.data, 0, w * h * sizeof(DATA32));
226         }
227         return im;
228      }
229    return NULL;
230 }
231
232 void
233 evas_fb_outbuf_fb_free_region_for_update(Outbuf *buf, RGBA_Image *update)
234 {
235    if (update != buf->priv.back_buf) evas_cache_image_drop(&update->cache_entry);
236 }
237
238 void
239 evas_fb_outbuf_fb_push_updated_region(Outbuf *buf, RGBA_Image *update, int x, int y, int w, int h)
240 {
241    if (!buf->priv.fb.fb) return;
242    if (buf->priv.back_buf)
243      {
244         if (update != buf->priv.back_buf)
245           evas_common_blit_rectangle(update, buf->priv.back_buf,
246                          0, 0, w, h, x, y);
247         evas_fb_outbuf_fb_update(buf, x, y, w, h);
248      }
249    else
250      {
251         Gfx_Func_Convert conv_func;
252         DATA8 *data;
253
254         data = NULL;
255         conv_func = NULL;
256         if (buf->rot == 0)
257           {
258              data = (DATA8 *)buf->priv.fb.fb->mem +
259                buf->priv.fb.fb->mem_offset +
260                buf->priv.fb.fb->bpp *
261                (x + (y * buf->priv.fb.fb->width));
262              conv_func = evas_common_convert_func_get(data, w, h,
263                                           buf->priv.fb.fb->fb_var.bits_per_pixel,
264                                           buf->priv.mask.r, buf->priv.mask.g,
265                                           buf->priv.mask.b, PAL_MODE_NONE,
266                                           buf->rot);
267           }
268         else if (buf->rot == 180)  
269           {
270              data = (DATA8 *)buf->priv.fb.fb->mem +
271                buf->priv.fb.fb->mem_offset +
272                buf->priv.fb.fb->bpp *  
273                (buf->w - x - w + ((buf->h - y - h) * buf->priv.fb.fb->width));
274              conv_func = evas_common_convert_func_get(data, w, h,
275                                           buf->priv.fb.fb->fb_var.bits_per_pixel,
276                                           buf->priv.mask.r, buf->priv.mask.g,
277                                           buf->priv.mask.b, PAL_MODE_NONE,
278                                           buf->rot);
279           }
280         else if (buf->rot == 270)
281           {
282              data = (DATA8 *)buf->priv.fb.fb->mem +
283                buf->priv.fb.fb->mem_offset +
284                buf->priv.fb.fb->bpp *
285                (buf->h - y - h + (x * buf->priv.fb.fb->width));
286              conv_func = evas_common_convert_func_get(data, h, w,
287                                           buf->priv.fb.fb->fb_var.bits_per_pixel,
288                                           buf->priv.mask.r, buf->priv.mask.g,
289                                           buf->priv.mask.b, PAL_MODE_NONE,
290                                           buf->rot);
291           }
292         else if (buf->rot == 90)
293           {
294              data = (DATA8 *)buf->priv.fb.fb->mem +
295                buf->priv.fb.fb->mem_offset +
296                buf->priv.fb.fb->bpp *
297                (y + ((buf->w - x - w) * buf->priv.fb.fb->width));
298              conv_func = evas_common_convert_func_get(data, h, w,
299                                           buf->priv.fb.fb->fb_var.bits_per_pixel,
300                                           buf->priv.mask.r, buf->priv.mask.g,
301                                           buf->priv.mask.b, PAL_MODE_NONE,
302                                           buf->rot);
303           }
304         if (conv_func)
305           {
306              DATA32 *src_data;
307
308              src_data = update->image.data;
309              if (buf->rot == 0 || buf->rot == 180)
310                {
311                   conv_func(src_data, data,
312                             0,
313                             buf->priv.fb.fb->width - w,
314                             w, h,
315                             x, y, NULL);
316                }
317              else if (buf->rot == 90 || buf->rot == 270)
318                {
319                   conv_func(src_data, data,
320                             0,
321                             buf->priv.fb.fb->width - h,
322                             h, w,
323                             x, y, NULL);
324                }
325           }
326      }
327 }
328
329 void
330 evas_fb_outbuf_fb_reconfigure(Outbuf *buf, int w, int h, int rot, Outbuf_Depth depth)
331 {
332    if ((w == buf->w) && (h == buf->h) &&
333        (rot == buf->rot) && (depth == buf->depth))
334      return;
335    if (buf->priv.back_buf)
336      {
337         evas_cache_image_drop(&buf->priv.back_buf->cache_entry);
338         buf->priv.back_buf = NULL;
339      }
340    if (buf->priv.fb.fb)
341      {
342         /* FIXME: impliment this */
343      }
344    /* if backbuf delet it */
345    /* resize window or reset fb mode */
346    /* if (dithered) create new backbuf */
347 }
348
349 int
350 evas_fb_outbuf_fb_get_width(Outbuf *buf)
351 {
352    return buf->w;
353 }
354
355 int
356 evas_fb_outbuf_fb_get_height(Outbuf *buf)
357 {
358    return buf->h;
359 }
360
361 Outbuf_Depth
362 evas_fb_outbuf_fb_get_depth(Outbuf *buf)
363 {
364    return buf->depth;
365 }
366
367 int
368 evas_fb_outbuf_fb_get_rot(Outbuf *buf)
369 {
370    return buf->rot;
371 }
372
373 int
374 evas_fb_outbuf_fb_get_have_backbuf(Outbuf *buf)
375 {
376    if (buf->priv.back_buf) return 1;
377    return 0;
378 }
379
380 void
381 evas_fb_outbuf_fb_set_have_backbuf(Outbuf *buf, int have_backbuf)
382 {
383    if (buf->priv.back_buf)
384      {
385         if (have_backbuf) return;
386         evas_cache_image_drop(&buf->priv.back_buf->cache_entry);
387         buf->priv.back_buf = NULL;
388      }
389    else
390      {
391         if (!have_backbuf) return;
392         if (buf->priv.fb.fb)
393           {
394              if (buf->priv.fb.fb->fb_var.bits_per_pixel  < 24)
395                {
396                   buf->priv.back_buf = (RGBA_Image *) evas_cache_image_empty(evas_common_image_cache_get());
397                   buf->priv.back_buf = (RGBA_Image *) evas_cache_image_size_set(&buf->priv.back_buf->cache_entry, buf->w, buf->h);
398                }
399           }
400      }
401 }