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