diff options
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.c | 1669 |
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 | |||
3 | static const GLenum rgba_fmt = GL_RGBA; | ||
4 | static const GLenum rgba_ifmt = GL_RGBA; | ||
5 | //#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX) | ||
6 | //static const GLenum rgb_fmt = GL_RGBA; | ||
7 | //static const GLenum rgb_ifmt = GL_RGBA; | ||
8 | //#else | ||
9 | static const GLenum rgb_fmt = GL_RGBA; | ||
10 | static const GLenum rgb_ifmt = GL_RGB; | ||
11 | //#endif | ||
12 | #ifdef GL_BGRA | ||
13 | # if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX) | ||
14 | static const GLenum bgra_fmt = GL_BGRA; | ||
15 | static const GLenum bgra_ifmt = GL_BGRA; | ||
16 | static const GLenum bgr_fmt = GL_BGRA; | ||
17 | static const GLenum bgr_ifmt = GL_BGRA; | ||
18 | # else | ||
19 | static const GLenum bgra_fmt = GL_BGRA; | ||
20 | static const GLenum bgra_ifmt = GL_RGBA; | ||
21 | static const GLenum bgr_fmt = GL_BGRA; | ||
22 | static const GLenum bgr_ifmt = GL_RGB; | ||
23 | # endif | ||
24 | #endif | ||
25 | static const GLenum alpha_fmt = GL_ALPHA; | ||
26 | static const GLenum alpha_ifmt = GL_ALPHA; | ||
27 | static const GLenum lum_fmt = GL_LUMINANCE; | ||
28 | static const GLenum lum_ifmt = GL_LUMINANCE; | ||
29 | static const GLenum lum_alpha_fmt = GL_LUMINANCE_ALPHA; | ||
30 | static const GLenum lum_alpha_ifmt = GL_LUMINANCE_ALPHA; | ||
31 | static const GLenum rgba8_ifmt = GL_RGBA; | ||
32 | static const GLenum rgba8_fmt = GL_BGRA; | ||
33 | |||
34 | static struct { | ||
35 | struct { | ||
36 | int num, pix; | ||
37 | } c, a, v, r, n, d; | ||
38 | } texinfo = {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}; | ||
39 | |||
40 | static void | ||
41 | _print_tex_count(void) | ||
42 | { | ||
43 | if (getenv("EVAS_GL_MEMINFO")) | ||
44 | { | ||
45 | fprintf(stderr, | ||
46 | "T: c:%i/%ik | a:%i/%ik | v:%i/%ik | r:%i/%ik | n:%i/%ik | d:%i/%ik\n", | ||
47 | texinfo.c.num, (texinfo.c.pix * 4) / 1024, | ||
48 | texinfo.a.num, (texinfo.a.pix ) / 1024, | ||
49 | texinfo.v.num, (texinfo.v.pix ) / 1024, | ||
50 | texinfo.r.num, (texinfo.r.pix * 4) / 1024, | ||
51 | texinfo.n.num, (texinfo.n.pix * 4) / 1024, | ||
52 | texinfo.d.num, (texinfo.d.pix * 4) / 1024 | ||
53 | ); | ||
54 | } | ||
55 | } | ||
56 | |||
57 | static int | ||
58 | _nearest_pow2(int num) | ||
59 | { | ||
60 | unsigned int n = num - 1; | ||
61 | n |= n >> 1; | ||
62 | n |= n >> 2; | ||
63 | n |= n >> 4; | ||
64 | n |= n >> 8; | ||
65 | n |= n >> 16; | ||
66 | return n + 1; | ||
67 | } | ||
68 | |||
69 | static void | ||
70 | _tex_adjust(Evas_Engine_GL_Context *gc, int *w, int *h) | ||
71 | { | ||
72 | if (gc->shared->info.tex_npo2) return; | ||
73 | /*if (gc->shared->info.tex_rect) return;*/ | ||
74 | *w = _nearest_pow2(*w); | ||
75 | *h = _nearest_pow2(*h); | ||
76 | } | ||
77 | |||
78 | static int | ||
79 | _tex_round_slot(Evas_Engine_GL_Context *gc, int h) | ||
80 | { | ||
81 | if (!gc->shared->info.tex_npo2) | ||
82 | h = _nearest_pow2(h); | ||
83 | return (h + gc->shared->info.tune.atlas.slot_size - 1) / | ||
84 | gc->shared->info.tune.atlas.slot_size; | ||
85 | } | ||
86 | |||
87 | static int | ||
88 | _tex_format_index(GLuint format) | ||
89 | { | ||
90 | switch (format) | ||
91 | { | ||
92 | case GL_RGBA: | ||
93 | #ifdef GL_BGRA | ||
94 | case GL_BGRA: | ||
95 | #endif | ||
96 | return 0; | ||
97 | case GL_RGB: | ||
98 | return 1; | ||
99 | case GL_ALPHA: | ||
100 | return 2; | ||
101 | case GL_LUMINANCE: // never used in atlas | ||
102 | return 3; | ||
103 | default: | ||
104 | return 0; | ||
105 | } | ||
106 | return 0; | ||
107 | } | ||
108 | |||
109 | static void | ||
110 | _tex_2d(int intfmt, int w, int h, int fmt, int type) | ||
111 | { | ||
112 | #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 | |||
129 | static 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 | |||
136 | static 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 | |||
189 | static 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 | |||
234 | static 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 | |||
283 | Evas_GL_Texture * | ||
284 | evas_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 | |||
350 | static 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 | |||
415 | static 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 | |||
476 | static 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) | ||
597 | error: | ||
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 | |||
610 | void | ||
611 | evas_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 | |||
680 | static void | ||
681 | pt_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 | |||
701 | static void | ||
702 | pt_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 | |||
712 | Evas_GL_Texture * | ||
713 | evas_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 | |||
750 | Evas_GL_Texture * | ||
751 | evas_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 | |||
788 | Evas_GL_Texture * | ||
789 | evas_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 | |||
826 | void | ||
827 | evas_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 | |||
955 | void | ||
956 | evas_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 | |||
994 | Evas_GL_Texture * | ||
995 | evas_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 | |||
1029 | void | ||
1030 | evas_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 | |||
1051 | Evas_GL_Texture * | ||
1052 | evas_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 | |||
1107 | void | ||
1108 | evas_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 | |||
1178 | static 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 | |||
1269 | Evas_GL_Texture * | ||
1270 | evas_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 | |||
1279 | Evas_GL_Texture * | ||
1280 | evas_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 | |||
1294 | Evas_GL_Texture * | ||
1295 | evas_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 | |||
1309 | void | ||
1310 | evas_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 | |||
1357 | void | ||
1358 | evas_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 | |||
1416 | void | ||
1417 | evas_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 | } | ||