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