MythTV  master
mythopenglvideoshaders.h
Go to the documentation of this file.
1 #ifndef MYTH_OPENGLVIDEOSHADERS_H
2 #define MYTH_OPENGLVIDEOSHADERS_H
3 
4 #include <QString>
5 
6 static const QString DefaultVertexShader =
7 "attribute highp vec2 a_position;\n"
8 "attribute highp vec2 a_texcoord0;\n"
9 "varying highp vec2 v_texcoord0;\n"
10 "uniform highp mat4 u_projection;\n"
11 "void main()\n"
12 "{\n"
13 " gl_Position = u_projection * vec4(a_position, 0.0, 1.0);\n"
14 " v_texcoord0 = a_texcoord0;\n"
15 "}\n";
16 
17 static const QString RGBFragmentShader =
18 "uniform sampler2D s_texture0;\n"
19 "varying highp vec2 v_texcoord0;\n"
20 "void main(void)\n"
21 "{\n"
22 " highp vec4 color = texture2D(s_texture0, v_texcoord0);\n"
23 " gl_FragColor = vec4(color.rgb, 1.0);\n"
24 "}\n";
25 
26 #ifdef USING_MEDIACODEC
27 static const QString MediaCodecVertexShader =
28 "attribute highp vec2 a_position;\n"
29 "attribute highp vec2 a_texcoord0;\n"
30 "varying highp vec2 v_texcoord0;\n"
31 "uniform highp mat4 u_projection;\n"
32 "uniform highp mat4 u_transform;\n"
33 "void main()\n"
34 "{\n"
35 " gl_Position = u_projection * vec4(a_position, 0.0, 1.0);\n"
36 " v_texcoord0 = (u_transform * vec4(a_texcoord0, 0.0, 1.0)).xy;\n"
37 "}\n";
38 #endif
39 
40 // these need to come first but obviously after the defines...
41 static const QString YUVFragmentExtensions =
42 "#define LINEHEIGHT m_frameData.x\n"
43 "#define COLUMN m_frameData.y\n"
44 "#define MAXHEIGHT m_frameData.z\n"
45 "#define FIELDSIZE m_frameData.w\n"
46 "#ifdef MYTHTV_RECTS\n"
47 "#extension GL_ARB_texture_rectangle : enable\n"
48 "#define texture2D texture2DRect\n"
49 "#define sampler2D sampler2DRect\n"
50 "#endif\n"
51 "#ifdef MYTHTV_EXTOES\n"
52 "#extension GL_OES_EGL_image_external : require\n"
53 "#define sampler2D samplerExternalOES\n"
54 "#endif\n";
55 
56 static const QString YUVFragmentShader =
57 "uniform highp mat4 m_colourMatrix;\n"
58 "uniform highp vec4 m_frameData;\n"
59 "varying highp vec2 v_texcoord0;\n"
60 "#ifdef MYTHTV_COLOURMAPPING\n"
61 "uniform highp mat4 m_primaryMatrix;\n"
62 "uniform highp float m_colourGamma;\n"
63 "uniform highp float m_displayGamma;\n"
64 "highp vec4 ColourMap(highp vec4 color)\n"
65 "{\n"
66 " highp vec4 res = clamp(color, 0.0, 1.0);\n"
67 " res.rgb = pow(res.rgb, vec3(m_colourGamma));\n"
68 " res = m_primaryMatrix * res;\n"
69 " return vec4(pow(res.rgb, vec3(m_displayGamma)), res.a);\n"
70 "}\n"
71 "#endif\n"
72 
73 // Chrom upsampling error filter
74 // Chroma for lines 1 and 3 comes from line 1-2
75 // Chroma for lines 2 and 4 comes from line 3-4
76 // This is a simple resample that ensures temporal consistency. A more advanced
77 // multitap filter would smooth the chroma - but at significant cost and potentially
78 // undesirable loss in detail.
79 
80 "highp vec2 chromaLocation(highp vec2 xy)\n"
81 "{\n"
82 "#ifdef MYTHTV_CUE\n"
83 " highp float temp = xy.y * FIELDSIZE;\n"
84 " highp float onetwo = min((floor(temp / 2.0) / (FIELDSIZE / 2.0)) + LINEHEIGHT, MAXHEIGHT);\n"
85 "#ifdef MYTHTV_CHROMALEFT\n"
86 " return vec2(xy.x + (0.5 / COLUMN), mix(onetwo, min(onetwo + (2.0 * LINEHEIGHT), MAXHEIGHT), step(0.5, fract(temp))));\n"
87 "#else\n"
88 " return vec2(xy.x, mix(onetwo, min(onetwo + (2.0 * LINEHEIGHT), MAXHEIGHT), step(0.5, fract(temp))));\n"
89 "#endif\n"
90 "#else\n"
91 "#ifdef MYTHTV_CHROMALEFT\n"
92 " return vec2(xy.x + (0.5 / COLUMN), xy.y);\n"
93 "#else\n"
94 " return xy;\n"
95 "#endif\n"
96 "#endif\n"
97 "}\n"
98 
99 "#ifdef MYTHTV_NV12\n"
100 "highp vec4 sampleYUV(in sampler2D texture1, in sampler2D texture2, highp vec2 texcoord)\n"
101 "{\n"
102 "#ifdef MYTHTV_RECTS\n"
103 " return vec4(texture2D(texture1, texcoord).r, texture2D(texture2, chromaLocation(texcoord) * vec2(0.5, 0.5)).rg, 1.0);\n"
104 "#else\n"
105 " return vec4(texture2D(texture1, texcoord).r, texture2D(texture2, chromaLocation(texcoord)).rg, 1.0);\n"
106 "#endif\n"
107 "}\n"
108 "#endif\n"
109 
110 "#ifdef MYTHTV_YV12\n"
111 "highp vec4 sampleYUV(in sampler2D texture1, in sampler2D texture2, in sampler2D texture3, highp vec2 texcoord)\n"
112 "{\n"
113 " highp vec2 chroma = chromaLocation(texcoord);\n"
114 " return vec4(texture2D(texture1, texcoord).r,\n"
115 " texture2D(texture2, chroma).r,\n"
116 " texture2D(texture3, chroma).r,\n"
117 " 1.0);\n"
118 "}\n"
119 "#endif\n"
120 
121 "#ifdef MYTHTV_YUY2\n"
122 "highp vec4 sampleYUV(in sampler2D texture1, highp vec2 texcoord)\n"
123 "{\n"
124 " return texture2D(texture1, texcoord);\n"
125 "}\n"
126 "#endif\n"
127 
128 "#ifdef MYTHTV_KERNEL\n"
129 "highp vec4 kernel(in highp vec4 yuv, sampler2D kernelTex0, sampler2D kernelTex1)\n"
130 "{\n"
131 " highp vec2 twoup = vec2(v_texcoord0.x, max(v_texcoord0.y - (2.0 * LINEHEIGHT), LINEHEIGHT));\n"
132 " highp vec2 twodown = vec2(v_texcoord0.x, min(v_texcoord0.y + (2.0 * LINEHEIGHT), MAXHEIGHT));\n"
133 " yuv *= 0.125;\n"
134 " yuv += 0.125 * sampleYUV(kernelTex1, v_texcoord0);\n"
135 " yuv += 0.5 * sampleYUV(kernelTex0, vec2(v_texcoord0.x, max(v_texcoord0.y - LINEHEIGHT, LINEHEIGHT)));\n"
136 " yuv += 0.5 * sampleYUV(kernelTex0, vec2(v_texcoord0.x, min(v_texcoord0.y + LINEHEIGHT, MAXHEIGHT)));\n"
137 " yuv += -0.0625 * sampleYUV(kernelTex0, twoup);\n"
138 " yuv += -0.0625 * sampleYUV(kernelTex0, twodown);\n"
139 " yuv += -0.0625 * sampleYUV(kernelTex1, twoup);\n"
140 " yuv += -0.0625 * sampleYUV(kernelTex1, twodown);\n"
141 " return yuv;\n"
142 "}\n"
143 "#endif\n"
144 
145 "void main(void)\n"
146 "{\n"
147 "#ifdef MYTHTV_ONEFIELD\n"
148 "#ifdef MYTHTV_TOPFIELD\n"
149 " highp float field = min(v_texcoord0.y + (step(0.5, fract(v_texcoord0.y * FIELDSIZE))) * LINEHEIGHT, MAXHEIGHT);\n"
150 "#else\n"
151 " highp float field = max(v_texcoord0.y + (step(0.5, 1.0 - fract(v_texcoord0.y * FIELDSIZE))) * LINEHEIGHT, 0.0);\n"
152 "#endif\n"
153 " highp vec4 yuv = sampleYUV(s_texture0, vec2(v_texcoord0.x, field));\n"
154 "#else\n"
155 "#ifdef MYTHTV_KERNEL\n"
156 " highp vec4 yuv = sampleYUV(s_texture1, v_texcoord0);\n"
157 "#else\n"
158 " highp vec4 yuv = sampleYUV(s_texture0, v_texcoord0);\n"
159 "#endif\n"
160 "#endif\n"
161 
162 "#ifdef MYTHTV_KERNEL\n"
163 "#ifdef MYTHTV_TOPFIELD\n"
164 " yuv = mix(kernel(yuv, s_texture1, s_texture2), yuv, step(fract(v_texcoord0.y * FIELDSIZE), 0.5));\n"
165 "#else\n"
166 " yuv = mix(yuv, kernel(yuv, s_texture1, s_texture0), step(fract(v_texcoord0.y * FIELDSIZE), 0.5));\n"
167 "#endif\n"
168 "#endif\n"
169 
170 "#ifdef MYTHTV_LINEARBLEND\n"
171 " highp vec4 above = sampleYUV(s_texture0, vec2(v_texcoord0.x, min(v_texcoord0.y + LINEHEIGHT, MAXHEIGHT)));\n"
172 " highp vec4 below = sampleYUV(s_texture0, vec2(v_texcoord0.x, max(v_texcoord0.y - LINEHEIGHT, 0.0)));\n"
173 "#ifdef MYTHTV_TOPFIELD\n"
174 " yuv = mix(mix(above, below, 0.5), yuv, step(fract(v_texcoord0.y * FIELDSIZE), 0.5));\n"
175 "#else\n"
176 " yuv = mix(yuv, mix(above, below, 0.5), step(fract(v_texcoord0.y * FIELDSIZE), 0.5));\n"
177 "#endif\n"
178 "#endif\n"
179 
180 "#ifdef MYTHTV_YUY2\n"
181 " gl_FragColor = vec4(mix(yuv.arb, yuv.grb, step(fract(v_texcoord0.x * COLUMN), 0.5)), 1.0) * m_colourMatrix;\n"
182 "#else\n"
183 " gl_FragColor = yuv * m_colourMatrix;\n"
184 "#ifdef MYTHTV_COLOURMAPPING\n"
185 " gl_FragColor = ColourMap(gl_FragColor);\n"
186 "#endif\n"
187 "#endif\n"
188 "}\n";
189 
190 // N.B. Currently unused
191 static const QString BicubicShader =
192 "uniform sampler2D s_texture0;\n"
193 "uniform sampler2D s_texture1;\n"
194 "varying highp vec2 v_texcoord0;\n"
195 "void main(void)\n"
196 "{\n"
197 " highp vec2 coord = (v_texcoord0 * vec2(%BICUBICWIDTH%, %BICUBICHEIGHT%)) - vec2(0.5, 0.5);\n"
198 " highp vec4 parmx = texture2D(s_texture1, vec2(coord.x, 0.0));\n"
199 " highp vec4 parmy = texture2D(s_texture1, vec2(coord.y, 0.0));\n"
200 " highp vec2 e_x = vec2(%BICUBICCWIDTH%, 0.0);\n"
201 " highp vec2 e_y = vec2(0.0, LINEHEIGHT);\n"
202 " highp vec2 coord10 = v_texcoord0 + parmx.x * e_x;\n"
203 " highp vec2 coord00 = v_texcoord0 - parmx.y * e_x;\n"
204 " highp vec2 coord11 = coord10 + parmy.x * e_y;\n"
205 " highp vec2 coord01 = coord00 + parmy.x * e_y;\n"
206 " coord10 = coord10 - parmy.y * e_y;\n"
207 " coord00 = coord00 - parmy.y * e_y;\n"
208 " highp vec4 tex00 = texture2D(s_texture0, coord00);\n"
209 " highp vec4 tex10 = texture2D(s_texture0, coord10);\n"
210 " highp vec4 tex01 = texture2D(s_texture0, coord01);\n"
211 " highp vec4 tex11 = texture2D(s_texture0, coord11);\n"
212 " tex00 = mix(tex00, tex01, parmy.z);\n"
213 " tex10 = mix(tex10, tex11, parmy.z);\n"
214 " gl_FragColor = mix(tex00, tex10, parmx.z);\n"
215 "}\n";
216 
217 /* These are updated versions of the video shaders that use GLSL 3.30 / GLSL ES 3.00.
218  * Used because OpenGL ES3.X requires unsigned integer texture formats for 16bit
219  * software video textures - and unsigned samplers need GLSL ES 3.00.
220  *
221  * Notable differences due to shader language changes:-
222  * - use of in/out instead of varying/attribute
223  * - gl_FragColor replaced with user defined 'out highp vec4 fragmentColor'
224  * - texture2D replaced with texture
225  * - no mix method for uint/uvec - so must be handled 'manually'
226  *
227  * Changes for unsigned integer sampling:-
228  * - sampler2D replaced with usampler2D (note - via define to ensure compatibility
229  * with texture sampling customisation in MythOpenGLVideo).
230  * - vec4 replaced with uvec4 as needed
231  * - kernel calculation forces intermediate conversion to float to maintain accuracy
232  *
233  * There is no support here for:-
234  * - rectangular textures (only currently required for VideoToolBox on OSX - no GLES)
235  * - MediaCodec vertex transforms (hardware textures only)
236  * - External OES textures (hardware textures only)
237  * - YUY2 textures (8bit only currently)
238  *
239  * Other usage considerations:-
240  * - the correct version define added as the FIRST line.
241  * - texture filtering must be GL_NEAREST.
242 */
243 
244 static const QString GLSL300VertexShader =
245 "in highp vec2 a_position;\n"
246 "in highp vec2 a_texcoord0;\n"
247 "out highp vec2 v_texcoord0;\n"
248 "uniform highp mat4 u_projection;\n"
249 "void main()\n"
250 "{\n"
251 " gl_Position = u_projection * vec4(a_position, 0.0, 1.0);\n"
252 " v_texcoord0 = a_texcoord0;\n"
253 "}\n";
254 
255 static const QString GLSL300YUVFragmentExtensions =
256 "#define LINEHEIGHT m_frameData.x\n"
257 "#define COLUMN m_frameData.y\n"
258 "#define MAXHEIGHT m_frameData.z\n"
259 "#define FIELDSIZE m_frameData.w\n"
260 "#define sampler2D highp usampler2D\n";
261 
262 static const QString GLSL300YUVFragmentShader =
263 "uniform highp mat4 m_colourMatrix;\n"
264 "uniform highp vec4 m_frameData;\n"
265 "in highp vec2 v_texcoord0;\n"
266 "out highp vec4 fragmentColor;\n"
267 "#ifdef MYTHTV_COLOURMAPPING\n"
268 "uniform highp mat4 m_primaryMatrix;\n"
269 "uniform highp float m_colourGamma;\n"
270 "uniform highp float m_displayGamma;\n"
271 "highp vec4 ColourMap(highp vec4 color)\n"
272 "{\n"
273 " highp vec4 res = clamp(color, 0.0, 1.0);\n"
274 " res.rgb = pow(res.rgb, vec3(m_colourGamma));\n"
275 " res = m_primaryMatrix * res;\n"
276 " return vec4(pow(res.rgb, vec3(m_displayGamma)), res.a);\n"
277 "}\n"
278 "#endif\n"
279 
280 // Chroma for lines 1 and 3 comes from line 1-2
281 // Chroma for lines 2 and 4 comes from line 3-4
282 // This is a simple resample that ensures temporal consistency. A more advanced
283 // multitap filter would smooth the chroma - but at significant cost and potentially
284 // undesirable loss in detail.
285 
286 "highp vec2 chromaLocation(highp vec2 xy)\n"
287 "{\n"
288 "#ifdef MYTHTV_CUE\n"
289 " highp float temp = xy.y * FIELDSIZE;\n"
290 " highp float onetwo = min((floor(temp / 2.0) / (FIELDSIZE / 2.0)) + LINEHEIGHT, MAXHEIGHT);\n"
291 "#ifdef MYTHTV_CHROMALEFT\n"
292 " return vec2(xy.x + (0.5 / COLUMN), mix(onetwo, min(onetwo + (2.0 * LINEHEIGHT), MAXHEIGHT), step(0.5, fract(temp))));\n"
293 "#else\n"
294 " return vec2(xy.x, mix(onetwo, min(onetwo + (2.0 * LINEHEIGHT), MAXHEIGHT), step(0.5, fract(temp))));\n"
295 "#endif\n"
296 "#else\n"
297 "#ifdef MYTHTV_CHROMALEFT\n"
298 " return vec2(xy.x + (0.5 / COLUMN), xy.y);\n"
299 "#else\n"
300 " return xy;\n"
301 "#endif\n"
302 "#endif\n"
303 "}\n"
304 
305 "#ifdef MYTHTV_NV12\n"
306 "highp uvec4 sampleYUV(in sampler2D texture1, in sampler2D texture2, highp vec2 texcoord)\n"
307 "{\n"
308 " return uvec4(texture(texture1, texcoord).r, texture(texture2, chromaLocation(texcoord)).rg, 1.0);\n"
309 "}\n"
310 "#endif\n"
311 
312 "#ifdef MYTHTV_YV12\n"
313 "highp uvec4 sampleYUV(in sampler2D texture1, in sampler2D texture2, in sampler2D texture3, highp vec2 texcoord)\n"
314 "{\n"
315 " highp vec2 chroma = chromaLocation(texcoord);\n"
316 " return uvec4(texture(texture1, texcoord).r,\n"
317 " texture(texture2, chroma).r,\n"
318 " texture(texture3, chroma).r,\n"
319 " 1.0);\n"
320 "}\n"
321 "#endif\n"
322 
323 "#ifdef MYTHTV_KERNEL\n"
324 "highp uvec4 kernel(in highp uvec4 yuv, sampler2D kernelTex0, sampler2D kernelTex1)\n"
325 "{\n"
326 " highp vec2 twoup = vec2(v_texcoord0.x, max(v_texcoord0.y - (2.0 * LINEHEIGHT), LINEHEIGHT));\n"
327 " highp vec2 twodown = vec2(v_texcoord0.x, min(v_texcoord0.y + (2.0 * LINEHEIGHT), MAXHEIGHT));\n"
328 " highp vec4 yuvf = 0.125 * vec4(yuv);\n"
329 " yuvf += 0.125 * vec4(sampleYUV(kernelTex1, v_texcoord0));\n"
330 " yuvf += 0.5 * vec4(sampleYUV(kernelTex0, vec2(v_texcoord0.x, max(v_texcoord0.y - LINEHEIGHT, LINEHEIGHT))));\n"
331 " yuvf += 0.5 * vec4(sampleYUV(kernelTex0, vec2(v_texcoord0.x, min(v_texcoord0.y + LINEHEIGHT, MAXHEIGHT))));\n"
332 " yuvf += -0.0625 * vec4(sampleYUV(kernelTex0, twoup));\n"
333 " yuvf += -0.0625 * vec4(sampleYUV(kernelTex0, twodown));\n"
334 " yuvf += -0.0625 * vec4(sampleYUV(kernelTex1, twoup));\n"
335 " yuvf += -0.0625 * vec4(sampleYUV(kernelTex1, twodown));\n"
336 " return uvec4(yuv);\n"
337 "}\n"
338 "#endif\n"
339 
340 "void main(void)\n"
341 "{\n"
342 "#ifdef MYTHTV_ONEFIELD\n"
343 "#ifdef MYTHTV_TOPFIELD\n"
344 " highp float field = min(v_texcoord0.y + (step(0.5, fract(v_texcoord0.y * FIELDSIZE))) * LINEHEIGHT, MAXHEIGHT);\n"
345 "#else\n"
346 " highp float field = max(v_texcoord0.y + (step(0.5, 1.0 - fract(v_texcoord0.y * FIELDSIZE))) * LINEHEIGHT, 0.0);\n"
347 "#endif\n"
348 " highp uvec4 yuv = sampleYUV(s_texture0, vec2(v_texcoord0.x, field));\n"
349 "#else\n"
350 "#ifdef MYTHTV_KERNEL\n"
351 " highp uvec4 yuv = sampleYUV(s_texture1, v_texcoord0);\n"
352 "#else\n"
353 " highp uvec4 yuv = sampleYUV(s_texture0, v_texcoord0);\n"
354 "#endif\n"
355 "#endif\n"
356 
357 "#ifdef MYTHTV_KERNEL\n"
358 " highp uint field = uint(step(fract(v_texcoord0.y * FIELDSIZE), 0.5));\n"
359 "#ifdef MYTHTV_TOPFIELD\n"
360 " yuv = (kernel(yuv, s_texture1, s_texture2) * uvec4(field)) + (yuv * uvec4(1u - field));\n"
361 "#else\n"
362 " yuv = (yuv * uvec4(field)) + (kernel(yuv, s_texture1, s_texture0) * uvec4(1u - field));\n"
363 "#endif\n"
364 "#endif\n"
365 
366 "#ifdef MYTHTV_LINEARBLEND\n"
367 " highp uvec4 mixed = (sampleYUV(s_texture0, vec2(v_texcoord0.x, min(v_texcoord0.y + LINEHEIGHT, MAXHEIGHT))) +\n"
368 " sampleYUV(s_texture0, vec2(v_texcoord0.x, max(v_texcoord0.y - LINEHEIGHT, 0.0)))) / uvec4(2.0);\n"
369 " highp uint field = uint(step(fract(v_texcoord0.y * FIELDSIZE), 0.5));\n"
370 "#ifdef MYTHTV_TOPFIELD\n"
371 " yuv = (mixed * uvec4(field)) + (yuv * uvec4(1u - field));\n"
372 "#else\n"
373 " yuv = (yuv * uvec4(field)) + (mixed * uvec4(1u - field));\n"
374 "#endif\n"
375 "#endif\n"
376 
377 " fragmentColor = (vec4(yuv) / vec4(65535.0, 65535.0, 65535.0, 1.0)) * m_colourMatrix;\n"
378 "#ifdef MYTHTV_COLOURMAPPING\n"
379 " fragmentColor = ColourMap(fragmentColor);\n"
380 "#endif\n"
381 "}\n";
382 
383 #endif // MYTH_OPENGLVIDEOSHADERS_H
BicubicShader
static const QString BicubicShader
Definition: mythopenglvideoshaders.h:191
GLSL300VertexShader
static const QString GLSL300VertexShader
Definition: mythopenglvideoshaders.h:244
GLSL300YUVFragmentExtensions
static const QString GLSL300YUVFragmentExtensions
Definition: mythopenglvideoshaders.h:255
YUVFragmentExtensions
static const QString YUVFragmentExtensions
Definition: mythopenglvideoshaders.h:41
DefaultVertexShader
static const QString DefaultVertexShader
Definition: mythopenglvideoshaders.h:6
YUVFragmentShader
static const QString YUVFragmentShader
Definition: mythopenglvideoshaders.h:56
RGBFragmentShader
static const QString RGBFragmentShader
Definition: mythopenglvideoshaders.h:17
GLSL300YUVFragmentShader
static const QString GLSL300YUVFragmentShader
Definition: mythopenglvideoshaders.h:262