Revert "Rollback to previous package. evas_1.0.0.001+svn.62695slp2+build31"
[framework/uifw/evas.git] / src / modules / engines / gl_common / evas_gl_texture.c
1 #include "evas_gl_private.h"
2
3 static const GLenum rgba_fmt   = GL_RGBA;
4 static const GLenum rgba_ifmt  = GL_RGBA;
5 //#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
6 //static const GLenum rgb_fmt    = GL_RGBA;
7 //static const GLenum rgb_ifmt   = GL_RGBA;
8 //#else
9 static const GLenum rgb_fmt    = GL_RGBA;
10 static const GLenum rgb_ifmt   = GL_RGB;
11 //#endif
12 #ifdef GL_BGRA
13 # if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
14 static const GLenum bgra_fmt   = GL_BGRA;
15 static const GLenum bgra_ifmt  = GL_BGRA;
16 static const GLenum bgr_fmt    = GL_BGRA;
17 static const GLenum bgr_ifmt   = GL_BGRA;
18 # else
19 static const GLenum bgra_fmt   = GL_BGRA;
20 static const GLenum bgra_ifmt  = GL_RGBA;
21 static const GLenum bgr_fmt    = GL_BGRA;
22 static const GLenum bgr_ifmt   = GL_RGB;
23 # endif
24 #endif
25 static const GLenum alpha_fmt      = GL_ALPHA;
26 static const GLenum alpha_ifmt     = GL_ALPHA;
27 static const GLenum lum_fmt        = GL_LUMINANCE;
28 static const GLenum lum_ifmt       = GL_LUMINANCE;
29 static const GLenum lum_alpha_fmt  = GL_LUMINANCE_ALPHA;
30 static const GLenum lum_alpha_ifmt = GL_LUMINANCE_ALPHA;
31 static const GLenum rgba8_ifmt     = GL_RGBA;
32 static const GLenum rgba8_fmt      = GL_BGRA;
33
34 static struct {
35    struct {
36       int num, pix;
37    } c, a, v, r, n, d;
38 } texinfo = {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}};
39
40 static void
41 _print_tex_count(void)
42 {
43    if (getenv("EVAS_GL_MEMINFO"))
44      {
45         fprintf(stderr,
46                 "T: c:%i/%ik | a:%i/%ik | v:%i/%ik | r:%i/%ik | n:%i/%ik | d:%i/%ik\n",
47                 texinfo.c.num, (texinfo.c.pix * 4) / 1024,
48                 texinfo.a.num, (texinfo.a.pix    ) / 1024,
49                 texinfo.v.num, (texinfo.v.pix    ) / 1024,
50                 texinfo.r.num, (texinfo.r.pix * 4) / 1024,
51                 texinfo.n.num, (texinfo.n.pix * 4) / 1024,
52                 texinfo.d.num, (texinfo.d.pix * 4) / 1024
53                );
54      }
55 }
56
57 static int
58 _nearest_pow2(int num)
59 {
60    unsigned int n = num - 1;
61    n |= n >> 1;
62    n |= n >> 2;
63    n |= n >> 4;
64    n |= n >> 8;
65    n |= n >> 16;
66    return n + 1;
67 }
68
69 static void
70 _tex_adjust(Evas_Engine_GL_Context *gc, int *w, int *h)
71 {
72    if (gc->shared->info.tex_npo2) return;
73    /*if (gc->shared->info.tex_rect) return;*/
74    *w = _nearest_pow2(*w);
75    *h = _nearest_pow2(*h);
76 }
77
78 static int
79 _tex_round_slot(Evas_Engine_GL_Context *gc, int h)
80 {
81    if (!gc->shared->info.tex_npo2)
82      h = _nearest_pow2(h);
83    return (h + gc->shared->info.tune.atlas.slot_size - 1) /
84       gc->shared->info.tune.atlas.slot_size;
85 }
86
87 static int
88 _tex_format_index(GLuint format)
89 {
90    switch (format)
91      {
92      case GL_RGBA:
93 #ifdef GL_BGRA
94      case GL_BGRA:
95 #endif
96         return 0;
97      case GL_RGB:
98         return 1;
99      case GL_ALPHA:
100         return 2;
101      case GL_LUMINANCE: // never used in atlas
102         return 3;
103      default:
104         return 0;
105      }
106    return 0;
107 }
108
109 static void
110 _tex_2d(int intfmt, int w, int h, int fmt, int type)
111 {
112    glTexImage2D(GL_TEXTURE_2D, 0, intfmt, w, h, 0, fmt, type, NULL);
113    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
114 }
115
116 static void
117 _tex_sub_2d(int x, int y, int w, int h, int fmt, int type, const void *pix)
118 {
119    glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, w, h, fmt, type, pix);
120    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
121 }
122
123 static Evas_GL_Texture_Pool *
124 _pool_tex_new(Evas_Engine_GL_Context *gc, int w, int h, int intformat, GLenum format)
125 {
126    Evas_GL_Texture_Pool *pt;
127
128    pt = calloc(1, sizeof(Evas_GL_Texture_Pool));
129    if (!pt) return NULL;
130    h = _tex_round_slot(gc, h) * gc->shared->info.tune.atlas.slot_size;
131    _tex_adjust(gc, &w, &h);
132    pt->gc = gc;
133    pt->w = w;
134    pt->h = h;
135    pt->intformat = intformat;
136    pt->format = format;
137    pt->dataformat = GL_UNSIGNED_BYTE;
138    pt->references = 0;
139
140    if (format == alpha_fmt)
141       {
142          texinfo.a.num++;
143          texinfo.a.pix += pt->w * pt->h;
144       }
145    else if (format == lum_fmt)
146       {
147          texinfo.v.num++;
148          texinfo.v.pix += pt->w * pt->h;
149       }
150    else
151       {
152          texinfo.c.num++;
153          texinfo.c.pix += pt->w * pt->h;
154       }
155
156    _print_tex_count();
157
158    glGenTextures(1, &(pt->texture));
159    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
160    glBindTexture(GL_TEXTURE_2D, pt->texture);
161    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
162    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
163    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
164    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
165    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
166    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
167    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
168    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
169    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
170    _tex_2d(pt->intformat, w, h, pt->format, pt->dataformat);
171    glBindTexture(GL_TEXTURE_2D, gc->pipe[0].shader.cur_tex);
172    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
173    return pt;
174 }
175
176 static int
177 _pool_tex_alloc(Evas_GL_Texture_Pool *pt, int w, int h __UNUSED__, int *u, int *v, Eina_List **l_after)
178 {
179    Eina_List *l;
180    Evas_GL_Texture *tex, *tex2;
181    int nx, d, b;
182
183    if (pt->allocations)
184      {
185         tex = pt->allocations->data;
186         // if firest tex is not at left edge...
187         if (tex->x > (0 + 1))
188           {
189              if ((tex->x - 1) >= w)
190                {
191                   *u = 0;
192                   *v = 0;
193                   *l_after = NULL;
194                   return 1;
195                }
196           }
197      }
198    EINA_LIST_FOREACH(pt->allocations, l, tex)
199      {
200         b = tex->x + tex->w + 2;
201         if (l->next)
202           {
203              tex2 = l->next->data;
204              nx = tex2->x - 1;
205           }
206         else
207           nx = pt->w - 1;
208         d = nx - b;
209         if (d >= w)
210           {
211              *u = b;
212              *v = 0;
213              *l_after = l;
214              return 1;
215           }
216      }
217    *l_after = NULL;
218    return 0;
219 }
220
221 static Evas_GL_Texture_Pool *
222 _pool_tex_find(Evas_Engine_GL_Context *gc, int w, int h,
223                int intformat, int format, int *u, int *v,
224                Eina_List **l_after, int atlas_w)
225 {
226    Evas_GL_Texture_Pool *pt = NULL;
227    Eina_List *l;
228    int th, th2;
229
230    if (atlas_w > gc->shared->info.max_texture_size)
231       atlas_w = gc->shared->info.max_texture_size;
232    if ((w > gc->shared->info.tune.atlas.max_w) ||
233        (h > gc->shared->info.tune.atlas.max_h))
234      {
235         pt = _pool_tex_new(gc, w, h, intformat, format);
236         gc->shared->tex.whole = eina_list_prepend(gc->shared->tex.whole, pt);
237         pt->slot = -1;
238         pt->fslot = -1;
239         pt->whole = 1;
240         *u = 0;
241         *v = 0;
242         *l_after = NULL;
243         return pt;
244      }
245
246    th = _tex_round_slot(gc, h);
247    th2 = _tex_format_index(intformat);
248    EINA_LIST_FOREACH(gc->shared->tex.atlas[th][th2], l, pt)
249      {
250         if (_pool_tex_alloc(pt, w, h, u, v, l_after))
251           {
252              gc->shared->tex.atlas[th][th2] =
253                eina_list_remove_list(gc->shared->tex.atlas[th][th2], l);
254              gc->shared->tex.atlas[th][th2] =
255                eina_list_prepend(gc->shared->tex.atlas[th][th2], pt);
256              return pt;
257           }
258      }
259    pt = _pool_tex_new(gc, atlas_w, h, intformat, format);
260    gc->shared->tex.atlas[th][th2] =
261      eina_list_prepend(gc->shared->tex.atlas[th][th2], pt);
262    pt->slot = th;
263    pt->fslot = th2;
264    *u = 0;
265    *v = 0;
266    *l_after = NULL;
267    return pt;
268 }
269
270 Evas_GL_Texture *
271 evas_gl_common_texture_new(Evas_Engine_GL_Context *gc, RGBA_Image *im)
272 {
273    Evas_GL_Texture *tex;
274    Eina_List *l_after = NULL;
275    int u = 0, v = 0;
276
277    tex = calloc(1, sizeof(Evas_GL_Texture));
278    if (!tex) return NULL;
279
280    tex->gc = gc;
281    tex->references = 1;
282
283    if (im->cache_entry.flags.alpha)
284      {
285         if (gc->shared->info.bgra)
286            tex->pt = _pool_tex_find(gc, im->cache_entry.w + 2,
287                                     im->cache_entry.h + 1, bgra_ifmt, bgra_fmt,
288                                     &u, &v, &l_after,
289                                     gc->shared->info.tune.atlas.max_alloc_size);
290         else
291            tex->pt = _pool_tex_find(gc, im->cache_entry.w + 2,
292                                     im->cache_entry.h + 1, rgba_ifmt, rgba_fmt,
293                                     &u, &v, &l_after,
294                                     gc->shared->info.tune.atlas.max_alloc_size);
295         tex->alpha = 1;
296      }
297    else
298      {
299         if (gc->shared->info.bgra)
300            tex->pt = _pool_tex_find(gc, im->cache_entry.w + 3,
301                                     im->cache_entry.h + 1, bgr_ifmt, bgr_fmt,
302                                     &u, &v, &l_after,
303                                     gc->shared->info.tune.atlas.max_alloc_size);
304         else
305 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
306            tex->pt = _pool_tex_find(gc, im->cache_entry.w + 3,
307                                     im->cache_entry.h + 1, rgba_ifmt, rgba_fmt,
308                                     &u, &v, &l_after,
309                                     gc->shared->info.tune.atlas.max_alloc_size);
310 #else
311            tex->pt = _pool_tex_find(gc, im->cache_entry.w + 3,
312                                     im->cache_entry.h + 1, rgb_ifmt, rgb_fmt,
313                                     &u, &v, &l_after,
314                                     gc->shared->info.tune.atlas.max_alloc_size);
315 #endif
316      }
317    if (!tex->pt)
318      {
319         free(tex);
320         return NULL;
321      }
322    tex->x = u + 1;
323    tex->y = v;
324    tex->w = im->cache_entry.w;
325    tex->h = im->cache_entry.h;
326    if (l_after)
327      tex->pt->allocations =
328      eina_list_append_relative_list(tex->pt->allocations, tex, l_after);
329    else
330      tex->pt->allocations =
331      eina_list_prepend(tex->pt->allocations, tex);
332    tex->pt->references++;
333    evas_gl_common_texture_update(tex, im);
334    return tex;
335 }
336
337 static Evas_GL_Texture_Pool *
338 _pool_tex_render_new(Evas_Engine_GL_Context *gc, int w, int h, int intformat, int format)
339 {
340    Evas_GL_Texture_Pool *pt;
341
342    pt = calloc(1, sizeof(Evas_GL_Texture_Pool));
343    if (!pt) return NULL;
344    h = _tex_round_slot(gc, h) * gc->shared->info.tune.atlas.slot_size;
345    _tex_adjust(gc, &w, &h);
346    pt->gc = gc;
347    pt->w = w;
348    pt->h = h;
349    pt->intformat = intformat;
350    pt->format = format;
351    pt->dataformat = GL_UNSIGNED_BYTE;
352    pt->render = 1;
353    pt->references = 0;
354 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
355 # ifndef GL_FRAMEBUFFER
356 #  define GL_FRAMEBUFFER GL_FRAMEBUFFER_OES
357 # endif
358 # ifndef GL_COLOR_ATTACHMENT0
359 #  define GL_COLOR_ATTACHMENT0 GL_COLOR_ATTACHMENT0_OES
360 # endif
361 #else
362 # ifndef GL_FRAMEBUFFER
363 #  define GL_FRAMEBUFFER GL_FRAMEBUFFER_EXT
364 # endif
365 # ifndef GL_COLOR_ATTACHMENT0
366 #  define GL_COLOR_ATTACHMENT0 GL_COLOR_ATTACHMENT0_EXT
367 # endif
368 #endif
369    texinfo.r.num++;
370    texinfo.r.pix += pt->w * pt->h;
371
372    _print_tex_count();
373
374    glGenTextures(1, &(pt->texture));
375    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
376    glBindTexture(GL_TEXTURE_2D, pt->texture);
377    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
378    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
379    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
380    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
381    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
382    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
383    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
384    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
385    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
386    _tex_2d(pt->intformat, w, h, pt->format, pt->dataformat);
387
388    glsym_glGenFramebuffers(1, &(pt->fb));
389    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
390    glsym_glBindFramebuffer(GL_FRAMEBUFFER, pt->fb);
391    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
392    glsym_glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, pt->texture, 0);
393    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
394    glsym_glBindFramebuffer(GL_FRAMEBUFFER, 0);
395    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
396
397    glBindTexture(GL_TEXTURE_2D, gc->pipe[0].shader.cur_tex);
398    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
399    return pt;
400 }
401
402 static Evas_GL_Texture_Pool *
403 _pool_tex_native_new(Evas_Engine_GL_Context *gc, int w, int h, int intformat, int format, Evas_GL_Image *im)
404 {
405    Evas_GL_Texture_Pool *pt;
406
407    pt = calloc(1, sizeof(Evas_GL_Texture_Pool));
408    if (!pt) return NULL;
409    pt->gc = gc;
410 #ifdef GL_TEXTURE_RECTANGLE_ARB
411    if (im->native.target == GL_TEXTURE_RECTANGLE_ARB)
412      {
413         printf("REEEEEEEEECT\n");
414         pt->w = w;
415         pt->h = h;
416      }
417    else
418 #endif
419      {
420         // FIXME: handle po2 only textures
421         pt->w = w;
422         pt->h = h;
423      }
424    pt->intformat = intformat;
425    pt->format = format;
426    pt->dataformat = GL_UNSIGNED_BYTE;
427    pt->references = 0;
428    pt->native = 1;
429    texinfo.n.num++;
430    texinfo.n.pix += pt->w * pt->h;
431
432    _print_tex_count();
433
434    glGenTextures(1, &(pt->texture));
435    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
436    glBindTexture(im->native.target, pt->texture);
437    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
438
439 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
440 #else
441    if (im->native.loose)
442      {
443         if (im->native.func.bind)
444           im->native.func.bind(im->native.func.data, im);
445      }
446 #endif
447
448    glTexParameteri(im->native.target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
449    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
450    glTexParameteri(im->native.target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
451    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
452    glTexParameteri(im->native.target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
453    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
454    glTexParameteri(im->native.target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
455    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
456    glBindTexture(im->native.target, 0);
457    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
458    glBindTexture(im->native.target, gc->pipe[0].shader.cur_tex);
459    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
460    return pt;
461 }
462
463 static Evas_GL_Texture_Pool *
464 _pool_tex_dynamic_new(Evas_Engine_GL_Context *gc, int w, int h, int intformat, int format)
465 {
466    Evas_GL_Texture_Pool *pt = NULL;
467
468 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
469    int fmt; // EGL_MAP_GL_TEXTURE_RGBA_SEC or EGL_MAP_GL_TEXTURE_RGB_SEC or bust
470    int pixtype; // EGL_MAP_GL_TEXTURE_UNSIGNED_BYTE_SEC or bust
471    int glformat;
472    int attr[] =
473      {
474         EGL_MAP_GL_TEXTURE_WIDTH_SEC, 32,
475         EGL_MAP_GL_TEXTURE_HEIGHT_SEC, 32,
476         EGL_MAP_GL_TEXTURE_FORMAT_SEC, EGL_MAP_GL_TEXTURE_RGBA_SEC,
477         EGL_MAP_GL_TEXTURE_PIXEL_TYPE_SEC, EGL_MAP_GL_TEXTURE_UNSIGNED_BYTE_SEC,
478         EGL_NONE
479      };
480    void *egldisplay;
481
482    if (intformat != format) return NULL;
483
484    switch (intformat)
485      {
486 #ifdef EGL_MAP_GL_TEXTURE_LUMINANCE_SEC
487      case GL_LUMINANCE: attr[5] = EGL_MAP_GL_TEXTURE_LUMINANCE_SEC; break;
488 #endif
489 #ifdef EGL_MAP_GL_TEXTURE_LUMINANCE_ALPHA_SEC
490      case GL_LUMINANCE_ALPHA: attr[5] = EGL_MAP_GL_TEXTURE_LUMINANCE_ALPHA_SEC; break;
491 #endif
492      case GL_RGBA: attr[5] = EGL_MAP_GL_TEXTURE_RGBA_SEC; break;
493      default: fprintf(stderr, "unknown format\n"); return NULL;
494      }
495
496    pt = calloc(1, sizeof(Evas_GL_Texture_Pool));
497    if (!pt) return NULL;
498    h = _tex_round_slot(gc, h) * gc->shared->info.tune.atlas.slot_size;
499    _tex_adjust(gc, &w, &h);
500    pt->gc = gc;
501    pt->w = w;
502    pt->h = h;
503    pt->intformat = intformat;
504    pt->format = format;
505    pt->dataformat = GL_UNSIGNED_BYTE;
506    pt->render = 1;
507    pt->references = 0;
508    texinfo.d.num++;
509    texinfo.d.pix += pt->w * pt->h;
510
511    _print_tex_count();
512
513    glGenTextures(1, &(pt->texture));
514    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
515    glBindTexture(GL_TEXTURE_2D, pt->texture);
516    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
517    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
518    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
519    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
520    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
521    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
522    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
523    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
524    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
525
526    egldisplay = pt->gc->egldisp;
527
528    attr[1] = pt->w;
529    attr[3] = pt->h;
530
531    // FIXME: seems a bit slower than i'd like - maybe too many flushes?
532    // FIXME: YCbCr no support as yet
533    pt->dyn.img = secsym_eglCreateImage(egldisplay,
534                                        EGL_NO_CONTEXT,
535                                        EGL_MAP_GL_TEXTURE_2D_SEC,
536                                        0, attr);
537    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
538    if (!pt->dyn.img)
539      {
540         glBindTexture(GL_TEXTURE_2D, 0);
541         GLERR(__FUNCTION__, __FILE__, __LINE__, "");
542         glDeleteTextures(1, &(pt->texture));
543         GLERR(__FUNCTION__, __FILE__, __LINE__, "");
544         free(pt);
545         return NULL;
546      }
547    if (secsym_eglGetImageAttribSEC(egldisplay,
548                                    pt->dyn.img,
549                                    EGL_MAP_GL_TEXTURE_WIDTH_SEC,
550                                    &(pt->dyn.w)) != EGL_TRUE) goto error;
551    if (secsym_eglGetImageAttribSEC(egldisplay,
552                                    pt->dyn.img,
553                                    EGL_MAP_GL_TEXTURE_HEIGHT_SEC,
554                                    &(pt->dyn.h)) != EGL_TRUE) goto error;
555    if (secsym_eglGetImageAttribSEC(egldisplay,
556                                    pt->dyn.img,
557                                    EGL_MAP_GL_TEXTURE_STRIDE_IN_BYTES_SEC,
558                                    &(pt->dyn.stride)) != EGL_TRUE) goto error;
559    if (secsym_eglGetImageAttribSEC(egldisplay,
560                                    pt->dyn.img,
561                                    EGL_MAP_GL_TEXTURE_FORMAT_SEC,
562                                    &(fmt)) != EGL_TRUE) goto error;
563
564    if (secsym_eglGetImageAttribSEC(egldisplay,
565                                    pt->dyn.img,
566                                    EGL_MAP_GL_TEXTURE_PIXEL_TYPE_SEC,
567                                    &(pixtype)) != EGL_TRUE) goto error;
568
569    if (pixtype != EGL_MAP_GL_TEXTURE_UNSIGNED_BYTE_SEC) goto error;
570
571    glBindTexture(GL_TEXTURE_2D, gc->pipe[0].shader.cur_tex);
572    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
573 #else
574    gc = NULL;
575    w = 0;
576    h = 0;
577    intformat = 0;
578    format = 0;
579 #endif
580    return pt;
581
582 /* ERROR HANDLING */
583 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
584 error:
585   secsym_eglDestroyImage(egldisplay, pt->dyn.img);
586   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
587   pt->dyn.img = NULL;
588   glBindTexture(GL_TEXTURE_2D, 0);
589   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
590   glDeleteTextures(1, &(pt->texture));
591   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
592   free(pt);
593   return NULL;
594 #endif   
595 }
596
597 void
598 evas_gl_texture_pool_empty(Evas_GL_Texture_Pool *pt)
599 {
600    if (!pt->gc) return;
601
602    if (pt->format == alpha_fmt)
603       {
604          texinfo.a.num--;
605          texinfo.a.pix -= pt->w * pt->h;
606       }
607    else if (pt->format == lum_fmt)
608       {
609          texinfo.v.num--;
610          texinfo.v.pix -= pt->w * pt->h;
611       }
612    else if (pt->dyn.img)
613       {
614          texinfo.d.num--;
615          texinfo.d.pix -= pt->w * pt->h;
616       }
617    else if (pt->render)
618       {
619          texinfo.r.num--;
620          texinfo.r.pix -= pt->w * pt->h;
621       }
622    else if (pt->native)
623       {
624          texinfo.n.num--;
625          texinfo.n.pix -= pt->w * pt->h;
626       }
627    else
628       {
629          texinfo.c.num--;
630          texinfo.c.pix -= pt->w * pt->h;
631       }
632
633    _print_tex_count();
634
635 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
636    if (pt->dyn.img)
637      {
638         secsym_eglDestroyImage(pt->gc->egldisp, pt->dyn.img);
639         pt->dyn.img = NULL;
640         pt->dyn.data = NULL;
641         pt->dyn.w = 0;
642         pt->dyn.h = 0;
643         pt->dyn.stride = 0;
644      }
645 #endif
646
647    glDeleteTextures(1, &(pt->texture));
648    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
649    if (pt->fb)
650      {
651         glsym_glDeleteFramebuffers(1, &(pt->fb));
652         GLERR(__FUNCTION__, __FILE__, __LINE__, "");
653         pt->fb = 0;
654      }
655    while (pt->allocations)
656       pt->allocations =
657       eina_list_remove_list(pt->allocations, pt->allocations);
658    pt->texture = 0;
659    pt->gc = NULL;
660    pt->w = 0;
661    pt->h = 0;
662 }
663
664 static void
665 pt_unref(Evas_GL_Texture_Pool *pt)
666 {
667    if (!pt) return;
668    if (!pt->gc) return;
669    pt->references--;
670    if (pt->references != 0) return;
671
672    if (!((pt->render) || (pt->native)))
673      {
674         if (pt->whole)
675            pt->gc->shared->tex.whole =
676            eina_list_remove(pt->gc->shared->tex.whole, pt);
677         else
678            pt->gc->shared->tex.atlas [pt->slot][pt->fslot] =
679            eina_list_remove(pt->gc->shared->tex.atlas[pt->slot][pt->fslot], pt);
680      }
681    evas_gl_texture_pool_empty(pt);
682    free(pt);
683 }
684
685 static void
686 pt_link(Evas_Engine_GL_Context *gc, Evas_GL_Texture *tex, Evas_GL_Texture_Pool *pt)
687 {
688    gc->shared->tex.whole = eina_list_prepend(gc->shared->tex.whole, pt);
689    pt->slot = -1;
690    pt->fslot = -1;
691    pt->whole = 1;
692    pt->allocations = eina_list_prepend(pt->allocations, tex);
693    pt->references++;
694 }
695
696 Evas_GL_Texture *
697 evas_gl_common_texture_native_new(Evas_Engine_GL_Context *gc, unsigned int w, unsigned int h, int alpha, Evas_GL_Image *im)
698 {
699    Evas_GL_Texture *tex;
700
701    tex = calloc(1, sizeof(Evas_GL_Texture));
702    if (!tex) return NULL;
703
704    tex->gc = gc;
705    tex->references = 1;
706    tex->alpha = alpha;
707    if (alpha)
708      {
709         if (gc->shared->info.bgra)
710           tex->pt = _pool_tex_native_new(gc, w, h, rgba_ifmt, rgba_fmt, im);
711         else
712           tex->pt = _pool_tex_native_new(gc, w, h, rgba_ifmt, rgba_fmt, im);
713      }
714    else
715      {
716         if (gc->shared->info.bgra)
717           tex->pt = _pool_tex_native_new(gc, w, h, rgb_ifmt, rgb_fmt, im);
718         else
719           tex->pt = _pool_tex_native_new(gc, w, h, rgb_ifmt, rgb_fmt, im);
720      }
721    if (!tex->pt)
722      {
723         free(tex);
724         return NULL;
725      }
726    tex->x = 0;
727    tex->y = 0;
728    tex->w = w;
729    tex->h = h;
730    tex->pt->references++;
731    return tex;
732 }
733
734 Evas_GL_Texture *
735 evas_gl_common_texture_render_new(Evas_Engine_GL_Context *gc, unsigned int w, unsigned int h, int alpha)
736 {
737    Evas_GL_Texture *tex;
738
739    tex = calloc(1, sizeof(Evas_GL_Texture));
740    if (!tex) return NULL;
741
742    tex->gc = gc;
743    tex->references = 1;
744    tex->alpha = alpha;
745    if (alpha)
746      {
747         if (gc->shared->info.bgra)
748           tex->pt = _pool_tex_render_new(gc, w, h, rgba_ifmt, rgba_fmt);
749         else
750           tex->pt = _pool_tex_render_new(gc, w, h, rgba_ifmt, rgba_fmt);
751      }
752    else
753      {
754         if (gc->shared->info.bgra)
755           tex->pt = _pool_tex_render_new(gc, w, h, rgb_ifmt, rgb_fmt);
756         else
757           tex->pt = _pool_tex_render_new(gc, w, h, rgb_ifmt, rgb_fmt);
758      }
759    if (!tex->pt)
760      {
761         free(tex);
762         return NULL;
763      }
764    tex->x = 0;
765    tex->y = 0;
766    tex->w = w;
767    tex->h = h;
768    tex->pt->references++;
769    return tex;
770 }
771
772 Evas_GL_Texture *
773 evas_gl_common_texture_dynamic_new(Evas_Engine_GL_Context *gc, Evas_GL_Image *im)
774 {
775    Evas_GL_Texture *tex;
776
777    tex = calloc(1, sizeof(Evas_GL_Texture));
778    if (!tex) return NULL;
779
780    tex->gc = gc;
781    tex->references = 1;
782    tex->alpha = im->alpha;
783    tex->x = 0;
784    tex->y = 0;
785    tex->w = im->w;
786    tex->h = im->h;
787    if (tex->alpha)
788      {
789         if (gc->shared->info.bgra)
790           tex->pt = _pool_tex_dynamic_new(gc, tex->w, tex->h, bgra_ifmt, bgra_fmt);
791         else
792           tex->pt = _pool_tex_dynamic_new(gc, tex->w, tex->h, bgra_ifmt, bgra_fmt);
793      }
794    else
795      {
796         if (gc->shared->info.bgra)
797           tex->pt = _pool_tex_dynamic_new(gc, tex->w, tex->h, bgra_ifmt, bgra_fmt);
798         else
799           tex->pt = _pool_tex_dynamic_new(gc, tex->w, tex->h, bgra_ifmt, bgra_fmt);
800      }
801    if (!tex->pt)
802      {
803         free(tex);
804         return NULL;
805      }
806    tex->pt->references++;
807    return tex;
808 }
809
810 void
811 evas_gl_common_texture_update(Evas_GL_Texture *tex, RGBA_Image *im)
812 {
813    GLuint fmt;
814
815    if (tex->alpha != im->cache_entry.flags.alpha)
816      {
817         tex->pt->allocations = eina_list_remove(tex->pt->allocations, tex);
818         pt_unref(tex->pt);
819         tex->alpha = im->cache_entry.flags.alpha;
820         if (tex->alpha)
821           {
822              if (tex->gc->shared->info.bgra)
823                tex->pt = _pool_tex_render_new(tex->gc, tex->w, tex->h, bgra_ifmt, bgra_fmt);
824              else
825                tex->pt = _pool_tex_render_new(tex->gc, tex->w, tex->h, rgba_ifmt, rgba_fmt);
826           }
827         else
828           {
829              if (tex->gc->shared->info.bgra)
830                tex->pt = _pool_tex_render_new(tex->gc, tex->w, tex->h, bgr_ifmt, bgr_fmt);
831              else
832                tex->pt = _pool_tex_render_new(tex->gc, tex->w, tex->h, rgb_ifmt, rgb_fmt);
833           }
834      }
835    if (!tex->pt) return;
836    if (!im->image.data) return;
837
838    fmt = tex->pt->format;
839    glBindTexture(GL_TEXTURE_2D, tex->pt->texture);
840    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
841 #ifdef GL_UNPACK_ROW_LENGTH
842    glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
843    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
844 #endif
845    glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
846    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
847
848 //   printf("tex upload %ix%i\n", im->cache_entry.w, im->cache_entry.h);
849    //  +-+
850    //  +-+
851    //
852    _tex_sub_2d(tex->x, tex->y,
853                im->cache_entry.w, im->cache_entry.h,
854                fmt, tex->pt->dataformat,
855                im->image.data);
856    // |xxx
857    // |xxx
858    //
859    _tex_sub_2d(tex->x - 1, tex->y,
860                1, im->cache_entry.h,
861                fmt, tex->pt->dataformat,
862                im->image.data);
863    //  xxx|
864    //  xxx|
865    //
866    _tex_sub_2d(tex->x + im->cache_entry.w, tex->y,
867                1, im->cache_entry.h,
868                fmt, tex->pt->dataformat,
869                im->image.data + (im->cache_entry.w - 1));
870    //  xxx
871    //  xxx
872    //  ---
873    _tex_sub_2d(tex->x, tex->y + im->cache_entry.h,
874                im->cache_entry.w, 1,
875                fmt, tex->pt->dataformat,
876                im->image.data + ((im->cache_entry.h - 1) * im->cache_entry.w));
877    //  xxx
878    //  xxx
879    // o
880    _tex_sub_2d(tex->x - 1, tex->y + im->cache_entry.h,
881                1, 1,
882                fmt, tex->pt->dataformat,
883                im->image.data + ((im->cache_entry.h - 1) * im->cache_entry.w));
884    //  xxx
885    //  xxx
886    //     o
887    _tex_sub_2d(tex->x + im->cache_entry.w, tex->y + im->cache_entry.h,
888                1, 1,
889                fmt, tex->pt->dataformat,
890                im->image.data + ((im->cache_entry.h - 1) * im->cache_entry.w) + (im->cache_entry.w - 1));
891    if (tex->pt->texture != tex->gc->pipe[0].shader.cur_tex)
892      {
893         glBindTexture(GL_TEXTURE_2D, tex->gc->pipe[0].shader.cur_tex);
894         GLERR(__FUNCTION__, __FILE__, __LINE__, "");
895      }
896 }
897
898 void
899 evas_gl_common_texture_free(Evas_GL_Texture *tex)
900 {
901    if (!tex) return;
902    tex->references--;
903    if (tex->references != 0) return;
904    if (tex->double_buffer.pt[0])
905      {
906         tex->double_buffer.pt[0]->allocations = eina_list_remove(tex->double_buffer.pt[0]->allocations, tex);
907         tex->double_buffer.pt[1]->allocations = eina_list_remove(tex->double_buffer.pt[1]->allocations, tex);
908         tex->double_buffer.ptuv[0]->allocations = eina_list_remove(tex->double_buffer.ptuv[0]->allocations, tex);
909         tex->double_buffer.ptuv[1]->allocations = eina_list_remove(tex->double_buffer.ptuv[1]->allocations, tex);
910      }
911    else
912      {
913         if (tex->pt)
914           {
915              tex->pt->allocations = eina_list_remove(tex->pt->allocations, tex);
916              pt_unref(tex->pt);
917           }
918         if (tex->ptu)
919           {
920              tex->ptu->allocations = eina_list_remove(tex->ptu->allocations, tex);
921              pt_unref(tex->ptu);
922           }
923         if (tex->ptv)
924           {
925              tex->ptv->allocations = eina_list_remove(tex->ptv->allocations, tex);
926              pt_unref(tex->ptv);
927           }
928         if (tex->ptuv)
929           {
930              tex->ptuv->allocations = eina_list_remove(tex->ptuv->allocations, tex);
931              pt_unref(tex->ptuv);
932           }
933      }
934    free(tex);
935 }
936
937 Evas_GL_Texture *
938 evas_gl_common_texture_alpha_new(Evas_Engine_GL_Context *gc, DATA8 *pixels,
939                                  unsigned int w, unsigned int h, int fh)
940 {
941    Evas_GL_Texture *tex;
942    Eina_List *l_after = NULL;
943    int u = 0, v = 0;
944
945    tex = calloc(1, sizeof(Evas_GL_Texture));
946    if (!tex) return NULL;
947
948    tex->gc = gc;
949    tex->references = 1;
950    tex->pt = _pool_tex_find(gc, w + 3, fh, alpha_ifmt, alpha_fmt, &u, &v,
951                             &l_after,
952                             gc->shared->info.tune.atlas.max_alloc_alpha_size);
953    if (!tex->pt)
954      {
955         free(tex);
956         return NULL;
957      }
958    tex->x = u + 1;
959    tex->y = v;
960    tex->w = w;
961    tex->h = h;
962    if (l_after)
963      tex->pt->allocations =
964      eina_list_append_relative_list(tex->pt->allocations, tex, l_after);
965    else
966      tex->pt->allocations = eina_list_prepend(tex->pt->allocations, tex);
967    tex->pt->references++;
968    evas_gl_common_texture_alpha_update(tex, pixels, w, h, fh);
969    return tex;
970 }
971
972 void
973 evas_gl_common_texture_alpha_update(Evas_GL_Texture *tex, DATA8 *pixels,
974                                     unsigned int w, unsigned int h, int fh __UNUSED__)
975 {
976    if (!tex->pt) return;
977    glBindTexture(GL_TEXTURE_2D, tex->pt->texture);
978    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
979 #ifdef GL_UNPACK_ROW_LENGTH
980    glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
981    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
982 #endif
983    glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
984    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
985    _tex_sub_2d(tex->x, tex->y, w, h, tex->pt->format, tex->pt->dataformat,
986                pixels);
987    if (tex->pt->texture != tex->gc->pipe[0].shader.cur_tex)
988      {
989         glBindTexture(GL_TEXTURE_2D, tex->gc->pipe[0].shader.cur_tex);
990         GLERR(__FUNCTION__, __FILE__, __LINE__, "");
991      }
992 }
993
994 Evas_GL_Texture *
995 evas_gl_common_texture_yuv_new(Evas_Engine_GL_Context *gc, DATA8 **rows, unsigned int w, unsigned int h)
996 {
997    Evas_GL_Texture *tex;
998
999    tex = calloc(1, sizeof(Evas_GL_Texture));
1000    if (!tex) return NULL;
1001
1002    tex->gc = gc;
1003    tex->references = 1;
1004    tex->pt = _pool_tex_new(gc, w + 1, h  + 1, lum_ifmt, lum_fmt);
1005    if (!tex->pt)
1006      {
1007         free(tex);
1008         return NULL;
1009      }
1010    gc->shared->tex.whole = eina_list_prepend(gc->shared->tex.whole, tex->pt);
1011    tex->pt->slot = -1;
1012    tex->pt->fslot = -1;
1013    tex->pt->whole = 1;
1014    tex->ptu = _pool_tex_new(gc, (w / 2) + 1, (h / 2)  + 1, lum_ifmt, lum_fmt);
1015    if (!tex->ptu)
1016      {
1017         free(tex);
1018         return NULL;
1019      }
1020    gc->shared->tex.whole = eina_list_prepend(gc->shared->tex.whole, tex->ptu);
1021    tex->ptu->slot = -1;
1022    tex->ptu->fslot = -1;
1023    tex->ptu->whole = 1;
1024    tex->ptv = _pool_tex_new(gc, (w / 2) + 1, (h / 2)  + 1, lum_ifmt, lum_fmt);
1025    if (!tex->ptv)
1026      {
1027         pt_unref(tex->pt);
1028         pt_unref(tex->ptu);
1029         free(tex);
1030         return NULL;
1031      }
1032    gc->shared->tex.whole = eina_list_prepend(gc->shared->tex.whole, tex->ptv);
1033    tex->ptv->slot = -1;
1034    tex->ptv->fslot = -1;
1035    tex->ptv->whole = 1;
1036    tex->x = 0;
1037    tex->y = 0;
1038    tex->w = w;
1039    tex->h = h;
1040    tex->pt->allocations = eina_list_prepend(tex->pt->allocations, tex);
1041    tex->ptu->allocations = eina_list_prepend(tex->ptu->allocations, tex);
1042    tex->ptv->allocations = eina_list_prepend(tex->ptv->allocations, tex);
1043    tex->pt->references++;
1044    tex->ptu->references++;
1045    tex->ptv->references++;
1046    evas_gl_common_texture_yuv_update(tex, rows, w, h);
1047    return tex;
1048 }
1049
1050 void
1051 evas_gl_common_texture_yuv_update(Evas_GL_Texture *tex, DATA8 **rows, unsigned int w, unsigned int h)
1052 {
1053    if (!tex->pt) return;
1054    // FIXME: works on lowest size 4 pixel high buffers. must also be multiple of 2
1055 #ifdef GL_UNPACK_ROW_LENGTH
1056    glPixelStorei(GL_UNPACK_ROW_LENGTH, rows[1] - rows[0]);
1057    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
1058    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
1059    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
1060    glBindTexture(GL_TEXTURE_2D, tex->pt->texture);
1061    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
1062    _tex_2d(tex->pt->intformat, w, h, tex->pt->format, tex->pt->dataformat);
1063    _tex_sub_2d(0, 0, w, h, tex->pt->format, tex->pt->dataformat, rows[0]);
1064    glBindTexture(GL_TEXTURE_2D, tex->ptu->texture);
1065    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
1066    glPixelStorei(GL_UNPACK_ROW_LENGTH, rows[h + 1] - rows[h]);
1067    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
1068    _tex_2d(tex->ptu->intformat, w / 2, h / 2, tex->ptu->format, tex->ptu->dataformat);
1069    _tex_sub_2d(0, 0, w / 2, h / 2, tex->ptu->format, tex->ptu->dataformat, rows[h]);
1070    glBindTexture(GL_TEXTURE_2D, tex->ptv->texture);
1071    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
1072    glPixelStorei(GL_UNPACK_ROW_LENGTH, rows[h + (h / 2) + 1] - rows[h + (h / 2)]);
1073    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
1074    _tex_2d(tex->ptv->intformat, w / 2, h / 2, tex->ptv->format, tex->ptv->dataformat);
1075    _tex_sub_2d(0, 0, w / 2, h / 2, tex->ptv->format, tex->ptv->dataformat, rows[h + (h / 2)]);
1076 #else
1077    unsigned int y;
1078
1079    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
1080    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
1081    glBindTexture(GL_TEXTURE_2D, tex->pt->texture);
1082    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
1083    _tex_2d(tex->pt->intformat, w, h, tex->pt->format, tex->pt->dataformat);
1084    if ((rows[1] - rows[0]) == (int)w)
1085      _tex_sub_2d(0, 0, w, h, tex->pt->format, tex->pt->dataformat, rows[0]);
1086    else
1087      {
1088         for (y = 0; y < h; y++)
1089           _tex_sub_2d(0, y, w, 1, tex->pt->format, tex->pt->dataformat, rows[y]);
1090      }
1091
1092    glBindTexture(GL_TEXTURE_2D, tex->ptu->texture);
1093    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
1094    _tex_2d(tex->ptu->intformat, w / 2, h / 2, tex->ptu->format, tex->ptu->dataformat);
1095    if ((rows[h + 1] - rows[h]) == (int)(w / 2))
1096      _tex_sub_2d(0, 0, w / 2, h / 2, tex->ptu->format, tex->ptu->dataformat, rows[h]);
1097    else
1098      {
1099         for (y = 0; y < (h / 2); y++)
1100           _tex_sub_2d(0, y, w / 2, 1, tex->ptu->format, tex->ptu->dataformat, rows[h + y]);
1101      }
1102
1103    glBindTexture(GL_TEXTURE_2D, tex->ptv->texture);
1104    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
1105    _tex_2d(tex->ptv->intformat, w / 2, h / 2, tex->ptv->format, tex->ptv->dataformat);
1106    if ((rows[h + (h / 2) + 1] - rows[h + (h / 2)]) == (int)(w / 2))
1107      _tex_sub_2d(0, 0, w / 2, h / 2, tex->ptv->format, tex->ptv->dataformat, rows[h + (h / 2)]);
1108    else
1109      {
1110         for (y = 0; y < (h / 2); y++)
1111           _tex_sub_2d(0, y, w / 2, 1, tex->ptv->format, tex->ptv->dataformat, rows[h + (h / 2) + y]);
1112      }
1113 #endif
1114    if (tex->pt->texture != tex->gc->pipe[0].shader.cur_tex)
1115      {
1116         glBindTexture(GL_TEXTURE_2D, tex->gc->pipe[0].shader.cur_tex);
1117         GLERR(__FUNCTION__, __FILE__, __LINE__, "");
1118      }
1119 }
1120
1121 static Evas_GL_Texture *
1122 _evas_gl_common_texture_y2uv_new(Evas_Engine_GL_Context *gc,
1123                                  unsigned int yw, unsigned int yh,
1124                                  unsigned int uvw, unsigned int uvh,
1125                                  GLenum y_ifmt, GLenum y_fmt,
1126                                  GLenum uv_ifmt, GLenum uv_fmt,
1127                                  Eina_Bool dynamic)
1128 {
1129    Evas_GL_Texture_Pool *pt[2] = { NULL, NULL };
1130    Evas_GL_Texture_Pool *ptuv[2] = { NULL, NULL };
1131    Evas_GL_Texture *tex;
1132
1133    if (!dynamic)
1134      {
1135        pt[0] = _pool_tex_new(gc, yw + 1, yh  + 1, y_ifmt, y_fmt);
1136        pt[1] = _pool_tex_new(gc, yw + 1, yh  + 1, y_ifmt, y_fmt);
1137
1138        ptuv[0] = _pool_tex_new(gc, uvw + 1, uvh  + 1, uv_ifmt, uv_fmt);
1139        ptuv[1] = _pool_tex_new(gc, uvw + 1, uvh  + 1, uv_ifmt, uv_fmt);
1140      }
1141    else
1142      {
1143        pt[0] = _pool_tex_dynamic_new(gc, yw + 1, yh  + 1, y_ifmt, y_fmt);
1144        pt[1] = _pool_tex_dynamic_new(gc, yw + 1, yh  + 1, y_ifmt, y_fmt);
1145
1146        ptuv[0] = _pool_tex_dynamic_new(gc, uvw + 1, uvh  + 1, uv_ifmt, uv_fmt);
1147        ptuv[1] = _pool_tex_dynamic_new(gc, uvw + 1, uvh  + 1, uv_ifmt, uv_fmt);
1148      }
1149
1150    if (!pt[0] || !pt[1] || !ptuv[0] || !ptuv[1])
1151      goto on_error;
1152
1153    tex = calloc(1, sizeof(Evas_GL_Texture));
1154    if (!tex)
1155      goto on_error;
1156
1157    tex->gc = gc;
1158    tex->references = 1;
1159    tex->pt = pt[0];
1160    tex->ptuv = ptuv[0];
1161    tex->dyn = dynamic;
1162
1163    pt_link(gc, tex, pt[0]);
1164    pt_link(gc, tex, pt[1]);
1165    pt_link(gc, tex, ptuv[0]);
1166    pt_link(gc, tex, ptuv[1]);
1167
1168    tex->x = 0;
1169    tex->y = 0;
1170    tex->w = yw;
1171    tex->h = yh;
1172    tex->double_buffer.source = 0;
1173    memcpy(tex->double_buffer.pt, pt, sizeof (Evas_GL_Texture_Pool *) * 2);
1174    memcpy(tex->double_buffer.ptuv, ptuv, sizeof (Evas_GL_Texture_Pool *) * 2);
1175
1176    return tex;
1177
1178  on_error:
1179    pt_unref(pt[0]);
1180    pt_unref(pt[1]);
1181    pt_unref(ptuv[0]);
1182    pt_unref(ptuv[1]);
1183    return NULL;
1184 }
1185
1186 Evas_GL_Texture *
1187 evas_gl_common_texture_yuy2_new(Evas_Engine_GL_Context *gc, DATA8 **rows, unsigned int w, unsigned int h)
1188 {
1189    Evas_GL_Texture *tex;
1190
1191    tex = _evas_gl_common_texture_y2uv_new(gc, w, h, w / 2, h, lum_alpha_ifmt, lum_alpha_fmt, rgba8_ifmt, rgba8_fmt, 0);
1192    evas_gl_common_texture_yuy2_update(tex, rows, w, h);
1193    return tex;
1194 }
1195
1196 Evas_GL_Texture *
1197 evas_gl_common_texture_nv12_new(Evas_Engine_GL_Context *gc, DATA8 **rows, unsigned int w, unsigned int h)
1198 {
1199    Evas_GL_Texture *tex;
1200
1201 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
1202    tex = _evas_gl_common_texture_y2uv_new(gc, w, h, w / 2, h / 2, lum_ifmt, lum_fmt, lum_alpha_ifmt, lum_alpha_fmt, 1);
1203    if (!tex)
1204 #endif
1205      tex = _evas_gl_common_texture_y2uv_new(gc, w, h, w / 2, h / 2, lum_ifmt, lum_fmt, lum_alpha_ifmt, lum_alpha_fmt, 0);
1206
1207    evas_gl_common_texture_nv12_update(tex, rows, w, h);
1208    return tex;
1209 }
1210
1211 Evas_GL_Texture *
1212 evas_gl_common_texture_nv12tiled_new(Evas_Engine_GL_Context *gc, DATA8 **rows, unsigned int w, unsigned int h)
1213 {
1214    Evas_GL_Texture *tex = NULL;
1215
1216 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
1217    tex = _evas_gl_common_texture_y2uv_new(gc, w, h, w, h, lum_ifmt, lum_fmt, lum_alpha_ifmt, lum_alpha_fmt, 1);
1218    if (!tex)
1219 #endif
1220      tex = _evas_gl_common_texture_y2uv_new(gc, w, h, w, h, lum_ifmt, lum_fmt, lum_alpha_ifmt, lum_alpha_fmt, 0);
1221
1222    evas_gl_common_texture_nv12tiled_update(tex, rows, w, h);
1223    return tex;
1224 }
1225
1226 void
1227 evas_gl_common_texture_yuy2_update(Evas_GL_Texture *tex, DATA8 **rows, unsigned int w, unsigned int h)
1228 {
1229    if (!tex->pt) return;
1230    // FIXME: works on lowest size 4 pixel high buffers. must also be multiple of 2
1231    unsigned int y;
1232
1233    tex->double_buffer.source = 1 - tex->double_buffer.source;
1234    tex->pt = tex->double_buffer.pt[tex->double_buffer.source];
1235    tex->ptuv = tex->double_buffer.ptuv[tex->double_buffer.source];
1236
1237    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
1238    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
1239    glBindTexture(GL_TEXTURE_2D, tex->pt->texture);
1240    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
1241    _tex_2d(tex->pt->intformat, w, h, tex->pt->format, tex->pt->dataformat);
1242    if ((rows[1] - rows[0]) == (int)w * 4)
1243      _tex_sub_2d(0, 0, w, h, tex->pt->format, tex->pt->dataformat, rows[0]);
1244    else
1245      {
1246         for (y = 0; y < h; y++)
1247           _tex_sub_2d(0, y, w, 1, tex->pt->format, tex->pt->dataformat, rows[y]);
1248      }
1249
1250    glBindTexture(GL_TEXTURE_2D, tex->ptuv->texture);
1251    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
1252    _tex_2d(tex->ptuv->intformat, w / 2, h, tex->ptuv->format, tex->ptuv->dataformat);
1253    if ((rows[1] - rows[0]) == (int)(w * 2))
1254      _tex_sub_2d(0, 0, w / 2, h, tex->ptuv->format, tex->ptuv->dataformat, rows[0]);
1255    else
1256      {
1257         for (y = 0; y < h; y++)
1258           _tex_sub_2d(0, y, w / 2, 1, tex->ptuv->format, tex->ptuv->dataformat, rows[y]);
1259      }
1260
1261    if (tex->pt->texture != tex->gc->pipe[0].shader.cur_tex)
1262      {
1263         glBindTexture(GL_TEXTURE_2D, tex->gc->pipe[0].shader.cur_tex);
1264         GLERR(__FUNCTION__, __FILE__, __LINE__, "");
1265      }
1266 }
1267
1268 void
1269 evas_gl_common_texture_nv12_update(Evas_GL_Texture *tex, DATA8 **rows, unsigned int w, unsigned int h)
1270 {
1271    if (!tex->pt) return;
1272
1273    tex->double_buffer.source = 1 - tex->double_buffer.source;
1274    tex->pt = tex->double_buffer.pt[tex->double_buffer.source];
1275    tex->ptuv = tex->double_buffer.ptuv[tex->double_buffer.source];
1276
1277    // FIXME: works on lowest size 4 pixel high buffers. must also be multiple of 2
1278 #ifdef GL_UNPACK_ROW_LENGTH
1279    glPixelStorei(GL_UNPACK_ROW_LENGTH, rows[1] - rows[0]);
1280    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
1281    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
1282    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
1283    glBindTexture(GL_TEXTURE_2D, tex->pt->texture);
1284    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
1285    _tex_2d(tex->pt->intformat, w, h, tex->pt->format, tex->pt->dataformat);
1286    _tex_sub_2d(0, 0, w, h, tex->pt->format, tex->pt->dataformat, rows[0]);
1287    glBindTexture(GL_TEXTURE_2D, tex->ptuv->texture);
1288    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
1289    glPixelStorei(GL_UNPACK_ROW_LENGTH, rows[h + 1] - rows[h]);
1290    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
1291    _tex_2d(tex->ptuv->intformat, w / 2, h / 2, tex->ptuv->format, tex->ptuv->dataformat);
1292    _tex_sub_2d(0, 0, w / 2, h / 2, tex->ptuv->format, tex->ptuv->dataformat, rows[h]);
1293 #else
1294    unsigned int y;
1295
1296    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
1297    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
1298    glBindTexture(GL_TEXTURE_2D, tex->pt->texture);
1299    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
1300    _tex_2d(tex->pt->intformat, w, h, tex->pt->format, tex->pt->dataformat);
1301    if ((rows[1] - rows[0]) == (int)w)
1302      _tex_sub_2d(0, 0, w, h, tex->pt->format, tex->pt->dataformat, rows[0]);
1303    else
1304      {
1305         for (y = 0; y < h; y++)
1306           _tex_sub_2d(0, y, w, 1, tex->pt->format, tex->pt->dataformat, rows[y]);
1307      }
1308
1309    glBindTexture(GL_TEXTURE_2D, tex->ptuv->texture);
1310    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
1311    _tex_2d(tex->ptuv->intformat, w / 2, h / 2, tex->ptuv->format, tex->ptuv->dataformat);
1312    if ((rows[h + 1] - rows[h]) == (int)(w / 2))
1313      _tex_sub_2d(0, 0, w / 2, h / 2, tex->ptuv->format, tex->ptuv->dataformat, rows[h]);
1314    else
1315      {
1316         for (y = 0; y < (h / 2); y++)
1317           _tex_sub_2d(0, y, w / 2, 1, tex->ptuv->format, tex->ptuv->dataformat, rows[h + y]);
1318      }
1319 #endif
1320    if (tex->pt->texture != tex->gc->pipe[0].shader.cur_tex)
1321      {
1322         glBindTexture(GL_TEXTURE_2D, tex->gc->pipe[0].shader.cur_tex);
1323         GLERR(__FUNCTION__, __FILE__, __LINE__, "");
1324      }
1325 }
1326
1327 void
1328 evas_gl_common_texture_nv12tiled_update(Evas_GL_Texture *tex, DATA8 **rows, unsigned int w, unsigned int h)
1329 {
1330    unsigned int mb_x, mb_y, mb_w, mb_h;
1331    unsigned int base_h;
1332
1333    if (!tex->pt) return;
1334
1335    tex->double_buffer.source = 1 - tex->double_buffer.source;
1336    tex->pt = tex->double_buffer.pt[tex->double_buffer.source];
1337    tex->ptuv = tex->double_buffer.ptuv[tex->double_buffer.source];
1338
1339    mb_w = w / 64 + (w % 64 ? 1 : 0);
1340    mb_h = h / 32 + (h % 32 ? 1 : 0);
1341
1342 #if ( defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX) )
1343    if (tex->dyn)
1344      {
1345         char *texture_addr;
1346         char *tmp;
1347
1348         texture_addr = secsym_eglMapImageSEC(tex->gc->egldisp, tex->pt->dyn.img);
1349
1350         /* Iterate each Y macroblock like we do in evas_convert_yuv.c */
1351         for (mb_y = 0; mb_y < (mb_h >> 1); mb_y++)
1352           {
1353              int step = 2;
1354              int offset = 0;
1355              int x = 0;
1356              int rmb_x = 0;
1357              int ry[2];
1358
1359              ry[0] = mb_y * 2 * 32 * tex->pt->dyn.stride;
1360              ry[1] = ry[0] + 32 * tex->pt->dyn.stride;
1361
1362              for (mb_x = 0; mb_x < mb_w * 2; mb_x++, rmb_x += 64 * 32)
1363                {
1364                   unsigned int i;
1365
1366                   tmp = texture_addr + x + ry[offset];
1367
1368                   for (i = 0; i < 32 * 64; i += 64, tmp += tex->pt->dyn.stride)
1369                     memcpy(tmp, rows[mb_y] + rmb_x + i, 64);
1370
1371                   step++;
1372                   if ((step & 0x3) == 0)
1373                     {
1374                        offset = 1 - offset;
1375                        x -= 64;
1376                     }
1377                   else
1378                     {
1379                        x += 64;
1380                     }
1381                }
1382           }
1383
1384         if (mb_h & 0x1)
1385           {
1386              int rmb_x = 0;
1387              int x = 0;
1388              int ry;
1389
1390              ry = mb_y * 2 * 32 * tex->pt->dyn.stride;
1391
1392              for (mb_x = 0; mb_x < mb_w; mb_x++, x += 64, rmb_x += 64 * 32)
1393                {
1394                   unsigned int i;
1395
1396                   tmp = texture_addr + x + ry;
1397
1398                   for (i = 0; i < 32 * 64; i += 64, tmp += tex->pt->dyn.stride)
1399                     memcpy(tmp, rows[mb_y] + rmb_x + i, 64);
1400                }
1401           }
1402
1403         secsym_eglUnmapImageSEC(tex->gc->egldisp, tex->pt->dyn.img);
1404
1405         texture_addr = secsym_eglMapImageSEC(tex->gc->egldisp, tex->ptuv->dyn.img);
1406
1407         /* Iterate each UV macroblock like we do in evas_convert_yuv.c */
1408         base_h = (mb_h >> 1) + (mb_h & 0x1);
1409
1410         /* h is always a multiple of 32 */
1411         mb_h = h / 2;
1412         mb_h = (mb_h / 32 + (mb_h % 32 ? 1 : 0));
1413
1414         mb_w = w / 2;
1415         mb_w = (mb_w / 32 + (mb_w % 32 ? 1 : 0));
1416
1417         for (mb_y = 0; mb_y < (mb_h >> 1); mb_y++)
1418           {
1419              int step = 2;
1420              int offset = 0;
1421              int x = 0;
1422              int rmb_x = 0;
1423              int ry[2];
1424
1425              ry[0] = mb_y * 2 * 32 * tex->ptuv->dyn.stride;
1426              ry[1] = ry[0] + 32 * tex->ptuv->dyn.stride;
1427
1428              for (mb_x = 0; mb_x < mb_w * 4; mb_x++, rmb_x += 64 * 32)
1429                {
1430                   unsigned int i = 0;
1431
1432                   tmp = texture_addr + x + ry[offset];
1433
1434                   for (i = 0; i < 32 * 64; i += 64, tmp += tex->ptuv->dyn.stride)
1435                     memcpy(tmp, rows[mb_y + base_h] + rmb_x + i, 64);
1436
1437                   step++;
1438                   if ((step & 0x3) == 0)
1439                     {
1440                        offset = 1 - offset;
1441                        x -= 64;
1442                     }
1443                   else
1444                     {
1445                        x += 64;
1446                     }
1447                }
1448           }
1449
1450         if (mb_h & 0x1)
1451           {
1452              int rmb_x = 0;
1453              int x = 0;
1454              int ry;
1455
1456              ry = mb_y * 2 * 32 * tex->ptuv->dyn.stride;
1457
1458              for (mb_x = 0; mb_x < mb_w * 2; mb_x++, x += 64, rmb_x += 64 * 32)
1459                {
1460                   unsigned int i;
1461
1462                   tmp = texture_addr + x + ry;
1463
1464                   /* It has horizontaly half the pixels, but they are double the size*/
1465                   for (i = 0; i < 32 * 64; i += 64, tmp += tex->ptuv->dyn.stride)
1466                     memcpy(tmp, rows[mb_y + base_h] + rmb_x + i, 64);
1467                }
1468           }
1469
1470         secsym_eglUnmapImageSEC(tex->gc->egldisp, tex->ptuv->dyn.img);
1471         return ;
1472      }
1473 #endif
1474
1475    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
1476    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
1477
1478    glBindTexture(GL_TEXTURE_2D, tex->pt->texture);
1479    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
1480
1481    // We are telling the driver to not swizzle back the buffer as we are going to replace all pixel
1482    _tex_2d(tex->pt->intformat, w, h, tex->pt->format, tex->pt->dataformat);
1483
1484    /* Iterate each Y macroblock like we do in evas_convert_yuv.c */
1485    for (mb_y = 0; mb_y < (mb_h >> 1); mb_y++)
1486      {
1487         int step = 2;
1488         int offset = 0;
1489         int x = 0;
1490         int rmb_x = 0;
1491         int ry[2];
1492
1493         ry[0] = mb_y * 2 * 32;
1494         ry[1] = ry[0] + 32;
1495
1496         for (mb_x = 0; mb_x < mb_w * 2; mb_x++, rmb_x += 64 * 32)
1497           {
1498              _tex_sub_2d(x, ry[offset], 64, 32, tex->pt->format, tex->pt->dataformat, rows[mb_y] + rmb_x);
1499
1500              step++;
1501              if ((step & 0x3) == 0)
1502                {
1503                   offset = 1 - offset;
1504                   x -= 64;
1505                }
1506              else
1507                {
1508                   x += 64;
1509                }
1510           }
1511      }
1512
1513    if (mb_h & 0x1)
1514      {
1515         int rmb_x = 0;
1516         int x = 0;
1517         int ry;
1518
1519         ry = mb_y * 2 * 32;
1520
1521         for (mb_x = 0; mb_x < mb_w; mb_x++, x += 64, rmb_x += 64 * 32)
1522           _tex_sub_2d(x, ry, 64, 32, tex->pt->format, tex->pt->dataformat, rows[mb_y] + rmb_x);
1523      }
1524
1525    glBindTexture(GL_TEXTURE_2D, tex->ptuv->texture);
1526    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
1527
1528    _tex_2d(tex->ptuv->intformat, w, h, tex->ptuv->format, tex->ptuv->dataformat);
1529
1530    /* Iterate each UV macroblock like we do in evas_convert_yuv.c */
1531    base_h = (mb_h >> 1) + (mb_h & 0x1);
1532
1533    /* h is always a multiple of 32 */
1534    mb_h = h / 2;
1535    mb_h = (mb_h / 32 + (mb_h % 32 ? 1 : 0));
1536
1537    mb_w = w / 2;
1538    mb_w = (mb_w / 32 + (mb_w % 32 ? 1 : 0));
1539
1540    for (mb_y = 0; mb_y < (mb_h >> 1); mb_y++)
1541      {
1542         int step = 2;
1543         int offset = 0;
1544         int x = 0;
1545         int rmb_x = 0;
1546         int ry[2];
1547
1548         ry[0] = mb_y * 2 * 32;
1549         ry[1] = ry[0] + 32;
1550
1551         for (mb_x = 0; mb_x < mb_w * 2; mb_x++, rmb_x += 64 * 32)
1552           {
1553              _tex_sub_2d(x, ry[offset], 32, 32,
1554                          tex->ptuv->format, tex->ptuv->dataformat,
1555                          rows[mb_y + base_h] + rmb_x);
1556              step++;
1557              if ((step & 0x3) == 0)
1558                {
1559                   offset = 1 - offset;
1560                   x -= 32;
1561                }
1562              else
1563                {
1564                   x += 32;
1565                }
1566           }
1567      }
1568
1569    if (mb_h & 0x1)
1570      {
1571         int rmb_x = 0;
1572         int x = 0;
1573         int ry;
1574
1575         ry = mb_y * 2 * 32;
1576
1577         for (mb_x = 0; mb_x < mb_w; mb_x++, x += 32, rmb_x += 64 * 32)
1578           _tex_sub_2d(x, ry, 64, 32, tex->ptuv->format, tex->ptuv->dataformat, rows[mb_y + base_h] + rmb_x);
1579      }
1580 }