1 #include "evas_gl_private.h"
2 
3 void
evas_gl_common_image_alloc_ensure(Evas_GL_Image * im)4 evas_gl_common_image_alloc_ensure(Evas_GL_Image *im)
5 {
6    if (!im->im) return;
7    im->im = (RGBA_Image *)evas_cache_image_size_set(&im->im->cache_entry,
8                                                     im->w, im->h);
9 }
10 
11 EAPI void
evas_gl_common_image_all_unload(Evas_Engine_GL_Context * gc)12 evas_gl_common_image_all_unload(Evas_Engine_GL_Context *gc)
13 {
14    Eina_List *l;
15    Evas_GL_Image *im;
16 
17    EINA_LIST_FOREACH(gc->shared->images, l, im)
18      {
19         if (im->im)
20           evas_cache_image_unload_data(&im->im->cache_entry);
21         if (im->tex)
22           {
23              if (!im->tex->pt->dyn.img)
24                {
25                   evas_gl_common_texture_free(im->tex, EINA_TRUE);
26                   im->tex = NULL;
27                }
28           }
29      }
30 }
31 
32 static void
_evas_gl_image_cache_trim(Evas_Engine_GL_Context * gc)33 _evas_gl_image_cache_trim(Evas_Engine_GL_Context *gc)
34 {
35    int size = evas_common_image_get_cache();
36 
37    while (gc->shared->images_size > size)
38      {
39         Evas_GL_Image *im2;
40         Eina_List *l = NULL;
41         Eina_Bool removed = EINA_FALSE;
42 
43         EINA_LIST_REVERSE_FOREACH(gc->shared->images, l, im2)
44           {
45              if (im2->references == 0)
46                {
47                   im2->cached = 0;
48                   im2->gc->shared->images =
49                      eina_list_remove_list(im2->gc->shared->images, l);
50                   im2->gc->shared->images_size -= (im2->csize);
51                   evas_gl_common_image_free(im2);
52                   l = NULL;
53                   removed = EINA_TRUE;
54                   break;
55                }
56           }
57 
58         if (!removed || !gc->shared->images)
59           {
60              // still have referenced images - need to let others release
61              // refs on their own
62              break;
63           }
64      }
65 }
66 
67 static Eina_Bool
_evas_gl_image_cache_add(Evas_GL_Image * im)68 _evas_gl_image_cache_add(Evas_GL_Image *im)
69 {
70    if (im->references == 0)
71      {
72         im->csize = im->w * im->h * 4;
73         im->gc->shared->images_size += im->csize;
74         _evas_gl_image_cache_trim(im->gc);
75         return EINA_TRUE;
76      }
77    else
78      {
79         im->gc->shared->images = eina_list_remove(im->gc->shared->images, im);
80         im->cached = 0;
81      }
82    return EINA_FALSE;
83 }
84 
85 EAPI void
evas_gl_common_image_ref(Evas_GL_Image * im)86 evas_gl_common_image_ref(Evas_GL_Image *im)
87 {
88    if (im->references == 0)
89      {
90         im->gc->shared->images_size -= (im->csize);
91      }
92    im->references++;
93 }
94 
95 EAPI void
evas_gl_common_image_unref(Evas_GL_Image * im)96 evas_gl_common_image_unref(Evas_GL_Image *im)
97 {
98    im->references--;
99    if (im->references == 0)
100      {
101         _evas_gl_image_cache_add(im);
102      }
103 }
104 
105 static void
_evas_gl_cspace_list_fill(Evas_Engine_GL_Context * gc)106 _evas_gl_cspace_list_fill(Evas_Engine_GL_Context *gc)
107 {
108 #define CS_APPEND(cs) gc->shared->info.cspaces = eina_list_append \
109    (gc->shared->info.cspaces, (void *) (intptr_t) cs)
110    if (gc->shared->info.etc2)
111      {
112         CS_APPEND(EVAS_COLORSPACE_RGBA8_ETC2_EAC);
113         CS_APPEND(EVAS_COLORSPACE_RGB8_ETC2);
114         CS_APPEND(EVAS_COLORSPACE_ETC1);
115         CS_APPEND(EVAS_COLORSPACE_ETC1_ALPHA);
116      }
117    else if (gc->shared->info.etc1)
118      {
119         CS_APPEND(EVAS_COLORSPACE_ETC1);
120         CS_APPEND(EVAS_COLORSPACE_ETC1_ALPHA);
121      }
122    if (gc->shared->info.s3tc)
123      {
124         CS_APPEND(EVAS_COLORSPACE_RGB_S3TC_DXT1);
125         CS_APPEND(EVAS_COLORSPACE_RGBA_S3TC_DXT1);
126         CS_APPEND(EVAS_COLORSPACE_RGBA_S3TC_DXT2);
127         CS_APPEND(EVAS_COLORSPACE_RGBA_S3TC_DXT3);
128         CS_APPEND(EVAS_COLORSPACE_RGBA_S3TC_DXT4);
129         CS_APPEND(EVAS_COLORSPACE_RGBA_S3TC_DXT5);
130      }
131    CS_APPEND(EVAS_COLORSPACE_GRY8);
132    CS_APPEND(EVAS_COLORSPACE_AGRY88);
133    CS_APPEND(EVAS_COLORSPACE_ARGB8888);
134 }
135 
136 void
evas_gl_common_image_preload_done(void * data)137 evas_gl_common_image_preload_done(void *data)
138 {
139    Evas_GL_Image *im = data;
140 
141    if (im->im)
142      {
143         Evas_Colorspace cspace = EVAS_COLORSPACE_ARGB8888;
144 
145         if (im->im->cache_entry.cspaces)
146           {
147              Evas_Colorspace cs;
148              unsigned int i;
149              Eina_List *l2;
150              void *ldata;
151 
152              cspace = EVAS_COLORSPACE_ARGB8888;
153              for (i = 0;
154                   im->im->cache_entry.cspaces[i] != EVAS_COLORSPACE_ARGB8888;
155                   i++)
156                {
157                   EINA_LIST_FOREACH(im->gc->shared->info.cspaces, l2, ldata)
158                     {
159                        cs = (Evas_Colorspace) (intptr_t) ldata;
160                        if (cs == im->im->cache_entry.cspaces[i])
161                          {
162                             cspace = cs;
163                             goto found_cspace;
164                          }
165                     }
166                }
167 found_cspace:
168              if (cspace == EVAS_COLORSPACE_ETC1 && im->gc->shared->info.etc2)
169                cspace = EVAS_COLORSPACE_RGB8_ETC2;
170              im->im->cache_entry.space = cspace;
171           }
172         im->cs.space = cspace;
173         im->orient = EVAS_IMAGE_ORIENT_NONE;
174         im->alpha = im->im->cache_entry.flags.alpha;
175         im->w = im->im->cache_entry.w;
176         im->h = im->im->cache_entry.h;
177      }
178 }
179 
180 //FIXME: This is a hacky way. Need an proper interface...
181 void
evas_gl_common_image_preload_unwatch(Evas_GL_Image * im)182 evas_gl_common_image_preload_unwatch(Evas_GL_Image *im)
183 {
184    Eina_Inlist *l2;
185    Evas_Cache_Target *tg;
186 
187    if (!im->im) return;
188    EINA_INLIST_FOREACH_SAFE(im->im->cache_entry.targets, l2, tg)
189      {
190         if ((tg->preloaded_cb != evas_gl_common_image_preload_done) || (tg->preloaded_data != im))
191           continue;
192         tg->delete_me = EINA_TRUE;
193         break;
194      }
195 }
196 
197 Evas_GL_Image *
evas_gl_common_image_new_from_rgbaimage(Evas_Engine_GL_Context * gc,RGBA_Image * im_im,Evas_Image_Load_Opts * lo,int * error)198 evas_gl_common_image_new_from_rgbaimage(Evas_Engine_GL_Context *gc, RGBA_Image *im_im,
199                                         Evas_Image_Load_Opts *lo, int *error)
200 {
201    Evas_GL_Image *im;
202    Eina_List     *l;
203    Evas_Colorspace cspace = EVAS_COLORSPACE_ARGB8888;
204 
205    /* i'd LOVe to do this, but we can't because we load to load header
206     * to get image size to know if its too big or not! so this disallows
207     * us to know that - photocam thus suffers
208    if (((int)im_im->cache_entry.w > gc->shared->info.max_texture_size) ||
209        ((int)im_im->cache_entry.h > gc->shared->info.max_texture_size))
210      {
211         evas_cache_image_drop(&(im_im->cache_entry));
212         if (error) *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
213         return NULL;
214      }
215     */
216 
217    if (error) *error = EVAS_LOAD_ERROR_NONE;
218 
219    // FIXME: keep unreffed shared images around
220    EINA_LIST_FOREACH(gc->shared->images, l, im)
221      {
222         if (im->im == im_im)
223           {
224              evas_cache_image_drop(&(im_im->cache_entry));
225              gc->shared->images = eina_list_remove_list(gc->shared->images, l);
226              gc->shared->images = eina_list_prepend(gc->shared->images, im);
227              evas_gl_common_image_ref(im);
228              if (error) *error = EVAS_LOAD_ERROR_NONE;
229              return im;
230           }
231      }
232 
233    im = calloc(1, sizeof(Evas_GL_Image));
234    if (!im)
235      {
236         evas_cache_image_drop(&(im_im->cache_entry));
237         if (error) *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
238         return NULL;
239      }
240    if (im_im->cache_entry.cspaces)
241      {
242         Evas_Colorspace cs;
243         unsigned int i;
244         Eina_List *l2;
245         void *ldata;
246 
247         if (!gc->shared->info.cspaces)
248           _evas_gl_cspace_list_fill(gc);
249 
250         cspace = EVAS_COLORSPACE_ARGB8888;
251         for (i = 0; im_im->cache_entry.cspaces[i] != EVAS_COLORSPACE_ARGB8888; i++)
252           EINA_LIST_FOREACH(gc->shared->info.cspaces, l2, ldata)
253             {
254                cs = (Evas_Colorspace) (intptr_t) ldata;
255                if (cs == im_im->cache_entry.cspaces[i])
256                  {
257                     cspace = cs;
258                     goto found_cspace;
259                  }
260             }
261 
262 found_cspace:
263         // ETC2 is backwards compatible with ETC1 but we prefer ETC2
264         if (cspace == EVAS_COLORSPACE_ETC1 && gc->shared->info.etc2)
265           cspace = EVAS_COLORSPACE_RGB8_ETC2;
266 
267         im_im->cache_entry.space = cspace;
268      }
269 
270    im->references = 1;
271    im->im = im_im;
272    im->gc = gc;
273    im->cached = 1;
274    im->cs.space = cspace;
275    im->orient = EVAS_IMAGE_ORIENT_NONE;
276    im->alpha = im->im->cache_entry.flags.alpha;
277    im->w = im->im->cache_entry.w;
278    im->h = im->im->cache_entry.h;
279    if (lo) im->load_opts = *lo;
280    gc->shared->images = eina_list_prepend(gc->shared->images, im);
281    return im;
282 }
283 
284 Evas_GL_Image *
evas_gl_common_image_load(Evas_Engine_GL_Context * gc,const char * file,const char * key,Evas_Image_Load_Opts * lo,int * error)285 evas_gl_common_image_load(Evas_Engine_GL_Context *gc, const char *file, const char *key, Evas_Image_Load_Opts *lo, int *error)
286 {
287    RGBA_Image *im_im;
288 
289 #ifdef EVAS_CSERVE2
290    if (evas_cserve2_use_get())
291      {
292         im_im = (RGBA_Image *) evas_cache2_image_open
293           (evas_common_image_cache2_get(), file, key, lo, error);
294         if (im_im)
295           {
296              *error = evas_cache2_image_open_wait(&im_im->cache_entry);
297              if ((*error != EVAS_LOAD_ERROR_NONE)
298                  && im_im->cache_entry.animated.animated)
299                {
300                   evas_cache2_image_close(&im_im->cache_entry);
301                   im_im = NULL;
302                }
303              else
304                return evas_gl_common_image_new_from_rgbaimage(gc, im_im, lo, error);
305           }
306      }
307 #endif
308 
309    im_im = evas_common_load_image_from_file(file, key, lo, error);
310    if (!im_im) return NULL;
311 
312    return evas_gl_common_image_new_from_rgbaimage(gc, im_im, lo, error);
313 }
314 
315 Evas_GL_Image *
evas_gl_common_image_mmap(Evas_Engine_GL_Context * gc,Eina_File * f,const char * key,Evas_Image_Load_Opts * lo,int * error)316 evas_gl_common_image_mmap(Evas_Engine_GL_Context *gc, Eina_File *f, const char *key, Evas_Image_Load_Opts *lo, int *error)
317 {
318    RGBA_Image *im_im;
319 
320    im_im = evas_common_load_image_from_mmap(f, key, lo, error);
321    if (!im_im) return NULL;
322 
323    return evas_gl_common_image_new_from_rgbaimage(gc, im_im, lo, error);
324 }
325 
326 EAPI Evas_GL_Image *
evas_gl_common_image_new_from_data(Evas_Engine_GL_Context * gc,unsigned int w,unsigned int h,DATA32 * data,int alpha,Evas_Colorspace cspace)327 evas_gl_common_image_new_from_data(Evas_Engine_GL_Context *gc, unsigned int w, unsigned int h, DATA32 *data, int alpha, Evas_Colorspace cspace)
328 {
329    Evas_GL_Image *im;
330    Eina_List *l;
331 
332    if (((int)w > gc->shared->info.max_texture_size) ||
333        ((int)h > gc->shared->info.max_texture_size))
334      return NULL;
335 
336    if (data)
337      {
338         EINA_LIST_FOREACH(gc->shared->images, l, im)
339           {
340              if (((void *)(im->im->image.data) == (void *)data) &&
341                  (im->im->cache_entry.w == w) &&
342                  (im->im->cache_entry.h == h))
343                {
344                   gc->shared->images = eina_list_remove_list(gc->shared->images, l);
345                   gc->shared->images = eina_list_prepend(gc->shared->images, im);
346                   evas_gl_common_image_ref(im);
347                   return im;
348                }
349           }
350      }
351    im = calloc(1, sizeof(Evas_GL_Image));
352    if (!im) return NULL;
353    im->references = 1;
354    im->im = (RGBA_Image *) evas_cache_image_data(evas_common_image_cache_get(),
355                                                  w, h, data, alpha, cspace);
356    if (!im->im)
357      {
358 	free(im);
359 	return NULL;
360      }
361    im->gc = gc;
362    im->cs.space = cspace;
363    im->alpha = im->im->cache_entry.flags.alpha;
364    im->w = im->im->cache_entry.w;
365    im->h = im->im->cache_entry.h;
366    switch (cspace)
367      {
368       case EVAS_COLORSPACE_ARGB8888:
369       case EVAS_COLORSPACE_GRY8:
370       case EVAS_COLORSPACE_AGRY88:
371         break;
372       case EVAS_COLORSPACE_ETC1:
373       case EVAS_COLORSPACE_ETC1_ALPHA:
374         if (gc->shared->info.etc1 && !gc->shared->info.etc2) break;
375         ERR("We don't know what to do with ETC1 on this hardware. You need to add a software converter here.");
376         break;
377       case EVAS_COLORSPACE_RGB8_ETC2:
378       case EVAS_COLORSPACE_RGBA8_ETC2_EAC:
379         if (gc->shared->info.etc2) break;
380         ERR("We don't know what to do with ETC2 on this hardware. You need to add a software converter here.");
381         break;
382       case EVAS_COLORSPACE_YCBCR422P601_PL:
383       case EVAS_COLORSPACE_YCBCR422P709_PL:
384 	im->cs.data = data;
385 	im->cs.no_free = 1;
386 	break;
387       default:
388         ERR("color space not supported: %d", cspace);
389 	break;
390      }
391    return im;
392 }
393 
394 Evas_GL_Image *
evas_gl_common_image_new_from_copied_data(Evas_Engine_GL_Context * gc,unsigned int w,unsigned int h,DATA32 * data,int alpha,Evas_Colorspace cspace)395 evas_gl_common_image_new_from_copied_data(Evas_Engine_GL_Context *gc, unsigned int w, unsigned int h, DATA32 *data, int alpha, Evas_Colorspace cspace)
396 {
397    Evas_GL_Image *im;
398 
399    if (((int)w > gc->shared->info.max_texture_size) ||
400        ((int)h > gc->shared->info.max_texture_size))
401      return NULL;
402 
403    im = calloc(1, sizeof(Evas_GL_Image));
404    if (!im) return NULL;
405    im->references = 1;
406    im->im = (RGBA_Image *) evas_cache_image_copied_data(evas_common_image_cache_get(),
407                                                         w, h, data, alpha, cspace);
408    if (!im->im)
409      {
410 	free(im);
411 	return NULL;
412      }
413    im->gc = gc;
414    im->cs.space = cspace;
415    im->alpha = im->im->cache_entry.flags.alpha;
416    im->w = im->im->cache_entry.w;
417    im->h = im->im->cache_entry.h;
418    switch (cspace)
419      {
420       case EVAS_COLORSPACE_ARGB8888:
421       case EVAS_COLORSPACE_GRY8:
422       case EVAS_COLORSPACE_AGRY88:
423         break;
424       case EVAS_COLORSPACE_ETC1:
425       case EVAS_COLORSPACE_ETC1_ALPHA:
426         if (gc->shared->info.etc1 && !gc->shared->info.etc2) break;
427         ERR("We don't know what to do with ETC1 on this hardware. You need to add a software converter here.");
428         break;
429       case EVAS_COLORSPACE_RGB8_ETC2:
430       case EVAS_COLORSPACE_RGBA8_ETC2_EAC:
431         if (gc->shared->info.etc2) break;
432         ERR("We don't know what to do with ETC2 on this hardware. You need to add a software converter here.");
433         break;
434       case EVAS_COLORSPACE_YCBCR422P601_PL:
435       case EVAS_COLORSPACE_YCBCR422P709_PL:
436         if (im->im->cache_entry.h > 0)
437           im->cs.data = calloc(1, im->im->cache_entry.h * sizeof(unsigned char *) * 2);
438         if ((data) && (im->cs.data))
439           memcpy(im->cs.data, data, im->im->cache_entry.h * sizeof(unsigned char *) * 2);
440         break;
441       default:
442         ERR("color space not supported: %d", cspace);
443         break;
444      }
445    return im;
446 }
447 
448 Evas_GL_Image *
evas_gl_common_image_new(Evas_Engine_GL_Context * gc,unsigned int w,unsigned int h,int alpha,Evas_Colorspace cspace)449 evas_gl_common_image_new(Evas_Engine_GL_Context *gc, unsigned int w, unsigned int h, int alpha, Evas_Colorspace cspace)
450 {
451    Evas_GL_Image *im;
452 
453    if (((int)w > gc->shared->info.max_texture_size) ||
454        ((int)h > gc->shared->info.max_texture_size))
455      return NULL;
456 
457    im = calloc(1, sizeof(Evas_GL_Image));
458    if (!im) return NULL;
459    im->references = 1;
460    im->im = (RGBA_Image *)evas_cache_image_empty(evas_common_image_cache_get());
461    if (!im->im)
462      {
463 	free(im);
464 	return NULL;
465      }
466    im->gc = gc;
467    im->im->cache_entry.flags.alpha = alpha ? 1 : 0;
468    im->cs.space = cspace;
469    im->alpha = im->im->cache_entry.flags.alpha;
470    im->im->cache_entry.w = w;
471    im->im->cache_entry.h = h;
472    im->w = im->im->cache_entry.w;
473    im->h = im->im->cache_entry.h;
474    evas_cache_image_colorspace(&im->im->cache_entry, cspace);
475    im->im = (RGBA_Image *)evas_cache_image_size_set(&im->im->cache_entry, w, h);
476    switch (cspace)
477      {
478       case EVAS_COLORSPACE_ARGB8888:
479       case EVAS_COLORSPACE_GRY8:
480       case EVAS_COLORSPACE_AGRY88:
481          break;
482       case EVAS_COLORSPACE_ETC1:
483       case EVAS_COLORSPACE_ETC1_ALPHA:
484         if (gc->shared->info.etc1 && !gc->shared->info.etc2) break;
485         ERR("We don't know what to do with ETC1 on this hardware. You need to add a software converter here.");
486         break;
487       case EVAS_COLORSPACE_RGB8_ETC2:
488       case EVAS_COLORSPACE_RGBA8_ETC2_EAC:
489         if (gc->shared->info.etc2) break;
490         ERR("We don't know what to do with ETC2 on this hardware. You need to add a software converter here.");
491         break;
492       case EVAS_COLORSPACE_YCBCR422P601_PL:
493       case EVAS_COLORSPACE_YCBCR422P709_PL:
494       case EVAS_COLORSPACE_YCBCR422601_PL:
495       case EVAS_COLORSPACE_YCBCR420NV12601_PL:
496       case EVAS_COLORSPACE_YCBCR420TM12601_PL:
497 //        if (im->tex) evas_gl_common_texture_free(im->tex);
498 	im->tex = NULL;
499 	im->cs.no_free = 0;
500         if (im->im->cache_entry.h > 0)
501           im->cs.data = calloc(1, im->im->cache_entry.h * sizeof(unsigned char *) * 2);
502 	break;
503       default:
504 	abort();
505 	break;
506      }
507    return im;
508 }
509 
510 Evas_GL_Image *
evas_gl_common_image_alpha_set(Evas_GL_Image * im,int alpha)511 evas_gl_common_image_alpha_set(Evas_GL_Image *im, int alpha)
512 {
513    if (!im) return NULL;
514    if (im->alpha == alpha) return im;
515    im->alpha = alpha;
516    if (!im->im) return im;
517    evas_gl_common_image_alloc_ensure(im);
518    evas_cache_image_load_data(&im->im->cache_entry);
519    im->im->cache_entry.flags.alpha = alpha ? 1 : 0;
520 
521    if (im->tex) evas_gl_common_texture_free(im->tex, EINA_TRUE);
522    if (im->tex_only)
523      {
524         im->tex = evas_gl_common_texture_native_new(im->gc, im->w, im->h,
525                                                     im->alpha, im);
526      }
527    else
528      {
529         im->tex = evas_gl_common_texture_new(im->gc, im->im, EINA_FALSE);
530         if (im->tex) evas_gl_common_texture_update(im->tex, im->im);
531      }
532    return im;
533 }
534 
535 EAPI void
evas_gl_common_image_native_enable(Evas_GL_Image * im)536 evas_gl_common_image_native_enable(Evas_GL_Image *im)
537 {
538    if (im->cs.data)
539      {
540 	if (!im->cs.no_free) free(im->cs.data);
541         im->cs.data = NULL;
542      }
543    im->cs.no_free = 0;
544    if (im->cached)
545      {
546         if (im->references == 0)
547            im->gc->shared->images_size -= (im->csize);
548         im->gc->shared->images = eina_list_remove(im->gc->shared->images, im);
549         im->cached = 0;
550      }
551    if (im->im)
552      {
553         evas_cache_image_drop(&im->im->cache_entry);
554         im->im = NULL;
555      }
556    if (im->tex)
557      {
558         evas_gl_common_texture_free(im->tex, EINA_TRUE);
559         im->tex = NULL;
560      }
561 
562    im->cs.space = EVAS_COLORSPACE_ARGB8888;
563    im->tex = evas_gl_common_texture_native_new(im->gc, im->w, im->h, im->alpha, im);
564    im->tex_only = 1;
565 }
566 
567 EAPI void
evas_gl_common_image_native_disable(Evas_GL_Image * im)568 evas_gl_common_image_native_disable(Evas_GL_Image *im)
569 {
570    if (im->im)
571      {
572         evas_cache_image_drop(&im->im->cache_entry);
573         im->im = NULL;
574      }
575    if (im->tex)
576      {
577         evas_gl_common_texture_free(im->tex, EINA_TRUE);
578         im->tex = NULL;
579      }
580    im->tex_only = 0;
581    im->im = (RGBA_Image *)evas_cache_image_empty(evas_common_image_cache_get());
582    im->im->cache_entry.flags.alpha = im->alpha;
583    im->cs.space = EVAS_COLORSPACE_ARGB8888;
584    evas_cache_image_colorspace(&im->im->cache_entry, im->cs.space);
585 /*
586    im->im = (RGBA_Image *)evas_cache_image_size_set(&im->im->cache_entry, im->w, im->h);
587    if (!im->tex)
588      im->tex = evas_gl_common_texture_new(im->gc, im->im);
589  */
590 }
591 
592 void
evas_gl_common_image_scale_hint_set(Evas_GL_Image * im,int hint)593 evas_gl_common_image_scale_hint_set(Evas_GL_Image *im, int hint)
594 {
595    im->scale_hint = hint;
596    // FIXME: take advantage of this even in gl (eg if image is
597    // 1600x1200 but we always use it at 800x600 or even less - drop
598    // the texture res down for "non dynamic" stuff to save memory)
599 }
600 
601 void
evas_gl_common_image_content_hint_set(Evas_GL_Image * im,int hint)602 evas_gl_common_image_content_hint_set(Evas_GL_Image *im, int hint)
603 {
604    if (im->content_hint == hint) return;
605    im->content_hint = hint;
606    if (!im->gc) return;
607    if (!im->gc->shared->info.bgra) return;
608    // does not handle yuv yet.
609    // TODO: Check this list of cspaces
610    switch (im->cs.space)
611      {
612       case EVAS_COLORSPACE_YCBCR422P601_PL:
613       case EVAS_COLORSPACE_YCBCR422P709_PL:
614       case EVAS_COLORSPACE_RGB565_A5P:
615       case EVAS_COLORSPACE_YCBCR422601_PL:
616       case EVAS_COLORSPACE_YCBCR420NV12601_PL:
617       case EVAS_COLORSPACE_YCBCR420TM12601_PL:
618       case EVAS_COLORSPACE_ETC1_ALPHA:
619         return;
620       default: break;
621      }
622    if (im->content_hint == EVAS_IMAGE_CONTENT_HINT_DYNAMIC)
623      {
624         if ((!im->gc->shared->info.sec_image_map) &&
625             ((!im->gc->shared->info.sec_tbm_surface) || (!im->gc->shared->info.egl_tbm_ext))) return;
626         if (im->cs.data)
627           {
628              if (!im->cs.no_free) free(im->cs.data);
629              im->cs.data = NULL;
630           }
631         im->cs.no_free = 0;
632         if (im->cached)
633           {
634              if (im->references == 0)
635                 im->gc->shared->images_size -= im->csize;
636              im->gc->shared->images = eina_list_remove(im->gc->shared->images, im);
637              im->cached = 0;
638           }
639         if (im->im)
640           {
641              evas_cache_image_drop(&im->im->cache_entry);
642              im->im = NULL;
643           }
644         if (im->tex)
645           {
646              evas_gl_common_texture_free(im->tex, EINA_TRUE);
647              im->tex = NULL;
648           }
649         im->tex = evas_gl_common_texture_dynamic_new(im->gc, im);
650         im->tex_only = 1;
651      }
652    else
653      {
654         if (im->im)
655           {
656              evas_cache_image_drop(&im->im->cache_entry);
657              im->im = NULL;
658           }
659         if (im->tex)
660           {
661              evas_gl_common_texture_free(im->tex, EINA_TRUE);
662              im->tex = NULL;
663           }
664         im->tex_only = 0;
665 
666         im->im = (RGBA_Image *)evas_cache_image_empty(evas_common_image_cache_get());
667         im->im->cache_entry.flags.alpha = im->alpha;
668         im->im->cache_entry.space = im->cs.space;
669         evas_cache_image_colorspace(&im->im->cache_entry, im->cs.space);
670         im->im = (RGBA_Image *)evas_cache_image_size_set(&im->im->cache_entry, im->w, im->h);
671         if (!im->tex)
672            im->tex = evas_gl_common_texture_new(im->gc, im->im, EINA_FALSE);
673      }
674 }
675 
676 void
evas_gl_common_image_cache_flush(Evas_Engine_GL_Context * gc)677 evas_gl_common_image_cache_flush(Evas_Engine_GL_Context *gc)
678 {
679    _evas_gl_image_cache_trim(gc);
680 }
681 
682 EAPI void
evas_gl_common_image_free(Evas_GL_Image * im)683 evas_gl_common_image_free(Evas_GL_Image *im)
684 {
685    if (!im) return;
686 
687    im->references--;
688    if (im->references > 0) return;
689 
690    if (im->gc && (im->gc->pipe[0].shader.surface == im))
691      evas_gl_common_context_target_surface_set(im->gc, im->gc->def_surface);
692 
693    if (im->fglyph)
694      {
695         if (im->gc)
696           im->gc->font_glyph_images = eina_list_remove(im->gc->font_glyph_images, im);
697         im->fglyph->ext_dat = NULL;
698         im->fglyph->ext_dat_free = NULL;
699      }
700 
701    if (im->gc)
702      evas_gl_common_context_flush(im->gc);
703 
704    evas_gl_common_image_preload_unwatch(im);
705 
706    if (im->scaled.origin)
707      {
708         evas_gl_common_image_free(im->scaled.origin);
709         im->scaled.origin = NULL;
710      }
711 
712    if (im->native.func.free)
713      im->native.func.free(im);
714 
715    if (im->cs.data)
716      {
717         if (!im->cs.no_free) free(im->cs.data);
718      }
719    if (im->cached && im->gc)
720      {
721         if (_evas_gl_image_cache_add(im)) return;
722      }
723    if (im->tex) evas_gl_common_texture_free(im->tex, EINA_TRUE);
724    if (im->im)
725      evas_cache_image_drop(&im->im->cache_entry);
726 
727    free(im);
728 }
729 
730 Evas_GL_Image *
evas_gl_common_image_surface_new(Evas_Engine_GL_Context * gc,unsigned int w,unsigned int h,int alpha,int stencil)731 evas_gl_common_image_surface_new(Evas_Engine_GL_Context *gc, unsigned int w, unsigned int h, int alpha, int stencil)
732 {
733    Evas_GL_Image *im;
734 
735    if (((int)w > gc->shared->info.max_texture_size) ||
736        ((int)h > gc->shared->info.max_texture_size))
737      return NULL;
738 
739    im = calloc(1, sizeof(Evas_GL_Image));
740    if (!im) return NULL;
741    im->references = 1;
742    im->gc = gc;
743    im->cs.space = EVAS_COLORSPACE_ARGB8888;
744    im->alpha = alpha;
745    im->w = w;
746    im->h = h;
747    im->tex = evas_gl_common_texture_render_new(gc, w, h, alpha, stencil);
748    im->tex_only = 1;
749    return im;
750 }
751 
752 Evas_GL_Image *
evas_gl_common_image_surface_noscale_new(Evas_Engine_GL_Context * gc,unsigned int w,unsigned int h,int alpha)753 evas_gl_common_image_surface_noscale_new(Evas_Engine_GL_Context *gc, unsigned int w, unsigned int h, int alpha)
754 {
755    Evas_GL_Image *im;
756 
757    if (((int)w > gc->shared->info.max_texture_size) ||
758        ((int)h > gc->shared->info.max_texture_size))
759      return NULL;
760 
761    im = calloc(1, sizeof(Evas_GL_Image));
762    if (!im) return NULL;
763    im->references = 1;
764    im->gc = gc;
765    im->cs.space = EVAS_COLORSPACE_ARGB8888;
766    im->alpha = alpha;
767    im->w = w;
768    im->h = h;
769    im->tex = evas_gl_common_texture_render_noscale_new(gc, w, h, alpha);
770    im->tex_only = 1;
771    return im;
772 }
773 
774 void
evas_gl_common_image_dirty(Evas_GL_Image * im,unsigned int x,unsigned int y,unsigned int w,unsigned int h)775 evas_gl_common_image_dirty(Evas_GL_Image *im, unsigned int x, unsigned int y, unsigned int w, unsigned int h)
776 {
777    if ((w == 0) && (h == 0) && (x == 0) && (y == 0))
778      {
779         w = im->w;
780         h = im->h;
781      }
782    if (im->im)
783      {
784         evas_gl_common_image_alloc_ensure(im);
785         im->im = (RGBA_Image *)evas_cache_image_dirty(&im->im->cache_entry, x, y, w, h);
786      }
787    im->dirty = 1;
788 }
789 
790 void
evas_gl_common_image_update(Evas_Engine_GL_Context * gc,Evas_GL_Image * im)791 evas_gl_common_image_update(Evas_Engine_GL_Context *gc, Evas_GL_Image *im)
792 {
793    Image_Entry *ie;
794    if (!im->im) return;
795 
796    ie = &im->im->cache_entry;
797    if (!im->tex && ie->preload) return;
798 
799    evas_gl_common_image_alloc_ensure(im);
800    // alloc ensure can change im->im, so only get the local variable later.
801    ie = &im->im->cache_entry;
802 /*
803    if ((im->cs.space == EVAS_COLORSPACE_YCBCR422P601_PL) ||
804        (im->cs.space == EVAS_COLORSPACE_YCBCR422P709_PL))
805      {
806         // SOFTWARE convert. do multi texture later
807         if ((im->cs.data) && (*((unsigned char **)im->cs.data)))
808           {
809              if (im->dirty || !im->im->image.data)
810                {
811                   free(im->im->image.data);
812                   im->im->image.data = malloc(im->im->cache_entry.w * im->im->cache_entry.h * sizeof(DATA32));
813                   if (im->im->image.data)
814                     evas_common_convert_yuv_422p_601_rgba(im->cs.data,
815                                                           (void *)im->im->image.data,
816                                                           im->im->cache_entry.w, im->im->cache_entry.h);
817                }
818           }
819         space = EVAS_COLORSPACE_ARGB8888;
820      }
821    else
822  */
823    switch (im->cs.space)
824      {
825       case EVAS_COLORSPACE_ARGB8888:
826       case EVAS_COLORSPACE_GRY8:
827       case EVAS_COLORSPACE_AGRY88:
828       case EVAS_COLORSPACE_ETC1:
829       case EVAS_COLORSPACE_RGB8_ETC2:
830       case EVAS_COLORSPACE_RGBA8_ETC2_EAC:
831       case EVAS_COLORSPACE_RGB_S3TC_DXT1:
832       case EVAS_COLORSPACE_RGBA_S3TC_DXT1:
833       case EVAS_COLORSPACE_RGBA_S3TC_DXT2:
834       case EVAS_COLORSPACE_RGBA_S3TC_DXT3:
835       case EVAS_COLORSPACE_RGBA_S3TC_DXT4:
836       case EVAS_COLORSPACE_RGBA_S3TC_DXT5:
837          if ((im->tex) &&
838              ((im->dirty) || (ie->animated.animated) || (ie->flags.updated_data)))
839           {
840              ie->load_error = evas_cache_image_load_data(ie);
841              evas_gl_common_texture_update(im->tex, im->im);
842              evas_cache_image_unload_data(ie);
843           }
844         else if (!im->tex &&
845                  ((ie->load_error == EVAS_LOAD_ERROR_NONE) ||
846                   (ie->load_error == EVAS_LOAD_ERROR_CANCELLED)))
847           {
848              ie->load_error = evas_cache_image_load_data(ie);
849              im->tex = evas_gl_common_texture_new(gc, im->im, im->disable_atlas);
850              evas_cache_image_unload_data(ie);
851           }
852         ie->flags.updated_data = EINA_FALSE;
853         im->dirty = 0;
854         break;
855       case EVAS_COLORSPACE_ETC1_ALPHA:
856         if ((im->tex) && (im->dirty))
857           {
858              ie->load_error = evas_cache_image_load_data(ie);
859              evas_gl_common_texture_rgb_a_pair_update(im->tex, im->im);
860              evas_cache_image_unload_data(ie);
861           }
862         else if (!im->tex &&
863                  ((ie->load_error == EVAS_LOAD_ERROR_NONE) ||
864                   (ie->load_error == EVAS_LOAD_ERROR_CANCELLED)))
865           {
866              ie->load_error = evas_cache_image_load_data(ie);
867              im->tex = evas_gl_common_texture_rgb_a_pair_new(gc, im->im);
868              evas_cache_image_unload_data(ie);
869           }
870         im->dirty = 0;
871         break;
872       case EVAS_COLORSPACE_YCBCR422P601_PL:
873       case EVAS_COLORSPACE_YCBCR422P709_PL:
874         if ((im->tex) && (im->dirty))
875           {
876              evas_gl_common_texture_yuv_update(im->tex, im->cs.data, ie->w, ie->h);
877              im->dirty = 0;
878           }
879         if ((!im->tex) && (im->cs.data) && (*((unsigned char **)im->cs.data)))
880           {
881              im->tex = evas_gl_common_texture_yuv_new(gc, im->cs.data, ie->w, ie->h);
882              im->dirty = 0;
883           }
884         break;
885       case EVAS_COLORSPACE_YCBCR422601_PL:
886         if ((im->tex) && (im->dirty))
887           {
888              evas_gl_common_texture_yuy2_update(im->tex, im->cs.data, ie->w, ie->h);
889              im->dirty = 0;
890           }
891         if ((!im->tex) && (im->cs.data) && (*((unsigned char **)im->cs.data)))
892           {
893              im->tex = evas_gl_common_texture_yuy2_new(gc, im->cs.data, ie->w, ie->h);
894              im->dirty = 0;
895           }
896         break;
897       case EVAS_COLORSPACE_YCBCR420NV12601_PL:
898         if ((im->tex) && (im->dirty))
899           {
900              evas_gl_common_texture_nv12_update(im->tex, im->cs.data, ie->w, ie->h);
901              im->dirty = 0;
902           }
903         if ((!im->tex) && (im->cs.data) && (*((unsigned char **)im->cs.data)))
904           {
905              im->tex = evas_gl_common_texture_nv12_new(gc, im->cs.data, ie->w, ie->h);
906              im->dirty = 0;
907           }
908         break;
909       case EVAS_COLORSPACE_YCBCR420TM12601_PL:
910         if ((im->tex) && (im->dirty))
911           {
912              evas_gl_common_texture_nv12tiled_update(im->tex, im->cs.data, ie->w, ie->h);
913              im->dirty = 0;
914           }
915         if ((!im->tex) && (im->cs.data) && (*((unsigned char **)im->cs.data)))
916           {
917              im->tex = evas_gl_common_texture_nv12tiled_new(gc, im->cs.data, ie->w, ie->h);
918              im->dirty = 0;
919           }
920         break;
921       default:
922         ERR("unhandled img format colorspace=%d", im->cs.space);
923         break;
924     }
925 }
926 
927 Evas_GL_Image *
evas_gl_common_image_surface_update(Evas_GL_Image * im)928 evas_gl_common_image_surface_update(Evas_GL_Image *im)
929 {
930    Evas_Engine_GL_Context *gc;
931    Evas_GL_Image *glim = NULL;
932    Eina_Bool alpha;
933    int w, h;
934 
935    if (!im || !im->gc || !im->im || !im->im->image.data)
936      goto fail;
937 
938    if (im->im->cache_entry.space == (Evas_Colorspace)EFL_GFX_COLORSPACE_ARGB8888)
939      alpha = EINA_FALSE;
940    else if (im->im->cache_entry.space == (Evas_Colorspace)EFL_GFX_COLORSPACE_GRY8)
941      alpha = EINA_TRUE;
942    else goto fail;
943 
944    gc = im->gc;
945    w = im->im->cache_entry.w;
946    h = im->im->cache_entry.h;
947    glim = evas_gl_common_image_surface_new(gc, w, h, EINA_TRUE, EINA_FALSE);
948    if (!glim) goto fail;
949 
950    if (alpha)
951      {
952         RGBA_Image *image;
953         uint32_t *rgba;
954         uint8_t *gry8;
955         int k;
956 
957         image = evas_common_image_new(w, h, EINA_TRUE);
958         if (!image) goto fail;
959 
960         rgba = image->image.data;
961         gry8 = im->im->image.data8;
962         for (k = 0; k < (w * h); k++)
963           {
964              const int c = *gry8++;
965              *rgba++ = ARGB_JOIN(c, c, c, c);
966           }
967 
968         glim->im = image;
969      }
970    else
971      {
972         evas_cache_image_ref(&im->im->cache_entry);
973         glim->im = im->im;
974      }
975 
976    glim->dirty = EINA_TRUE;
977    evas_gl_common_image_update(gc, glim);
978    evas_gl_common_image_free(im);
979 
980    return glim;
981 
982 fail:
983    ERR("Failed to update surface pixels!");
984    if (glim) evas_gl_common_image_free(glim);
985    return NULL;
986 }
987 
988 Evas_GL_Image *
evas_gl_common_image_surface_detach(Evas_GL_Image * im)989 evas_gl_common_image_surface_detach(Evas_GL_Image *im)
990 {
991    if (!im || !im->im) return im;
992 
993    evas_cache_image_drop(&im->im->cache_entry);
994    im->im = NULL;
995 
996    return im;
997 }
998 
999 Evas_GL_Image *
evas_gl_common_image_virtual_scaled_get(Evas_GL_Image * scaled,Evas_GL_Image * image,int dst_w,int dst_h,Eina_Bool smooth)1000 evas_gl_common_image_virtual_scaled_get(Evas_GL_Image *scaled, Evas_GL_Image *image,
1001                                         int dst_w, int dst_h, Eina_Bool smooth)
1002 {
1003    Evas_GL_Image *dst = scaled, *newdst;
1004    Evas_GL_Image *src = image;
1005    Evas_Engine_GL_Context *gc;
1006    Eina_Bool reffed = EINA_FALSE;
1007 
1008    if (!src) return NULL;
1009 
1010    // masking will work only with single texture images
1011    switch (src->cs.space)
1012      {
1013       case EVAS_COLORSPACE_AGRY88:
1014       case EVAS_COLORSPACE_ARGB8888:
1015       case EVAS_COLORSPACE_GRY8:
1016       case EVAS_COLORSPACE_RGBA8_ETC2_EAC:
1017       case EVAS_COLORSPACE_RGBA_S3TC_DXT1:
1018       case EVAS_COLORSPACE_RGBA_S3TC_DXT2:
1019       case EVAS_COLORSPACE_RGBA_S3TC_DXT3:
1020       case EVAS_COLORSPACE_RGBA_S3TC_DXT4:
1021       case EVAS_COLORSPACE_RGBA_S3TC_DXT5:
1022         break;
1023       default:
1024         DBG("cspace %d can't be used for masking's fast path", src->cs.space);
1025         return NULL;
1026      }
1027 
1028    gc = src->gc;
1029    if (dst && (dst->scaled.origin == src) &&
1030        (dst->w == dst_w) && (dst->h == dst_h))
1031      return dst;
1032 
1033    evas_gl_common_image_update(gc, src);
1034    if (!src->tex)
1035      {
1036         ERR("No source texture.");
1037         return NULL;
1038      }
1039 
1040    newdst = calloc(1, sizeof(Evas_GL_Image));
1041    if (!newdst) return NULL;
1042 
1043    if (dst)
1044      {
1045         if (dst->scaled.origin == src)
1046           {
1047              if (dst->references == 1)
1048                {
1049                   dst->w = dst_w;
1050                   dst->h = dst_h;
1051                   dst->scaled.smooth = smooth;
1052                   free(newdst);
1053                   return dst;
1054                }
1055              src->references++;
1056              reffed = EINA_TRUE;
1057           }
1058         evas_gl_common_image_free(dst);
1059      }
1060 
1061    newdst->references = 1;
1062    newdst->gc = gc;
1063    newdst->cs.space = src->cs.space;
1064    newdst->alpha = src->alpha;
1065    newdst->w = dst_w;
1066    newdst->h = dst_h;
1067    newdst->tex = src->tex;
1068    newdst->tex->references++;
1069    newdst->tex_only = 1;
1070 
1071    if (!reffed) src->references++;
1072    newdst->scaled.origin = src;
1073    newdst->scaled.smooth = smooth;
1074 
1075    return newdst;
1076 }
1077 
1078 void
evas_gl_common_image_map_draw(Evas_Engine_GL_Context * gc,Evas_GL_Image * im,int npoints,RGBA_Map_Point * p,int smooth,int level EINA_UNUSED)1079 evas_gl_common_image_map_draw(Evas_Engine_GL_Context *gc, Evas_GL_Image *im,
1080                               int npoints, RGBA_Map_Point *p, int smooth, int level EINA_UNUSED)
1081 {
1082    int mx = 0, my = 0, mw = 0, mh = 0;
1083    RGBA_Draw_Context *dc = gc->dc;
1084    Eina_Bool mask_smooth = EINA_FALSE;
1085    Evas_GL_Image *mask = dc->clip.mask;
1086    Evas_GL_Texture *mtex = NULL;
1087    Eina_Bool mask_color = EINA_FALSE;
1088    int r, g, b, a;
1089    int c, cx, cy, cw, ch;
1090    int offset = 0;
1091 
1092    if (dc->mul.use)
1093      {
1094         a = (dc->mul.col >> 24) & 0xff;
1095         r = (dc->mul.col >> 16) & 0xff;
1096         g = (dc->mul.col >> 8 ) & 0xff;
1097         b = (dc->mul.col      ) & 0xff;
1098      }
1099    else
1100      {
1101         r = g = b = a = 255;
1102      }
1103 
1104    evas_gl_common_image_update(gc, im);
1105 
1106    c = dc->clip.use;
1107    cx = dc->clip.x;   cy = dc->clip.y;
1108    cw = dc->clip.w;   ch = dc->clip.h;
1109    if (!im->tex) return;
1110    im->tex->im = im;
1111 
1112    if (mask)
1113      {
1114         evas_gl_common_image_update(gc, mask);
1115         mtex = mask->tex;
1116         if (mtex && mtex->pt && mtex->pt->w && mtex->pt->h)
1117           {
1118              // canvas coords
1119              mx = gc->dc->clip.mask_x;
1120              my = gc->dc->clip.mask_y;
1121              mw = mask->w;
1122              mh = mask->h;
1123              mask_smooth = mask->scaled.smooth;
1124              mask_color = dc->clip.mask_color;
1125           }
1126         else mtex = NULL;
1127      }
1128 
1129    while (npoints >= 4)
1130      {
1131         evas_gl_common_context_image_map_push(gc, im->tex, npoints, &p[offset],
1132                                               c, cx, cy, cw, ch,
1133                                               mtex, mx, my, mw, mh, mask_smooth, mask_color,
1134                                               r, g, b, a, smooth, im->tex_only,
1135                                               im->cs.space);
1136         offset += 4;
1137         npoints -= 4;
1138      }
1139 }
1140 
1141 static void
_evas_gl_common_image_push(Evas_Engine_GL_Context * gc,Evas_GL_Image * im,int dx,int dy,int dw,int dh,int sx,int sy,int sw,int sh,int cx,int cy,int cw,int ch,int r,int g,int b,int a,Evas_GL_Image * mask,Eina_Bool smooth,Eina_Bool yuv,Eina_Bool yuv_709,Eina_Bool yuy2,Eina_Bool nv12,Eina_Bool rgb_a_pair)1142 _evas_gl_common_image_push(Evas_Engine_GL_Context *gc, Evas_GL_Image *im,
1143                            int dx, int dy, int dw, int dh,
1144                            int sx, int sy, int sw, int sh,
1145                            int cx, int cy, int cw, int ch,
1146                            int r, int g, int b, int a,
1147                            Evas_GL_Image *mask,
1148                            Eina_Bool smooth,
1149                            Eina_Bool yuv, Eina_Bool yuv_709,
1150                            Eina_Bool yuy2, Eina_Bool nv12,
1151                            Eina_Bool rgb_a_pair)
1152 {
1153    int mx = 0, my = 0, mw = 0, mh = 0;
1154    double ssx, ssy, ssw, ssh;
1155    Evas_GL_Texture *mtex = NULL;
1156    Eina_Bool mask_smooth = EINA_FALSE;
1157    Eina_Bool mask_color = EINA_FALSE;
1158    int nx, ny, nw, nh;
1159 
1160    nx = dx; ny = dy; nw = dw; nh = dh;
1161    RECTS_CLIP_TO_RECT(nx, ny, nw, nh,
1162                       cx, cy, cw, ch);
1163    if ((nw < 1) || (nh < 1)) return;
1164    if (!im->tex) return;
1165 
1166    if (mask)
1167      {
1168         evas_gl_common_image_update(gc, mask);
1169         mtex = mask->tex;
1170         if (mtex && mtex->pt && mtex->pt->w && mtex->pt->h)
1171           {
1172              // canvas coords
1173              mx = gc->dc->clip.mask_x;
1174              my = gc->dc->clip.mask_y;
1175              mw = mask->w;
1176              mh = mask->h;
1177              mask_smooth = mask->scaled.smooth;
1178              mask_color = gc->dc->clip.mask_color;
1179           }
1180         else mtex = NULL;
1181      }
1182 
1183    if ((nx == dx) && (ny == dy) && (nw == dw) && (nh == dh))
1184      {
1185         if (yuv)
1186           evas_gl_common_context_yuv_push(gc,
1187                                           im->tex,
1188                                           sx, sy, sw, sh,
1189                                           dx, dy, dw, dh,
1190                                           mtex, mx, my, mw, mh, mask_smooth, mask_color,
1191                                           r, g, b, a,
1192                                           smooth);
1193         else if (yuv_709)
1194           evas_gl_common_context_yuv_709_push(gc,
1195                                               im->tex,
1196                                               sx, sy, sw, sh,
1197                                               dx, dy, dw, dh,
1198                                               mtex, mx, my, mw, mh, mask_smooth, mask_color,
1199                                               r, g, b, a,
1200                                               smooth);
1201         else if (yuy2)
1202           evas_gl_common_context_yuy2_push(gc,
1203                                            im->tex,
1204                                            sx, sy, sw, sh,
1205                                            dx, dy, dw, dh,
1206                                            mtex, mx, my, mw, mh, mask_smooth, mask_color,
1207                                            r, g, b, a,
1208                                            smooth);
1209         else if (nv12)
1210           evas_gl_common_context_nv12_push(gc,
1211                                            im->tex,
1212                                            sx, sy, sw, sh,
1213                                            dx, dy, dw, dh,
1214                                            mtex, mx, my, mw, mh, mask_smooth, mask_color,
1215                                            r, g, b, a,
1216                                            smooth);
1217         else if (rgb_a_pair)
1218           evas_gl_common_context_rgb_a_pair_push(gc,
1219                                                  im->tex,
1220                                                  sx, sy, sw, sh,
1221                                                  dx, dy, dw, dh,
1222                                                  mtex, mx, my, mw, mh, mask_smooth, mask_color,
1223                                                  r, g, b, a,
1224                                                  smooth);
1225         else
1226           evas_gl_common_context_image_push(gc,
1227                                             im->tex,
1228                                             sx, sy, sw, sh,
1229                                             dx, dy, dw, dh,
1230                                             mtex, mx, my, mw, mh, mask_smooth, mask_color,
1231                                             r, g, b, a,
1232                                             smooth, im->tex_only, EINA_FALSE);
1233         return;
1234      }
1235 
1236    ssx = (double)sx + ((double)(sw * (nx - dx)) / (double)(dw));
1237    ssy = (double)sy + ((double)(sh * (ny - dy)) / (double)(dh));
1238    ssw = ((double)sw * (double)(nw)) / (double)(dw);
1239    ssh = ((double)sh * (double)(nh)) / (double)(dh);
1240 
1241    if (yuv)
1242      evas_gl_common_context_yuv_push(gc,
1243                                      im->tex,
1244                                      ssx, ssy, ssw, ssh,
1245                                      nx, ny, nw, nh,
1246                                      mtex, mx, my, mw, mh, mask_smooth, mask_color,
1247                                      r, g, b, a,
1248                                      smooth);
1249    else if (yuv_709)
1250      evas_gl_common_context_yuv_709_push(gc,
1251                                          im->tex,
1252                                          ssx, ssy, ssw, ssh,
1253                                          nx, ny, nw, nh,
1254                                          mtex, mx, my, mw, mh, mask_smooth, mask_color,
1255                                          r, g, b, a,
1256                                          smooth);
1257    else if (yuy2)
1258      evas_gl_common_context_yuy2_push(gc,
1259                                       im->tex,
1260                                       ssx, ssy, ssw, ssh,
1261                                       nx, ny, nw, nh,
1262                                       mtex, mx, my, mw, mh, mask_smooth, mask_color,
1263                                       r, g, b, a,
1264                                       smooth);
1265    else if (nv12)
1266      evas_gl_common_context_nv12_push(gc,
1267                                       im->tex,
1268                                       ssx, ssy, ssw, ssh,
1269                                       nx, ny, nw, nh,
1270                                       mtex, mx, my, mw, mh, mask_smooth, mask_color,
1271                                       r, g, b, a,
1272                                       smooth);
1273    else if (rgb_a_pair)
1274      evas_gl_common_context_rgb_a_pair_push(gc,
1275                                             im->tex,
1276                                             ssx, ssy, ssw, ssh,
1277                                             nx, ny, nw, nh,
1278                                             mtex, mx, my, mw, mh, mask_smooth, mask_color,
1279                                             r, g, b, a,
1280                                             smooth);
1281    else
1282      evas_gl_common_context_image_push(gc,
1283                                        im->tex,
1284                                        ssx, ssy, ssw, ssh,
1285                                        nx, ny, nw, nh,
1286                                        mtex, mx, my, mw, mh, mask_smooth, mask_color,
1287                                        r, g, b, a,
1288                                        smooth, im->tex_only, EINA_FALSE);
1289 }
1290 
1291 void
evas_gl_common_image_draw(Evas_Engine_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)1292 evas_gl_common_image_draw(Evas_Engine_GL_Context *gc, Evas_GL_Image *im,
1293                           int sx, int sy, int sw, int sh,
1294                           int dx, int dy, int dw, int dh,
1295                           int smooth)
1296 {
1297    RGBA_Draw_Context *dc;
1298    int r, g, b, a;
1299    Cutout_Rect  *rct;
1300    int c, cx, cy, cw, ch;
1301    int i;
1302    Eina_Bool yuv = EINA_FALSE;
1303    Eina_Bool yuv_709 = EINA_FALSE;
1304    Eina_Bool yuy2 = EINA_FALSE;
1305    Eina_Bool nv12 = EINA_FALSE;
1306    Eina_Bool rgb_a_pair = EINA_FALSE;
1307    Evas_GL_Image *mask;
1308 
1309    if (sw < 1) sw = 1;
1310    if (sh < 1) sh = 1;
1311    dc = gc->dc;
1312    if (dc->mul.use)
1313      {
1314 	a = (dc->mul.col >> 24) & 0xff;
1315         r = (dc->mul.col >> 16) & 0xff;
1316         g = (dc->mul.col >> 8 ) & 0xff;
1317         b = (dc->mul.col      ) & 0xff;
1318      }
1319    else
1320      {
1321 	r = g = b = a = 255;
1322      }
1323 
1324    evas_gl_common_image_update(gc, im);
1325    if (!im->tex)
1326      {
1327         evas_gl_common_rect_draw(gc, dx, dy, dw, dh);
1328         return;
1329      }
1330 
1331    mask = gc->dc->clip.mask;
1332 
1333    switch (im->cs.space)
1334      {
1335       case EVAS_COLORSPACE_YCBCR422P601_PL:
1336         yuv = EINA_TRUE;
1337         break;
1338       case EVAS_COLORSPACE_YCBCR422P709_PL:
1339         yuv_709 = EINA_TRUE;
1340         break;
1341       case EVAS_COLORSPACE_YCBCR422601_PL:
1342         yuy2 = EINA_TRUE;
1343         break;
1344       case EVAS_COLORSPACE_YCBCR420NV12601_PL:
1345       case EVAS_COLORSPACE_YCBCR420TM12601_PL:
1346         nv12 = EINA_TRUE;
1347         break;
1348       case EVAS_COLORSPACE_ETC1_ALPHA:
1349         rgb_a_pair = EINA_TRUE;
1350         break;
1351       default: break;
1352      }
1353 
1354    if ((sw == dw) && (sh == dh)) smooth = 0;
1355 
1356    im->tex->im = im;
1357    if ((!gc->dc->cutout.rects) ||
1358        ((gc->shared->info.tune.cutout.max > 0) &&
1359            (gc->dc->cutout.active > gc->shared->info.tune.cutout.max)))
1360      {
1361         if (mask || gc->dc->clip.use)
1362           {
1363              _evas_gl_common_image_push(gc, im,
1364                                         dx, dy, dw, dh,
1365                                         sx, sy, sw, sh,
1366                                         gc->dc->clip.x, gc->dc->clip.y,
1367                                         gc->dc->clip.w, gc->dc->clip.h,
1368                                         r, g, b, a,
1369                                         mask,
1370                                         smooth,
1371                                         yuv, yuv_709, yuy2, nv12, rgb_a_pair);
1372           }
1373         else
1374           {
1375              _evas_gl_common_image_push(gc, im,
1376                                         dx, dy, dw, dh,
1377                                         sx, sy, sw, sh,
1378                                         dx, dy, dw, dh,
1379                                         r, g, b, a,
1380                                         mask,
1381                                         smooth,
1382                                         yuv, yuv_709, yuy2, nv12, rgb_a_pair);
1383           }
1384         return;
1385      }
1386 
1387    /* save out clip info */
1388    c = gc->dc->clip.use; cx = gc->dc->clip.x; cy = gc->dc->clip.y; cw = gc->dc->clip.w; ch = gc->dc->clip.h;
1389    evas_common_draw_context_clip_clip(gc->dc, 0, 0, gc->shared->w, gc->shared->h);
1390    evas_common_draw_context_clip_clip(gc->dc, dx, dy, dw, dh);
1391    /* our clip is 0 size.. abort */
1392    if ((gc->dc->clip.w <= 0) || (gc->dc->clip.h <= 0))
1393      {
1394         gc->dc->clip.use = c; gc->dc->clip.x = cx; gc->dc->clip.y = cy; gc->dc->clip.w = cw; gc->dc->clip.h = ch;
1395         return;
1396      }
1397    _evas_gl_common_cutout_rects = evas_common_draw_context_apply_cutouts(dc, _evas_gl_common_cutout_rects);
1398    for (i = 0; i < _evas_gl_common_cutout_rects->active; ++i)
1399      {
1400         rct = _evas_gl_common_cutout_rects->rects + i;
1401 
1402         _evas_gl_common_image_push(gc, im,
1403                                    dx, dy, dw, dh,
1404                                    sx, sy, sw, sh,
1405                                    rct->x, rct->y, rct->w, rct->h,
1406                                    r, g, b, a,
1407                                    mask,
1408                                    smooth,
1409                                    yuv, yuv_709, yuy2, nv12, rgb_a_pair);
1410      }
1411    evas_common_draw_context_cutouts_free(_evas_gl_common_cutout_rects);
1412    /* restore clip info */
1413    gc->dc->clip.use = c; gc->dc->clip.x = cx; gc->dc->clip.y = cy; gc->dc->clip.w = cw; gc->dc->clip.h = ch;
1414 }
1415