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