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