726ba0f454893a9ff8274c1de398dd14d6e4d000
[framework/uifw/evas.git] / src / modules / engines / gl_common / evas_gl_image.c
1 #include "evas_gl_private.h"
2
3 void
4 evas_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
23 static 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
61 static 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
79 void
80 evas_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
89 void
90 evas_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
99 Evas_GL_Image *
100 evas_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    // FIXME: keep unreffed shared images around
110    EINA_LIST_FOREACH(gc->shared->images, l, im)
111      {
112         if (im->im == im_im)
113           {
114 // why did i put this here? i think to free the rgba pixel data once a texture
115 // exists.
116 //             evas_cache_image_drop(&im_im->cache_entry);
117              gc->shared->images = eina_list_remove_list(gc->shared->images, l);
118              gc->shared->images = eina_list_prepend(gc->shared->images, im);
119              evas_gl_common_image_ref(im);
120              *error = EVAS_LOAD_ERROR_NONE;
121              return im;
122           }
123      }
124
125    im = calloc(1, sizeof(Evas_GL_Image));
126    if (!im)
127      {
128         *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
129         return NULL;
130      }
131    im->references = 1;
132    im->im = im_im;
133    im->gc = gc;
134    im->cached = 1;
135    im->cs.space = EVAS_COLORSPACE_ARGB8888;
136    im->alpha = im->im->cache_entry.flags.alpha;
137    im->w = im->im->cache_entry.w;
138    im->h = im->im->cache_entry.h;
139    if (lo) im->load_opts = *lo;
140    gc->shared->images = eina_list_prepend(gc->shared->images, im);
141    return im;
142 }
143
144 Evas_GL_Image *
145 evas_gl_common_image_new_from_data(Evas_Engine_GL_Context *gc, unsigned int w, unsigned int h, DATA32 *data, int alpha, int cspace)
146 {
147    Evas_GL_Image *im;
148    Eina_List *l;
149
150    if (data)
151      {
152         EINA_LIST_FOREACH(gc->shared->images, l, im)
153           {
154              if (((void *)(im->im->image.data) == (void *)data) &&
155                  (im->im->cache_entry.w == w) &&
156                  (im->im->cache_entry.h == h))
157                {
158                   gc->shared->images = eina_list_remove_list(gc->shared->images, l);
159                   gc->shared->images = eina_list_prepend(gc->shared->images, im);
160                   evas_gl_common_image_ref(im);
161                   return im;
162                }
163           }
164      }
165    im = calloc(1, sizeof(Evas_GL_Image));
166    if (!im) return NULL;
167    im->references = 1;
168    im->im = (RGBA_Image *) evas_cache_image_data(evas_common_image_cache_get(),
169                                                  w, h, data, alpha, cspace);
170    if (!im->im)
171      {
172         free(im);
173         return NULL;
174      }
175    im->gc = gc;
176    im->cs.space = cspace;
177    im->alpha = im->im->cache_entry.flags.alpha;
178    im->w = im->im->cache_entry.w;
179    im->h = im->im->cache_entry.h;
180    switch (cspace)
181      {
182       case EVAS_COLORSPACE_ARGB8888:
183         break;
184       case EVAS_COLORSPACE_YCBCR422P601_PL:
185       case EVAS_COLORSPACE_YCBCR422P709_PL:
186         if (im->tex) evas_gl_common_texture_free(im->tex);
187         im->tex = NULL;
188         im->cs.data = data;
189         im->cs.no_free = 1;
190         break;
191       default:
192         abort();
193         break;
194      }
195    return im;
196 }
197
198 Evas_GL_Image *
199 evas_gl_common_image_new_from_copied_data(Evas_Engine_GL_Context *gc, unsigned int w, unsigned int h, DATA32 *data, int alpha, int cspace)
200 {
201    Evas_GL_Image *im;
202
203    im = calloc(1, sizeof(Evas_GL_Image));
204    if (!im) return NULL;
205    im->references = 1;
206    im->im = (RGBA_Image *) evas_cache_image_copied_data(evas_common_image_cache_get(),
207                                                         w, h, data, alpha, cspace);
208    if (!im->im)
209      {
210         free(im);
211         return NULL;
212      }
213    im->gc = gc;
214    im->cs.space = cspace;
215    im->alpha = im->im->cache_entry.flags.alpha;
216    im->w = im->im->cache_entry.w;
217    im->h = im->im->cache_entry.h;
218    switch (cspace)
219      {
220       case EVAS_COLORSPACE_ARGB8888:
221         break;
222       case EVAS_COLORSPACE_YCBCR422P601_PL:
223       case EVAS_COLORSPACE_YCBCR422P709_PL:
224         if (im->tex) evas_gl_common_texture_free(im->tex);
225         im->tex = NULL;
226         im->cs.no_free = 0;
227         if (im->im->cache_entry.h > 0)
228           im->cs.data = calloc(1, im->im->cache_entry.h * sizeof(unsigned char *) * 2);
229         if ((data) && (im->cs.data))
230           memcpy(im->cs.data, data, im->im->cache_entry.h * sizeof(unsigned char *) * 2);
231         break;
232       default:
233         abort();
234         break;
235      }
236    return im;
237 }
238
239 Evas_GL_Image *
240 evas_gl_common_image_new(Evas_Engine_GL_Context *gc, unsigned int w, unsigned int h, int alpha, int cspace)
241 {
242    Evas_GL_Image *im;
243
244    im = calloc(1, sizeof(Evas_GL_Image));
245    if (!im) return NULL;
246    im->references = 1;
247    im->im = (RGBA_Image *)evas_cache_image_empty(evas_common_image_cache_get());
248    if (!im->im)
249      {
250         free(im);
251         return NULL;
252      }
253    im->gc = gc;
254    im->im->cache_entry.flags.alpha = alpha ? 1 : 0;
255    im->cs.space = cspace;
256    im->alpha = im->im->cache_entry.flags.alpha;
257    im->im->cache_entry.w = w;
258    im->im->cache_entry.h = h;
259    im->w = im->im->cache_entry.w;
260    im->h = im->im->cache_entry.h;
261    evas_cache_image_colorspace(&im->im->cache_entry, cspace);
262    im->im = (RGBA_Image *)evas_cache_image_size_set(&im->im->cache_entry, w, h);
263    switch (cspace)
264      {
265       case EVAS_COLORSPACE_ARGB8888:
266         break;
267       case EVAS_COLORSPACE_YCBCR422P601_PL:
268       case EVAS_COLORSPACE_YCBCR422P709_PL:
269 //        if (im->tex) evas_gl_common_texture_free(im->tex);
270         im->tex = NULL;
271         im->cs.no_free = 0;
272         if (im->im->cache_entry.h > 0)
273           im->cs.data = calloc(1, im->im->cache_entry.h * sizeof(unsigned char *) * 2);
274         break;
275       default:
276         abort();
277         break;
278      }
279    return im;
280 }
281
282 Evas_GL_Image *
283 evas_gl_common_image_alpha_set(Evas_GL_Image *im, int alpha)
284 {
285    if (!im) return NULL;
286    if (im->alpha == alpha) return im;
287    im->alpha = alpha;
288    if (!im->im) return im;
289    im->im->cache_entry.flags.alpha = alpha ? 1 : 0;
290    if (im->tex)
291      {
292         evas_gl_common_texture_free(im->tex);
293         im->tex = NULL;
294      }
295    if (!im->tex)
296      im->tex = evas_gl_common_texture_new(im->gc, im->im);
297    return im;
298 }
299
300 void
301 evas_gl_common_image_native_enable(Evas_GL_Image *im)
302 {
303    if (im->cs.data)
304      {
305         if (!im->cs.no_free) free(im->cs.data);
306         im->cs.data = NULL;
307      }
308    im->cs.no_free = 0;
309    if (im->cached)
310      {
311         if (im->references == 0)
312            im->gc->shared->images_size -= (im->csize);
313         im->gc->shared->images = eina_list_remove(im->gc->shared->images, im);
314         im->cached = 0;
315      }
316    if (im->im)
317      {
318         evas_cache_image_drop(&im->im->cache_entry);
319         im->im = NULL;
320      }
321    if (im->tex)
322      {
323         evas_gl_common_texture_free(im->tex);
324         im->tex = NULL;
325      }
326
327    im->cs.space = EVAS_COLORSPACE_ARGB8888;
328    im->tex = evas_gl_common_texture_native_new(im->gc, im->w, im->h, im->alpha, im);
329    im->tex_only = 1;
330 }
331
332 void
333 evas_gl_common_image_native_disable(Evas_GL_Image *im)
334 {
335    if (im->im)
336      {
337         evas_cache_image_drop(&im->im->cache_entry);
338         im->im = NULL;
339      }
340    if (im->tex)
341      {
342         evas_gl_common_texture_free(im->tex);
343         im->tex = NULL;
344      }
345    im->tex_only = 0;
346
347    im->im = (RGBA_Image *)evas_cache_image_empty(evas_common_image_cache_get());
348    im->im->cache_entry.flags.alpha = im->alpha;
349    im->cs.space = EVAS_COLORSPACE_ARGB8888;
350    evas_cache_image_colorspace(&im->im->cache_entry, im->cs.space);
351    im->im = (RGBA_Image *)evas_cache_image_size_set(&im->im->cache_entry, im->w, im->h);
352    if (!im->tex)
353      im->tex = evas_gl_common_texture_new(im->gc, im->im);
354 }
355
356 void
357 evas_gl_common_image_scale_hint_set(Evas_GL_Image *im, int hint)
358 {
359    im->scale_hint = hint;
360    // FIXME: take advantage of this even in gl (eg if image is
361    // 1600x1200 but we always use it at 800x600 or even less - drop
362    // the texture res down for "non dynamic" stuff to save memory)
363 }
364
365 void
366 evas_gl_common_image_content_hint_set(Evas_GL_Image *im, int hint)
367 {
368    if (im->content_hint == hint) return;
369    im->content_hint = hint;
370    if (!im->gc) return;
371    if (!im->gc->shared->info.sec_image_map) return;
372    if (!im->gc->shared->info.bgra) return;
373    // does not handle yuv yet.
374    if (im->cs.space != EVAS_COLORSPACE_ARGB8888) return;
375    if (im->content_hint == EVAS_IMAGE_CONTENT_HINT_DYNAMIC)
376      {
377         if (im->cs.data)
378           {
379              if (!im->cs.no_free) free(im->cs.data);
380              im->cs.data = NULL;
381           }
382         im->cs.no_free = 0;
383         if (im->cached)
384           {
385              if (im->references == 0)
386                 im->gc->shared->images_size -= im->csize;
387              im->gc->shared->images = eina_list_remove(im->gc->shared->images, im);
388              im->cached = 0;
389           }
390         if (im->im)
391           {
392              evas_cache_image_drop(&im->im->cache_entry);
393              im->im = NULL;
394           }
395         if (im->tex)
396           {
397              evas_gl_common_texture_free(im->tex);
398              im->tex = NULL;
399           }
400         im->tex = evas_gl_common_texture_dynamic_new(im->gc, im);
401         im->tex_only = 1;
402      }
403    else
404      {
405         if (im->im)
406           {
407              evas_cache_image_drop(&im->im->cache_entry);
408              im->im = NULL;
409           }
410         if (im->tex)
411           {
412              evas_gl_common_texture_free(im->tex);
413              im->tex = NULL;
414           }
415         im->tex_only = 0;
416
417         im->im = (RGBA_Image *)evas_cache_image_empty(evas_common_image_cache_get());
418         im->im->cache_entry.flags.alpha = im->alpha;
419         im->cs.space = EVAS_COLORSPACE_ARGB8888;
420         evas_cache_image_colorspace(&im->im->cache_entry, im->cs.space);
421         im->im = (RGBA_Image *)evas_cache_image_size_set(&im->im->cache_entry, im->w, im->h);
422         if (!im->tex)
423            im->tex = evas_gl_common_texture_new(im->gc, im->im);
424      }
425 }
426
427 void
428 evas_gl_common_image_cache_flush(Evas_Engine_GL_Context *gc)
429 {
430    _evas_gl_image_cache_trim(gc);
431 }
432
433 void
434 evas_gl_common_image_free(Evas_GL_Image *im)
435 {
436 #if 0 // filtering disabled
437    Filtered_Image *fi;
438 #endif
439
440    evas_gl_common_context_flush(im->gc);
441    im->references--;
442    if (im->references > 0) return;
443
444    if (im->native.func.free)
445      im->native.func.free(im->native.func.data, im);
446
447    if (im->cs.data)
448      {
449         if (!im->cs.no_free) free(im->cs.data);
450      }
451    if (im->cached)
452      {
453         if (_evas_gl_image_cache_add(im)) return;
454      }
455    if (im->im) evas_cache_image_drop(&im->im->cache_entry);
456    if (im->tex) evas_gl_common_texture_free(im->tex);
457
458 #if 0 // filtering disabled
459    EINA_LIST_FREE(im->filtered, fi)
460      {
461         free(fi->key);
462         evas_gl_common_image_free((Evas_GL_Image *)fi->image);
463         free(fi);
464      }
465 #endif
466
467    free(im);
468 }
469
470 Evas_GL_Image *
471 evas_gl_common_image_surface_new(Evas_Engine_GL_Context *gc, unsigned int w, unsigned int h, int alpha)
472 {
473    Evas_GL_Image *im;
474
475    im = calloc(1, sizeof(Evas_GL_Image));
476    if (!im) return NULL;
477    im->references = 1;
478    im->gc = gc;
479    im->cs.space = EVAS_COLORSPACE_ARGB8888;
480    im->alpha = alpha;
481    im->w = w;
482    im->h = h;
483    im->tex = evas_gl_common_texture_render_new(gc, w, h, alpha);
484    im->tex_only = 1;
485    return im;
486 }
487
488 void
489 evas_gl_common_image_dirty(Evas_GL_Image *im, unsigned int x, unsigned int y, unsigned int w, unsigned int h)
490 {
491    if ((w == 0) && (h == 0) && (x == 0) && (y == 0))
492      {
493         w = im->w;
494         h = im->h;
495      }
496    if (im->im)
497      {
498         im->im = (RGBA_Image *)evas_cache_image_dirty(&im->im->cache_entry, x, y, w, h);
499      }
500    im->dirty = 1;
501 }
502
503 void
504 evas_gl_common_image_update(Evas_Engine_GL_Context *gc, Evas_GL_Image *im)
505 {
506    if (!im->im) return;
507 /*
508    if ((im->cs.space == EVAS_COLORSPACE_YCBCR422P601_PL) ||
509        (im->cs.space == EVAS_COLORSPACE_YCBCR422P709_PL))
510      {
511         // SOFTWARE convert. do multi texture later
512         if ((im->cs.data) && (*((unsigned char **)im->cs.data)))
513           {
514              if (im->dirty || !im->im->image.data)
515                {
516                   free(im->im->image.data);
517                   im->im->image.data = malloc(im->im->cache_entry.w * im->im->cache_entry.h * sizeof(DATA32));
518                   if (im->im->image.data)
519                     evas_common_convert_yuv_420p_601_rgba(im->cs.data,
520                                                           (void *)im->im->image.data,
521                                                           im->im->cache_entry.w, im->im->cache_entry.h);
522                }
523           }
524         space = EVAS_COLORSPACE_ARGB8888;
525      }
526    else
527  */
528    switch (im->cs.space)
529      {
530       case EVAS_COLORSPACE_ARGB8888:
531         if ((im->tex) && (im->dirty))
532           {
533              evas_cache_image_load_data(&im->im->cache_entry);
534              evas_gl_common_texture_update(im->tex, im->im);
535              evas_cache_image_unload_data(&im->im->cache_entry);
536           }
537         if (!im->tex)
538           {
539              evas_cache_image_load_data(&im->im->cache_entry);
540              im->tex = evas_gl_common_texture_new(gc, im->im);
541              evas_cache_image_unload_data(&im->im->cache_entry);
542           }
543         im->dirty = 0;
544         if (!im->tex) return;
545         break;
546       case EVAS_COLORSPACE_YCBCR422P601_PL:
547       case EVAS_COLORSPACE_YCBCR422P709_PL:
548         if ((im->tex) && (im->dirty))
549           {
550              evas_gl_common_texture_yuv_update(im->tex, im->cs.data,
551                                                im->im->cache_entry.w,
552                                                im->im->cache_entry.h);
553              im->dirty = 0;
554           }
555         if ((!im->tex) && (im->cs.data) && (*((unsigned char **)im->cs.data)))
556           {
557              im->tex = evas_gl_common_texture_yuv_new(gc, im->cs.data,
558                                                       im->im->cache_entry.w,
559                                                       im->im->cache_entry.h);
560              im->dirty = 0;
561           }
562         if (!im->tex) return;
563         break;
564       default:
565          ERR("unhandled img format colorspace=%d", im->cs.space);
566         break;
567     }
568 }
569
570 void
571 evas_gl_common_image_map_draw(Evas_Engine_GL_Context *gc, Evas_GL_Image *im,
572                               int npoints, RGBA_Map_Point *p, int smooth, int level __UNUSED__)
573 {
574    RGBA_Draw_Context *dc;
575    int r, g, b, a;
576    int c, cx, cy, cw, ch;
577    Eina_Bool yuv = 0;
578
579    dc = gc->dc;
580    if (dc->mul.use)
581      {
582         a = (dc->mul.col >> 24) & 0xff;
583         r = (dc->mul.col >> 16) & 0xff;
584         g = (dc->mul.col >> 8 ) & 0xff;
585         b = (dc->mul.col      ) & 0xff;
586      }
587    else
588      {
589         r = g = b = a = 255;
590      }
591
592    evas_gl_common_image_update(gc, im);
593
594    c = gc->dc->clip.use;
595    cx = gc->dc->clip.x; cy = gc->dc->clip.y;
596    cw = gc->dc->clip.w; ch = gc->dc->clip.h;
597    im->tex->im = im;
598    if ((im->cs.space == EVAS_COLORSPACE_YCBCR422P601_PL) ||
599        (im->cs.space == EVAS_COLORSPACE_YCBCR422P709_PL))
600       yuv = 1;
601    evas_gl_common_context_image_map_push(gc, im->tex, npoints, p,
602                                          c, cx, cy, cw, ch,
603                                          r, g, b, a, smooth, im->tex_only,
604                                          yuv);
605 }
606
607 void
608 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)
609 {
610    RGBA_Draw_Context *dc;
611    Evas_GL_Image *imm;
612    int r, g, b, a;
613    double ssx, ssy, ssw, ssh;
614    double mssx, mssy, mssw, mssh;
615    Cutout_Rects *rects;
616    Cutout_Rect  *rct;
617    int c, cx, cy, cw, ch;
618    int i;
619    int yuv = 0;
620
621    if (sw < 1) sw = 1;
622    if (sh < 1) sh = 1;
623    dc = gc->dc;
624    imm = (Evas_GL_Image *)dc->mask.mask;
625    if (dc->mul.use)
626      {
627         a = (dc->mul.col >> 24) & 0xff;
628         r = (dc->mul.col >> 16) & 0xff;
629         g = (dc->mul.col >> 8 ) & 0xff;
630         b = (dc->mul.col      ) & 0xff;
631      }
632    else
633      {
634         r = g = b = a = 255;
635      }
636
637    evas_gl_common_image_update(gc, im);
638    if (!im->tex)
639      {
640         evas_gl_common_rect_draw(gc, dx, dy, dw, dh);
641         return;
642      }
643    if (imm)
644      {
645         evas_gl_common_image_update(gc, imm);
646         if (!imm->tex) imm = NULL; /* Turn of mask on error */
647      }
648
649    if ((im->cs.space == EVAS_COLORSPACE_YCBCR422P601_PL) ||
650        (im->cs.space == EVAS_COLORSPACE_YCBCR422P709_PL))
651      yuv = 1;
652
653    im->tex->im = im;
654    if (imm) imm->tex->im = imm;
655    if ((!gc->dc->cutout.rects) ||
656        ((gc->shared->info.tune.cutout.max > 0) &&
657            (gc->dc->cutout.active > gc->shared->info.tune.cutout.max)))
658      {
659         if (gc->dc->clip.use)
660           {
661              int nx, ny, nw, nh;
662              double scalex,scaley;
663
664              nx = dx; ny = dy; nw = dw; nh = dh;
665              RECTS_CLIP_TO_RECT(nx, ny, nw, nh,
666                                 gc->dc->clip.x, gc->dc->clip.y,
667                                 gc->dc->clip.w, gc->dc->clip.h);
668              if ((nw < 1) || (nh < 1)) return;
669              if ((!imm) && (nx == dx) && (ny == dy) && (nw == dw) && (nh == dh))
670                {
671                   if (yuv)
672                     evas_gl_common_context_yuv_push(gc,
673                                                     im->tex,
674                                                     sx, sy, sw, sh,
675                                                     dx, dy, dw, dh,
676                                                     r, g, b, a,
677                                                     smooth);
678                   else
679                     evas_gl_common_context_image_push(gc,
680                                                       im->tex,
681                                                       sx, sy, sw, sh,
682                                                       dx, dy, dw, dh,
683                                                       r, g, b, a,
684                                                       smooth, im->tex_only);
685                   return;
686                }
687
688              ssx = (double)sx + ((double)(sw * (nx - dx)) / (double)(dw));
689              ssy = (double)sy + ((double)(sh * (ny - dy)) / (double)(dh));
690              ssw = ((double)sw * (double)(nw)) / (double)(dw);
691              ssh = ((double)sh * (double)(nh)) / (double)(dh);
692              if (imm)
693                {
694                   /* Correct ones here */
695                   scalex = imm->w / (double)dc->mask.w;
696                   scaley = imm->h / (double)dc->mask.h;
697                   mssx = scalex * (nx - dc->mask.x);
698                   mssy = scaley * (ny - dc->mask.y);
699                   mssw = scalex * nw;
700                   mssh = scaley * nh;
701
702                   /* No yuv + imm I'm afraid */
703                   evas_gl_common_context_image_mask_push(gc,
704                                                im->tex,
705                                                imm->tex,
706                                                ssx, ssy, ssw, ssh,
707                                                mssx, mssy, mssw, mssh,
708                                                //dc->mask.x, dc->mask.y, dc->mask.w, dc->mask.h,
709                                                nx, ny, nw, nh,
710                                                r, g, b, a,
711                                                smooth);
712                }
713              else if (yuv)
714                evas_gl_common_context_yuv_push(gc,
715                                                im->tex,
716                                                ssx, ssy, ssw, ssh,
717                                                nx, ny, nw, nh,
718                                                r, g, b, a,
719                                                smooth);
720              else
721                evas_gl_common_context_image_push(gc,
722                                                  im->tex,
723                                                  ssx, ssy, ssw, ssh,
724                                                  nx, ny, nw, nh,
725                                                  r, g, b, a,
726                                                  smooth, im->tex_only);
727           }
728         else
729           {
730              if (yuv)
731                evas_gl_common_context_yuv_push(gc,
732                                                im->tex,
733                                                sx, sy, sw, sh,
734                                                dx, dy, dw, dh,
735                                                r, g, b, a,
736                                                smooth);
737              else
738                evas_gl_common_context_image_push(gc,
739                                                  im->tex,
740                                                  sx, sy, sw, sh,
741                                                  dx, dy, dw, dh,
742                                                  r, g, b, a,
743                                                  smooth, im->tex_only);
744           }
745         return;
746      }
747
748    /* save out clip info */
749    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;
750    evas_common_draw_context_clip_clip(gc->dc, 0, 0, gc->w, gc->h);
751    evas_common_draw_context_clip_clip(gc->dc, dx, dy, dw, dh);
752    /* our clip is 0 size.. abort */
753    if ((gc->dc->clip.w <= 0) || (gc->dc->clip.h <= 0))
754      {
755         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;
756         return;
757      }
758    rects = evas_common_draw_context_apply_cutouts(dc);
759    for (i = 0; i < rects->active; ++i)
760      {
761         int nx, ny, nw, nh;
762
763         rct = rects->rects + i;
764         nx = dx; ny = dy; nw = dw; nh = dh;
765         RECTS_CLIP_TO_RECT(nx, ny, nw, nh, rct->x, rct->y, rct->w, rct->h);
766         if ((nw < 1) || (nh < 1)) continue;
767         if ((nx == dx) && (ny == dy) && (nw == dw) && (nh == dh))
768           {
769              if (yuv)
770                evas_gl_common_context_yuv_push(gc,
771                                                im->tex,
772                                                sx, sy, sw, sh,
773                                                dx, dy, dw, dh,
774                                                r, g, b, a,
775                                                smooth);
776              else
777                evas_gl_common_context_image_push(gc,
778                                                  im->tex,
779                                                  sx, sy, sw, sh,
780                                                  dx, dy, dw, dh,
781                                                  r, g, b, a,
782                                                  smooth, im->tex_only);
783              continue;
784           }
785         ssx = (double)sx + ((double)(sw * (nx - dx)) / (double)(dw));
786         ssy = (double)sy + ((double)(sh * (ny - dy)) / (double)(dh));
787         ssw = ((double)sw * (double)(nw)) / (double)(dw);
788         ssh = ((double)sh * (double)(nh)) / (double)(dh);
789         if (yuv)
790           evas_gl_common_context_yuv_push(gc,
791                                           im->tex,
792                                           ssx, ssy, ssw, ssh,
793                                           nx, ny, nw, nh,
794                                           r, g, b, a,
795                                           smooth);
796         else
797           evas_gl_common_context_image_push(gc,
798                                             im->tex,
799                                             ssx, ssy, ssw, ssh,
800                                             nx, ny, nw, nh,
801                                             r, g, b, a,
802                                             smooth, im->tex_only);
803      }
804    evas_common_draw_context_apply_clear_cutouts(rects);
805    /* restore clip info */
806    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;
807 }