move around - flatter.
[profile/ivi/evas.git] / src / modules / engines / gl_common / evas_gl_image.c
1 #include "evas_gl_private.h"
2
3 Evas_GL_Image *
4 evas_gl_common_image_load(Evas_GL_Context *gc, const char *file, const char *key, Evas_Image_Load_Opts *lo)
5 {
6    Evas_GL_Image        *im;
7    RGBA_Image           *im_im;
8    Evas_List            *l;
9
10    im_im = evas_common_load_image_from_file(file, key, lo);
11    if (!im_im) return NULL;
12
13    for (l = gc->images; l; l = l->next)
14      {
15         im = l->data;
16         if (im->im == im_im)
17           {
18              evas_cache_image_drop(&im_im->cache_entry);
19              gc->images = evas_list_remove_list(gc->images, l);
20              gc->images = evas_list_prepend(gc->images, im);
21              im->references++;
22              return im;
23           }
24      }
25
26    im = calloc(1, sizeof(Evas_GL_Image));
27    if (!im) return NULL;
28    im->references = 1;
29    im->im = im_im;
30    if (!im->im)
31      {
32         free(im);
33         return NULL;
34      }
35    im->gc = gc;
36    im->references = 1;
37    im->cached = 1;
38    im->cs.space = EVAS_COLORSPACE_ARGB8888;
39    if (lo) im->load_opts = *lo;
40    gc->images = evas_list_prepend(gc->images, im);
41    return im;
42 }
43
44 Evas_GL_Image *
45 evas_gl_common_image_new_from_data(Evas_GL_Context *gc, int w, int h, DATA32 *data, int alpha, int cspace)
46 {
47    Evas_GL_Image *im;
48    Evas_List *l;
49
50    for (l = gc->images; l; l = l->next)
51      {
52         im = l->data;
53         if (((void *)(im->im->image.data) == (void *)data) &&
54             (im->im->cache_entry.w == w) &&
55             (im->im->cache_entry.h == h))
56           {
57              gc->images = evas_list_remove_list(gc->images, l);
58              gc->images = evas_list_prepend(gc->images, im);
59              im->references++;
60              return im;
61           }
62      }
63    im = calloc(1, sizeof(Evas_GL_Image));
64    if (!im) return NULL;
65    im->references = 1;
66    im->im = (RGBA_Image *) evas_cache_image_data(evas_common_image_cache_get(),
67                                                  w, h, data, alpha, cspace);
68    if (!im->im)
69      {
70         free(im);
71         return NULL;
72      }
73    im->gc = gc;
74    im->cs.space = cspace;
75    switch (cspace)
76      {
77       case EVAS_COLORSPACE_ARGB8888:
78         break;
79       case EVAS_COLORSPACE_YCBCR422P601_PL:
80       case EVAS_COLORSPACE_YCBCR422P709_PL:
81         if (im->tex) evas_gl_common_texture_free(im->tex);
82         im->tex = NULL;
83         im->cs.data = data;
84         im->cs.no_free = 1;
85         break;
86       default:
87         abort();
88         break;
89      }
90    /*
91     im->cached = 1;
92     gc->images = evas_list_prepend(gc->images, im);
93     */
94    printf("new im cs = %i\n", im->cs.space);
95    return im;
96 }
97
98 Evas_GL_Image *
99 evas_gl_common_image_new_from_copied_data(Evas_GL_Context *gc, int w, int h, DATA32 *data, int alpha, int cspace)
100 {
101    Evas_GL_Image *im;
102
103    im = calloc(1, sizeof(Evas_GL_Image));
104    if (!im) return NULL;
105    im->references = 1;
106    im->im = (RGBA_Image *) evas_cache_image_copied_data(evas_common_image_cache_get(),
107                                                         w, h, data, alpha, cspace);
108    if (!im->im)
109      {
110         free(im);
111         return NULL;
112      }
113    im->gc = gc;
114    im->cs.space = cspace;
115    switch (cspace)
116      {
117       case EVAS_COLORSPACE_ARGB8888:
118         break;
119       case EVAS_COLORSPACE_YCBCR422P601_PL:
120       case EVAS_COLORSPACE_YCBCR422P709_PL:
121         if (im->tex) evas_gl_common_texture_free(im->tex);
122         im->tex = NULL;
123         im->cs.no_free = 0;
124         im->cs.data = calloc(1, im->im->cache_entry.h * sizeof(unsigned char *) * 2);
125         if ((data) && (im->cs.data))
126           memcpy(im->cs.data, data, im->im->cache_entry.h * sizeof(unsigned char *) * 2);
127         break;
128       default:
129         abort();
130         break;
131      }
132    return im;
133 }
134
135 Evas_GL_Image *
136 evas_gl_common_image_new(Evas_GL_Context *gc, int w, int h, int alpha, int cspace)
137 {
138    Evas_GL_Image *im;
139
140    im = calloc(1, sizeof(Evas_GL_Image));
141    if (!im) return NULL;
142    im->references = 1;
143    im->im = (RGBA_Image *) evas_cache_image_empty(evas_common_image_cache_get());
144    if (!im->im)
145      {
146         free(im);
147         return NULL;
148      }
149    im->gc = gc;
150    im->cs.space = cspace;
151    im->im->cache_entry.flags.alpha = alpha ? 1 : 0;
152    evas_cache_image_colorspace(&im->im->cache_entry, cspace);
153    im->im = (RGBA_Image *) evas_cache_image_size_set(&im->im->cache_entry, w, h);
154    switch (cspace)
155      {
156       case EVAS_COLORSPACE_ARGB8888:
157         break;
158       case EVAS_COLORSPACE_YCBCR422P601_PL:
159       case EVAS_COLORSPACE_YCBCR422P709_PL:
160 //        if (im->tex) evas_gl_common_texture_free(im->tex);
161         im->tex = NULL;
162         im->cs.no_free = 0;
163         im->cs.data = calloc(1, im->im->cache_entry.h * sizeof(unsigned char *) * 2);
164         break;
165       default:
166         abort();
167         break;
168      }
169    return im;
170 }
171
172 void
173 evas_gl_common_image_free(Evas_GL_Image *im)
174 {
175    im->references--;
176    if (im->references > 0) return;
177
178    if (im->cs.data)
179      {
180         if (!im->cs.no_free) free(im->cs.data);
181      }
182    if (im->cached) im->gc->images = evas_list_remove(im->gc->images, im);
183    if (im->im) evas_cache_image_drop(&im->im->cache_entry);
184    if (im->tex) evas_gl_common_texture_free(im->tex);
185    free(im);
186 }
187
188 void
189 evas_gl_common_image_dirty(Evas_GL_Image *im)
190 {
191    im->im = (RGBA_Image *) evas_cache_image_dirty(&im->im->cache_entry, 0, 0, im->im->cache_entry.w, im->im->cache_entry.h);
192    im->dirty = 1;
193 }
194
195 void
196 evas_gl_common_image_draw(Evas_GL_Context *gc, Evas_GL_Image *im, int sx, int sy, int sw, int sh, int dx, int dy, int dw, int dh, int smooth)
197 {
198    RGBA_Draw_Context *dc;
199    int r, g, b, a;
200    double tx1, ty1, tx2, ty2;
201    int    ow, oh;
202    int    space;
203
204    if (sw < 1) sw = 1;
205    if (sh < 1) sh = 1;
206    dc = gc->dc;
207    if (dc->mul.use)
208      {
209         a = (dc->mul.col >> 24) & 0xff;
210         r = (dc->mul.col >> 16) & 0xff;
211         g = (dc->mul.col >> 8 ) & 0xff;
212         b = (dc->mul.col      ) & 0xff;
213      }
214    else
215      {
216         r = g = b = a = 255;
217      }
218    
219    if (!gc->ext.arb_program && (im->cs.space == EVAS_COLORSPACE_YCBCR422P601_PL
220       || im->cs.space == EVAS_COLORSPACE_YCBCR422P709_PL))
221      {
222         if ((im->cs.data) && (*((unsigned char **)im->cs.data)))
223           {
224              if (im->dirty || !im->im->image.data)
225                {
226                   free(im->im->image.data);
227                   im->im->image.data = malloc(im->im->cache_entry.w * im->im->cache_entry.h * sizeof(DATA32));
228                   if (im->im->image.data)
229                     evas_common_convert_yuv_420p_601_rgba(im->cs.data, 
230                                                           (void *)im->im->image.data,
231                                                           im->im->cache_entry.w, im->im->cache_entry.h);
232                }
233           }
234         space = EVAS_COLORSPACE_ARGB8888;
235      }
236    else
237      space = im->cs.space;
238    
239 /* leak in this switch */
240    switch (space)
241      {
242       case EVAS_COLORSPACE_ARGB8888:
243         evas_cache_image_load_data(&im->im->cache_entry);
244         if ((im->tex) && (im->dirty))
245           {
246              evas_gl_common_texture_update(im->tex, im->im, im->tex->smooth);
247              im->dirty = 0;
248           }
249         if (!im->tex)
250           im->tex = evas_gl_common_texture_new(gc, im->im, smooth);
251         ow = (dw * im->tex->tw) / sw;
252         oh = (dh * im->tex->th) / sh;
253         if (im->tex->rectangle)
254           {
255              tx1 = sx;
256              ty1 = sy;
257              tx2 = sx + sw;
258              ty2 = sy + sh;
259           }
260         else
261           {
262              tx1 = (double)(sx     ) / (double)(im->tex->w);
263              ty1 = (double)(sy     ) / (double)(im->tex->h);
264              tx2 = (double)(sx + sw) / (double)(im->tex->w);
265              ty2 = (double)(sy + sh) / (double)(im->tex->h);
266           }
267         evas_gl_common_context_texture_set(gc, im->tex, smooth, ow, oh);
268         break;
269       case EVAS_COLORSPACE_YCBCR422P601_PL:
270       case EVAS_COLORSPACE_YCBCR422P709_PL:
271         if ((im->tex) && (im->dirty))
272           {
273              evas_gl_common_ycbcr601pl_texture_update(im->tex, im->cs.data, im->im->cache_entry.w, im->im->cache_entry.h, smooth);
274              im->dirty = 0;
275           }
276         if ((!im->tex) && (im->cs.data) && (*((unsigned char **)im->cs.data)))
277           {
278              im->tex = evas_gl_common_ycbcr601pl_texture_new(gc, im->cs.data, im->im->cache_entry.w, im->im->cache_entry.h, smooth);
279           }
280         if (!im->tex) return;
281         ow = (dw * im->tex->tw) / sw;
282         oh = (dh * im->tex->th) / sh;
283         if (im->tex->rectangle)
284           {
285              tx1 = sx;
286              ty1 = sy;
287              tx2 = sx + sw;
288              ty2 = sy + sh;
289           }
290         else
291           {
292              tx1 = (double)(sx     ) / (double)(im->tex->w);
293              ty1 = (double)(sy     ) / (double)(im->tex->h);
294              tx2 = (double)(sx + sw) / (double)(im->tex->w);
295              ty2 = (double)(sy + sh) / (double)(im->tex->h);
296           }
297         evas_gl_common_context_texture_set(gc, im->tex, smooth, ow, oh);
298
299         break;
300       default:
301         abort();
302         break;
303     }
304
305 //   if ((!im->tex->have_mipmaps) && (smooth) &&
306 //       ((im->tex->uw < im->tex->tw) || (im->tex->uh < im->tex->th)) &&
307 //       (!gc->ext.sgis_generate_mipmap))
308 //     evas_gl_common_texture_mipmaps_build(im->tex, im->im, smooth);
309
310    evas_gl_common_context_color_set(gc, r, g, b, a);
311    if ((a < 255) || im->im->cache_entry.flags.alpha)
312      evas_gl_common_context_blend_set(gc, 1);
313    else evas_gl_common_context_blend_set(gc, 0);
314    if (dc->clip.use)
315      evas_gl_common_context_clip_set(gc, 1,
316                                      dc->clip.x, dc->clip.y,
317                                      dc->clip.w, dc->clip.h);
318    else
319      evas_gl_common_context_clip_set(gc, 0,
320                                      0, 0, 0, 0);
321    evas_gl_common_context_read_buf_set(gc, GL_BACK);
322    evas_gl_common_context_write_buf_set(gc, GL_BACK);
323
324    glBegin(GL_QUADS);
325    glTexCoord2d(tx1, ty1); glVertex2i(dx     , dy     );
326    glTexCoord2d(tx2, ty1); glVertex2i(dx + dw, dy     );
327    glTexCoord2d(tx2, ty2); glVertex2i(dx + dw, dy + dh);
328    glTexCoord2d(tx1, ty2); glVertex2i(dx     , dy + dh);
329    glEnd();
330 }