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