/src/gpac/src/utils/gltools.c
Line | Count | Source |
1 | | /* |
2 | | * GPAC - Multimedia Framework C SDK |
3 | | * |
4 | | * Authors: Jean Le Feuvre |
5 | | * Copyright (c) Telecom ParisTech 2000-2022 |
6 | | * All rights reserved |
7 | | * |
8 | | * This file is part of GPAC / OpenGL tools used by compositor filter, vout filter and WebGL bindings |
9 | | * |
10 | | * GPAC is free software; you can redistribute it and/or modify |
11 | | * it under the terms of the GNU Lesser General Public License as published by |
12 | | * the Free Software Foundation; either version 2, or (at your option) |
13 | | * any later version. |
14 | | * |
15 | | * GPAC is distributed in the hope that it will be useful, |
16 | | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
17 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
18 | | * GNU Lesser General Public License for more details. |
19 | | * |
20 | | * You should have received a copy of the GNU Lesser General Public |
21 | | * License along with this library; see the file COPYING. If not, write to |
22 | | * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. |
23 | | * |
24 | | */ |
25 | | |
26 | | #include <gpac/tools.h> |
27 | | #include <gpac/filters.h> |
28 | | |
29 | | #ifndef GPAC_DISABLE_3D |
30 | | |
31 | | #include "../compositor/gl_inc.h" |
32 | | |
33 | | #if (defined(WIN32) || defined(_WIN32_WCE)) && !defined(__GNUC__) |
34 | | # if defined(GPAC_USE_TINYGL) |
35 | | # pragma comment(lib, "TinyGL") |
36 | | |
37 | | # elif defined(GPAC_USE_GLES1X) |
38 | | |
39 | | # if 0 |
40 | | # pragma message("Using OpenGL-ES Common Lite Profile") |
41 | | # pragma comment(lib, "libGLES_CL") |
42 | | # define GL_ES_CL_PROFILE |
43 | | # else |
44 | | # pragma message("Using OpenGL-ES Common Profile") |
45 | | # pragma comment(lib, "libGLES_CM") |
46 | | # endif |
47 | | |
48 | | # elif defined(GPAC_USE_GLES2) |
49 | | # pragma comment(lib, "libGLESv2") |
50 | | |
51 | | # else |
52 | | # pragma comment(lib, "opengl32") |
53 | | # endif |
54 | | |
55 | | #ifdef GPAC_HAS_GLU |
56 | | # pragma comment(lib, "glu32") |
57 | | #endif |
58 | | |
59 | | #endif |
60 | | |
61 | | /*!! HORRIBLE HACK, but on my test devices, it seems that glClipPlanex is missing on the device but not in the SDK lib !!*/ |
62 | | #if defined(GL_MAX_CLIP_PLANES) && defined(__SYMBIAN32__) |
63 | | #undef GL_MAX_CLIP_PLANES |
64 | | #endif |
65 | | |
66 | | |
67 | | #ifdef LOAD_GL_1_3 |
68 | | |
69 | | GLDECL_FUNC(glActiveTexture); |
70 | | GLDECL_FUNC(glClientActiveTexture); |
71 | | GLDECL_FUNC(glBlendEquation); |
72 | | |
73 | | #endif //LOAD_GL_1_3 |
74 | | |
75 | | #ifdef LOAD_GL_1_4 |
76 | | |
77 | | GLDECL_FUNC(glPointParameterf); |
78 | | GLDECL_FUNC(glPointParameterfv); |
79 | | |
80 | | #endif //LOAD_GL_1_4 |
81 | | |
82 | | |
83 | | #ifdef LOAD_GL_1_5 |
84 | | GLDECL_FUNC(glGenBuffers); |
85 | | GLDECL_FUNC(glDeleteBuffers); |
86 | | GLDECL_FUNC(glBindBuffer); |
87 | | GLDECL_FUNC(glBufferData); |
88 | | GLDECL_FUNC(glBufferSubData); |
89 | | GLDECL_FUNC(glMapBuffer); |
90 | | GLDECL_FUNC(glUnmapBuffer); |
91 | | #endif //LOAD_GL_1_5 |
92 | | |
93 | | #ifdef LOAD_GL_2_0 |
94 | | |
95 | | GLDECL_FUNC(glCreateProgram); |
96 | | GLDECL_FUNC(glDeleteProgram); |
97 | | GLDECL_FUNC(glLinkProgram); |
98 | | GLDECL_FUNC(glUseProgram); |
99 | | GLDECL_FUNC(glCreateShader); |
100 | | GLDECL_FUNC(glDeleteShader); |
101 | | GLDECL_FUNC(glShaderSource); |
102 | | GLDECL_FUNC(glCompileShader); |
103 | | GLDECL_FUNC(glAttachShader); |
104 | | GLDECL_FUNC(glDetachShader); |
105 | | GLDECL_FUNC(glGetShaderiv); |
106 | | GLDECL_FUNC(glGetInfoLogARB); |
107 | | GLDECL_FUNC(glGetUniformLocation); |
108 | | GLDECL_FUNC(glGetUniformfv); |
109 | | GLDECL_FUNC(glGetUniformiv); |
110 | | GLDECL_FUNC(glUniform1f); |
111 | | GLDECL_FUNC(glUniform2f); |
112 | | GLDECL_FUNC(glUniform3f); |
113 | | GLDECL_FUNC(glUniform4f); |
114 | | GLDECL_FUNC(glUniform1i); |
115 | | GLDECL_FUNC(glUniform2i); |
116 | | GLDECL_FUNC(glUniform3i); |
117 | | GLDECL_FUNC(glUniform4i); |
118 | | GLDECL_FUNC(glUniform1fv); |
119 | | GLDECL_FUNC(glUniform2fv); |
120 | | GLDECL_FUNC(glUniform3fv); |
121 | | GLDECL_FUNC(glUniform4fv); |
122 | | GLDECL_FUNC(glUniform1iv); |
123 | | GLDECL_FUNC(glUniform2iv); |
124 | | GLDECL_FUNC(glUniform3iv); |
125 | | GLDECL_FUNC(glUniform4iv); |
126 | | GLDECL_FUNC(glUniformMatrix2fv); |
127 | | GLDECL_FUNC(glUniformMatrix3fv); |
128 | | GLDECL_FUNC(glUniformMatrix4fv); |
129 | | GLDECL_FUNC(glUniformMatrix2x3fv); |
130 | | GLDECL_FUNC(glUniformMatrix3x2fv); |
131 | | GLDECL_FUNC(glUniformMatrix2x4fv); |
132 | | GLDECL_FUNC(glUniformMatrix4x2fv); |
133 | | GLDECL_FUNC(glUniformMatrix3x4fv); |
134 | | GLDECL_FUNC(glUniformMatrix4x3fv); |
135 | | GLDECL_FUNC(glGetProgramiv); |
136 | | GLDECL_FUNC(glGetProgramInfoLog); |
137 | | GLDECL_FUNC(glGetAttribLocation); |
138 | | GLDECL_FUNC(glBindFramebuffer); |
139 | | GLDECL_FUNC(glFramebufferTexture2D); |
140 | | GLDECL_FUNC(glGenFramebuffers); |
141 | | GLDECL_FUNC(glGenRenderbuffers); |
142 | | GLDECL_FUNC(glBindRenderbuffer); |
143 | | GLDECL_FUNC(glRenderbufferStorage); |
144 | | GLDECL_FUNC(glFramebufferRenderbuffer); |
145 | | GLDECL_FUNC(glDeleteFramebuffers); |
146 | | GLDECL_FUNC(glDeleteRenderbuffers); |
147 | | GLDECL_FUNC(glCheckFramebufferStatus); |
148 | | |
149 | | GLDECL_FUNC(glBlendColor); |
150 | | GLDECL_FUNC(glBlendEquationSeparate); |
151 | | GLDECL_FUNC(glBlendFuncSeparate); |
152 | | GLDECL_FUNC(glCompressedTexImage2D); |
153 | | GLDECL_FUNC(glCompressedTexSubImage2D); |
154 | | GLDECL_FUNC(glGenerateMipmap); |
155 | | GLDECL_FUNC(glGetShaderInfoLog); |
156 | | GLDECL_FUNC(glGetShaderSource); |
157 | | GLDECL_FUNC(glGetActiveAttrib); |
158 | | GLDECL_FUNC(glGetActiveUniform); |
159 | | GLDECL_FUNC(glGetAttachedShaders); |
160 | | GLDECL_FUNC(glBindAttribLocation); |
161 | | GLDECL_FUNC(glIsBuffer); |
162 | | GLDECL_FUNC(glIsFramebuffer); |
163 | | GLDECL_FUNC(glIsProgram); |
164 | | GLDECL_FUNC(glIsRenderbuffer); |
165 | | GLDECL_FUNC(glIsShader); |
166 | | GLDECL_FUNC(glSampleCoverage); |
167 | | GLDECL_FUNC(glStencilFuncSeparate); |
168 | | GLDECL_FUNC(glStencilOpSeparate); |
169 | | GLDECL_FUNC(glStencilMaskSeparate); |
170 | | GLDECL_FUNC(glValidateProgram); |
171 | | GLDECL_FUNC(glVertexAttrib1fv); |
172 | | GLDECL_FUNC(glVertexAttrib1f); |
173 | | GLDECL_FUNC(glVertexAttrib2f); |
174 | | GLDECL_FUNC(glVertexAttrib2fv); |
175 | | GLDECL_FUNC(glVertexAttrib3f); |
176 | | GLDECL_FUNC(glVertexAttrib3fv); |
177 | | GLDECL_FUNC(glVertexAttrib4f); |
178 | | GLDECL_FUNC(glVertexAttrib4fv); |
179 | | GLDECL_FUNC(glGetBufferParameteriv); |
180 | | GLDECL_FUNC(glGetFramebufferAttachmentParameteriv); |
181 | | GLDECL_FUNC(glGetVertexAttribiv); |
182 | | GLDECL_FUNC(glGetVertexAttribfv); |
183 | | GLDECL_FUNC(glGetVertexAttribPointerv); |
184 | | GLDECL_FUNC(glGetRenderbufferParameteriv); |
185 | | |
186 | | #ifndef GPAC_CONFIG_ANDROID |
187 | | GLDECL_FUNC(glEnableVertexAttribArray); |
188 | | GLDECL_FUNC(glDisableVertexAttribArray); |
189 | | GLDECL_FUNC(glVertexAttribPointer); |
190 | | GLDECL_FUNC(glVertexAttribIPointer); |
191 | | #endif |
192 | | |
193 | | #endif //LOAD_GL_2_0 |
194 | | |
195 | | static Bool gl_fun_loaded = GF_FALSE; |
196 | | void gf_opengl_init() |
197 | | { |
198 | | if (gl_fun_loaded) return; |
199 | | gl_fun_loaded = GF_TRUE; |
200 | | |
201 | | |
202 | | #ifndef GPAC_USE_TINYGL |
203 | | |
204 | | #ifdef LOAD_GL_1_3 |
205 | | GET_GLFUN(glActiveTexture); |
206 | | GET_GLFUN(glClientActiveTexture); |
207 | | GET_GLFUN(glBlendEquation); |
208 | | #endif |
209 | | |
210 | | #ifdef LOAD_GL_1_4 |
211 | | GET_GLFUN(glPointParameterf); |
212 | | GET_GLFUN(glPointParameterfv); |
213 | | #endif |
214 | | |
215 | | #ifdef LOAD_GL_1_5 |
216 | | GET_GLFUN(glGenBuffers); |
217 | | GET_GLFUN(glDeleteBuffers); |
218 | | GET_GLFUN(glBindBuffer); |
219 | | GET_GLFUN(glBufferData); |
220 | | GET_GLFUN(glBufferSubData); |
221 | | |
222 | | GET_GLFUN(glMapBuffer); |
223 | | GET_GLFUN(glUnmapBuffer); |
224 | | #endif |
225 | | |
226 | | |
227 | | #ifdef LOAD_GL_2_0 |
228 | | GET_GLFUN(glCreateProgram); |
229 | | |
230 | | GET_GLFUN(glDeleteProgram); |
231 | | GET_GLFUN(glLinkProgram); |
232 | | GET_GLFUN(glUseProgram); |
233 | | GET_GLFUN(glCreateShader); |
234 | | GET_GLFUN(glDeleteShader); |
235 | | GET_GLFUN(glShaderSource); |
236 | | GET_GLFUN(glCompileShader); |
237 | | GET_GLFUN(glAttachShader); |
238 | | GET_GLFUN(glDetachShader); |
239 | | GET_GLFUN(glGetShaderiv); |
240 | | GET_GLFUN(glGetInfoLogARB); |
241 | | GET_GLFUN(glGetUniformLocation); |
242 | | GET_GLFUN(glGetUniformfv); |
243 | | GET_GLFUN(glGetUniformiv); |
244 | | GET_GLFUN(glUniform1f); |
245 | | GET_GLFUN(glUniform2f); |
246 | | GET_GLFUN(glUniform3f); |
247 | | GET_GLFUN(glUniform4f); |
248 | | GET_GLFUN(glUniform1i); |
249 | | GET_GLFUN(glUniform2i); |
250 | | GET_GLFUN(glUniform3i); |
251 | | GET_GLFUN(glUniform4i); |
252 | | GET_GLFUN(glUniform1fv); |
253 | | GET_GLFUN(glUniform2fv); |
254 | | GET_GLFUN(glUniform3fv); |
255 | | GET_GLFUN(glUniform4fv); |
256 | | GET_GLFUN(glUniform1iv); |
257 | | GET_GLFUN(glUniform2iv); |
258 | | GET_GLFUN(glUniform3iv); |
259 | | GET_GLFUN(glUniform4iv); |
260 | | GET_GLFUN(glUniformMatrix2fv); |
261 | | GET_GLFUN(glUniformMatrix3fv); |
262 | | GET_GLFUN(glUniformMatrix4fv); |
263 | | GET_GLFUN(glUniformMatrix2x3fv); |
264 | | GET_GLFUN(glUniformMatrix3x2fv); |
265 | | GET_GLFUN(glUniformMatrix2x4fv); |
266 | | GET_GLFUN(glUniformMatrix4x2fv); |
267 | | GET_GLFUN(glUniformMatrix3x4fv); |
268 | | GET_GLFUN(glUniformMatrix4x3fv); |
269 | | GET_GLFUN(glGetProgramiv); |
270 | | GET_GLFUN(glGetProgramInfoLog); |
271 | | GET_GLFUN(glBlendColor); |
272 | | GET_GLFUN(glBlendEquationSeparate); |
273 | | GET_GLFUN(glBlendFuncSeparate); |
274 | | GET_GLFUN(glCompressedTexImage2D); |
275 | | GET_GLFUN(glCompressedTexSubImage2D); |
276 | | GET_GLFUN(glGenerateMipmap); |
277 | | GET_GLFUN(glGetShaderInfoLog); |
278 | | GET_GLFUN(glGetShaderSource); |
279 | | GET_GLFUN(glGetActiveAttrib); |
280 | | GET_GLFUN(glGetActiveUniform); |
281 | | GET_GLFUN(glGetAttachedShaders); |
282 | | GET_GLFUN(glBindAttribLocation); |
283 | | GET_GLFUN(glIsBuffer); |
284 | | GET_GLFUN(glIsFramebuffer); |
285 | | GET_GLFUN(glIsProgram); |
286 | | GET_GLFUN(glIsRenderbuffer); |
287 | | GET_GLFUN(glIsShader); |
288 | | GET_GLFUN(glSampleCoverage); |
289 | | GET_GLFUN(glStencilFuncSeparate); |
290 | | GET_GLFUN(glStencilOpSeparate); |
291 | | GET_GLFUN(glStencilMaskSeparate); |
292 | | GET_GLFUN(glValidateProgram); |
293 | | GET_GLFUN(glVertexAttrib1fv); |
294 | | GET_GLFUN(glVertexAttrib1f); |
295 | | GET_GLFUN(glVertexAttrib2f); |
296 | | GET_GLFUN(glVertexAttrib2fv); |
297 | | GET_GLFUN(glVertexAttrib3f); |
298 | | GET_GLFUN(glVertexAttrib3fv); |
299 | | GET_GLFUN(glVertexAttrib4f); |
300 | | GET_GLFUN(glVertexAttrib4fv); |
301 | | GET_GLFUN(glGetBufferParameteriv); |
302 | | GET_GLFUN(glGetFramebufferAttachmentParameteriv); |
303 | | GET_GLFUN(glGetVertexAttribiv); |
304 | | GET_GLFUN(glGetVertexAttribfv); |
305 | | GET_GLFUN(glGetVertexAttribPointerv); |
306 | | GET_GLFUN(glGetRenderbufferParameteriv); |
307 | | |
308 | | #ifndef GPAC_CONFIG_ANDROID |
309 | | GET_GLFUN(glEnableVertexAttribArray); |
310 | | GET_GLFUN(glDisableVertexAttribArray); |
311 | | GET_GLFUN(glVertexAttribPointer); |
312 | | GET_GLFUN(glVertexAttribIPointer); |
313 | | GET_GLFUN(glGetAttribLocation); |
314 | | |
315 | | GET_GLFUN(glBindFramebuffer); |
316 | | GET_GLFUN(glFramebufferTexture2D); |
317 | | GET_GLFUN(glGenFramebuffers); |
318 | | GET_GLFUN(glGenRenderbuffers); |
319 | | GET_GLFUN(glBindRenderbuffer); |
320 | | GET_GLFUN(glRenderbufferStorage); |
321 | | GET_GLFUN(glFramebufferRenderbuffer); |
322 | | GET_GLFUN(glDeleteFramebuffers); |
323 | | GET_GLFUN(glDeleteRenderbuffers); |
324 | | GET_GLFUN(glCheckFramebufferStatus); |
325 | | |
326 | | #endif |
327 | | |
328 | | #endif //LOAD_GL_2_0 |
329 | | |
330 | | #endif //GPAC_USE_TINYGL |
331 | | |
332 | | } |
333 | | |
334 | | static char *gl_shader_yuv_matrix = \ |
335 | | "uniform mat4 _gf_%s_mx;\n\ |
336 | | "; |
337 | | |
338 | | |
339 | | #if 0 //old code |
340 | | static char *gl_shader_yuv_coefs = \ |
341 | | "const vec3 offset = vec3(-0.0625, -0.5, -0.5);\n\ |
342 | | const vec3 R_mul = vec3(1.164, 0.000, 1.596);\n\ |
343 | | const vec3 G_mul = vec3(1.164, -0.391, -0.813);\n\ |
344 | | const vec3 B_mul = vec3(1.164, 2.018, 0.000);\n\ |
345 | | "; |
346 | | |
347 | | static char *gl_shader_yuv_coefs_jpeg = \ |
348 | | "const vec3 offset = vec3(0.0, -0.5, -0.5);\n\ |
349 | | const vec3 R_mul = vec3(1, 0.000, 1.40200);\n\ |
350 | | const vec3 G_mul = vec3(1, -0.34414, -0.71414);\n\ |
351 | | const vec3 B_mul = vec3(1, 1.77200, 0.000);\n\ |
352 | | "; |
353 | | #endif |
354 | | |
355 | | static char *gl_shader_vars_yuv = \ |
356 | | "uniform sampler2D _gf_%s_1;\n\ |
357 | | uniform sampler2D _gf_%s_2;\n\ |
358 | | uniform sampler2D _gf_%s_3;\n\ |
359 | | "; |
360 | | |
361 | | #if defined(GPAC_USE_GLES1X) || defined(GPAC_USE_GLES2) |
362 | | static char *gl_shader_fun_yuv_gles10 = \ |
363 | | "vec2 texc;\n\ |
364 | | vec4 yuv, col;\n\ |
365 | | texc = _gpacTexCoord.st;\n\ |
366 | | col = texture2D(_gf_%s_1, texc);\n\ |
367 | | yuv.x = (col.a*65280.0 + col.r*255.0)/1023.0;\n\ |
368 | | col = texture2D(_gf_%s_2, texc);\n\ |
369 | | yuv.y = (col.a*65280.0 + col.r*255.0)/1023.0;\n\ |
370 | | col = texture2D(_gf_%s_3, texc);\n\ |
371 | | yuv.z = (col.a*65280.0 + col.r*255.0)/1023.0;\n\ |
372 | | yuv.w = 1.0;\n\ |
373 | | yuv = _gf_%s_mx * yuv;\n\ |
374 | | yuv.w = 1.0;\n\ |
375 | | return yuv;\n\ |
376 | | "; |
377 | | #endif |
378 | | |
379 | | static char *gl_shader_fun_yuv = \ |
380 | | "vec2 texc;\n\ |
381 | | vec4 yuv;\n\ |
382 | | texc = _gpacTexCoord.st;\n\ |
383 | | yuv.x = texture2D(_gf_%s_1, texc).r;\n\ |
384 | | yuv.y = texture2D(_gf_%s_2, texc).r;\n\ |
385 | | yuv.z = texture2D(_gf_%s_3, texc).r;\n\ |
386 | | yuv.w = 1.0;\n\ |
387 | | yuv = _gf_%s_mx * yuv;\n\ |
388 | | yuv.w = 1.0;\n\ |
389 | | return yuv;\n\ |
390 | | "; |
391 | | |
392 | | |
393 | | static char *gl_shader_fun_yvu = \ |
394 | | "vec2 texc;\n\ |
395 | | vec4 yuv;\n\ |
396 | | texc = _gpacTexCoord.st;\n\ |
397 | | yuv.x = texture2D(_gf_%s_1, texc).r;\n\ |
398 | | yuv.y = texture2D(_gf_%s_3, texc).r;\n\ |
399 | | yuv.z = texture2D(_gf_%s_2, texc).r;\n\ |
400 | | yuv.w = 1.0;\n\ |
401 | | yuv = _gf_%s_mx * yuv;\n\ |
402 | | yuv.w = 1.0;\n\ |
403 | | return yuv;\n\ |
404 | | "; |
405 | | static char *gl_shader_vars_yuva = \ |
406 | | "uniform sampler2D _gf_%s_1;\n\ |
407 | | uniform sampler2D _gf_%s_2;\n\ |
408 | | uniform sampler2D _gf_%s_3;\n\ |
409 | | uniform sampler2D _gf_%s_4;\n\ |
410 | | "; |
411 | | |
412 | | static char *gl_shader_fun_yuva = \ |
413 | | "vec2 texc;\n\ |
414 | | vec4 yuv;\n\ |
415 | | texc = _gpacTexCoord.st;\n\ |
416 | | yuv.x = texture2D(_gf_%s_1, texc).r;\n\ |
417 | | yuv.y = texture2D(_gf_%s_2, texc).r;\n\ |
418 | | yuv.z = texture2D(_gf_%s_3, texc).r;\n\ |
419 | | yuv.w = 1.0;\n\ |
420 | | yuv = _gf_%s_mx * yuv;\n\ |
421 | | yuv.w = texture2D(_gf_%s_4, texc).r;\n\ |
422 | | return yuv;\n\ |
423 | | "; |
424 | | |
425 | | static char *gl_shader_vars_nv12 = \ |
426 | | "uniform sampler2D _gf_%s_1;\n\ |
427 | | uniform sampler2D _gf_%s_2;\n\ |
428 | | "; |
429 | | |
430 | | static char *gl_shader_fun_nv12 = \ |
431 | | "vec2 texc;\n\ |
432 | | vec4 yuv;\n\ |
433 | | texc = _gpacTexCoord.st;\n\ |
434 | | yuv.x = texture2D(_gf_%s_1, texc).r;\n\ |
435 | | yuv.yz = texture2D(_gf_%s_2, texc).ra;\n\ |
436 | | yuv.w = 1.0;\n\ |
437 | | yuv = _gf_%s_mx * yuv;\n\ |
438 | | yuv.w = 1.0;\n\ |
439 | | return yuv;\n\ |
440 | | "; |
441 | | |
442 | | |
443 | | static char *gl_shader_vars_nv21 = \ |
444 | | "uniform sampler2D _gf_%s_1;\n\ |
445 | | uniform sampler2D _gf_%s_2;\n\ |
446 | | "; |
447 | | |
448 | | static char *gl_shader_fun_nv21 = \ |
449 | | "vec2 texc;\n\ |
450 | | vec4 yuv;\n\ |
451 | | texc = _gpacTexCoord.st;\n\ |
452 | | yuv.x = texture2D(_gf_%s_1, texc).r;\n\ |
453 | | yuv.yz = texture2D(_gf_%s_2, texc).ar;\n\ |
454 | | yuv.w = 1.0;\n\ |
455 | | yuv = _gf_%s_mx * yuv;\n\ |
456 | | yuv.w = 1.0;\n\ |
457 | | return yuv;\n\ |
458 | | "; |
459 | | |
460 | | |
461 | | static char *gl_shader_vars_uyvu = \ |
462 | | "uniform sampler2D _gf_%s_1;\ |
463 | | uniform float _gf_%s_width;\ |
464 | | "; |
465 | | |
466 | | static char *gl_shader_fun_uyvy = \ |
467 | | "vec2 texc, t_texc;\ |
468 | | vec4 yuv;\ |
469 | | vec4 uyvy;\ |
470 | | float tex_s;\ |
471 | | texc = _gpacTexCoord.st;\ |
472 | | t_texc = texc * vec2(1, 1);\ |
473 | | uyvy = texture2D(_gf_%s_1, t_texc); \ |
474 | | tex_s = texc.x*_gf_%s_width;\ |
475 | | if (tex_s - (2.0 * floor(tex_s/2.0)) == 1.0) {\ |
476 | | uyvy.g = uyvy.a; \ |
477 | | }\ |
478 | | yuv.r = uyvy.g;\ |
479 | | yuv.g = uyvy.r;\ |
480 | | yuv.b = uyvy.b;\ |
481 | | yuv.w = 1.0;\n\ |
482 | | yuv = _gf_%s_mx * yuv;\n\ |
483 | | yuv.w = 1.0;\n\ |
484 | | return yuv;\n\ |
485 | | "; |
486 | | |
487 | | |
488 | | static char *gl_shader_fun_vyuy = \ |
489 | | "vec2 texc, t_texc;\ |
490 | | vec4 yuv;\ |
491 | | vec4 vyuy;\ |
492 | | float tex_s;\ |
493 | | texc = _gpacTexCoord.st;\ |
494 | | t_texc = texc * vec2(1, 1);\ |
495 | | vyuy = texture2D(_gf_%s_1, t_texc); \ |
496 | | tex_s = texc.x*_gf_%s_width;\ |
497 | | if (tex_s - (2.0 * floor(tex_s/2.0)) == 1.0) {\ |
498 | | vyuy.g = vyuy.a; \ |
499 | | }\ |
500 | | yuv.r = vyuy.g;\ |
501 | | yuv.g = vyuy.b;\ |
502 | | yuv.b = vyuy.r;\ |
503 | | yuv.w = 1.0;\n\ |
504 | | yuv = _gf_%s_mx * yuv;\n\ |
505 | | yuv.w = 1.0;\n\ |
506 | | return yuv;\n\ |
507 | | "; |
508 | | |
509 | | |
510 | | static char *gl_shader_fun_yuyv = \ |
511 | | "vec2 texc, t_texc;\ |
512 | | vec4 yuv;\ |
513 | | vec4 yvyu;\ |
514 | | float tex_s;\ |
515 | | texc = _gpacTexCoord.st;\ |
516 | | t_texc = texc * vec2(1, 1);\ |
517 | | yvyu = texture2D(_gf_%s_1, t_texc); \ |
518 | | tex_s = texc.x*_gf_%s_width;\ |
519 | | if (tex_s - (2.0 * floor(tex_s/2.0)) == 1.0) {\ |
520 | | yvyu.r = yvyu.b; \ |
521 | | }\ |
522 | | yuv.r = yvyu.r;\ |
523 | | yuv.g = yvyu.g;\ |
524 | | yuv.b = yvyu.a;\ |
525 | | yuv.w = 1.0;\n\ |
526 | | yuv = _gf_%s_mx * yuv;\n\ |
527 | | yuv.w = 1.0;\n\ |
528 | | return yuv;\n\ |
529 | | "; |
530 | | |
531 | | static char *gl_shader_fun_yvyu = \ |
532 | | "vec2 texc, t_texc;\ |
533 | | vec4 yuv;\ |
534 | | vec4 yuyv;\ |
535 | | float tex_s;\ |
536 | | texc = _gpacTexCoord.st;\ |
537 | | t_texc = texc * vec2(1, 1);\ |
538 | | yuyv = texture2D(_gf_%s_1, t_texc); \ |
539 | | tex_s = texc.x*_gf_%s_width;\ |
540 | | if (tex_s - (2.0 * floor(tex_s/2.0)) == 1.0) {\ |
541 | | yuyv.r = yuyv.b; \ |
542 | | }\ |
543 | | yuv.r = yuyv.r;\ |
544 | | yuv.g = yuyv.a;\ |
545 | | yuv.b = yuyv.g;\ |
546 | | yuv.w = 1.0;\n\ |
547 | | yuv = _gf_%s_mx * yuv;\n\ |
548 | | yuv.w = 1.0;\n\ |
549 | | return yuv;\n\ |
550 | | "; |
551 | | |
552 | | |
553 | | |
554 | | static char *gl_shader_vars_yuv4_pack = \ |
555 | | "uniform sampler2D _gf_%s_1;\n\ |
556 | | "; |
557 | | |
558 | | static char *gl_shader_fun_yuv4_pack = \ |
559 | | "vec2 texc;\n\ |
560 | | vec4 yuv;\n\ |
561 | | texc = _gpacTexCoord.st;\n\ |
562 | | yuv = texture2D(_gf_%s_1, texc);\n\ |
563 | | yuv.w = 1.0;\n\ |
564 | | yuv = _gf_%s_mx * yuv;\n\ |
565 | | yuv.w = 1.0;\n\ |
566 | | return yuv;\n\ |
567 | | "; |
568 | | |
569 | | static char *gl_shader_fun_vyu4_pack = \ |
570 | | "vec2 texc;\n\ |
571 | | vec4 yuv;\n\ |
572 | | texc = _gpacTexCoord.st;\n\ |
573 | | yuv.rgb = texture2D(_gf_%s_1, texc).gbr;\n\ |
574 | | yuv.w = 1.0;\n\ |
575 | | yuv = _gf_%s_mx * yuv;\n\ |
576 | | yuv.w = 1.0;\n\ |
577 | | return yuv;\n\ |
578 | | "; |
579 | | |
580 | | |
581 | | static char *gl_shader_fun_yuv4a_pack = \ |
582 | | "vec2 texc;\n\ |
583 | | vec4 tex;\n\ |
584 | | vec4 yuv;\n\ |
585 | | texc = _gpacTexCoord.st;\n\ |
586 | | tex = texture2D(_gf_%s_1, texc);\n\ |
587 | | yuv.rgb = tex.rgb;\n\ |
588 | | yuv.w = 1.0;\n\ |
589 | | yuv = _gf_%s_mx * yuv;\n\ |
590 | | yuv.w = tex.a;\n\ |
591 | | return yuv;\n\ |
592 | | "; |
593 | | |
594 | | static char *gl_shader_fun_uyv4a_pack = \ |
595 | | "vec2 texc;\n\ |
596 | | vec4 tex;\n\ |
597 | | vec4 yuv;\n\ |
598 | | texc = _gpacTexCoord.st;\n\ |
599 | | tex = texture2D(_gf_%s_1, texc);\n\ |
600 | | yuv.rgb = tex.grb;\n\ |
601 | | yuv.w = 1.0;\n\ |
602 | | yuv = _gf_%s_mx * yuv;\n\ |
603 | | yuv.w = tex.a;\n\ |
604 | | return yuv;\n\ |
605 | | "; |
606 | | |
607 | | //uploaded as RGBA describing 10 bit V + 10 bit Y + 10 bit U + 2 bits lost, lost bits in R (first byte) |
608 | | //V: 8 bit A + 2 bits B |
609 | | //Y: 6 bit B + 4 bits G |
610 | | //U: 4 bit G + 6 bits R |
611 | | // |
612 | | //we do the maths for bit reading, we should add support for GLES3 shift operators as well (but no support in WebGL1) |
613 | | static char *gl_shader_fun_yuv4_10_pack = \ |
614 | | "vec2 texc;\n\ |
615 | | vec4 val;\n\ |
616 | | int valr, valg, valb, vala, interm1, interm2;\n\ |
617 | | vec4 yuv;\n\ |
618 | | texc = _gpacTexCoord.st;\n\ |
619 | | val = texture2D(_gf_%s_1, texc).rgba;\n\ |
620 | | vala = int(val.a*255.0);\n\ |
621 | | valb = int(val.b*255.0);\n\ |
622 | | valg = int(val.g*255.0);\n\ |
623 | | valr = int(val.r*255.0 / 64.0);\n\ |
624 | | interm1 = valb / 64;\n\ |
625 | | yuv.b = float( (vala * 4) + (interm1) ) / 1023.0;\n\ |
626 | | interm1 *= 64;\n\ |
627 | | interm2 = valg / 16;\n\ |
628 | | yuv.r = float( ((valb - interm1) * 16) + (interm2) ) / 1023.0;\n\ |
629 | | interm2 *= 16;\n\ |
630 | | yuv.g = float( ((valg - interm2) * 64) + valr ) / 1023.0;\n\ |
631 | | yuv.w = 1.0;\n\ |
632 | | yuv = _gf_%s_mx * yuv;\n\ |
633 | | yuv.w = 1.0;\n\ |
634 | | return yuv;\n\ |
635 | | "; |
636 | | |
637 | | |
638 | | static char *gl_shader_vars_v210 = \ |
639 | | "uniform sampler2D _gf_%s_1;\ |
640 | | uniform float _gf_%s_width;\ |
641 | | uniform float _gf_%s_gpu_width;\ |
642 | | "; |
643 | | |
644 | | //uploaded as RGBA describing 2 bits lost (in A, last byte) + 3 * 10 bit {U,Y,V} , pattern repeating 6 times |
645 | | //first pattern (x%6==0) is {00b, Cr, Y, Cb} in {A, B, G, R} bytes |
646 | | //we decompose RGBA pixel x and x+1 as follows |
647 | | //.R: 8 bit R + 2 bits G |
648 | | //.G: 6 bit G + 4 bits B |
649 | | //.B: 4 bit G + 6 bits A |
650 | | // |
651 | | //s coordinate is remapped to line pos x in source width pixels |
652 | | //the GPU sees the texture as a {stride/4, height} texture |
653 | | //so when we fetch from sampler2D we need to convert 6 pixels v210 to 4 pixels RGBA for x |
654 | | //but the next pixel we need is 1/gpu_width after x |
655 | | // |
656 | | //we do the maths for bit reading, we should add support for GLES3 shift operators as well (but no support in WebGL1) |
657 | | static char *gl_shader_fun_v210 = \ |
658 | | "vec2 texc;\n\ |
659 | | vec4 yuv, yuv1, yuv2, val;\n\ |
660 | | int x, off_x, dec_x, valr, valg, valb, vala, interm1, interm2;\n\ |
661 | | float tx_width = _gf_%s_width;\n\ |
662 | | float tx_gpu_width = _gf_%s_gpu_width;\n\ |
663 | | x = int(_gpacTexCoord.s * tx_width);\n\ |
664 | | interm1 = x/6;\n\ |
665 | | off_x = x - (interm1 * 6);\n\ |
666 | | x-=off_x;\n\ |
667 | | if (off_x>=4) dec_x = 2;\n\ |
668 | | else if (off_x>=2) dec_x = 1;\n\ |
669 | | else dec_x = 0;\n\ |
670 | | texc.t = _gpacTexCoord.t;\n\ |
671 | | texc.s = float(x * 4 / 6 + dec_x) / tx_gpu_width;\n\ |
672 | | val = texture2D(_gf_%s_1, texc);\n\ |
673 | | vala = int(val.a*255.0);\n\ |
674 | | valb = int(val.b*255.0);\n\ |
675 | | valg = int(val.g*255.0);\n\ |
676 | | valr = int(val.r*255.0);\n\ |
677 | | vala = vala - ((vala/64) * 64);\n\ |
678 | | interm1 = valg / 4;\n\ |
679 | | yuv1.r = float( valr + (valg - interm1*4)*256 ) / 1023.0;\n\ |
680 | | interm2 = valb / 16;\n\ |
681 | | yuv1.g = float( (valb - interm2*16) * 64 + interm1 ) / 1023.0;\n\ |
682 | | yuv1.b = float( interm2 + vala*16 ) / 1023.0;\n\ |
683 | | if (off_x==0) {\n\ |
684 | | yuv.g = yuv1.r;\n\ |
685 | | yuv.r = yuv1.g;\n\ |
686 | | yuv.b = yuv1.b;\n\ |
687 | | } else {\n\ |
688 | | texc.s = float(x * 4 / 6 + dec_x + 1) / tx_gpu_width;\n\ |
689 | | val = texture2D(_gf_%s_1, texc);\n\ |
690 | | vala = int(val.a*255.0);\n\ |
691 | | valb = int(val.b*255.0);\n\ |
692 | | valg = int(val.g*255.0);\n\ |
693 | | valr = int(val.r*255.0);\n\ |
694 | | vala = vala - ((vala/64) * 64);\n\ |
695 | | interm1 = valg / 4;\n\ |
696 | | yuv2.r = float( valr + (valg - interm1*4)*256 ) / 1023.0;\n\ |
697 | | interm2 = valb / 16;\n\ |
698 | | yuv2.g = float( (valb - interm2*16) * 64 + interm1 ) / 1023.0;\n\ |
699 | | yuv2.b = float( interm2 + vala*16 ) / 1023.0;\n\ |
700 | | if (off_x==1) {\n\ |
701 | | yuv.g = yuv1.r;\n\ |
702 | | yuv.r = yuv2.r;\n\ |
703 | | yuv.b = yuv1.b;\n\ |
704 | | } else if (off_x==2) {\n\ |
705 | | yuv.g = yuv1.g;\n\ |
706 | | yuv.r = yuv1.b;\n\ |
707 | | yuv.b = yuv2.r;\n\ |
708 | | } else if (off_x==3) {\n\ |
709 | | yuv.g = yuv1.g;\n\ |
710 | | yuv.r = yuv2.g;\n\ |
711 | | yuv.b = yuv2.r;\n\ |
712 | | } else if (off_x==4) {\n\ |
713 | | yuv.g = yuv1.b;\n\ |
714 | | yuv.r = yuv2.r;\n\ |
715 | | yuv.b = yuv2.g;\n\ |
716 | | } else {\n\ |
717 | | yuv.g = yuv1.b;\n\ |
718 | | yuv.r = yuv2.b;\n\ |
719 | | yuv.b = yuv2.g;\n\ |
720 | | }\n\ |
721 | | }\n\ |
722 | | yuv.w = 1.0;\n\ |
723 | | yuv = _gf_%s_mx * yuv;\n\ |
724 | | yuv.w = 1.0;\n\ |
725 | | return yuv;\n\ |
726 | | "; |
727 | | |
728 | | |
729 | | |
730 | | static char *gl_shader_vars_rgb = \ |
731 | | "uniform sampler2D _gf_%s_1;\n\ |
732 | | "; |
733 | | |
734 | | static char *gl_shader_fun_alphagrey = \ |
735 | | "vec4 col, ocol;\n\ |
736 | | col = texture2D(_gf_%s_1, _gpacTexCoord.st);\n\ |
737 | | ocol.r = ocol.g = ocol.b = col.a;\n\ |
738 | | ocol.a = col.r;\n\ |
739 | | return ocol;\n\ |
740 | | "; |
741 | | |
742 | | static char *gl_shader_fun_rgb332 = \ |
743 | | "vec4 col, ocol;\n\ |
744 | | float res, col_r, col_g, col_b;\n\ |
745 | | col = texture2D(_gf_%s_1, _gpacTexCoord.st);\n\ |
746 | | res = floor( 255.0 * col.r );\n\ |
747 | | col_r = floor(res / 32.0);\n\ |
748 | | col_g = floor((res - col_r*32.0)/4.0);\n\ |
749 | | col_b = floor(res - col_r*128.0 - col_g*4.0);\n\ |
750 | | ocol.r = col_r / 7.0;\n\ |
751 | | ocol.g = col_g / 7.0;\n\ |
752 | | ocol.b = col_b / 3.0;\n\ |
753 | | ocol.a = 1.0;\n\ |
754 | | return ocol;\ |
755 | | "; |
756 | | |
757 | | static char *gl_shader_fun_rgb444 = \ |
758 | | "vec4 col, ocol;\n\ |
759 | | float res, col_g, col_b;\n\ |
760 | | col = texture2D(_gf_%s_1, _gpacTexCoord.st);\n\ |
761 | | res = floor( 255.0 * col.a );\n\ |
762 | | col_g = floor(res / 16.0);\n\ |
763 | | col_b = floor(res - col_g*16.0);\n\ |
764 | | ocol.r = col.r * 17.0;\n\ |
765 | | ocol.g = col_g / 15.0;\n\ |
766 | | ocol.b = col_b / 15.0;\n\ |
767 | | ocol.a = 1.0;\n\ |
768 | | return ocol;\ |
769 | | "; |
770 | | |
771 | | |
772 | | static char *gl_shader_fun_rgb555 = \ |
773 | | "vec4 col, ocol;\n\ |
774 | | float res, col_r, col_g1, col_g, col_b;\n\ |
775 | | col = texture2D(_gf_%s_1, _gpacTexCoord.st);\n\ |
776 | | res = floor(255.0 * col.r);\n\ |
777 | | col_r = floor(res / 4.0);\n\ |
778 | | col_g1 = floor(res - col_r*4.0);\n\ |
779 | | res = floor(255.0 * col.a);\n\ |
780 | | col_g = floor(res / 32);\n\ |
781 | | col_b = floor(res - col_g*32.0);\n\ |
782 | | col_g += col_g1 * 8;\n\ |
783 | | ocol.r = col_r / 31.0;\n\ |
784 | | ocol.g = col_g / 31.0;\n\ |
785 | | ocol.b = col_b / 31.0;\n\ |
786 | | ocol.a = 1.0;\n\ |
787 | | return ocol;\ |
788 | | "; |
789 | | |
790 | | static char *gl_shader_fun_rgb565 = \ |
791 | | "vec4 col, ocol;\n\ |
792 | | float res, col_r, col_g1, col_g, col_b;\n\ |
793 | | col = texture2D(_gf_%s_1, _gpacTexCoord.st);\n\ |
794 | | res = floor(255.0 * col.r);\n\ |
795 | | col_r = floor(res / 8.0);\n\ |
796 | | col_g1 = floor(res - col_r*8.0);\n\ |
797 | | res = floor(255.0 * col.a);\n\ |
798 | | col_g = floor(res / 32);\n\ |
799 | | col_b = floor(res - col_g*32.0);\n\ |
800 | | col_g += col_g1 * 8;\n\ |
801 | | ocol.r = col_r / 31.0;\n\ |
802 | | ocol.g = col_g / 63.0;\n\ |
803 | | ocol.b = col_b / 31.0;\n\ |
804 | | ocol.a = 1.0;\n\ |
805 | | return ocol;\ |
806 | | "; |
807 | | |
808 | | |
809 | | static char *gl_shader_fun_argb = \ |
810 | | "vec4 col, ocol;\n\ |
811 | | col = texture2D(_gf_%s_1, _gpacTexCoord.st);\n\ |
812 | | ocol.r = col.g;\n\ |
813 | | ocol.g = col.b;\n\ |
814 | | ocol.b = col.a;\n\ |
815 | | ocol.a = col.r;\n\ |
816 | | return ocol;\ |
817 | | "; |
818 | | |
819 | | static char *gl_shader_fun_abgr = \ |
820 | | "vec4 col, ocol;\n\ |
821 | | col = texture2D(_gf_%s_1, _gpacTexCoord.st);\n\ |
822 | | ocol.r = col.a;\n\ |
823 | | ocol.g = col.b;\n\ |
824 | | ocol.b = col.g;\n\ |
825 | | ocol.a = col.r;\n\ |
826 | | return ocol;\ |
827 | | "; |
828 | | |
829 | | |
830 | | static char *gl_shader_fun_bgra = \ |
831 | | "vec4 col, ocol;\n\ |
832 | | col = texture2D(_gf_%s_1, _gpacTexCoord.st);\n\ |
833 | | ocol.r = col.b;\n\ |
834 | | ocol.g = col.g;\n\ |
835 | | ocol.b = col.r;\n\ |
836 | | ocol.a = col.a;\n\ |
837 | | return ocol;\ |
838 | | "; |
839 | | |
840 | | |
841 | | static char *gl_shader_fun_rgb = \ |
842 | | "return texture2D(_gf_%s_1, _gpacTexCoord.st);\ |
843 | | "; |
844 | | |
845 | | static char *gl_shader_vars_externalOES = \ |
846 | | "uniform samplerExternalOES _gf_%s_1;\n\ |
847 | | "; |
848 | | |
849 | | |
850 | | Bool gf_gl_txw_insert_fragment_shader(u32 pix_fmt, const char *tx_name, char **f_source, Bool y_flip) |
851 | | { |
852 | | char szCode[4000]; |
853 | | const char *shader_vars = NULL; |
854 | | const char *shader_fun = NULL; |
855 | | |
856 | | switch (pix_fmt) { |
857 | | case GF_PIXEL_NV21: |
858 | | case GF_PIXEL_NV21_10: |
859 | | shader_vars = gl_shader_vars_nv21; |
860 | | shader_fun = gl_shader_fun_nv21; |
861 | | break; |
862 | | case GF_PIXEL_NV12: |
863 | | case GF_PIXEL_NV12_10: |
864 | | shader_vars = gl_shader_vars_nv12; |
865 | | shader_fun = gl_shader_fun_nv12; |
866 | | break; |
867 | | case GF_PIXEL_UYVY: |
868 | | case GF_PIXEL_UYVY_10: |
869 | | shader_vars = gl_shader_vars_uyvu; |
870 | | shader_fun = gl_shader_fun_uyvy; |
871 | | break; |
872 | | case GF_PIXEL_YUYV: |
873 | | case GF_PIXEL_YUYV_10: |
874 | | shader_vars = gl_shader_vars_uyvu; //same as uyvy |
875 | | shader_fun = gl_shader_fun_yuyv; |
876 | | break; |
877 | | case GF_PIXEL_VYUY: |
878 | | case GF_PIXEL_VYUY_10: |
879 | | shader_vars = gl_shader_vars_uyvu; //same as uyvy |
880 | | shader_fun = gl_shader_fun_vyuy; |
881 | | break; |
882 | | case GF_PIXEL_YVYU: |
883 | | case GF_PIXEL_YVYU_10: |
884 | | shader_vars = gl_shader_vars_uyvu; //same as uyvy |
885 | | shader_fun = gl_shader_fun_yvyu; |
886 | | break; |
887 | | case GF_PIXEL_YUV444_PACK: |
888 | | shader_vars = gl_shader_vars_yuv4_pack; |
889 | | shader_fun = gl_shader_fun_yuv4_pack; |
890 | | break; |
891 | | case GF_PIXEL_VYU444_PACK: |
892 | | shader_vars = gl_shader_vars_yuv4_pack; |
893 | | shader_fun = gl_shader_fun_vyu4_pack; |
894 | | break; |
895 | | case GF_PIXEL_YUVA444_PACK: |
896 | | shader_vars = gl_shader_vars_yuv4_pack; |
897 | | shader_fun = gl_shader_fun_yuv4a_pack; |
898 | | break; |
899 | | case GF_PIXEL_UYVA444_PACK: |
900 | | shader_vars = gl_shader_vars_yuv4_pack; |
901 | | shader_fun = gl_shader_fun_uyv4a_pack; |
902 | | break; |
903 | | case GF_PIXEL_YUV444_10_PACK: |
904 | | shader_vars = gl_shader_vars_yuv4_pack; |
905 | | shader_fun = gl_shader_fun_yuv4_10_pack; |
906 | | break; |
907 | | case GF_PIXEL_V210: |
908 | | shader_vars = gl_shader_vars_v210; |
909 | | shader_fun = gl_shader_fun_v210; |
910 | | break; |
911 | | case GF_PIXEL_ALPHAGREY: |
912 | | shader_vars = gl_shader_vars_rgb; |
913 | | shader_fun = gl_shader_fun_alphagrey; |
914 | | break; |
915 | | case GF_PIXEL_RGB_332: |
916 | | shader_vars = gl_shader_vars_rgb; |
917 | | shader_fun = gl_shader_fun_rgb332; |
918 | | break; |
919 | | case GF_PIXEL_RGB_444: |
920 | | shader_vars = gl_shader_vars_rgb; |
921 | | shader_fun = gl_shader_fun_rgb444; |
922 | | break; |
923 | | case GF_PIXEL_RGB_555: |
924 | | shader_vars = gl_shader_vars_rgb; |
925 | | shader_fun = gl_shader_fun_rgb555; |
926 | | break; |
927 | | case GF_PIXEL_RGB_565: |
928 | | shader_vars = gl_shader_vars_rgb; |
929 | | shader_fun = gl_shader_fun_rgb565; |
930 | | break; |
931 | | case GF_PIXEL_ARGB: |
932 | | case GF_PIXEL_XRGB: |
933 | | shader_vars = gl_shader_vars_rgb; |
934 | | shader_fun = gl_shader_fun_argb; |
935 | | break; |
936 | | case GF_PIXEL_ABGR: |
937 | | case GF_PIXEL_XBGR: |
938 | | shader_vars = gl_shader_vars_rgb; |
939 | | shader_fun = gl_shader_fun_abgr; |
940 | | break; |
941 | | case GF_PIXEL_BGR: |
942 | | case GF_PIXEL_BGRA: |
943 | | case GF_PIXEL_BGRX: |
944 | | shader_vars = gl_shader_vars_rgb; |
945 | | shader_fun = gl_shader_fun_bgra; |
946 | | break; |
947 | | |
948 | | case GF_PIXEL_YUV_10: |
949 | | case GF_PIXEL_YUV422_10: |
950 | | case GF_PIXEL_YUV444_10: |
951 | | #if defined(GPAC_USE_GLES1X) || defined(GPAC_USE_GLES2) |
952 | | shader_vars = gl_shader_vars_yuv; |
953 | | shader_fun = gl_shader_fun_yuv_gles10; |
954 | | break; |
955 | | #endif |
956 | | case GF_PIXEL_YUVD: |
957 | | case GF_PIXEL_YUV422: |
958 | | case GF_PIXEL_YUV444: |
959 | | case GF_PIXEL_YUV: |
960 | | shader_vars = gl_shader_vars_yuv; |
961 | | shader_fun = gl_shader_fun_yuv; |
962 | | break; |
963 | | case GF_PIXEL_YVU: |
964 | | shader_vars = gl_shader_vars_yuv; |
965 | | shader_fun = gl_shader_fun_yvu; |
966 | | break; |
967 | | case GF_PIXEL_YUVA: |
968 | | case GF_PIXEL_YUVA444: |
969 | | shader_vars = gl_shader_vars_yuva; |
970 | | shader_fun = gl_shader_fun_yuva; |
971 | | break; |
972 | | case GF_PIXEL_GL_EXTERNAL: |
973 | | shader_vars = gl_shader_vars_externalOES; |
974 | | shader_fun = gl_shader_fun_rgb; |
975 | | break; |
976 | | default: |
977 | | shader_vars = gl_shader_vars_rgb; |
978 | | shader_fun = gl_shader_fun_rgb; |
979 | | break; |
980 | | } |
981 | | |
982 | | if (!shader_vars || !shader_fun) return GF_FALSE; |
983 | | /*format with max 4 tx_name (for yuva)*/ |
984 | | sprintf(szCode, shader_vars, tx_name, tx_name, tx_name, tx_name); |
985 | | gf_dynstrcat(f_source, szCode, NULL); |
986 | | |
987 | | if (gf_pixel_fmt_is_yuv(pix_fmt)) { |
988 | | // gf_dynstrcat(f_source, gl_shader_yuv_matrix, NULL); |
989 | | |
990 | | sprintf(szCode, gl_shader_yuv_matrix, tx_name); |
991 | | gf_dynstrcat(f_source, szCode, NULL); |
992 | | } |
993 | | |
994 | | gf_dynstrcat(f_source, "\nvec4 ", NULL); |
995 | | gf_dynstrcat(f_source, tx_name, NULL); |
996 | | gf_dynstrcat(f_source, "_sample(vec2 _gpacTexCoord) {\n", NULL); |
997 | | if (y_flip) { |
998 | | gf_dynstrcat(f_source, "_gpacTexCoord.t = 1.0 - _gpacTexCoord.t;\n", NULL); |
999 | | } |
1000 | | /*format with max 4 tx_name (for yuva) + matrix for yuv*/ |
1001 | | sprintf(szCode, shader_fun, tx_name, tx_name, tx_name, tx_name, tx_name); |
1002 | | |
1003 | | gf_dynstrcat(f_source, szCode, NULL); |
1004 | | gf_dynstrcat(f_source, "\n}\n", NULL); |
1005 | | |
1006 | | return GF_TRUE; |
1007 | | } |
1008 | | |
1009 | | |
1010 | | Bool gf_gl_txw_setup(GF_GLTextureWrapper *tx, u32 pix_fmt, u32 width, u32 height, u32 stride, u32 uv_stride, Bool linear_interp, GF_FilterFrameInterface *frame_ifce, Bool full_range, s32 matrix_coef_or_neg) |
1011 | | { |
1012 | | u32 i; |
1013 | | |
1014 | | tx->width = width; |
1015 | | tx->height = height; |
1016 | | tx->pix_fmt = pix_fmt; |
1017 | | tx->stride = stride; |
1018 | | tx->uv_stride = uv_stride; |
1019 | | tx->internal_textures = GF_TRUE; |
1020 | | tx->nb_textures = 1; |
1021 | | tx->is_yuv = GF_FALSE; |
1022 | | tx->bit_depth = 8; |
1023 | | tx->gl_format = GL_LUMINANCE; |
1024 | | tx->bytes_per_pix = 1; |
1025 | | tx->fullrange = full_range; |
1026 | | if (matrix_coef_or_neg==GF_CICP_MX_UNSPECIFIED) |
1027 | | tx->mx_cicp = -1; |
1028 | | else |
1029 | | tx->mx_cicp = matrix_coef_or_neg; |
1030 | | |
1031 | | if (!tx->stride) |
1032 | | gf_pixel_get_size_info(tx->pix_fmt, tx->width, tx->height, NULL, &tx->stride, &tx->uv_stride, NULL, &tx->uv_h); |
1033 | | |
1034 | | switch (tx->pix_fmt) { |
1035 | | case GF_PIXEL_YUV444_10: |
1036 | | tx->bit_depth = 10; |
1037 | | case GF_PIXEL_YUV444: |
1038 | | case GF_PIXEL_YUVA444: |
1039 | | tx->uv_w = tx->width; |
1040 | | tx->uv_h = tx->height; |
1041 | | if (!tx->uv_stride) |
1042 | | tx->uv_stride = tx->stride; |
1043 | | tx->is_yuv = GF_TRUE; |
1044 | | tx->nb_textures = 3; |
1045 | | if (tx->pix_fmt==GF_PIXEL_YUVA444) { |
1046 | | tx->nb_textures = 4; |
1047 | | tx->has_alpha = GF_TRUE; |
1048 | | } |
1049 | | break; |
1050 | | case GF_PIXEL_YUV422_10: |
1051 | | tx->bit_depth = 10; |
1052 | | case GF_PIXEL_YUV422: |
1053 | | tx->uv_w = tx->width/2; |
1054 | | tx->uv_h = tx->height; |
1055 | | if (!tx->uv_stride) |
1056 | | tx->uv_stride = tx->stride/2; |
1057 | | tx->is_yuv = GF_TRUE; |
1058 | | tx->nb_textures = 3; |
1059 | | break; |
1060 | | case GF_PIXEL_YUV_10: |
1061 | | tx->bit_depth = 10; |
1062 | | case GF_PIXEL_YUV: |
1063 | | case GF_PIXEL_YVU: |
1064 | | case GF_PIXEL_YUVA: |
1065 | | tx->uv_w = tx->width/2; |
1066 | | if (tx->width % 2) tx->uv_w++; |
1067 | | tx->uv_h = tx->height/2; |
1068 | | if (tx->height % 2) tx->uv_h++; |
1069 | | if (!tx->uv_stride) { |
1070 | | tx->uv_stride = tx->stride/2; |
1071 | | if (tx->stride%2) tx->uv_stride ++; |
1072 | | } |
1073 | | tx->is_yuv = GF_TRUE; |
1074 | | tx->nb_textures = 3; |
1075 | | if (tx->pix_fmt==GF_PIXEL_YUVA) { |
1076 | | tx->nb_textures = 4; |
1077 | | tx->has_alpha = GF_TRUE; |
1078 | | } |
1079 | | break; |
1080 | | case GF_PIXEL_NV12_10: |
1081 | | case GF_PIXEL_NV21_10: |
1082 | | tx->bit_depth = 10; |
1083 | | case GF_PIXEL_NV12: |
1084 | | case GF_PIXEL_NV21: |
1085 | | tx->uv_w = tx->width/2; |
1086 | | tx->uv_h = tx->height/2; |
1087 | | if (!tx->uv_stride) |
1088 | | tx->uv_stride = tx->stride; |
1089 | | tx->is_yuv = GF_TRUE; |
1090 | | tx->nb_textures = 2; |
1091 | | break; |
1092 | | case GF_PIXEL_UYVY_10: |
1093 | | case GF_PIXEL_YUYV_10: |
1094 | | case GF_PIXEL_YVYU_10: |
1095 | | case GF_PIXEL_VYUY_10: |
1096 | | tx->bit_depth = 16; |
1097 | | case GF_PIXEL_UYVY: |
1098 | | case GF_PIXEL_YUYV: |
1099 | | case GF_PIXEL_YVYU: |
1100 | | case GF_PIXEL_VYUY: |
1101 | | tx->uv_w = tx->width/2; |
1102 | | tx->uv_h = tx->height; |
1103 | | if (!tx->uv_stride) { |
1104 | | tx->uv_stride = tx->stride/2; |
1105 | | if (tx->stride%2) tx->uv_stride ++; |
1106 | | } |
1107 | | tx->is_yuv = GF_TRUE; |
1108 | | tx->nb_textures = 1; |
1109 | | break; |
1110 | | case GF_PIXEL_V210: |
1111 | | tx->is_yuv = GF_TRUE; |
1112 | | tx->nb_textures = 1; |
1113 | | break; |
1114 | | |
1115 | | case GF_PIXEL_YUVA444_PACK: |
1116 | | case GF_PIXEL_UYVA444_PACK: |
1117 | | tx->has_alpha = GF_TRUE; |
1118 | | case GF_PIXEL_YUV444_PACK: |
1119 | | case GF_PIXEL_VYU444_PACK: |
1120 | | case GF_PIXEL_YUV444_10_PACK: |
1121 | | tx->uv_w = tx->width; |
1122 | | tx->uv_h = tx->height; |
1123 | | if (!tx->uv_stride) { |
1124 | | tx->uv_stride = tx->stride; |
1125 | | } |
1126 | | tx->is_yuv = GF_TRUE; |
1127 | | tx->nb_textures = 1; |
1128 | | break; |
1129 | | case GF_PIXEL_GREYSCALE: |
1130 | | tx->gl_format = GL_LUMINANCE; |
1131 | | tx->bytes_per_pix = 1; |
1132 | | break; |
1133 | | case GF_PIXEL_ALPHAGREY: |
1134 | | case GF_PIXEL_GREYALPHA: |
1135 | | tx->gl_format = GL_LUMINANCE_ALPHA; |
1136 | | tx->bytes_per_pix = 2; |
1137 | | break; |
1138 | | case GF_PIXEL_RGB: |
1139 | | tx->gl_format = GL_RGB; |
1140 | | tx->bytes_per_pix = 3; |
1141 | | break; |
1142 | | case GF_PIXEL_BGR: |
1143 | | tx->gl_format = GL_RGB; |
1144 | | tx->bytes_per_pix = 3; |
1145 | | break; |
1146 | | case GF_PIXEL_BGRA: |
1147 | | tx->has_alpha = GF_TRUE; |
1148 | | case GF_PIXEL_BGRX: |
1149 | | tx->gl_format = GL_RGBA; |
1150 | | tx->bytes_per_pix = 4; |
1151 | | break; |
1152 | | case GF_PIXEL_ARGB: |
1153 | | tx->has_alpha = GF_TRUE; |
1154 | | case GF_PIXEL_XRGB: |
1155 | | tx->gl_format = GL_RGBA; |
1156 | | tx->bytes_per_pix = 4; |
1157 | | break; |
1158 | | case GF_PIXEL_ABGR: |
1159 | | tx->has_alpha = GF_TRUE; |
1160 | | case GF_PIXEL_XBGR: |
1161 | | tx->gl_format = GL_RGBA; |
1162 | | tx->bytes_per_pix = 4; |
1163 | | break; |
1164 | | case GF_PIXEL_RGBA: |
1165 | | tx->has_alpha = GF_TRUE; |
1166 | | case GF_PIXEL_RGBX: |
1167 | | tx->gl_format = GL_RGBA; |
1168 | | tx->bytes_per_pix = 4; |
1169 | | break; |
1170 | | case GF_PIXEL_RGB_332: |
1171 | | tx->gl_format = GL_LUMINANCE; |
1172 | | tx->bytes_per_pix = 1; |
1173 | | break; |
1174 | | case GF_PIXEL_RGB_444: |
1175 | | tx->gl_format = GL_LUMINANCE_ALPHA; |
1176 | | tx->bytes_per_pix = 2; |
1177 | | break; |
1178 | | case GF_PIXEL_RGB_555: |
1179 | | tx->gl_format = GL_LUMINANCE_ALPHA; |
1180 | | tx->bytes_per_pix = 2; |
1181 | | break; |
1182 | | case GF_PIXEL_RGB_565: |
1183 | | tx->gl_format = GL_LUMINANCE_ALPHA; |
1184 | | tx->bytes_per_pix = 2; |
1185 | | break; |
1186 | | case GF_PIXEL_GL_EXTERNAL: |
1187 | | tx->internal_textures = GF_FALSE; |
1188 | | break; |
1189 | | default: |
1190 | | GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[Core] Pixel format %s unsupported, cannot setup texture wrapper\n", gf_4cc_to_str(tx->pix_fmt))); |
1191 | | return GF_FALSE; |
1192 | | } |
1193 | | |
1194 | | if (tx->bit_depth>8) |
1195 | | tx->bytes_per_pix = 2; |
1196 | | |
1197 | | if (frame_ifce && frame_ifce->get_gl_texture) { |
1198 | | tx->internal_textures = GF_FALSE; |
1199 | | } |
1200 | | |
1201 | | /*create textures*/ |
1202 | | if (tx->internal_textures) { |
1203 | | #if !defined(GPAC_USE_GLES1X) |
1204 | | u32 glmode = GL_NEAREST; |
1205 | | if ((tx->nb_textures==1) && linear_interp && !tx->is_yuv) |
1206 | | glmode = GL_LINEAR; |
1207 | | #endif |
1208 | | tx->first_tx_load = GF_TRUE; |
1209 | | tx->scale_10bit = 0; |
1210 | | |
1211 | | tx->memory_format = GL_UNSIGNED_BYTE; |
1212 | | if (tx->is_yuv && tx->bit_depth>8) { |
1213 | | #if !defined(GPAC_USE_GLES1X) && !defined(GPAC_USE_GLES2) |
1214 | | //we use x bits but GL will normalise using 16 bits, so we need to multiply the normalized result by 2^(16-x) |
1215 | | u32 nb_bits = (16 - tx->bit_depth); |
1216 | | u32 scale = 1; |
1217 | | while (nb_bits) { |
1218 | | scale*=2; |
1219 | | nb_bits--; |
1220 | | } |
1221 | | tx->scale_10bit = scale; |
1222 | | tx->memory_format = GL_UNSIGNED_SHORT; |
1223 | | #else |
1224 | | |
1225 | | switch (tx->pix_fmt) { |
1226 | | case GF_PIXEL_YUV_10: |
1227 | | case GF_PIXEL_YUV422_10: |
1228 | | case GF_PIXEL_YUV444_10: |
1229 | | tx->gl_format = GL_LUMINANCE_ALPHA; |
1230 | | tx->memory_format = GL_UNSIGNED_BYTE; |
1231 | | break; |
1232 | | default: |
1233 | | GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[Core] Pixel format %s unsupported, cannot setup texture wrapper\n", gf_4cc_to_str(tx->pix_fmt))); |
1234 | | return GF_FALSE; |
1235 | | } |
1236 | | #endif |
1237 | | } |
1238 | | |
1239 | | |
1240 | | GL_CHECK_ERR() |
1241 | | glGenTextures(tx->nb_textures, tx->textures); |
1242 | | GL_CHECK_ERR() |
1243 | | |
1244 | | #ifndef GPAC_USE_GLES2 |
1245 | | glEnable(GL_TEXTURE_2D); |
1246 | | GL_CHECK_ERR() |
1247 | | #endif |
1248 | | |
1249 | | for (i=0; i<tx->nb_textures; i++) { |
1250 | | #if !defined(GPAC_USE_GLES1X) |
1251 | | glBindTexture(GL_TEXTURE_2D, tx->textures[i] ); |
1252 | | GL_CHECK_ERR() |
1253 | | #if defined(GPAC_USE_GLES2) |
1254 | | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); |
1255 | | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); |
1256 | | #else |
1257 | | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); |
1258 | | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); |
1259 | | #endif |
1260 | | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, glmode); |
1261 | | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, glmode); |
1262 | | #endif |
1263 | | GL_CHECK_ERR() |
1264 | | } |
1265 | | |
1266 | | |
1267 | | #if !defined(GPAC_DISABLE_3D) && !defined(GPAC_USE_TINYGL) && !defined(GPAC_USE_GLES1X) && !defined(GPAC_USE_GLES2) |
1268 | | if (tx->is_yuv && tx->pbo_state) { |
1269 | | tx->first_tx_load = GF_FALSE; |
1270 | | glGenBuffers(1, &tx->PBOs[0]); |
1271 | | glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, tx->PBOs[0]); |
1272 | | |
1273 | | if (tx->nb_textures>1) { |
1274 | | glBufferData(GL_PIXEL_UNPACK_BUFFER_ARB, tx->bytes_per_pix * tx->width*tx->height, NULL, GL_DYNAMIC_DRAW_ARB); |
1275 | | |
1276 | | glGenBuffers(1, &tx->PBOs[1]); |
1277 | | glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, tx->PBOs[1]); |
1278 | | } else { |
1279 | | //packed YUV |
1280 | | glBufferData(GL_PIXEL_UNPACK_BUFFER_ARB, tx->bytes_per_pix * 4*tx->width/2*tx->height, NULL, GL_DYNAMIC_DRAW_ARB); |
1281 | | } |
1282 | | |
1283 | | if (tx->nb_textures==3) { |
1284 | | glBufferData(GL_PIXEL_UNPACK_BUFFER_ARB, tx->bytes_per_pix * tx->uv_w*tx->uv_h, NULL, GL_DYNAMIC_DRAW_ARB); |
1285 | | |
1286 | | glGenBuffers(1, &tx->PBOs[2]); |
1287 | | glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, tx->PBOs[2]); |
1288 | | glBufferData(GL_PIXEL_UNPACK_BUFFER_ARB, tx->bytes_per_pix * tx->uv_w*tx->uv_h, NULL, GL_DYNAMIC_DRAW_ARB); |
1289 | | } |
1290 | | //nv12/21 |
1291 | | else { |
1292 | | glBufferData(GL_PIXEL_UNPACK_BUFFER_ARB, tx->bytes_per_pix * 2*tx->uv_w*tx->uv_h, NULL, GL_DYNAMIC_DRAW_ARB); |
1293 | | } |
1294 | | glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, 0); |
1295 | | } |
1296 | | #endif |
1297 | | |
1298 | | #ifndef GPAC_USE_GLES2 |
1299 | | glDisable(GL_TEXTURE_2D); |
1300 | | GL_CHECK_ERR() |
1301 | | #endif |
1302 | | } |
1303 | | return GF_TRUE; |
1304 | | } |
1305 | | |
1306 | | Bool gf_gl_txw_upload(GF_GLTextureWrapper *tx, const u8 *data, GF_FilterFrameInterface *frame_ifce) |
1307 | | { |
1308 | | Bool use_stride = GF_FALSE; |
1309 | | u32 stride_luma, stride_chroma; |
1310 | | const u8 *pY=NULL, *pU=NULL, *pV=NULL, *pA=NULL; |
1311 | | |
1312 | | |
1313 | | tx->frame_ifce = NULL; |
1314 | | |
1315 | | if (!frame_ifce && !data) return GF_FALSE; |
1316 | | |
1317 | | if (!tx->internal_textures) { |
1318 | | if (frame_ifce && frame_ifce->get_gl_texture) { |
1319 | | tx->frame_ifce = frame_ifce; |
1320 | | return GF_TRUE; |
1321 | | } |
1322 | | return GF_FALSE; |
1323 | | } |
1324 | | |
1325 | | stride_luma = tx->stride; |
1326 | | stride_chroma = tx->uv_stride; |
1327 | | if (!frame_ifce) { |
1328 | | if (tx->is_yuv) { |
1329 | | if (tx->nb_textures==2) { |
1330 | | if (tx->has_alpha) { |
1331 | | pA = data + tx->stride * tx->height; |
1332 | | } else { |
1333 | | pU = data + tx->stride * tx->height; |
1334 | | } |
1335 | | } else if (tx->nb_textures>=3) { |
1336 | | pU = data + tx->stride * tx->height; |
1337 | | pV = pU + tx->uv_stride * tx->uv_h; |
1338 | | if (tx->nb_textures==4) { |
1339 | | pA = pV + tx->uv_stride * tx->uv_h; |
1340 | | } |
1341 | | } |
1342 | | } |
1343 | | } else { |
1344 | | u32 st_o; |
1345 | | if (!frame_ifce->get_plane) |
1346 | | return GF_FALSE; |
1347 | | if (tx->nb_textures) |
1348 | | frame_ifce->get_plane(frame_ifce, 0, &data, &stride_luma); |
1349 | | if (tx->nb_textures>1) |
1350 | | frame_ifce->get_plane(frame_ifce, 1, &pU, &stride_chroma); |
1351 | | //todo we need to cleanup alpha frame fetch, how do we differentiate between NV12+alpha (3 planes) and YUV420 ? |
1352 | | if (tx->nb_textures>2) |
1353 | | frame_ifce->get_plane(frame_ifce, 2, &pV, &st_o); |
1354 | | if (tx->nb_textures>3) |
1355 | | frame_ifce->get_plane(frame_ifce, 3, &pA, &st_o); |
1356 | | } |
1357 | | |
1358 | | pY = data; |
1359 | | |
1360 | | if (tx->is_yuv && (stride_luma != tx->width)) { |
1361 | | use_stride = GF_TRUE; //whether >8bits or real stride |
1362 | | } |
1363 | | GL_CHECK_ERR() |
1364 | | |
1365 | | //push data |
1366 | | #ifndef GPAC_USE_GLES2 |
1367 | | glEnable(GL_TEXTURE_2D); |
1368 | | GL_CHECK_ERR() |
1369 | | #endif |
1370 | | |
1371 | | |
1372 | | if (tx->scale_10bit) { |
1373 | | #if !defined(GPAC_USE_GLES1X) && !defined(GPAC_USE_GLES2) |
1374 | | glPixelTransferi(GL_RED_SCALE, tx->scale_10bit); |
1375 | | if (tx->nb_textures==2) |
1376 | | glPixelTransferi(GL_ALPHA_SCALE, tx->scale_10bit); |
1377 | | |
1378 | | glPixelStorei(GL_UNPACK_ALIGNMENT, 2); |
1379 | | #endif |
1380 | | } else { |
1381 | | #if !defined(GPAC_USE_GLES1X) && !defined(GPAC_USE_GLES2) |
1382 | | glPixelTransferi(GL_RED_SCALE, 1); |
1383 | | glPixelTransferi(GL_ALPHA_SCALE, 1); |
1384 | | glPixelStorei(GL_UNPACK_LSB_FIRST, 0); |
1385 | | #endif |
1386 | | glPixelStorei(GL_UNPACK_ALIGNMENT, 1); |
1387 | | } |
1388 | | GL_CHECK_ERR() |
1389 | | |
1390 | | |
1391 | | if (!tx->is_yuv) { |
1392 | | glBindTexture(GL_TEXTURE_2D, tx->textures[0] ); |
1393 | | GL_CHECK_ERR() |
1394 | | if (use_stride) { |
1395 | | #if !defined(GPAC_GL_NO_STRIDE) |
1396 | | glPixelStorei(GL_UNPACK_ROW_LENGTH, tx->stride / tx->bytes_per_pix); |
1397 | | #endif |
1398 | | } |
1399 | | if (tx->first_tx_load) { |
1400 | | glTexImage2D(GL_TEXTURE_2D, 0, tx->gl_format, tx->width, tx->height, 0, tx->gl_format, GL_UNSIGNED_BYTE, data); |
1401 | | tx->first_tx_load = GF_FALSE; |
1402 | | } else { |
1403 | | glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, tx->width, tx->height, tx->gl_format, tx->memory_format, data); |
1404 | | } |
1405 | | #if !defined(GPAC_GL_NO_STRIDE) |
1406 | | if (use_stride) glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); |
1407 | | #endif |
1408 | | |
1409 | | GL_CHECK_ERR() |
1410 | | } |
1411 | | #if !defined(GPAC_USE_GLES1X) && !defined(GPAC_USE_GLES2) |
1412 | | else if (tx->pbo_state && tx->PBOs[0]) { |
1413 | | u32 i, linesize, count, p_stride; |
1414 | | u8 *ptr; |
1415 | | |
1416 | | //packed YUV |
1417 | | if (tx->nb_textures==1) { |
1418 | | if (tx->pbo_state!=GF_GL_PBO_TEXIMG) { |
1419 | | glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); |
1420 | | |
1421 | | glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, tx->PBOs[0]); |
1422 | | ptr =(u8 *)glMapBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, GL_WRITE_ONLY_ARB); |
1423 | | |
1424 | | switch (tx->pix_fmt) { |
1425 | | case GF_PIXEL_YUV444_PACK: |
1426 | | case GF_PIXEL_VYU444_PACK: |
1427 | | linesize = 3 * tx->width; |
1428 | | break; |
1429 | | case GF_PIXEL_YUVA444_PACK: |
1430 | | case GF_PIXEL_UYVA444_PACK: |
1431 | | linesize = 4 * tx->width; |
1432 | | break; |
1433 | | case GF_PIXEL_YUV444_10_PACK: |
1434 | | linesize = 4 * tx->width; |
1435 | | break; |
1436 | | case GF_PIXEL_V210: |
1437 | | linesize = tx->width * 16 / 6; |
1438 | | break; |
1439 | | default: |
1440 | | linesize = tx->width/2 * tx->bytes_per_pix * 4; |
1441 | | } |
1442 | | |
1443 | | p_stride = stride_luma; |
1444 | | count = tx->height; |
1445 | | |
1446 | | for (i=0; i<count; i++) { |
1447 | | memcpy(ptr, pY, linesize); |
1448 | | pY += p_stride; |
1449 | | ptr += linesize; |
1450 | | } |
1451 | | |
1452 | | glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER_ARB); |
1453 | | } |
1454 | | if (tx->pbo_state!=GF_GL_PBO_PUSH) { |
1455 | | glBindTexture(GL_TEXTURE_2D, tx->textures[0] ); |
1456 | | glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, tx->PBOs[0]); |
1457 | | |
1458 | | if ((tx->pix_fmt==GF_PIXEL_YUV444_PACK) || (tx->pix_fmt==GF_PIXEL_VYU444_PACK)) |
1459 | | glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, tx->width, tx->height, 0, GL_RGB, tx->memory_format, NULL); |
1460 | | else if ((tx->pix_fmt==GF_PIXEL_YUVA444_PACK) || (tx->pix_fmt==GF_PIXEL_UYVA444_PACK)) |
1461 | | glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tx->width, tx->height, 0, GL_RGBA, tx->memory_format, NULL); |
1462 | | else if (tx->pix_fmt==GF_PIXEL_YUV444_10_PACK) |
1463 | | glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tx->width, tx->height, 0, GL_RGBA, tx->memory_format, NULL); |
1464 | | else if (tx->pix_fmt==GF_PIXEL_V210) |
1465 | | glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tx->width, tx->height, 0, GL_RGBA, tx->memory_format, NULL); |
1466 | | else |
1467 | | glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tx->width/2, tx->height, 0, GL_RGBA, tx->memory_format, NULL); |
1468 | | glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, 0); |
1469 | | } |
1470 | | } else { |
1471 | | if (tx->pbo_state!=GF_GL_PBO_TEXIMG) { |
1472 | | glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); |
1473 | | |
1474 | | glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, tx->PBOs[0]); |
1475 | | ptr =(u8 *)glMapBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, GL_WRITE_ONLY_ARB); |
1476 | | |
1477 | | linesize = tx->width*tx->bytes_per_pix; |
1478 | | p_stride = stride_luma; |
1479 | | count = tx->height; |
1480 | | |
1481 | | for (i=0; i<count; i++) { |
1482 | | memcpy(ptr, pY, linesize); |
1483 | | pY += p_stride; |
1484 | | ptr += linesize; |
1485 | | } |
1486 | | |
1487 | | glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER_ARB); |
1488 | | |
1489 | | if (pU) { |
1490 | | glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, tx->PBOs[1]); |
1491 | | ptr =(u8 *)glMapBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, GL_WRITE_ONLY_ARB); |
1492 | | |
1493 | | linesize = tx->uv_w * tx->bytes_per_pix; |
1494 | | p_stride = stride_chroma; |
1495 | | count = tx->uv_h; |
1496 | | //NV12 and NV21 |
1497 | | if (!pV) { |
1498 | | linesize *= 2; |
1499 | | } |
1500 | | |
1501 | | for (i=0; i<count; i++) { |
1502 | | memcpy(ptr, pU, linesize); |
1503 | | pU += p_stride; |
1504 | | ptr += linesize; |
1505 | | } |
1506 | | |
1507 | | glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER_ARB); |
1508 | | } |
1509 | | |
1510 | | |
1511 | | if (pV) { |
1512 | | glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, tx->PBOs[2]); |
1513 | | ptr =(u8 *)glMapBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, GL_WRITE_ONLY_ARB); |
1514 | | |
1515 | | for (i=0; i<count; i++) { |
1516 | | memcpy(ptr, pV, linesize); |
1517 | | pV += p_stride; |
1518 | | ptr += linesize; |
1519 | | } |
1520 | | |
1521 | | glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER_ARB); |
1522 | | } |
1523 | | } |
1524 | | |
1525 | | if (tx->pbo_state!=GF_GL_PBO_PUSH) { |
1526 | | glBindTexture(GL_TEXTURE_2D, tx->textures[0] ); |
1527 | | glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, tx->PBOs[0]); |
1528 | | glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, tx->width, tx->height, 0, tx->gl_format, tx->memory_format, NULL); |
1529 | | |
1530 | | glBindTexture(GL_TEXTURE_2D, tx->textures[1] ); |
1531 | | glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, tx->PBOs[1]); |
1532 | | glTexImage2D(GL_TEXTURE_2D, 0, pV ? GL_LUMINANCE : GL_LUMINANCE_ALPHA, tx->uv_w, tx->uv_h, 0, pV ? GL_LUMINANCE : GL_LUMINANCE_ALPHA, tx->memory_format, NULL); |
1533 | | |
1534 | | if (pV) { |
1535 | | glBindTexture(GL_TEXTURE_2D, tx->textures[2] ); |
1536 | | glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, tx->PBOs[2]); |
1537 | | glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, tx->uv_w, tx->uv_h, 0, tx->gl_format, tx->memory_format, NULL); |
1538 | | } |
1539 | | |
1540 | | glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, 0); |
1541 | | } |
1542 | | } |
1543 | | } |
1544 | | #endif |
1545 | | else if ((tx->nb_textures==1) || ((tx->nb_textures==2) && tx->has_alpha)) { |
1546 | | #if !defined(GPAC_GL_NO_STRIDE) |
1547 | | u32 uv_stride = 0; |
1548 | | #endif |
1549 | | glBindTexture(GL_TEXTURE_2D, tx->textures[0] ); |
1550 | | |
1551 | | use_stride = GF_FALSE; |
1552 | | if ((tx->pix_fmt==GF_PIXEL_YUV444_PACK) |
1553 | | || (tx->pix_fmt==GF_PIXEL_VYU444_PACK) |
1554 | | || (tx->pix_fmt==GF_PIXEL_YUVA444_PACK) |
1555 | | || (tx->pix_fmt==GF_PIXEL_UYVA444_PACK) |
1556 | | || (tx->pix_fmt==GF_PIXEL_YUV444_10_PACK) |
1557 | | || (tx->pix_fmt==GF_PIXEL_V210) |
1558 | | ) { |
1559 | | u32 tx_width = tx->width; |
1560 | | u32 nb_bytes = 3; |
1561 | | GLuint fmt = GL_RGB; |
1562 | | switch (tx->pix_fmt) { |
1563 | | case GF_PIXEL_YUV444_PACK: |
1564 | | case GF_PIXEL_VYU444_PACK: |
1565 | | break; |
1566 | | default: |
1567 | | nb_bytes = 4; |
1568 | | fmt = GL_RGBA; |
1569 | | } |
1570 | | if (tx->pix_fmt==GF_PIXEL_V210) { |
1571 | | //inverse stride to get number of pixels - this is less than out actual width, we'll undo while repacking |
1572 | | tx_width = tx->stride / 4; |
1573 | | use_stride = GF_FALSE; |
1574 | | } |
1575 | | else if (stride_luma > nb_bytes*tx->width) { |
1576 | | use_stride = GF_TRUE; |
1577 | | } |
1578 | | |
1579 | | #if !defined(GPAC_GL_NO_STRIDE) |
1580 | | if (use_stride) glPixelStorei(GL_UNPACK_ROW_LENGTH, stride_luma/tx->bytes_per_pix); |
1581 | | #endif |
1582 | | if (tx->first_tx_load) { |
1583 | | glTexImage2D(GL_TEXTURE_2D, 0, fmt, tx_width, tx->height, 0, fmt, tx->memory_format, pY); |
1584 | | tx->first_tx_load = GF_FALSE; |
1585 | | } else { |
1586 | | glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, tx_width, tx->height, fmt, tx->memory_format, pY); |
1587 | | } |
1588 | | |
1589 | | } else { |
1590 | | u32 scaler = tx->scale_10bit ? 4 : 2; |
1591 | | if (stride_luma > scaler*tx->width) { |
1592 | | //stride is given in bytes for packed formats, so divide by 2 to get the number of pixels |
1593 | | //for YUYV, and we upload as a texture with half the wsize so redivide again by two |
1594 | | //since GL_UNPACK_ROW_LENGTH counts in component and we moved the set 2 bytes per comp on 10 bits |
1595 | | //no need to further divide |
1596 | | #if !defined(GPAC_GL_NO_STRIDE) |
1597 | | uv_stride = stride_luma/scaler/2; |
1598 | | #endif |
1599 | | use_stride = GF_TRUE; |
1600 | | } |
1601 | | #if !defined(GPAC_GL_NO_STRIDE) |
1602 | | if (use_stride) glPixelStorei(GL_UNPACK_ROW_LENGTH, uv_stride); |
1603 | | #endif |
1604 | | if (tx->first_tx_load) { |
1605 | | glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tx->width/2, tx->height, 0, GL_RGBA, tx->memory_format, pY); |
1606 | | tx->first_tx_load = GF_FALSE; |
1607 | | } else { |
1608 | | glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, tx->width/2, tx->height, GL_RGBA, tx->memory_format, pY); |
1609 | | } |
1610 | | } |
1611 | | |
1612 | | #if !defined(GPAC_GL_NO_STRIDE) |
1613 | | if (use_stride) glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); |
1614 | | #endif |
1615 | | |
1616 | | } |
1617 | | else if (tx->first_tx_load) { |
1618 | | glBindTexture(GL_TEXTURE_2D, tx->textures[0] ); |
1619 | | #if !defined(GPAC_GL_NO_STRIDE) |
1620 | | if (use_stride) glPixelStorei(GL_UNPACK_ROW_LENGTH, stride_luma/tx->bytes_per_pix); |
1621 | | #endif |
1622 | | glTexImage2D(GL_TEXTURE_2D, 0, tx->gl_format, tx->width, tx->height, 0, tx->gl_format, tx->memory_format, pY); |
1623 | | |
1624 | | glBindTexture(GL_TEXTURE_2D, tx->textures[1] ); |
1625 | | #if !defined(GPAC_GL_NO_STRIDE) |
1626 | | if (use_stride) glPixelStorei(GL_UNPACK_ROW_LENGTH, pV ? stride_chroma/tx->bytes_per_pix : stride_chroma/tx->bytes_per_pix/2); |
1627 | | #endif |
1628 | | glTexImage2D(GL_TEXTURE_2D, 0, pV ? tx->gl_format : GL_LUMINANCE_ALPHA, tx->uv_w, tx->uv_h, 0, pV ? tx->gl_format : GL_LUMINANCE_ALPHA, tx->memory_format, pU); |
1629 | | |
1630 | | if (pV) { |
1631 | | glBindTexture(GL_TEXTURE_2D, tx->textures[2] ); |
1632 | | #if !defined(GPAC_GL_NO_STRIDE) |
1633 | | if (use_stride) glPixelStorei(GL_UNPACK_ROW_LENGTH, stride_chroma/tx->bytes_per_pix); |
1634 | | #endif |
1635 | | glTexImage2D(GL_TEXTURE_2D, 0, tx->gl_format, tx->uv_w, tx->uv_h, 0, tx->gl_format, tx->memory_format, pV); |
1636 | | } |
1637 | | |
1638 | | if (pA) { |
1639 | | glBindTexture(GL_TEXTURE_2D, tx->textures[3] ); |
1640 | | #if !defined(GPAC_GL_NO_STRIDE) |
1641 | | if (use_stride) glPixelStorei(GL_UNPACK_ROW_LENGTH, stride_luma/tx->bytes_per_pix); |
1642 | | #endif |
1643 | | glTexImage2D(GL_TEXTURE_2D, 0, tx->gl_format, tx->width, tx->height, 0, tx->gl_format, tx->memory_format, pA); |
1644 | | } |
1645 | | |
1646 | | #if !defined(GPAC_GL_NO_STRIDE) |
1647 | | if (use_stride) glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); |
1648 | | #endif |
1649 | | tx->first_tx_load = GF_FALSE; |
1650 | | } |
1651 | | else { |
1652 | | glBindTexture(GL_TEXTURE_2D, tx->textures[0] ); |
1653 | | #if !defined(GPAC_GL_NO_STRIDE) |
1654 | | if (use_stride) glPixelStorei(GL_UNPACK_ROW_LENGTH, stride_luma/tx->bytes_per_pix); |
1655 | | #endif |
1656 | | glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, tx->width, tx->height, tx->gl_format, tx->memory_format, pY); |
1657 | | glBindTexture(GL_TEXTURE_2D, 0); |
1658 | | |
1659 | | glBindTexture(GL_TEXTURE_2D, tx->textures[1] ); |
1660 | | #if !defined(GPAC_GL_NO_STRIDE) |
1661 | | if (use_stride) glPixelStorei(GL_UNPACK_ROW_LENGTH, pV ? stride_chroma/tx->bytes_per_pix : stride_chroma/tx->bytes_per_pix/2); |
1662 | | #endif |
1663 | | glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, tx->uv_w, tx->uv_h, pV ? tx->gl_format : GL_LUMINANCE_ALPHA, tx->memory_format, pU); |
1664 | | glBindTexture(GL_TEXTURE_2D, 0); |
1665 | | |
1666 | | if (pV) { |
1667 | | glBindTexture(GL_TEXTURE_2D, tx->textures[2] ); |
1668 | | #if !defined(GPAC_GL_NO_STRIDE) |
1669 | | if (use_stride) glPixelStorei(GL_UNPACK_ROW_LENGTH, stride_chroma/tx->bytes_per_pix); |
1670 | | #endif |
1671 | | glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, tx->uv_w, tx->uv_h, tx->gl_format, tx->memory_format, pV); |
1672 | | glBindTexture(GL_TEXTURE_2D, 0); |
1673 | | } |
1674 | | |
1675 | | if (pA) { |
1676 | | glBindTexture(GL_TEXTURE_2D, tx->textures[3] ); |
1677 | | #if !defined(GPAC_GL_NO_STRIDE) |
1678 | | if (use_stride) glPixelStorei(GL_UNPACK_ROW_LENGTH, stride_luma/tx->bytes_per_pix); |
1679 | | #endif |
1680 | | glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, tx->width, tx->height, tx->gl_format, tx->memory_format, pA); |
1681 | | glBindTexture(GL_TEXTURE_2D, 0); |
1682 | | } |
1683 | | |
1684 | | #if !defined(GPAC_GL_NO_STRIDE) |
1685 | | if (use_stride) glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); |
1686 | | #endif |
1687 | | } |
1688 | | |
1689 | | //restore red/alpha scale |
1690 | | if (tx->scale_10bit) { |
1691 | | #if !defined(GPAC_USE_GLES1X) && !defined(GPAC_USE_GLES2) |
1692 | | glPixelTransferi(GL_RED_SCALE, 1); |
1693 | | glPixelTransferi(GL_ALPHA_SCALE, 1); |
1694 | | glPixelStorei(GL_UNPACK_LSB_FIRST, 0); |
1695 | | #endif |
1696 | | glPixelStorei(GL_UNPACK_ALIGNMENT, 1); |
1697 | | } |
1698 | | |
1699 | | return GF_TRUE; |
1700 | | } |
1701 | | |
1702 | | |
1703 | | struct yuv_coefs { |
1704 | | u32 cicp; |
1705 | | Double Kr, Kb; |
1706 | | } YUVMatrices[] = { |
1707 | | {GF_CICP_MX_BT709, 0.2126, 0.0722}, |
1708 | | {GF_CICP_MX_FCC47, 0.3, 0.11}, |
1709 | | {GF_CICP_MX_BT601_625, 0.299, 0.114}, |
1710 | | {GF_CICP_MX_SMPTE170, 0.299, 0.114}, |
1711 | | {GF_CICP_MX_SMPTE240, 0.212, 0.087}, |
1712 | | {GF_CICP_MX_BT2020, 0.2627, 0.0593}, |
1713 | | {GF_CICP_MX_BT2020_CL, 0.2627, 0.0593} |
1714 | | }; |
1715 | | |
1716 | | static void get_yuv_color_matrix(GF_GLTextureWrapper *tx, GF_Matrix *mx) |
1717 | | { |
1718 | | Double Kg; |
1719 | | struct yuv_coefs *yc = NULL; |
1720 | | |
1721 | | //setup YUV->RGB matrix, in row-major |
1722 | | gf_mx_init(*mx); |
1723 | | |
1724 | | if (tx->mx_cicp>=0) { |
1725 | | u32 i, count=GF_ARRAY_LENGTH(YUVMatrices); |
1726 | | u32 mx_code = (u32) tx->mx_cicp; |
1727 | | |
1728 | | if (mx_code==GF_CICP_MX_IDENTITY) { |
1729 | | return; |
1730 | | } |
1731 | | |
1732 | | if (mx_code==GF_CICP_MX_YCgCo) { |
1733 | | GF_LOG(GF_LOG_WARNING, GF_LOG_MMIO, ("[GL] YCgCo matrix not supported, will use BT709\n")); |
1734 | | yc = &YUVMatrices[1]; |
1735 | | } |
1736 | | else if (mx_code==GF_CICP_MX_YDzDx) { |
1737 | | GF_LOG(GF_LOG_WARNING, GF_LOG_MMIO, ("[GL] YDxDy matrix not supported, will use BT709\n")); |
1738 | | yc = &YUVMatrices[1]; |
1739 | | } else { |
1740 | | for (i=0; i<count; i++) { |
1741 | | if (YUVMatrices[i].cicp == mx_code) { |
1742 | | yc = &YUVMatrices[i]; |
1743 | | break; |
1744 | | } |
1745 | | } |
1746 | | if (!yc) { |
1747 | | GF_LOG(GF_LOG_ERROR, GF_LOG_MMIO, ("[GL] Unrecognized matrix coefficient value %d, will use BT709\n", mx_code)); |
1748 | | yc = &YUVMatrices[1]; |
1749 | | } |
1750 | | } |
1751 | | } else { |
1752 | | yc = &YUVMatrices[1]; |
1753 | | } |
1754 | | |
1755 | | Kg = 1.0 - yc->Kr - yc->Kb; |
1756 | | |
1757 | | mx->m[0] = 1.0f; |
1758 | | mx->m[2] = (Float) (2.0 * (1.0 - yc->Kr) ); |
1759 | | |
1760 | | mx->m[4] = 1.0; |
1761 | | mx->m[5] = (Float) ( - 2.0 * (1.0 - yc->Kb) * yc->Kb / Kg ); |
1762 | | mx->m[6] = (Float) ( - 2.0 * (1.0 - yc->Kr) * yc->Kr / Kg ); |
1763 | | |
1764 | | mx->m[8] = 1.0f; |
1765 | | mx->m[9] = (Float) (2.0 * (1.0 - yc->Kb) ); |
1766 | | mx->m[10] = 0.0; |
1767 | | |
1768 | | //move to column major |
1769 | | gf_mx_transpose(mx); |
1770 | | |
1771 | | if (tx->fullrange) { |
1772 | | gf_mx_add_translation(mx, 0, FLT2FIX(-0.5), FLT2FIX(-0.5)); |
1773 | | } else { |
1774 | | gf_mx_add_scale(mx, FLT2FIX(255.0/216.0), FLT2FIX(255.0/224.0), FLT2FIX(255.0/224.0) ); |
1775 | | gf_mx_add_translation(mx, FLT2FIX(-0.0625), FLT2FIX(-0.5), FLT2FIX(-0.5)); |
1776 | | } |
1777 | | |
1778 | | GF_LOG(GF_LOG_INFO, GF_LOG_MMIO, ("[GL] YUV2RGB matrix is (column-major):\n" |
1779 | | "\t%.4f\t%.4f\t%.4f\t%.4f\n" |
1780 | | "\t%.4f\t%.4f\t%.4f\t%.4f\n" |
1781 | | "\t%.4f\t%.4f\t%.4f\t%.4f\n" |
1782 | | "\t%.4f\t%.4f\t%.4f\t%.4f\n", |
1783 | | mx->m[0], mx->m[1], mx->m[2], mx->m[3], |
1784 | | mx->m[4], mx->m[5], mx->m[6], mx->m[7], |
1785 | | mx->m[8], mx->m[9], mx->m[10], mx->m[11], |
1786 | | mx->m[12], mx->m[13], mx->m[14], mx->m[15] |
1787 | | )); |
1788 | | |
1789 | | } |
1790 | | |
1791 | | |
1792 | | Bool gf_gl_txw_bind(GF_GLTextureWrapper *tx, const char *tx_name, u32 gl_program, u32 texture_unit) |
1793 | | { |
1794 | | if (!texture_unit) |
1795 | | texture_unit = GL_TEXTURE0; |
1796 | | |
1797 | | if (gl_program && (gl_program != tx->last_program)) { |
1798 | | tx->last_program = gl_program; |
1799 | | tx->uniform_setup = GF_FALSE; |
1800 | | } |
1801 | | |
1802 | | #if !defined(GPAC_USE_TINYGL) && !defined(GPAC_USE_GLES1X) |
1803 | | if ((!tx->uniform_setup || (tx->init_active_texture != texture_unit)) && gl_program) { |
1804 | | char szName[100]; |
1805 | | u32 i; |
1806 | | u32 start_idx = texture_unit - GL_TEXTURE0; |
1807 | | s32 loc; |
1808 | | tx->init_active_texture = texture_unit; |
1809 | | for (i=0; i<tx->nb_textures; i++) { |
1810 | | sprintf(szName, "_gf_%s_%d", tx_name, i+1); |
1811 | | loc = glGetUniformLocation(gl_program, szName); |
1812 | | if (!i && (loc == -1)) |
1813 | | loc = glGetUniformLocation(gl_program, tx_name); |
1814 | | |
1815 | | GL_CHECK_ERR() |
1816 | | if (loc == -1) { |
1817 | | GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[GL] Failed to locate texture %s in shader\n", szName)); |
1818 | | return GF_FALSE; |
1819 | | } |
1820 | | glUniform1i(loc, start_idx + i); |
1821 | | GL_CHECK_ERR() |
1822 | | } |
1823 | | GL_CHECK_ERR() |
1824 | | } |
1825 | | if (!tx->uniform_setup && gl_program) { |
1826 | | s32 loc; |
1827 | | Bool needs_gpu_width = GF_FALSE; |
1828 | | char szName[100]; |
1829 | | if (tx->is_yuv) { |
1830 | | GF_Matrix mx; |
1831 | | get_yuv_color_matrix(tx, &mx); |
1832 | | sprintf(szName, "_gf_%s_mx", tx_name); |
1833 | | loc = glGetUniformLocation(gl_program, szName); |
1834 | | if (loc == -1) { |
1835 | | GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[GL] Failed to locate matrix coefficients %s in shader\n", szName)); |
1836 | | return GF_FALSE; |
1837 | | } |
1838 | | glUniformMatrix4fv(loc, 1, GL_FALSE, mx.m); |
1839 | | } |
1840 | | switch (tx->pix_fmt) { |
1841 | | case GF_PIXEL_V210: |
1842 | | needs_gpu_width = GF_TRUE; |
1843 | | case GF_PIXEL_UYVY: |
1844 | | case GF_PIXEL_YUYV: |
1845 | | case GF_PIXEL_VYUY: |
1846 | | case GF_PIXEL_YVYU: |
1847 | | case GF_PIXEL_UYVY_10: |
1848 | | case GF_PIXEL_YUYV_10: |
1849 | | case GF_PIXEL_VYUY_10: |
1850 | | case GF_PIXEL_YVYU_10: |
1851 | | sprintf(szName, "_gf_%s_width", tx_name); |
1852 | | loc = glGetUniformLocation(gl_program, szName); |
1853 | | if (loc == -1) { |
1854 | | GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[GL] Failed to locate uniform %s in shader\n", szName)); |
1855 | | return GF_FALSE; |
1856 | | } |
1857 | | glUniform1f(loc, (GLfloat) tx->width); |
1858 | | if (needs_gpu_width) { |
1859 | | u32 gpu_width = tx->stride / 4; |
1860 | | sprintf(szName, "_gf_%s_gpu_width", tx_name); |
1861 | | loc = glGetUniformLocation(gl_program, szName); |
1862 | | if (loc == -1) { |
1863 | | GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[GL] Failed to locate uniform %s in shader\n", szName)); |
1864 | | return GF_FALSE; |
1865 | | } |
1866 | | glUniform1f(loc, (GLfloat) gpu_width); |
1867 | | } |
1868 | | break; |
1869 | | default: |
1870 | | break; |
1871 | | } |
1872 | | tx->uniform_setup = GF_TRUE; |
1873 | | } |
1874 | | #endif // !defined(GPAC_USE_TINYGL) && !defined(GPAC_USE_GLES1X) |
1875 | | |
1876 | | GL_CHECK_ERR() |
1877 | | |
1878 | | if (!tx->internal_textures) { |
1879 | | u32 i; |
1880 | | GF_Matrix txmx; |
1881 | | |
1882 | | gf_mx_init(txmx); |
1883 | | for (i=0; i<tx->nb_textures; i++) { |
1884 | | u32 gl_format = GL_TEXTURE_2D; |
1885 | | //everything we do is on this texture unit, including what the parent filter does when fetching the gl texture |
1886 | | glActiveTexture(texture_unit + i); |
1887 | | if (tx->frame_ifce && tx->frame_ifce->get_gl_texture(tx->frame_ifce, i, &gl_format, &tx->textures[i], &txmx) != GF_OK) { |
1888 | | if (!i) { |
1889 | | GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[GL] Failed to get frame interface OpenGL texture ID for plane %d\n", i)); |
1890 | | return GF_FALSE; |
1891 | | } |
1892 | | break; |
1893 | | } |
1894 | | #ifndef GPAC_USE_GLES2 |
1895 | | if (!gl_program) |
1896 | | glEnable(gl_format); |
1897 | | #endif |
1898 | | if (!tx->textures[i]) |
1899 | | break; |
1900 | | |
1901 | | glBindTexture(gl_format, tx->textures[i]); |
1902 | | glTexParameteri(gl_format, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); |
1903 | | glTexParameteri(gl_format, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); |
1904 | | glTexParameteri(gl_format, GL_TEXTURE_MIN_FILTER, GL_LINEAR); |
1905 | | glTexParameteri(gl_format, GL_TEXTURE_MAG_FILTER, GL_LINEAR); |
1906 | | /*todo pass matrix to shader !!*/ |
1907 | | } |
1908 | | tx->flip = (txmx.m[5]<0) ? GF_TRUE : GF_FALSE; |
1909 | | |
1910 | | if (tx->nb_textures) { |
1911 | | #ifndef GPAC_USE_GLES2 |
1912 | | glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); |
1913 | | glClientActiveTexture(texture_unit); |
1914 | | #endif |
1915 | | } |
1916 | | return GF_TRUE; |
1917 | | } |
1918 | | if (tx->nb_textures>3) { |
1919 | | glActiveTexture(texture_unit + 3); |
1920 | | glBindTexture(GL_TEXTURE_2D, tx->textures[3]); |
1921 | | } |
1922 | | if (tx->nb_textures>2) { |
1923 | | glActiveTexture(texture_unit + 2); |
1924 | | glBindTexture(GL_TEXTURE_2D, tx->textures[2]); |
1925 | | } |
1926 | | if (tx->nb_textures>1) { |
1927 | | glActiveTexture(texture_unit + 1); |
1928 | | glBindTexture(GL_TEXTURE_2D, tx->textures[1]); |
1929 | | } |
1930 | | if (tx->nb_textures) { |
1931 | | glActiveTexture(texture_unit); |
1932 | | glBindTexture(GL_TEXTURE_2D, tx->textures[0]); |
1933 | | |
1934 | | #ifndef GPAC_USE_GLES2 |
1935 | | glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); |
1936 | | glClientActiveTexture(texture_unit); |
1937 | | #endif |
1938 | | } |
1939 | | |
1940 | | #ifndef GPAC_USE_GLES2 |
1941 | | glEnable(GL_TEXTURE_2D); |
1942 | | #endif |
1943 | | |
1944 | | GL_CHECK_ERR() |
1945 | | return GF_TRUE; |
1946 | | } |
1947 | | |
1948 | | void gf_gl_txw_reset(GF_GLTextureWrapper *tx) |
1949 | | { |
1950 | | if (tx->nb_textures) { |
1951 | | if (tx->internal_textures) { |
1952 | | glDeleteTextures(tx->nb_textures, tx->textures); |
1953 | | if (tx->pbo_state && tx->PBOs[0]) { |
1954 | | glDeleteBuffers(tx->nb_textures, tx->PBOs); |
1955 | | } |
1956 | | } |
1957 | | tx->nb_textures = 0; |
1958 | | } |
1959 | | tx->width = 0; |
1960 | | tx->height = 0; |
1961 | | tx->pix_fmt = 0; |
1962 | | tx->stride = 0; |
1963 | | tx->uv_stride = 0; |
1964 | | tx->internal_textures = GF_FALSE; |
1965 | | tx->uniform_setup = GF_FALSE; |
1966 | | } |
1967 | | |
1968 | | #else |
1969 | | |
1970 | | void gf_opengl_init() |
1971 | 0 | { |
1972 | 0 | } |
1973 | | |
1974 | | Bool gf_gl_txw_insert_fragment_shader(u32 pix_fmt, const char *tx_name, char **f_source, Bool y_flip) |
1975 | 0 | { |
1976 | 0 | return GF_FALSE; |
1977 | 0 | } |
1978 | | Bool gf_gl_txw_setup(GF_GLTextureWrapper *tx, u32 pix_fmt, u32 width, u32 height, u32 stride, u32 uv_stride, Bool linear_interp, GF_FilterFrameInterface *frame_ifce, Bool full_range, s32 matrix_coef_or_neg) |
1979 | 0 | { |
1980 | 0 | return GF_FALSE; |
1981 | 0 | } |
1982 | | |
1983 | | Bool gf_gl_txw_upload(GF_GLTextureWrapper *tx, const u8 *data, GF_FilterFrameInterface *frame_ifce) |
1984 | 0 | { |
1985 | 0 | return GF_FALSE; |
1986 | 0 | } |
1987 | | |
1988 | | Bool gf_gl_txw_bind(GF_GLTextureWrapper *tx, const char *tx_name, u32 gl_program, u32 texture_unit) |
1989 | 0 | { |
1990 | 0 | return GF_FALSE; |
1991 | 0 | } |
1992 | | void gf_gl_txw_reset(GF_GLTextureWrapper *tx) |
1993 | 0 | { |
1994 | 0 | } |
1995 | | |
1996 | | #endif //GPAC_DISABLE_3D |