aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/evas/src/modules/engines/gl_common/evas_gl_image.c
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/evas/src/modules/engines/gl_common/evas_gl_image.c')
-rw-r--r--libraries/evas/src/modules/engines/gl_common/evas_gl_image.c968
1 files changed, 968 insertions, 0 deletions
diff --git a/libraries/evas/src/modules/engines/gl_common/evas_gl_image.c b/libraries/evas/src/modules/engines/gl_common/evas_gl_image.c
new file mode 100644
index 0000000..1d4b1f8
--- /dev/null
+++ b/libraries/evas/src/modules/engines/gl_common/evas_gl_image.c
@@ -0,0 +1,968 @@
1#include "evas_gl_private.h"
2
3void
4evas_gl_common_image_all_unload(Evas_Engine_GL_Context *gc)
5{
6 Eina_List *l;
7 Evas_GL_Image *im;
8
9 EINA_LIST_FOREACH(gc->shared->images, l, im)
10 {
11 if (im->im) evas_cache_image_unload_data(&im->im->cache_entry);
12 if (im->tex)
13 {
14 if (!im->tex->pt->dyn.img)
15 {
16 evas_gl_common_texture_free(im->tex);
17 im->tex = NULL;
18 }
19 }
20 }
21}
22
23static void
24_evas_gl_image_cache_trim(Evas_Engine_GL_Context *gc)
25{
26 int size = evas_common_image_get_cache();
27
28 while (gc->shared->images_size > size)
29 {
30 Evas_GL_Image *im2;
31 Eina_List *l = NULL;
32
33 EINA_LIST_REVERSE_FOREACH(gc->shared->images, l, im2)
34 {
35 if (im2->references == 0)
36 {
37 im2->cached = 0;
38 im2->gc->shared->images =
39 eina_list_remove_list(im2->gc->shared->images, l);
40 im2->gc->shared->images_size -= (im2->csize);
41 evas_gl_common_image_free(im2);
42 l = NULL;
43 break;
44 }
45 }
46 if ((gc->shared->images_size > size) && (l))
47 {
48// printf("EEK %i > %i, no 0 ref imgs\n",
49// gc->shared->images_size, size);
50 break;
51 }
52 if (!gc->shared->images)
53 {
54// printf("EEK %i > %i, no imgs\n",
55// gc->shared->images_size, size);
56 break;
57 }
58 }
59}
60
61static Eina_Bool
62_evas_gl_image_cache_add(Evas_GL_Image *im)
63{
64 if (im->references == 0)
65 {
66 im->csize = im->w * im->h * 4;
67 im->gc->shared->images_size += im->csize;
68 _evas_gl_image_cache_trim(im->gc);
69 return EINA_TRUE;
70 }
71 else
72 {
73 im->gc->shared->images = eina_list_remove(im->gc->shared->images, im);
74 im->cached = 0;
75 }
76 return EINA_FALSE;
77}
78
79void
80evas_gl_common_image_ref(Evas_GL_Image *im)
81{
82 if (im->references == 0)
83 {
84 im->gc->shared->images_size -= (im->csize);
85 }
86 im->references++;
87}
88
89void
90evas_gl_common_image_unref(Evas_GL_Image *im)
91{
92 im->references--;
93 if (im->references == 0)
94 {
95 _evas_gl_image_cache_add(im);
96 }
97}
98
99Evas_GL_Image *
100evas_gl_common_image_load(Evas_Engine_GL_Context *gc, const char *file, const char *key, Evas_Image_Load_Opts *lo, int *error)
101{
102 Evas_GL_Image *im;
103 RGBA_Image *im_im;
104 Eina_List *l;
105
106 im_im = evas_common_load_image_from_file(file, key, lo, error);
107 if (!im_im) return NULL;
108
109 /* i'd LOVe to do this, but we can't because we load to load header
110 * to get image size to know if its too big or not! so this disallows
111 * us to know that - photocam thus suffers
112 if (((int)im_im->cache_entry.w > gc->shared->info.max_texture_size) ||
113 ((int)im_im->cache_entry.h > gc->shared->info.max_texture_size))
114 {
115 evas_cache_image_drop(&(im_im->cache_entry));
116 *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
117 return NULL;
118 }
119 */
120
121 // FIXME: keep unreffed shared images around
122 EINA_LIST_FOREACH(gc->shared->images, l, im)
123 {
124 if (im->im == im_im)
125 {
126// why did i put this here? i think to free the rgba pixel data once a texture
127// exists.
128// evas_cache_image_drop(&(im_im->cache_entry));
129 gc->shared->images = eina_list_remove_list(gc->shared->images, l);
130 gc->shared->images = eina_list_prepend(gc->shared->images, im);
131 evas_gl_common_image_ref(im);
132 *error = EVAS_LOAD_ERROR_NONE;
133 return im;
134 }
135 }
136
137 im = calloc(1, sizeof(Evas_GL_Image));
138 if (!im)
139 {
140 evas_cache_image_drop(&(im_im->cache_entry));
141 *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
142 return NULL;
143 }
144 im->references = 1;
145 im->im = im_im;
146 im->gc = gc;
147 im->cached = 1;
148 im->cs.space = EVAS_COLORSPACE_ARGB8888;
149 im->alpha = im->im->cache_entry.flags.alpha;
150 im->w = im->im->cache_entry.w;
151 im->h = im->im->cache_entry.h;
152 if (lo) im->load_opts = *lo;
153 gc->shared->images = eina_list_prepend(gc->shared->images, im);
154 return im;
155}
156
157Evas_GL_Image *
158evas_gl_common_image_new_from_data(Evas_Engine_GL_Context *gc, unsigned int w, unsigned int h, DATA32 *data, int alpha, int cspace)
159{
160 Evas_GL_Image *im;
161 Eina_List *l;
162
163 if (((int)w > gc->shared->info.max_texture_size) ||
164 ((int)h > gc->shared->info.max_texture_size))
165 return NULL;
166
167 if (data)
168 {
169 EINA_LIST_FOREACH(gc->shared->images, l, im)
170 {
171 if (((void *)(im->im->image.data) == (void *)data) &&
172 (im->im->cache_entry.w == w) &&
173 (im->im->cache_entry.h == h))
174 {
175 gc->shared->images = eina_list_remove_list(gc->shared->images, l);
176 gc->shared->images = eina_list_prepend(gc->shared->images, im);
177 evas_gl_common_image_ref(im);
178 return im;
179 }
180 }
181 }
182 im = calloc(1, sizeof(Evas_GL_Image));
183 if (!im) return NULL;
184 im->references = 1;
185 im->im = (RGBA_Image *) evas_cache_image_data(evas_common_image_cache_get(),
186 w, h, data, alpha, cspace);
187 if (!im->im)
188 {
189 free(im);
190 return NULL;
191 }
192 im->gc = gc;
193 im->cs.space = cspace;
194 im->alpha = im->im->cache_entry.flags.alpha;
195 im->w = im->im->cache_entry.w;
196 im->h = im->im->cache_entry.h;
197 switch (cspace)
198 {
199 case EVAS_COLORSPACE_ARGB8888:
200 break;
201 case EVAS_COLORSPACE_YCBCR422P601_PL:
202 case EVAS_COLORSPACE_YCBCR422P709_PL:
203 if (im->tex) evas_gl_common_texture_free(im->tex);
204 im->tex = NULL;
205 im->cs.data = data;
206 im->cs.no_free = 1;
207 break;
208 default:
209 abort();
210 break;
211 }
212 return im;
213}
214
215Evas_GL_Image *
216evas_gl_common_image_new_from_copied_data(Evas_Engine_GL_Context *gc, unsigned int w, unsigned int h, DATA32 *data, int alpha, int cspace)
217{
218 Evas_GL_Image *im;
219
220 if (((int)w > gc->shared->info.max_texture_size) ||
221 ((int)h > gc->shared->info.max_texture_size))
222 return NULL;
223
224 im = calloc(1, sizeof(Evas_GL_Image));
225 if (!im) return NULL;
226 im->references = 1;
227 im->im = (RGBA_Image *) evas_cache_image_copied_data(evas_common_image_cache_get(),
228 w, h, data, alpha, cspace);
229 if (!im->im)
230 {
231 free(im);
232 return NULL;
233 }
234 im->gc = gc;
235 im->cs.space = cspace;
236 im->alpha = im->im->cache_entry.flags.alpha;
237 im->w = im->im->cache_entry.w;
238 im->h = im->im->cache_entry.h;
239 switch (cspace)
240 {
241 case EVAS_COLORSPACE_ARGB8888:
242 break;
243 case EVAS_COLORSPACE_YCBCR422P601_PL:
244 case EVAS_COLORSPACE_YCBCR422P709_PL:
245 if (im->tex) evas_gl_common_texture_free(im->tex);
246 im->tex = NULL;
247 im->cs.no_free = 0;
248 if (im->im->cache_entry.h > 0)
249 im->cs.data = calloc(1, im->im->cache_entry.h * sizeof(unsigned char *) * 2);
250 if ((data) && (im->cs.data))
251 memcpy(im->cs.data, data, im->im->cache_entry.h * sizeof(unsigned char *) * 2);
252 break;
253 default:
254 abort();
255 break;
256 }
257 return im;
258}
259
260Evas_GL_Image *
261evas_gl_common_image_new(Evas_Engine_GL_Context *gc, unsigned int w, unsigned int h, int alpha, int cspace)
262{
263 Evas_GL_Image *im;
264
265 if (((int)w > gc->shared->info.max_texture_size) ||
266 ((int)h > gc->shared->info.max_texture_size))
267 return NULL;
268
269 im = calloc(1, sizeof(Evas_GL_Image));
270 if (!im) return NULL;
271 im->references = 1;
272 im->im = (RGBA_Image *)evas_cache_image_empty(evas_common_image_cache_get());
273 if (!im->im)
274 {
275 free(im);
276 return NULL;
277 }
278 im->gc = gc;
279 im->im->cache_entry.flags.alpha = alpha ? 1 : 0;
280 im->cs.space = cspace;
281 im->alpha = im->im->cache_entry.flags.alpha;
282 im->im->cache_entry.w = w;
283 im->im->cache_entry.h = h;
284 im->w = im->im->cache_entry.w;
285 im->h = im->im->cache_entry.h;
286 evas_cache_image_colorspace(&im->im->cache_entry, cspace);
287 im->im = (RGBA_Image *)evas_cache_image_size_set(&im->im->cache_entry, w, h);
288 switch (cspace)
289 {
290 case EVAS_COLORSPACE_ARGB8888:
291 break;
292 case EVAS_COLORSPACE_YCBCR422P601_PL:
293 case EVAS_COLORSPACE_YCBCR422P709_PL:
294 case EVAS_COLORSPACE_YCBCR422601_PL:
295 case EVAS_COLORSPACE_YCBCR420NV12601_PL:
296 case EVAS_COLORSPACE_YCBCR420TM12601_PL:
297// if (im->tex) evas_gl_common_texture_free(im->tex);
298 im->tex = NULL;
299 im->cs.no_free = 0;
300 if (im->im->cache_entry.h > 0)
301 im->cs.data = calloc(1, im->im->cache_entry.h * sizeof(unsigned char *) * 2);
302 break;
303 default:
304 abort();
305 break;
306 }
307 return im;
308}
309
310Evas_GL_Image *
311evas_gl_common_image_alpha_set(Evas_GL_Image *im, int alpha)
312{
313 if (!im) return NULL;
314 if (im->alpha == alpha) return im;
315 im->alpha = alpha;
316 if (!im->im) return im;
317 im->im->cache_entry.flags.alpha = alpha ? 1 : 0;
318 if (im->tex)
319 {
320 evas_gl_common_texture_free(im->tex);
321 im->tex = NULL;
322 }
323 if (!im->tex)
324 im->tex = evas_gl_common_texture_new(im->gc, im->im);
325 return im;
326}
327
328void
329evas_gl_common_image_native_enable(Evas_GL_Image *im)
330{
331 if (im->cs.data)
332 {
333 if (!im->cs.no_free) free(im->cs.data);
334 im->cs.data = NULL;
335 }
336 im->cs.no_free = 0;
337 if (im->cached)
338 {
339 if (im->references == 0)
340 im->gc->shared->images_size -= (im->csize);
341 im->gc->shared->images = eina_list_remove(im->gc->shared->images, im);
342 im->cached = 0;
343 }
344 if (im->im)
345 {
346 evas_cache_image_drop(&im->im->cache_entry);
347 im->im = NULL;
348 }
349 if (im->tex)
350 {
351 evas_gl_common_texture_free(im->tex);
352 im->tex = NULL;
353 }
354
355 im->cs.space = EVAS_COLORSPACE_ARGB8888;
356 im->tex = evas_gl_common_texture_native_new(im->gc, im->w, im->h, im->alpha, im);
357 im->tex_only = 1;
358}
359
360void
361evas_gl_common_image_native_disable(Evas_GL_Image *im)
362{
363 if (im->im)
364 {
365 evas_cache_image_drop(&im->im->cache_entry);
366 im->im = NULL;
367 }
368 if (im->tex)
369 {
370 evas_gl_common_texture_free(im->tex);
371 im->tex = NULL;
372 }
373 im->tex_only = 0;
374
375 im->im = (RGBA_Image *)evas_cache_image_empty(evas_common_image_cache_get());
376 im->im->cache_entry.flags.alpha = im->alpha;
377 im->cs.space = EVAS_COLORSPACE_ARGB8888;
378 evas_cache_image_colorspace(&im->im->cache_entry, im->cs.space);
379 im->im = (RGBA_Image *)evas_cache_image_size_set(&im->im->cache_entry, im->w, im->h);
380 if (!im->tex)
381 im->tex = evas_gl_common_texture_new(im->gc, im->im);
382}
383
384void
385evas_gl_common_image_scale_hint_set(Evas_GL_Image *im, int hint)
386{
387 im->scale_hint = hint;
388 // FIXME: take advantage of this even in gl (eg if image is
389 // 1600x1200 but we always use it at 800x600 or even less - drop
390 // the texture res down for "non dynamic" stuff to save memory)
391}
392
393void
394evas_gl_common_image_content_hint_set(Evas_GL_Image *im, int hint)
395{
396 if (im->content_hint == hint) return;
397 im->content_hint = hint;
398 if (!im->gc) return;
399 if (!im->gc->shared->info.sec_image_map) return;
400 if (!im->gc->shared->info.bgra) return;
401 // does not handle yuv yet.
402 if (im->cs.space != EVAS_COLORSPACE_ARGB8888) return;
403 if (im->content_hint == EVAS_IMAGE_CONTENT_HINT_DYNAMIC)
404 {
405 if (im->cs.data)
406 {
407 if (!im->cs.no_free) free(im->cs.data);
408 im->cs.data = NULL;
409 }
410 im->cs.no_free = 0;
411 if (im->cached)
412 {
413 if (im->references == 0)
414 im->gc->shared->images_size -= im->csize;
415 im->gc->shared->images = eina_list_remove(im->gc->shared->images, im);
416 im->cached = 0;
417 }
418 if (im->im)
419 {
420 evas_cache_image_drop(&im->im->cache_entry);
421 im->im = NULL;
422 }
423 if (im->tex)
424 {
425 evas_gl_common_texture_free(im->tex);
426 im->tex = NULL;
427 }
428 im->tex = evas_gl_common_texture_dynamic_new(im->gc, im);
429 im->tex_only = 1;
430 }
431 else
432 {
433 if (im->im)
434 {
435 evas_cache_image_drop(&im->im->cache_entry);
436 im->im = NULL;
437 }
438 if (im->tex)
439 {
440 evas_gl_common_texture_free(im->tex);
441 im->tex = NULL;
442 }
443 im->tex_only = 0;
444
445 im->im = (RGBA_Image *)evas_cache_image_empty(evas_common_image_cache_get());
446 im->im->cache_entry.flags.alpha = im->alpha;
447 im->cs.space = EVAS_COLORSPACE_ARGB8888;
448 evas_cache_image_colorspace(&im->im->cache_entry, im->cs.space);
449 im->im = (RGBA_Image *)evas_cache_image_size_set(&im->im->cache_entry, im->w, im->h);
450 if (!im->tex)
451 im->tex = evas_gl_common_texture_new(im->gc, im->im);
452 }
453}
454
455void
456evas_gl_common_image_cache_flush(Evas_Engine_GL_Context *gc)
457{
458 _evas_gl_image_cache_trim(gc);
459}
460
461void
462evas_gl_common_image_free(Evas_GL_Image *im)
463{
464#if 0 // filtering disabled
465 Filtered_Image *fi;
466#endif
467
468 evas_gl_common_context_flush(im->gc);
469 im->references--;
470 if (im->references > 0) return;
471
472 if (im->native.func.free)
473 im->native.func.free(im->native.func.data, im);
474
475 if (im->cs.data)
476 {
477 if (!im->cs.no_free) free(im->cs.data);
478 }
479 if (im->cached)
480 {
481 if (_evas_gl_image_cache_add(im)) return;
482 }
483 if (im->im) evas_cache_image_drop(&im->im->cache_entry);
484 if (im->tex) evas_gl_common_texture_free(im->tex);
485
486#if 0 // filtering disabled
487 EINA_LIST_FREE(im->filtered, fi)
488 {
489 free(fi->key);
490 evas_gl_common_image_free((Evas_GL_Image *)fi->image);
491 free(fi);
492 }
493#endif
494
495 free(im);
496}
497
498Evas_GL_Image *
499evas_gl_common_image_surface_new(Evas_Engine_GL_Context *gc, unsigned int w, unsigned int h, int alpha)
500{
501 Evas_GL_Image *im;
502
503 if (((int)w > gc->shared->info.max_texture_size) ||
504 ((int)h > gc->shared->info.max_texture_size))
505 return NULL;
506
507 im = calloc(1, sizeof(Evas_GL_Image));
508 if (!im) return NULL;
509 im->references = 1;
510 im->gc = gc;
511 im->cs.space = EVAS_COLORSPACE_ARGB8888;
512 im->alpha = alpha;
513 im->w = w;
514 im->h = h;
515 im->tex = evas_gl_common_texture_render_new(gc, w, h, alpha);
516 im->tex_only = 1;
517 return im;
518}
519
520void
521evas_gl_common_image_dirty(Evas_GL_Image *im, unsigned int x, unsigned int y, unsigned int w, unsigned int h)
522{
523 if ((w == 0) && (h == 0) && (x == 0) && (y == 0))
524 {
525 w = im->w;
526 h = im->h;
527 }
528 if (im->im)
529 {
530 im->im = (RGBA_Image *)evas_cache_image_dirty(&im->im->cache_entry, x, y, w, h);
531 }
532 im->dirty = 1;
533}
534
535void
536evas_gl_common_image_update(Evas_Engine_GL_Context *gc, Evas_GL_Image *im)
537{
538 Image_Entry *ie;
539 if (!im->im) return;
540 ie = (Image_Entry *)(im->im);
541/*
542 if ((im->cs.space == EVAS_COLORSPACE_YCBCR422P601_PL) ||
543 (im->cs.space == EVAS_COLORSPACE_YCBCR422P709_PL))
544 {
545 // SOFTWARE convert. do multi texture later
546 if ((im->cs.data) && (*((unsigned char **)im->cs.data)))
547 {
548 if (im->dirty || !im->im->image.data)
549 {
550 free(im->im->image.data);
551 im->im->image.data = malloc(im->im->cache_entry.w * im->im->cache_entry.h * sizeof(DATA32));
552 if (im->im->image.data)
553 evas_common_convert_yuv_420p_601_rgba(im->cs.data,
554 (void *)im->im->image.data,
555 im->im->cache_entry.w, im->im->cache_entry.h);
556 }
557 }
558 space = EVAS_COLORSPACE_ARGB8888;
559 }
560 else
561 */
562 switch (im->cs.space)
563 {
564 case EVAS_COLORSPACE_ARGB8888:
565 if ((im->tex) &&
566 ((im->dirty) || (ie->flags.animated)))
567 {
568 evas_cache_image_load_data(&im->im->cache_entry);
569 evas_gl_common_texture_update(im->tex, im->im);
570 evas_cache_image_unload_data(&im->im->cache_entry);
571 }
572 if (!im->tex)
573 {
574 evas_cache_image_load_data(&im->im->cache_entry);
575 im->tex = evas_gl_common_texture_new(gc, im->im);
576 evas_cache_image_unload_data(&im->im->cache_entry);
577 }
578 im->dirty = 0;
579 if (!im->tex) return;
580 break;
581 case EVAS_COLORSPACE_YCBCR422P601_PL:
582 case EVAS_COLORSPACE_YCBCR422P709_PL:
583 if ((im->tex) && (im->dirty))
584 {
585 evas_gl_common_texture_yuv_update(im->tex, im->cs.data,
586 im->im->cache_entry.w,
587 im->im->cache_entry.h);
588 im->dirty = 0;
589 }
590 if ((!im->tex) && (im->cs.data) && (*((unsigned char **)im->cs.data)))
591 {
592 im->tex = evas_gl_common_texture_yuv_new(gc, im->cs.data,
593 im->im->cache_entry.w,
594 im->im->cache_entry.h);
595 im->dirty = 0;
596 }
597 if (!im->tex) return;
598 break;
599 case EVAS_COLORSPACE_YCBCR422601_PL:
600 if ((im->tex) && (im->dirty))
601 {
602 evas_gl_common_texture_yuy2_update(im->tex, im->cs.data,
603 im->im->cache_entry.w,
604 im->im->cache_entry.h);
605 im->dirty = 0;
606 }
607 if ((!im->tex) && (im->cs.data) && (*((unsigned char **)im->cs.data)))
608 {
609 im->tex = evas_gl_common_texture_yuy2_new(gc, im->cs.data,
610 im->im->cache_entry.w,
611 im->im->cache_entry.h);
612 im->dirty = 0;
613 }
614 if (!im->tex) return;
615 break;
616 case EVAS_COLORSPACE_YCBCR420NV12601_PL:
617 if ((im->tex) && (im->dirty))
618 {
619 evas_gl_common_texture_nv12_update(im->tex, im->cs.data,
620 im->im->cache_entry.w,
621 im->im->cache_entry.h);
622 im->dirty = 0;
623 }
624 if ((!im->tex) && (im->cs.data) && (*((unsigned char **)im->cs.data)))
625 {
626 im->tex = evas_gl_common_texture_nv12_new(gc, im->cs.data,
627 im->im->cache_entry.w,
628 im->im->cache_entry.h);
629 im->dirty = 0;
630 }
631 if (!im->tex) return;
632 break;
633 case EVAS_COLORSPACE_YCBCR420TM12601_PL:
634 if ((im->tex) && (im->dirty))
635 {
636 evas_gl_common_texture_nv12tiled_update(im->tex, im->cs.data,
637 im->im->cache_entry.w,
638 im->im->cache_entry.h);
639 im->dirty = 0;
640 }
641 if ((!im->tex) && (im->cs.data) && (*((unsigned char **)im->cs.data)))
642 {
643 im->tex = evas_gl_common_texture_nv12tiled_new(gc, im->cs.data,
644 im->im->cache_entry.w,
645 im->im->cache_entry.h);
646 im->dirty = 0;
647 }
648 if (!im->tex) return;
649 break;
650 default:
651 ERR("unhandled img format colorspace=%d", im->cs.space);
652 break;
653 }
654}
655
656void
657evas_gl_common_image_map_draw(Evas_Engine_GL_Context *gc, Evas_GL_Image *im,
658 int npoints, RGBA_Map_Point *p, int smooth, int level __UNUSED__)
659{
660 RGBA_Draw_Context *dc;
661 int r, g, b, a;
662 int c, cx, cy, cw, ch;
663
664 dc = gc->dc;
665 if (dc->mul.use)
666 {
667 a = (dc->mul.col >> 24) & 0xff;
668 r = (dc->mul.col >> 16) & 0xff;
669 g = (dc->mul.col >> 8 ) & 0xff;
670 b = (dc->mul.col ) & 0xff;
671 }
672 else
673 {
674 r = g = b = a = 255;
675 }
676
677 evas_gl_common_image_update(gc, im);
678
679 c = gc->dc->clip.use;
680 cx = gc->dc->clip.x; cy = gc->dc->clip.y;
681 cw = gc->dc->clip.w; ch = gc->dc->clip.h;
682 im->tex->im = im;
683
684 evas_gl_common_context_image_map_push(gc, im->tex, npoints, p,
685 c, cx, cy, cw, ch,
686 r, g, b, a, smooth, im->tex_only,
687 im->cs.space);
688}
689
690void
691evas_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)
692{
693 RGBA_Draw_Context *dc;
694 Evas_GL_Image *imm;
695 int r, g, b, a;
696 double ssx, ssy, ssw, ssh;
697 double mssx, mssy, mssw, mssh;
698 Cutout_Rects *rects;
699 Cutout_Rect *rct;
700 int c, cx, cy, cw, ch;
701 int i;
702 int yuv = 0;
703 int yuy2 = 0;
704 int nv12 = 0;
705
706 if (sw < 1) sw = 1;
707 if (sh < 1) sh = 1;
708 dc = gc->dc;
709 imm = (Evas_GL_Image *)dc->mask.mask;
710 if (dc->mul.use)
711 {
712 a = (dc->mul.col >> 24) & 0xff;
713 r = (dc->mul.col >> 16) & 0xff;
714 g = (dc->mul.col >> 8 ) & 0xff;
715 b = (dc->mul.col ) & 0xff;
716 }
717 else
718 {
719 r = g = b = a = 255;
720 }
721
722 evas_gl_common_image_update(gc, im);
723 if (!im->tex)
724 {
725 evas_gl_common_rect_draw(gc, dx, dy, dw, dh);
726 return;
727 }
728 if (imm)
729 {
730 evas_gl_common_image_update(gc, imm);
731 if (!imm->tex) imm = NULL; /* Turn of mask on error */
732 }
733
734 if ((im->cs.space == EVAS_COLORSPACE_YCBCR422P601_PL) ||
735 (im->cs.space == EVAS_COLORSPACE_YCBCR422P709_PL))
736 yuv = 1;
737 if (im->cs.space == EVAS_COLORSPACE_YCBCR422601_PL)
738 yuy2 = 1;
739 if ((im->cs.space == EVAS_COLORSPACE_YCBCR420NV12601_PL) ||
740 (im->cs.space == EVAS_COLORSPACE_YCBCR420TM12601_PL))
741 nv12 = 1;
742
743 im->tex->im = im;
744 if (imm) imm->tex->im = imm;
745 if ((!gc->dc->cutout.rects) ||
746 ((gc->shared->info.tune.cutout.max > 0) &&
747 (gc->dc->cutout.active > gc->shared->info.tune.cutout.max)))
748 {
749 if (gc->dc->clip.use)
750 {
751 int nx, ny, nw, nh;
752 double scalex,scaley;
753
754 nx = dx; ny = dy; nw = dw; nh = dh;
755 RECTS_CLIP_TO_RECT(nx, ny, nw, nh,
756 gc->dc->clip.x, gc->dc->clip.y,
757 gc->dc->clip.w, gc->dc->clip.h);
758 if ((nw < 1) || (nh < 1)) return;
759 if ((!imm) && (nx == dx) && (ny == dy) && (nw == dw) && (nh == dh))
760 {
761 if (yuv)
762 evas_gl_common_context_yuv_push(gc,
763 im->tex,
764 sx, sy, sw, sh,
765 dx, dy, dw, dh,
766 r, g, b, a,
767 smooth);
768 else if (yuy2)
769 evas_gl_common_context_yuy2_push(gc,
770 im->tex,
771 sx, sy, sw, sh,
772 dx, dy, dw, dh,
773 r, g, b, a,
774 smooth);
775 else if (nv12)
776 evas_gl_common_context_nv12_push(gc,
777 im->tex,
778 sx, sy, sw, sh,
779 dx, dy, dw, dh,
780 r, g, b, a,
781 smooth);
782 else
783
784 evas_gl_common_context_image_push(gc,
785 im->tex,
786 sx, sy, sw, sh,
787 dx, dy, dw, dh,
788 r, g, b, a,
789 smooth, im->tex_only);
790 return;
791 }
792
793 ssx = (double)sx + ((double)(sw * (nx - dx)) / (double)(dw));
794 ssy = (double)sy + ((double)(sh * (ny - dy)) / (double)(dh));
795 ssw = ((double)sw * (double)(nw)) / (double)(dw);
796 ssh = ((double)sh * (double)(nh)) / (double)(dh);
797 if (imm)
798 {
799 /* Correct ones here */
800 scalex = imm->w / (double)dc->mask.w;
801 scaley = imm->h / (double)dc->mask.h;
802 mssx = scalex * (nx - dc->mask.x);
803 mssy = scaley * (ny - dc->mask.y);
804 mssw = scalex * nw;
805 mssh = scaley * nh;
806
807 /* No yuv + imm I'm afraid */
808 evas_gl_common_context_image_mask_push(gc,
809 im->tex,
810 imm->tex,
811 ssx, ssy, ssw, ssh,
812 mssx, mssy, mssw, mssh,
813 //dc->mask.x, dc->mask.y, dc->mask.w, dc->mask.h,
814 nx, ny, nw, nh,
815 r, g, b, a,
816 smooth);
817 }
818 else if (yuv)
819 evas_gl_common_context_yuv_push(gc,
820 im->tex,
821 ssx, ssy, ssw, ssh,
822 nx, ny, nw, nh,
823 r, g, b, a,
824 smooth);
825 else if (yuy2)
826 evas_gl_common_context_yuy2_push(gc,
827 im->tex,
828 ssx, ssy, ssw, ssh,
829 nx, ny, nw, nh,
830 r, g, b, a,
831 smooth);
832 else if (nv12)
833 evas_gl_common_context_nv12_push(gc,
834 im->tex,
835 ssx, ssy, ssw, ssh,
836 nx, ny, nw, nh,
837 r, g, b, a,
838 smooth);
839 else
840 evas_gl_common_context_image_push(gc,
841 im->tex,
842 ssx, ssy, ssw, ssh,
843 nx, ny, nw, nh,
844 r, g, b, a,
845 smooth, im->tex_only);
846 }
847 else
848 {
849 if (yuv)
850 evas_gl_common_context_yuv_push(gc,
851 im->tex,
852 sx, sy, sw, sh,
853 dx, dy, dw, dh,
854 r, g, b, a,
855 smooth);
856 else if (yuy2)
857 evas_gl_common_context_yuy2_push(gc,
858 im->tex,
859 sx, sy, sw, sh,
860 dx, dy, dw, dh,
861 r, g, b, a,
862 smooth);
863 else if (nv12)
864 evas_gl_common_context_nv12_push(gc,
865 im->tex,
866 sx, sy, sw, sh,
867 dx, dy, dw, dh,
868 r, g, b, a,
869 smooth);
870 else
871 evas_gl_common_context_image_push(gc,
872 im->tex,
873 sx, sy, sw, sh,
874 dx, dy, dw, dh,
875 r, g, b, a,
876 smooth, im->tex_only);
877 }
878 return;
879 }
880
881 /* save out clip info */
882 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;
883 evas_common_draw_context_clip_clip(gc->dc, 0, 0, gc->w, gc->h);
884 evas_common_draw_context_clip_clip(gc->dc, dx, dy, dw, dh);
885 /* our clip is 0 size.. abort */
886 if ((gc->dc->clip.w <= 0) || (gc->dc->clip.h <= 0))
887 {
888 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;
889 return;
890 }
891 rects = evas_common_draw_context_apply_cutouts(dc);
892 for (i = 0; i < rects->active; ++i)
893 {
894 int nx, ny, nw, nh;
895
896 rct = rects->rects + i;
897 nx = dx; ny = dy; nw = dw; nh = dh;
898 RECTS_CLIP_TO_RECT(nx, ny, nw, nh, rct->x, rct->y, rct->w, rct->h);
899 if ((nw < 1) || (nh < 1)) continue;
900 if ((nx == dx) && (ny == dy) && (nw == dw) && (nh == dh))
901 {
902 if (yuv)
903 evas_gl_common_context_yuv_push(gc,
904 im->tex,
905 sx, sy, sw, sh,
906 dx, dy, dw, dh,
907 r, g, b, a,
908 smooth);
909 else if (yuy2)
910 evas_gl_common_context_yuy2_push(gc,
911 im->tex,
912 sx, sy, sw, sh,
913 dx, dy, dw, dh,
914 r, g, b, a,
915 smooth);
916 else if (nv12)
917 evas_gl_common_context_nv12_push(gc,
918 im->tex,
919 sx, sy, sw, sh,
920 dx, dy, dw, dh,
921 r, g, b, a,
922 smooth);
923 else
924 evas_gl_common_context_image_push(gc,
925 im->tex,
926 sx, sy, sw, sh,
927 dx, dy, dw, dh,
928 r, g, b, a,
929 smooth, im->tex_only);
930 continue;
931 }
932 ssx = (double)sx + ((double)(sw * (nx - dx)) / (double)(dw));
933 ssy = (double)sy + ((double)(sh * (ny - dy)) / (double)(dh));
934 ssw = ((double)sw * (double)(nw)) / (double)(dw);
935 ssh = ((double)sh * (double)(nh)) / (double)(dh);
936 if (yuv)
937 evas_gl_common_context_yuv_push(gc,
938 im->tex,
939 ssx, ssy, ssw, ssh,
940 nx, ny, nw, nh,
941 r, g, b, a,
942 smooth);
943 else if (yuy2)
944 evas_gl_common_context_yuy2_push(gc,
945 im->tex,
946 ssx, ssy, ssw, ssh,
947 nx, ny, nw, nh,
948 r, g, b, a,
949 smooth);
950 else if (nv12)
951 evas_gl_common_context_nv12_push(gc,
952 im->tex,
953 ssx, ssy, ssw, ssh,
954 nx, ny, nw, nh,
955 r, g, b, a,
956 smooth);
957 else
958 evas_gl_common_context_image_push(gc,
959 im->tex,
960 ssx, ssy, ssw, ssh,
961 nx, ny, nw, nh,
962 r, g, b, a,
963 smooth, im->tex_only);
964 }
965 evas_common_draw_context_apply_clear_cutouts(rects);
966 /* restore clip info */
967 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;
968}