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