move around - flatter.
[profile/ivi/evas.git] / src / modules / engines / buffer / evas_outbuf.c
1 #include "evas_common.h"
2 #include "evas_engine.h"
3 #include <sys/time.h>
4
5 void
6 evas_buffer_outbuf_buf_init(void)
7 {
8 }
9
10 void
11 evas_buffer_outbuf_buf_free(Outbuf *buf)
12 {
13    if (buf->priv.back_buf)
14      {
15         evas_cache_image_drop(&buf->priv.back_buf->cache_entry);
16      }
17    free(buf);
18 }
19
20 Outbuf *
21 evas_buffer_outbuf_buf_setup_fb(int w, int h, Outbuf_Depth depth, void *dest, int dest_row_bytes, int use_color_key, DATA32 color_key, int alpha_level,
22                                 void * (*new_update_region) (int x, int y, int w, int h, int *row_bytes),
23                                 void   (*free_update_region) (int x, int y, int w, int h, void *data)
24                                 )
25 {
26    Outbuf *buf;
27    int y;
28    int bpp;
29    
30    buf = calloc(1, sizeof(Outbuf));
31    if (!buf) return NULL;
32
33    buf->w = w;
34    buf->h = h;
35    buf->depth = depth;
36
37    buf->dest = dest;
38    buf->dest_row_bytes = dest_row_bytes;
39
40    buf->alpha_level = alpha_level;
41    buf->color_key = color_key;
42    buf->use_color_key = use_color_key;
43
44    buf->func.new_update_region = new_update_region;
45    buf->func.free_update_region = free_update_region;
46
47    bpp = sizeof(DATA32);
48    if ((buf->depth == OUTBUF_DEPTH_RGB_24BPP_888_888) ||
49        (buf->depth == OUTBUF_DEPTH_BGR_24BPP_888_888))
50      bpp = 3;
51
52    if ((buf->depth == OUTBUF_DEPTH_ARGB_32BPP_8888_8888) &&
53        (buf->dest) && (buf->dest_row_bytes == (buf->w * sizeof(DATA32))))
54      {
55         for (y = 0; y < h; y++)
56           memset(((unsigned char *)(buf->dest)) + (y * buf->dest_row_bytes), 
57                  0, w * bpp);
58         buf->priv.back_buf = (RGBA_Image *) evas_cache_image_data(evas_common_image_cache_get(),
59                                                                   w, h,
60                                                                   buf->dest,
61                                                                   1, EVAS_COLORSPACE_ARGB8888);
62      }
63    else if ((buf->depth == OUTBUF_DEPTH_RGB_32BPP_888_8888) &&
64        (buf->dest) && (buf->dest_row_bytes == (buf->w * sizeof(DATA32))))
65      {
66         buf->priv.back_buf = (RGBA_Image *) evas_cache_image_data(evas_common_image_cache_get(),
67                                                                   w, h,
68                                                                   buf->dest,
69                                                                   0, EVAS_COLORSPACE_ARGB8888);
70      }
71
72    return buf;
73 }
74
75 RGBA_Image *
76 evas_buffer_outbuf_buf_new_region_for_update(Outbuf *buf, int x, int y, int w, int h, int *cx, int *cy, int *cw, int *ch)
77 {
78    RGBA_Image *im;
79    DATA32 *ptr;
80
81    if (buf->priv.back_buf)
82      {
83         *cx = x; *cy = y; *cw = w; *ch = h;
84         if (buf->priv.back_buf->cache_entry.flags.alpha)
85           {
86              int  ww = w;
87              ptr = buf->priv.back_buf->image.data + (y * buf->priv.back_buf->cache_entry.w) + x;
88              while (h--)
89                {
90                   while (w--)
91                     *ptr++ = 0;
92                   w = ww;
93                   ptr += (buf->priv.back_buf->cache_entry.w - w);
94                }
95           }
96         return buf->priv.back_buf;
97      }
98    else
99      {
100         *cx = 0; *cy = 0; *cw = w; *ch = h;
101         im = (RGBA_Image *) evas_cache_image_empty(evas_common_image_cache_get());
102         if (im)
103           {
104              if (((buf->depth == OUTBUF_DEPTH_ARGB_32BPP_8888_8888)) ||
105                  ((buf->depth == OUTBUF_DEPTH_BGRA_32BPP_8888_8888)))
106                {
107                   im->cache_entry.flags.alpha = 1;
108                   im = (RGBA_Image *) evas_cache_image_size_set(&im->cache_entry, w, h);
109                   if (im)
110                     {
111                        memset(im->image.data, 0, w * h * sizeof(DATA32));
112                     }
113                }
114           }
115      }
116    return im;
117 }
118
119 void
120 evas_buffer_outbuf_buf_free_region_for_update(Outbuf *buf, RGBA_Image *update)
121 {
122    if (update != buf->priv.back_buf) evas_cache_image_drop(&update->cache_entry);
123 }
124
125 void
126 evas_buffer_outbuf_buf_push_updated_region(Outbuf *buf, RGBA_Image *update, int x, int y, int w, int h)
127 {
128    /* copy update image to out buf & convert */
129    switch (buf->depth)
130      {
131       case OUTBUF_DEPTH_RGB_24BPP_888_888:
132         /* copy & pack into 24bpp - if colorkey is enabled... etc. */
133           {
134              DATA8 thresh;
135              int xx, yy;
136              int row_bytes;
137              DATA8 *dest;
138              DATA32 colorkey;
139              DATA32 *src;
140              DATA8 *dst;
141
142              colorkey = buf->color_key;
143              thresh = buf->alpha_level;
144              row_bytes = buf->dest_row_bytes;
145              dest = (DATA8 *)(buf->dest) + (y * row_bytes) + (x * 3);
146              if (buf->func.new_update_region)
147                {
148                   dest = buf->func.new_update_region(x, y, w, h, &row_bytes);
149                }
150              if (!dest) break;
151              if (buf->use_color_key)
152                {
153                   for (yy = 0; yy < h; yy++)
154                     {
155                        dst = dest + (yy * row_bytes);
156                        src = update->image.data + (yy * update->cache_entry.w);
157                        for (xx = 0; xx < w; xx++)
158                          {
159                             if (A_VAL(src) > thresh)
160                               {
161                                  *dst++ = R_VAL(src);
162                                  *dst++ = G_VAL(src);
163                                  *dst++ = B_VAL(src);
164                               }
165                             else
166                               {
167                                  *dst++ = R_VAL(&colorkey);
168                                  *dst++ = G_VAL(&colorkey);
169                                  *dst++ = B_VAL(&colorkey);
170                               }
171                             src++;
172                          }
173                     }
174                }
175              else
176                {
177                   for (yy = 0; yy < h; yy++)
178                     {
179                        dst = dest + (yy * row_bytes);
180                        src = update->image.data + (yy * update->cache_entry.w);
181                        for (xx = 0; xx < w; xx++)
182                          {
183                             *dst++ = R_VAL(src);
184                             *dst++ = G_VAL(src);
185                             *dst++ = B_VAL(src);
186                             src++;
187                          }
188                     }
189                }
190              if (buf->func.free_update_region)
191                {
192                   buf->func.free_update_region(x, y, w, h, dest);
193                }
194           }
195         break;
196       case OUTBUF_DEPTH_BGR_24BPP_888_888:
197         /* copy & pack into 24bpp - if colorkey is enabled... etc. */
198           {
199              DATA8 thresh;
200              int xx, yy;
201              int row_bytes;
202              DATA8 *dest;
203              DATA32 colorkey;
204              DATA32 *src;
205              DATA8 *dst;
206
207              colorkey = buf->color_key;
208              thresh = buf->alpha_level;
209              row_bytes = buf->dest_row_bytes;
210              dest = (DATA8 *)(buf->dest) + (y * row_bytes) + (x * 3);
211              if (buf->func.new_update_region)
212                {
213                   dest = buf->func.new_update_region(x, y, w, h, &row_bytes);
214                }
215              if (!dest) break;
216              if (buf->use_color_key)
217                {
218                   for (yy = 0; yy < h; yy++)
219                     {
220                        dst = dest + (yy * row_bytes);
221                        src = update->image.data + (yy * update->cache_entry.w);
222                        for (xx = 0; xx < w; xx++)
223                          {
224                             if (A_VAL(src) > thresh)
225                               {
226                                  *dst++ = B_VAL(src);
227                                  *dst++ = G_VAL(src);
228                                  *dst++ = R_VAL(src);
229                               }
230                             else
231                               {
232                                  *dst++ = B_VAL(&colorkey);
233                                  *dst++ = G_VAL(&colorkey);
234                                  *dst++ = R_VAL(&colorkey);
235                               }
236                             src++;
237                          }
238                     }
239                }
240              else
241                {
242                   for (yy = 0; yy < h; yy++)
243                     {
244                        dst = dest + (yy * row_bytes);
245                        src = update->image.data + (yy * update->cache_entry.w);
246                        for (xx = 0; xx < w; xx++)
247                          {
248                             *dst++ = B_VAL(src);
249                             *dst++ = G_VAL(src);
250                             *dst++ = R_VAL(src);
251                             src++;
252                          }
253                     }
254                }
255              if (buf->func.free_update_region)
256                {
257                   buf->func.free_update_region(x, y, w, h, dest);
258                }
259           }
260         break;
261       case OUTBUF_DEPTH_RGB_32BPP_888_8888:
262       case OUTBUF_DEPTH_ARGB_32BPP_8888_8888:
263           {
264              DATA32 *dest, *src, *dst;
265              int yy, row_bytes;
266
267              row_bytes = buf->dest_row_bytes;
268              dest = (DATA8 *)(buf->dest) + (y * row_bytes) + (x * 4);
269              if (buf->func.new_update_region)
270                {
271                   dest = buf->func.new_update_region(x, y, w, h, &row_bytes);
272                }
273              /* no need src == dest */
274              if (!buf->priv.back_buf)
275                {
276                   Gfx_Func_Copy func;
277                   
278                   func = evas_common_draw_func_copy_get(w, 0);
279                   if (func)
280                     {
281                        for (yy = 0; yy < h; yy++)
282                          {
283                             src = update->image.data + (yy * update->cache_entry.w);
284                             dst = (DATA8 *)(buf->dest) + ((y + yy) * row_bytes);
285                             func(src, dst, w);
286                          }
287                        
288                     }
289                }
290              if (buf->func.free_update_region)
291                {
292                   buf->func.free_update_region(x, y, w, h, dest);
293                }
294           }
295         break;
296       case OUTBUF_DEPTH_BGR_32BPP_888_8888:
297           {
298              DATA32 *src, *dst;
299              DATA8 *dest;
300              int xx, yy, row_bytes;
301              
302              row_bytes = buf->dest_row_bytes;
303              dest = (DATA8 *)(buf->dest) + (y * row_bytes) + (x * 4);
304              if (buf->func.new_update_region)
305                {
306                   dest = buf->func.new_update_region(x, y, w, h, &row_bytes);
307                }
308              for (yy = 0; yy < h; yy++)
309                {
310                   dst = dest + (yy * row_bytes);
311                   src = update->image.data + (yy * update->cache_entry.w);
312                   for (xx = 0; xx < w; xx++)
313                     {
314                        A_VAL(dst) = B_VAL(src);
315                        R_VAL(dst) = G_VAL(src);
316                        G_VAL(dst) = R_VAL(src);
317                        dst++;
318                        src++;
319                     }
320                }
321              if (buf->func.free_update_region)
322                {
323                   buf->func.free_update_region(x, y, w, h, dest);
324                }
325          }
326         break;
327       case OUTBUF_DEPTH_BGRA_32BPP_8888_8888:
328           {
329              DATA32 *src, *dst;
330              DATA8 *dest;
331              int xx, yy, row_bytes;
332              
333              row_bytes = buf->dest_row_bytes;
334              dest = (DATA8 *)(buf->dest) + (y * row_bytes) + (x * 4);
335              if (buf->func.new_update_region)
336                {
337                   dest = buf->func.new_update_region(x, y, w, h, &row_bytes);
338                }
339              for (yy = 0; yy < h; yy++)
340                {
341                   dst = dest + (yy * row_bytes);
342                   src = update->image.data + (yy * update->cache_entry.w);
343                   for (xx = 0; xx < w; xx++)
344                     {
345                        A_VAL(dst) = B_VAL(src);
346                        R_VAL(dst) = G_VAL(src);
347                        G_VAL(dst) = R_VAL(src);
348                        dst++;
349                        src++;
350                     }
351                }
352              if (buf->func.free_update_region)
353                {
354                   buf->func.free_update_region(x, y, w, h, dest);
355                }
356          }
357         break;
358       default:
359         break;
360      }
361 }