aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRainer Hochecker <fernetmenta@online.de>2017-09-27 08:05:54 +0200
committerRainer Hochecker <fernetmenta@online.de>2017-10-05 18:06:26 +0200
commitc4c88062582ca87d6df4e48aa4cf79a5adb3301c (patch)
treea7ff777a56acefc7fe4660a0616dac00c2eb01b6
parent0a85f848e7986b4a995375cc66ddeec2987bd8ce (diff)
VideoPlayer: OpenGL - drop fixed function pipeline
-rw-r--r--system/shaders/gl_convolution-4x4.glsl113
-rw-r--r--system/shaders/gl_convolution-6x6.glsl124
-rw-r--r--system/shaders/gl_output.glsl58
-rw-r--r--system/shaders/gl_streatch.glsl40
-rw-r--r--system/shaders/gl_videofilter_frag.glsl30
-rw-r--r--system/shaders/gl_videofilter_vertex.glsl34
-rw-r--r--system/shaders/gl_yuv2rgb_basic.glsl122
-rw-r--r--system/shaders/gl_yuv2rgb_vertex.glsl (renamed from system/shaders/yuv2rgb_vertex.glsl)24
-rw-r--r--xbmc/cores/VideoPlayer/VideoRenderers/BaseRenderer.cpp1
-rw-r--r--xbmc/cores/VideoPlayer/VideoRenderers/BaseRenderer.h1
-rw-r--r--xbmc/cores/VideoPlayer/VideoRenderers/LinuxRendererGL.cpp655
-rw-r--r--xbmc/cores/VideoPlayer/VideoRenderers/LinuxRendererGL.h5
-rw-r--r--xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/CMakeLists.txt4
-rw-r--r--xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/GLSLOutput.cpp12
-rw-r--r--xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/GLSLOutputGLES.cpp200
-rw-r--r--xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/GLSLOutputGLES.h71
-rw-r--r--xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/VideoFilterShaderGL.cpp94
-rw-r--r--xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/VideoFilterShaderGL.h17
-rw-r--r--xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/VideoFilterShaderGLES.h3
-rw-r--r--xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/YUV2RGBShaderGL.cpp171
-rw-r--r--xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/YUV2RGBShaderGL.h123
-rw-r--r--xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/YUV2RGBShaderGLES.h2
22 files changed, 1317 insertions, 587 deletions
diff --git a/system/shaders/gl_convolution-4x4.glsl b/system/shaders/gl_convolution-4x4.glsl
new file mode 100644
index 0000000000..cf2a0f5378
--- /dev/null
+++ b/system/shaders/gl_convolution-4x4.glsl
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2010-2013 Team XBMC
+ * http://xbmc.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with XBMC; see the file COPYING. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ */
+
+uniform sampler2D img;
+uniform vec2 stepxy;
+uniform float m_stretch;
+varying vec2 m_cord;
+
+#if (USE1DTEXTURE)
+ uniform sampler1D kernelTex;
+#else
+ uniform sampler2D kernelTex;
+#endif
+
+//nvidia's half is a 16 bit float and can bring some speed improvements
+//without affecting quality
+#ifndef __GLSL_CG_DATA_TYPES
+ #define half float
+ #define half3 vec3
+ #define half4 vec4
+#endif
+
+half4 weight(float pos)
+{
+#if (HAS_FLOAT_TEXTURE)
+ #if (USE1DTEXTURE)
+ return texture1D(kernelTex, pos);
+ #else
+ return texture2D(kernelTex, vec2(pos, 0.5));
+ #endif
+#else
+ #if (USE1DTEXTURE)
+ return texture1D(kernelTex, pos) * 2.0 - 1.0;
+ #else
+ return texture2D(kernelTex, vec2(pos, 0.5)) * 2.0 - 1.0;
+ #endif
+#endif
+}
+
+vec2 stretch(vec2 pos)
+{
+#if (XBMC_STRETCH)
+ // our transform should map [0..1] to itself, with f(0) = 0, f(1) = 1, f(0.5) = 0.5, and f'(0.5) = b.
+ // a simple curve to do this is g(x) = b(x-0.5) + (1-b)2^(n-1)(x-0.5)^n + 0.5
+ // where the power preserves sign. n = 2 is the simplest non-linear case (required when b != 1)
+ float x = pos.x - 0.5;
+ return vec2(mix(x * abs(x) * 2.0, x, m_stretch) + 0.5, pos.y);
+#else
+ return pos;
+#endif
+}
+
+half3 pixel(float xpos, float ypos)
+{
+ return texture2D(img, vec2(xpos, ypos)).rgb;
+}
+
+half3 line (float ypos, vec4 xpos, half4 linetaps)
+{
+ return
+ pixel(xpos.r, ypos) * linetaps.r +
+ pixel(xpos.g, ypos) * linetaps.g +
+ pixel(xpos.b, ypos) * linetaps.b +
+ pixel(xpos.a, ypos) * linetaps.a;
+}
+
+vec4 process()
+{
+ vec4 rgb;
+ vec2 pos = stretch(m_cord) + stepxy * 0.5;
+ vec2 f = fract(pos / stepxy);
+
+ half4 linetaps = weight(1.0 - f.x);
+ half4 columntaps = weight(1.0 - f.y);
+
+ //make sure all taps added together is exactly 1.0, otherwise some (very small) distortion can occur
+ linetaps /= linetaps.r + linetaps.g + linetaps.b + linetaps.a;
+ columntaps /= columntaps.r + columntaps.g + columntaps.b + columntaps.a;
+
+ vec2 xystart = (-1.5 - f) * stepxy + pos;
+ vec4 xpos = vec4(xystart.x, xystart.x + stepxy.x, xystart.x + stepxy.x * 2.0, xystart.x + stepxy.x * 3.0);
+
+ rgb.rgb =
+ line(xystart.y , xpos, linetaps) * columntaps.r +
+ line(xystart.y + stepxy.y , xpos, linetaps) * columntaps.g +
+ line(xystart.y + stepxy.y * 2.0, xpos, linetaps) * columntaps.b +
+ line(xystart.y + stepxy.y * 3.0, xpos, linetaps) * columntaps.a;
+
+#ifdef GL_ES
+ rgb.a = m_alpha;
+#else
+ rgb.a = gl_Color.a;
+#endif
+
+ return rgb;
+}
diff --git a/system/shaders/gl_convolution-6x6.glsl b/system/shaders/gl_convolution-6x6.glsl
new file mode 100644
index 0000000000..c4f51fd431
--- /dev/null
+++ b/system/shaders/gl_convolution-6x6.glsl
@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) 2010-2013 Team XBMC
+ * http://xbmc.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with XBMC; see the file COPYING. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ */
+
+uniform sampler2D img;
+uniform vec2 stepxy;
+uniform float m_stretch;
+varying vec2 m_cord;
+
+#if (USE1DTEXTURE)
+ uniform sampler1D kernelTex;
+#else
+ uniform sampler2D kernelTex;
+#endif
+
+//nvidia's half is a 16 bit float and can bring some speed improvements
+//without affecting quality
+#ifndef __GLSL_CG_DATA_TYPES
+ #define half float
+ #define half3 vec3
+ #define half4 vec4
+#endif
+
+half3 weight(float pos)
+{
+#if (HAS_FLOAT_TEXTURE)
+ #if (USE1DTEXTURE)
+ return texture1D(kernelTex, pos).rgb;
+ #else
+ return texture2D(kernelTex, vec2(pos, 0.5)).rgb;
+ #endif
+#else
+ #if (USE1DTEXTURE)
+ return texture1D(kernelTex, pos).rgb * 2.0 - 1.0;
+ #else
+ return texture2D(kernelTex, vec2(pos, 0.5)).rgb * 2.0 - 1.0;
+ #endif
+#endif
+}
+
+vec2 stretch(vec2 pos)
+{
+#if (XBMC_STRETCH)
+ // our transform should map [0..1] to itself, with f(0) = 0, f(1) = 1, f(0.5) = 0.5, and f'(0.5) = b.
+ // a simple curve to do this is g(x) = b(x-0.5) + (1-b)2^(n-1)(x-0.5)^n + 0.5
+ // where the power preserves sign. n = 2 is the simplest non-linear case (required when b != 1)
+ float x = pos.x - 0.5;
+ return vec2(mix(x * abs(x) * 2.0, x, m_stretch) + 0.5, pos.y);
+#else
+ return pos;
+#endif
+}
+
+half3 pixel(float xpos, float ypos)
+{
+ return texture2D(img, vec2(xpos, ypos)).rgb;
+}
+
+half3 line (float ypos, vec3 xpos1, vec3 xpos2, half3 linetaps1, half3 linetaps2)
+{
+ return
+ pixel(xpos1.r, ypos) * linetaps1.r +
+ pixel(xpos1.g, ypos) * linetaps2.r +
+ pixel(xpos1.b, ypos) * linetaps1.g +
+ pixel(xpos2.r, ypos) * linetaps2.g +
+ pixel(xpos2.g, ypos) * linetaps1.b +
+ pixel(xpos2.b, ypos) * linetaps2.b;
+}
+
+vec4 process()
+{
+ vec4 rgb;
+ vec2 pos = stretch(m_cord) + stepxy * 0.5;
+ vec2 f = fract(pos / stepxy);
+
+ half3 linetaps1 = weight((1.0 - f.x) / 2.0);
+ half3 linetaps2 = weight((1.0 - f.x) / 2.0 + 0.5);
+ half3 columntaps1 = weight((1.0 - f.y) / 2.0);
+ half3 columntaps2 = weight((1.0 - f.y) / 2.0 + 0.5);
+
+ //make sure all taps added together is exactly 1.0, otherwise some (very small) distortion can occur
+ half sum = linetaps1.r + linetaps1.g + linetaps1.b + linetaps2.r + linetaps2.g + linetaps2.b;
+ linetaps1 /= sum;
+ linetaps2 /= sum;
+ sum = columntaps1.r + columntaps1.g + columntaps1.b + columntaps2.r + columntaps2.g + columntaps2.b;
+ columntaps1 /= sum;
+ columntaps2 /= sum;
+
+ vec2 xystart = (-2.5 - f) * stepxy + pos;
+ vec3 xpos1 = vec3(xystart.x, xystart.x + stepxy.x, xystart.x + stepxy.x * 2.0);
+ vec3 xpos2 = vec3(xystart.x + stepxy.x * 3.0, xystart.x + stepxy.x * 4.0, xystart.x + stepxy.x * 5.0);
+
+ rgb.rgb =
+ line(xystart.y , xpos1, xpos2, linetaps1, linetaps2) * columntaps1.r +
+ line(xystart.y + stepxy.y , xpos1, xpos2, linetaps1, linetaps2) * columntaps2.r +
+ line(xystart.y + stepxy.y * 2.0, xpos1, xpos2, linetaps1, linetaps2) * columntaps1.g +
+ line(xystart.y + stepxy.y * 3.0, xpos1, xpos2, linetaps1, linetaps2) * columntaps2.g +
+ line(xystart.y + stepxy.y * 4.0, xpos1, xpos2, linetaps1, linetaps2) * columntaps1.b +
+ line(xystart.y + stepxy.y * 5.0, xpos1, xpos2, linetaps1, linetaps2) * columntaps2.b;
+
+#ifdef GL_ES
+ rgb.a = m_alpha;
+#else
+ rgb.a = gl_Color.a;
+#endif
+
+ return rgb;
+}
diff --git a/system/shaders/gl_output.glsl b/system/shaders/gl_output.glsl
new file mode 100644
index 0000000000..d3294a8bb5
--- /dev/null
+++ b/system/shaders/gl_output.glsl
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2010-2017 Team XBMC
+ * http://xbmc.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with XBMC; see the file COPYING. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#if defined(XBMC_DITHER)
+uniform sampler2D m_dither;
+uniform float m_ditherquant;
+uniform vec2 m_dithersize;
+#endif
+#if defined(KODI_3DLUT)
+uniform float m_CLUTsize;
+uniform sampler3D m_CLUT;
+#endif
+
+void main()
+{
+ vec4 rgb = process();
+
+#if defined(KODI_3DLUT)
+ // FIXME: can this be optimized?
+ rgb = texture3D(m_CLUT, (rgb.rgb*(m_CLUTsize-1.0) + 0.5) / m_CLUTsize);
+#endif
+
+#if defined(XBMC_FULLRANGE)
+#if __VERSION__ <= 120
+ rgb = (rgb-(16.0/255.0)) * 255.0/219.0;
+#else
+ rgb = clamp((rgb-(16.0/255.0)) * 255.0/219.0, 0, 1);
+#endif
+#endif
+
+#if defined(XBMC_DITHER)
+ vec2 ditherpos = gl_FragCoord.xy / m_dithersize;
+ // ditherval is multiplied by 65536/(dither_size^2) to make it [0,1[
+ // FIXME: scale dither values before uploading?
+ float ditherval = texture2D(m_dither, ditherpos).r * 16.0;
+ rgb = floor(rgb * m_ditherquant + ditherval) / m_ditherquant;
+#endif
+
+ gl_FragColor = rgb;
+}
diff --git a/system/shaders/gl_streatch.glsl b/system/shaders/gl_streatch.glsl
new file mode 100644
index 0000000000..dc42318d50
--- /dev/null
+++ b/system/shaders/gl_streatch.glsl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2010-2013 Team XBMC
+ * http://xbmc.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with XBMC; see the file COPYING. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#version 120
+
+uniform sampler2D img;
+uniform float m_stretch;
+varying vec2 m_cord;
+
+vec2 stretch(vec2 pos)
+{
+ // our transform should map [0..1] to itself, with f(0) = 0, f(1) = 1, f(0.5) = 0.5, and f'(0.5) = b.
+ // a simple curve to do this is g(x) = b(x-0.5) + (1-b)2^(n-1)(x-0.5)^n + 0.5
+ // where the power preserves sign. n = 2 is the simplest non-linear case (required when b != 1)
+ float x = pos.x - 0.5;
+ return vec2(mix(x * abs(x) * 2.0, x, m_stretch) + 0.5, pos.y);
+}
+
+void main()
+{
+ gl_FragColor.rgb = texture2D(img, stretch(m_cord)).rgb;
+ gl_FragColor.a = gl_Color.a;
+}
diff --git a/system/shaders/gl_videofilter_frag.glsl b/system/shaders/gl_videofilter_frag.glsl
new file mode 100644
index 0000000000..ff7af3b678
--- /dev/null
+++ b/system/shaders/gl_videofilter_frag.glsl
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2010-2013 Team XBMC
+ * http://xbmc.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with XBMC; see the file COPYING. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#version 120
+
+uniform sampler2D img;
+varying vec2 m_cord;
+
+void main()
+{
+ gl_FragColor.rgb = texture2D(img, m_cord).rgb;
+ gl_FragColor.a = gl_Color.a;
+}
diff --git a/system/shaders/gl_videofilter_vertex.glsl b/system/shaders/gl_videofilter_vertex.glsl
new file mode 100644
index 0000000000..aa124b5350
--- /dev/null
+++ b/system/shaders/gl_videofilter_vertex.glsl
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2010-2013 Team XBMC
+ * http://xbmc.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with XBMC; see the file COPYING. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#version 120
+
+attribute vec4 m_attrpos;
+attribute vec2 m_attrcord;
+varying vec2 m_cord;
+uniform mat4 m_proj;
+uniform mat4 m_model;
+
+void main ()
+{
+ mat4 mvp = m_proj * m_model;
+ gl_Position = mvp * m_attrpos;
+ m_cord = m_attrcord;
+}
diff --git a/system/shaders/gl_yuv2rgb_basic.glsl b/system/shaders/gl_yuv2rgb_basic.glsl
new file mode 100644
index 0000000000..268d8c6682
--- /dev/null
+++ b/system/shaders/gl_yuv2rgb_basic.glsl
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2010-2013 Team XBMC
+ * http://xbmc.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with XBMC; see the file COPYING. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#if(XBMC_texture_rectangle)
+# extension GL_ARB_texture_rectangle : enable
+# define texture2D texture2DRect
+# define sampler2D sampler2DRect
+#endif
+
+uniform sampler2D m_sampY;
+uniform sampler2D m_sampU;
+uniform sampler2D m_sampV;
+varying vec2 m_cordY;
+varying vec2 m_cordU;
+varying vec2 m_cordV;
+uniform vec2 m_step;
+uniform mat4 m_yuvmat;
+uniform float m_stretch;
+
+vec2 stretch(vec2 pos)
+{
+#if (XBMC_STRETCH)
+ // our transform should map [0..1] to itself, with f(0) = 0, f(1) = 1, f(0.5) = 0.5, and f'(0.5) = b.
+ // a simple curve to do this is g(x) = b(x-0.5) + (1-b)2^(n-1)(x-0.5)^n + 0.5
+ // where the power preserves sign. n = 2 is the simplest non-linear case (required when b != 1)
+ #if(XBMC_texture_rectangle)
+ float x = (pos.x * m_step.x) - 0.5;
+ return vec2((mix(2.0 * x * abs(x), x, m_stretch) + 0.5) / m_step.x, pos.y);
+ #else
+ float x = pos.x - 0.5;
+ return vec2(mix(2.0 * x * abs(x), x, m_stretch) + 0.5, pos.y);
+ #endif
+#else
+ return pos;
+#endif
+}
+
+vec4 process()
+{
+ vec4 rgb;
+#if defined(XBMC_YV12) || defined(XBMC_NV12)
+
+ vec4 yuv;
+ yuv.rgba = vec4( texture2D(m_sampY, stretch(m_cordY)).r
+ , texture2D(m_sampU, stretch(m_cordU)).g
+ , texture2D(m_sampV, stretch(m_cordV)).a
+ , 1.0 );
+
+ rgb = m_yuvmat * yuv;
+ rgb.a = gl_Color.a;
+
+#elif defined(XBMC_NV12_RRG)
+
+ vec4 yuv;
+ yuv.rgba = vec4( texture2D(m_sampY, stretch(m_cordY)).r
+ , texture2D(m_sampU, stretch(m_cordU)).r
+ , texture2D(m_sampV, stretch(m_cordV)).g
+ , 1.0 );
+
+ rgb = m_yuvmat * yuv;
+ rgb.a = gl_Color.a;
+
+#elif defined(XBMC_YUY2) || defined(XBMC_UYVY)
+
+#if(XBMC_texture_rectangle)
+ vec2 stepxy = vec2(1.0, 1.0);
+ vec2 pos = stretch(m_cordY);
+ pos = vec2(pos.x - 0.25, pos.y);
+ vec2 f = fract(pos);
+#else
+ vec2 stepxy = m_step;
+ vec2 pos = stretch(m_cordY);
+ pos = vec2(pos.x - stepxy.x * 0.25, pos.y);
+ vec2 f = fract(pos / stepxy);
+#endif
+
+ //y axis will be correctly interpolated by opengl
+ //x axis will not, so we grab two pixels at the center of two columns and interpolate ourselves
+ vec4 c1 = texture2D(m_sampY, vec2(pos.x + (0.5 - f.x) * stepxy.x, pos.y));
+ vec4 c2 = texture2D(m_sampY, vec2(pos.x + (1.5 - f.x) * stepxy.x, pos.y));
+
+ /* each pixel has two Y subpixels and one UV subpixel
+ YUV Y YUV
+ check if we're left or right of the middle Y subpixel and interpolate accordingly*/
+#ifdef XBMC_YUY2 //BGRA = YUYV
+ float leftY = mix(c1.b, c1.r, f.x * 2.0);
+ float rightY = mix(c1.r, c2.b, f.x * 2.0 - 1.0);
+ vec2 outUV = mix(c1.ga, c2.ga, f.x);
+#else //BGRA = UYVY
+ float leftY = mix(c1.g, c1.a, f.x * 2.0);
+ float rightY = mix(c1.a, c2.g, f.x * 2.0 - 1.0);
+ vec2 outUV = mix(c1.br, c2.br, f.x);
+#endif //XBMC_YUY2
+
+ float outY = mix(leftY, rightY, step(0.5, f.x));
+
+ vec4 yuv = vec4(outY, outUV, 1.0);
+ rgb = m_yuvmat * yuv;
+
+ rgb.a = gl_Color.a;
+
+#endif
+
+ return rgb;
+}
diff --git a/system/shaders/yuv2rgb_vertex.glsl b/system/shaders/gl_yuv2rgb_vertex.glsl
index 2225040f9c..cdf3c56a71 100644
--- a/system/shaders/yuv2rgb_vertex.glsl
+++ b/system/shaders/gl_yuv2rgb_vertex.glsl
@@ -18,21 +18,21 @@
*
*/
+attribute vec4 m_attrpos;
+attribute vec2 m_attrcordY;
+attribute vec2 m_attrcordU;
+attribute vec2 m_attrcordV;
varying vec2 m_cordY;
varying vec2 m_cordU;
varying vec2 m_cordV;
+uniform mat4 m_proj;
+uniform mat4 m_model;
-void main()
+void main ()
{
-#if(XBMC_texture_rectangle_hack)
- m_cordY = vec2(gl_TextureMatrix[0] * gl_MultiTexCoord0 / 2);
- m_cordU = vec2(gl_TextureMatrix[1] * gl_MultiTexCoord1 * 2);
- m_cordV = vec2(gl_TextureMatrix[2] * gl_MultiTexCoord2);
-#else
- m_cordY = vec2(gl_TextureMatrix[0] * gl_MultiTexCoord0);
- m_cordU = vec2(gl_TextureMatrix[1] * gl_MultiTexCoord1);
- m_cordV = vec2(gl_TextureMatrix[2] * gl_MultiTexCoord2);
-#endif
- gl_Position = ftransform();
- gl_FrontColor = gl_Color;
+ mat4 mvp = m_proj * m_model;
+ gl_Position = mvp * m_attrpos;
+ m_cordY = m_attrcordY;
+ m_cordU = m_attrcordU;
+ m_cordV = m_attrcordV;
}
diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/BaseRenderer.cpp b/xbmc/cores/VideoPlayer/VideoRenderers/BaseRenderer.cpp
index 632dab8296..0994d7c316 100644
--- a/xbmc/cores/VideoPlayer/VideoRenderers/BaseRenderer.cpp
+++ b/xbmc/cores/VideoPlayer/VideoRenderers/BaseRenderer.cpp
@@ -590,7 +590,6 @@ void CBaseRenderer::SettingOptionsRenderMethodsFiller(std::shared_ptr<const CSet
#endif
#ifdef HAS_GL
- list.push_back(make_pair(g_localizeStrings.Get(13417), RENDER_METHOD_ARB));
list.push_back(make_pair(g_localizeStrings.Get(13418), RENDER_METHOD_GLSL));
#endif
}
diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/BaseRenderer.h b/xbmc/cores/VideoPlayer/VideoRenderers/BaseRenderer.h
index 949092cb51..606fa63619 100644
--- a/xbmc/cores/VideoPlayer/VideoRenderers/BaseRenderer.h
+++ b/xbmc/cores/VideoPlayer/VideoRenderers/BaseRenderer.h
@@ -46,7 +46,6 @@ enum EFIELDSYNC
enum RenderMethods
{
RENDER_METHOD_AUTO = 0,
- RENDER_METHOD_ARB,
RENDER_METHOD_GLSL,
RENDER_METHOD_SOFTWARE,
RENDER_METHOD_D3D_PS,
diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/LinuxRendererGL.cpp b/xbmc/cores/VideoPlayer/VideoRenderers/LinuxRendererGL.cpp
index 0c25e9e1a7..6a95b3c5dd 100644
--- a/xbmc/cores/VideoPlayer/VideoRenderers/LinuxRendererGL.cpp
+++ b/xbmc/cores/VideoPlayer/VideoRenderers/LinuxRendererGL.cpp
@@ -132,8 +132,8 @@ CLinuxRendererGL::CLinuxRendererGL()
m_iYV12RenderBuffer = 0;
m_currentField = FIELD_FULL;
m_reloadShaders = 0;
- m_pYUVShader = NULL;
- m_pVideoFilterShader = NULL;
+ m_pYUVShader = nullptr;
+ m_pVideoFilterShader = nullptr;
m_scalingMethod = VS_SCALINGMETHOD_LINEAR;
m_scalingMethodGui = (ESCALINGMETHOD)-1;
m_useDithering = CServiceBroker::GetSettings().GetBool("videoscreen.dither");
@@ -168,14 +168,13 @@ CLinuxRendererGL::~CLinuxRendererGL()
{
m_pYUVShader->Free();
delete m_pYUVShader;
- m_pYUVShader = NULL;
+ m_pYUVShader = nullptr;
}
if (m_pVideoFilterShader)
{
- m_pVideoFilterShader->Free();
delete m_pVideoFilterShader;
- m_pVideoFilterShader = NULL;
+ m_pVideoFilterShader = nullptr;
}
}
@@ -558,61 +557,140 @@ void CLinuxRendererGL::ClearBackBuffer()
//since it only sets pixels to black that aren't going to be overwritten by the video
void CLinuxRendererGL::DrawBlackBars()
{
- glColor4f(m_clearColour, m_clearColour, m_clearColour, 1.0f);
glDisable(GL_BLEND);
- glBegin(GL_QUADS);
+
+ struct Svertex
+ {
+ float x,y,z;
+ };
+ Svertex vertices[24];
+ Svertex vertex;
+ GLubyte count = 0;
+
+ //GLfloat vertex[4][3];
+ //GLubyte idx[4] = {0, 1, 3, 2}; //determines order of triangle strip
+
+ g_Windowing.EnableShader(SM_DEFAULT);
+ GLint posLoc = g_Windowing.ShaderGetPos();
+ GLint uniCol = g_Windowing.ShaderGetUniCol();
+
+ glUniform4f(uniCol, m_clearColour / 255.0f, m_clearColour / 255.0f, m_clearColour / 255.0f, 1.0f);
+ glVertexAttribPointer(posLoc, 3, GL_FLOAT, GL_FALSE, sizeof(Svertex), (char*)(&vertices[0]));
+ glEnableVertexAttribArray(posLoc);
//top quad
if (m_rotatedDestCoords[0].y > 0.0)
{
- glVertex4f(0.0, 0.0, 0.0, 1.0);
- glVertex4f(g_graphicsContext.GetWidth(), 0.0, 0.0, 1.0);
- glVertex4f(g_graphicsContext.GetWidth(), m_rotatedDestCoords[0].y, 0.0, 1.0);
- glVertex4f(0.0, m_rotatedDestCoords[0].y, 0.0, 1.0);
+ GLubyte quad = count;
+ vertices[quad].x = 0.0;
+ vertices[quad].y = 0.0;
+ vertices[quad].z = 0;
+ vertices[quad+1].x = g_graphicsContext.GetWidth();
+ vertices[quad+1].y = 0;
+ vertices[quad+1].z = 0;
+ vertices[quad+2].x = g_graphicsContext.GetWidth();
+ vertices[quad+2].y = m_rotatedDestCoords[0].y;
+ vertices[quad+2].z = 0;
+ vertices[quad+3] = vertices[quad+2];
+ vertices[quad+4].x = 0;
+ vertices[quad+4].y = m_rotatedDestCoords[0].y;
+ vertices[quad+4].z = 0;
+ vertices[quad+5] = vertices[quad];
+ count += 6;
}
//bottom quad
if (m_rotatedDestCoords[2].y < g_graphicsContext.GetHeight())
{
- glVertex4f(0.0, m_rotatedDestCoords[2].y, 0.0, 1.0);
- glVertex4f(g_graphicsContext.GetWidth(), m_rotatedDestCoords[2].y, 0.0, 1.0);
- glVertex4f(g_graphicsContext.GetWidth(), g_graphicsContext.GetHeight(), 0.0, 1.0);
- glVertex4f(0.0, g_graphicsContext.GetHeight(), 0.0, 1.0);
+ GLubyte quad = count;
+ vertices[quad].x = 0.0;
+ vertices[quad].y = m_rotatedDestCoords[2].y;
+ vertices[quad].z = 0;
+ vertices[quad+1].x = g_graphicsContext.GetWidth();
+ vertices[quad+1].y = m_rotatedDestCoords[2].y;
+ vertices[quad+1].z = 0;
+ vertices[quad+2].x = g_graphicsContext.GetWidth();
+ vertices[quad+2].y = g_graphicsContext.GetHeight();
+ vertices[quad+2].z = 0;
+ vertices[quad+3] = vertices[quad+2];
+ vertices[quad+4].x = 0;
+ vertices[quad+4].y = g_graphicsContext.GetHeight();
+ vertices[quad+4].z = 0;
+ vertices[quad+5] = vertices[quad];
+ count += 6;
}
//left quad
if (m_rotatedDestCoords[0].x > 0.0)
{
- glVertex4f(0.0, m_rotatedDestCoords[0].y, 0.0, 1.0);
- glVertex4f(m_rotatedDestCoords[0].x, m_rotatedDestCoords[0].y, 0.0, 1.0);
- glVertex4f(m_rotatedDestCoords[0].x, m_rotatedDestCoords[2].y, 0.0, 1.0);
- glVertex4f(0.0, m_rotatedDestCoords[2].y, 0.0, 1.0);
+ GLubyte quad = count;
+ vertices[quad].x = 0.0;
+ vertices[quad].y = m_rotatedDestCoords[0].y;
+ vertices[quad].z = 0;
+ vertices[quad+1].x = m_rotatedDestCoords[0].x;
+ vertices[quad+1].y = m_rotatedDestCoords[0].y;
+ vertices[quad+1].z = 0;
+ vertices[quad+2].x = m_rotatedDestCoords[3].x;
+ vertices[quad+2].y = m_rotatedDestCoords[3].y;
+ vertices[quad+2].z = 0;
+ vertices[quad+3] = vertices[quad+2];
+ vertices[quad+4].x = 0;
+ vertices[quad+4].y = m_rotatedDestCoords[3].y;
+ vertices[quad+4].z = 0;
+ vertices[quad+5] = vertices[quad];
+ count += 6;
}
//right quad
if (m_rotatedDestCoords[2].x < g_graphicsContext.GetWidth())
{
- glVertex4f(m_rotatedDestCoords[2].x, m_rotatedDestCoords[0].y, 0.0, 1.0);
- glVertex4f(g_graphicsContext.GetWidth(), m_rotatedDestCoords[0].y, 0.0, 1.0);
- glVertex4f(g_graphicsContext.GetWidth(), m_rotatedDestCoords[2].y, 0.0, 1.0);
- glVertex4f(m_rotatedDestCoords[2].x, m_rotatedDestCoords[2].y, 0.0, 1.0);
- }
-
- glEnd();
+ GLubyte quad = count;
+ vertices[quad].x = m_rotatedDestCoords[1].x;
+ vertices[quad].y = m_rotatedDestCoords[1].y;
+ vertices[quad].z = 0;
+ vertices[quad+1].x = g_graphicsContext.GetWidth();
+ vertices[quad+1].y = m_rotatedDestCoords[1].y;
+ vertices[quad+1].z = 0;
+ vertices[quad+2].x = g_graphicsContext.GetWidth();
+ vertices[quad+2].y = m_rotatedDestCoords[2].y;
+ vertices[quad+2].z = 0;
+ vertices[quad+3] = vertices[quad+2];
+ vertices[quad+4].x = m_rotatedDestCoords[1].x;
+ vertices[quad+4].y = m_rotatedDestCoords[2].y;
+ vertices[quad+4].z = 0;
+ vertices[quad+5] = vertices[quad];
+ count += 6;
+ }
+
+ glDrawArrays(GL_TRIANGLES, 0, count);
+ glDisableVertexAttribArray(posLoc);
+
+ g_Windowing.DisableShader();
}
void CLinuxRendererGL::UpdateVideoFilter()
{
- bool pixelRatioChanged = (CDisplaySettings::GetInstance().GetPixelRatio() > 1.001f || CDisplaySettings::GetInstance().GetPixelRatio() < 0.999f) !=
- (m_pixelRatio > 1.001f || m_pixelRatio < 0.999f);
+ if (!m_pVideoFilterShader)
+ {
+ m_pVideoFilterShader = new DefaultFilterShader();
+ if (!m_pVideoFilterShader->CompileAndLink())
+ {
+ CLog::Log(LOGERROR, "CLinuxRendererGL::UpdateVideoFilter: Error compiling and linking video filter shader");
+ return;
+ }
+ }
+
+ bool pixelRatioChanged = (CDisplaySettings::GetInstance().GetPixelRatio() > 1.001f ||
+ CDisplaySettings::GetInstance().GetPixelRatio() < 0.999f) !=
+ (m_pixelRatio > 1.001f || m_pixelRatio < 0.999f);
bool nonLinStretchChanged = false;
- bool cmsChanged = (m_cmsOn != m_ColorManager->IsEnabled())
- || (m_cmsOn && !m_ColorManager->CheckConfiguration(m_cmsToken, m_iFlags));
+ bool cmsChanged = (m_cmsOn != m_ColorManager->IsEnabled()) ||
+ (m_cmsOn && !m_ColorManager->CheckConfiguration(m_cmsToken, m_iFlags));
if (m_nonLinStretchGui != CDisplaySettings::GetInstance().IsNonLinearStretched() || pixelRatioChanged)
{
- m_nonLinStretchGui = CDisplaySettings::GetInstance().IsNonLinearStretched();
- m_pixelRatio = CDisplaySettings::GetInstance().GetPixelRatio();
- m_reloadShaders = 1;
+ m_nonLinStretchGui = CDisplaySettings::GetInstance().IsNonLinearStretched();
+ m_pixelRatio = CDisplaySettings::GetInstance().GetPixelRatio();
+ m_reloadShaders = 1;
nonLinStretchChanged = true;
if (m_nonLinStretchGui && (m_pixelRatio < 0.999f || m_pixelRatio > 1.001f) && Supports(RENDERFEATURE_NONLINSTRETCH))
@@ -655,9 +733,9 @@ void CLinuxRendererGL::UpdateVideoFilter()
}
m_scalingMethodGui = CMediaSettings::GetInstance().GetCurrentVideoSettings().m_ScalingMethod;
- m_scalingMethod = m_scalingMethodGui;
+ m_scalingMethod = m_scalingMethodGui;
- if(!Supports(m_scalingMethod))
+ if (!Supports(m_scalingMethod))
{
CLog::Log(LOGWARNING, "CLinuxRendererGL::UpdateVideoFilter - chosen scaling method %d, is not supported by renderer", (int)m_scalingMethod);
m_scalingMethod = VS_SCALINGMETHOD_LINEAR;
@@ -665,9 +743,8 @@ void CLinuxRendererGL::UpdateVideoFilter()
if (m_pVideoFilterShader)
{
- m_pVideoFilterShader->Free();
delete m_pVideoFilterShader;
- m_pVideoFilterShader = NULL;
+ m_pVideoFilterShader = nullptr;
}
m_fbo.fbo.Cleanup();
@@ -765,12 +842,17 @@ void CLinuxRendererGL::UpdateVideoFilter()
CLog::Log(LOGERROR, "GL: Falling back to bilinear due to failure to init scaler");
if (m_pVideoFilterShader)
{
- m_pVideoFilterShader->Free();
delete m_pVideoFilterShader;
- m_pVideoFilterShader = NULL;
+ m_pVideoFilterShader = nullptr;
}
m_fbo.fbo.Cleanup();
+ m_pVideoFilterShader = new DefaultFilterShader();
+ if (!m_pVideoFilterShader->CompileAndLink())
+ {
+ CLog::Log(LOGERROR, "CLinuxRendererGL::UpdateVideoFilter: Error compiling and linking defauilt video filter shader");
+ }
+
SetTextureFilter(GL_LINEAR);
m_renderQuality = RQ_SINGLEPASS;
}
@@ -791,89 +873,33 @@ void CLinuxRendererGL::LoadShaders(int field)
m_pYUVShader = NULL;
}
- bool tryGlsl = true;
- switch(requestedMethod)
+ // create regular progressive scan shader
+ // if single pass, create GLSLOutput helper and pass it to YUV2RGB shader
+ GLSLOutput *out = nullptr;
+ if (m_renderQuality == RQ_SINGLEPASS)
{
- case RENDER_METHOD_AUTO:
-#if defined(TARGET_POSIX) && !defined(TARGET_DARWIN)
- //with render method set to auto, don't try glsl on ati if we're on linux
- //it seems to be broken in a random way with every new driver release
- tryGlsl = !StringUtils::StartsWithNoCase(g_Windowing.GetRenderVendor(), "ati");
-#endif
-
- case RENDER_METHOD_GLSL:
- // Try GLSL shaders if supported and user requested auto or GLSL.
- if (tryGlsl)
- {
- // create regular progressive scan shader
- // if single pass, create GLSLOutput helper and pass it to YUV2RGB shader
- GLSLOutput *out = nullptr;
- if (m_renderQuality == RQ_SINGLEPASS)
- {
- out = new GLSLOutput(3, m_useDithering, m_ditherDepth,
- m_cmsOn ? m_fullRange : false,
- m_cmsOn ? m_tCLUTTex : 0,
- m_CLUTsize);
- }
- EShaderFormat shaderFormat = GetShaderFormat();
- m_pYUVShader = new YUV2RGBProgressiveShader(m_textureTarget==GL_TEXTURE_RECTANGLE_ARB, m_iFlags, shaderFormat,
- m_nonLinStretch && m_renderQuality == RQ_SINGLEPASS,
- out);
- if (!m_cmsOn)
- m_pYUVShader->SetConvertFullColorRange(m_fullRange);
-
- CLog::Log(LOGNOTICE, "GL: Selecting Single Pass YUV 2 RGB shader");
-
- if (m_pYUVShader && m_pYUVShader->CompileAndLink())
- {
- m_renderMethod = RENDER_GLSL;
- UpdateVideoFilter();
- break;
- }
- else if (m_pYUVShader)
- {
- m_pYUVShader->Free();
- delete m_pYUVShader;
- m_pYUVShader = NULL;
- }
- CLog::Log(LOGERROR, "GL: Error enabling YUV2RGB GLSL shader");
- // drop through and try ARB
- }
- case RENDER_METHOD_ARB:
- // Try ARB shaders if supported and user requested it or GLSL shaders failed.
- if (g_Windowing.IsExtSupported("GL_ARB_fragment_program"))
- {
- CLog::Log(LOGNOTICE, "GL: ARB shaders support detected");
- m_renderMethod = RENDER_ARB ;
+ out = new GLSLOutput(3, m_useDithering, m_ditherDepth,
+ m_cmsOn ? m_fullRange : false,
+ m_cmsOn ? m_tCLUTTex : 0,
+ m_CLUTsize);
+ }
+ EShaderFormat shaderFormat = GetShaderFormat();
+ m_pYUVShader = new YUV2RGBProgressiveShader(m_textureTarget==GL_TEXTURE_RECTANGLE_ARB, m_iFlags, shaderFormat,
+ m_nonLinStretch && m_renderQuality == RQ_SINGLEPASS,
+ out);
+ if (!m_cmsOn)
+ m_pYUVShader->SetConvertFullColorRange(m_fullRange);
- // create regular progressive scan shader
- EShaderFormat shaderFormat = GetShaderFormat();
- m_pYUVShader = new YUV2RGBProgressiveShaderARB(m_textureTarget==GL_TEXTURE_RECTANGLE_ARB, m_iFlags, shaderFormat);
- m_pYUVShader->SetConvertFullColorRange(m_fullRange);
- CLog::Log(LOGNOTICE, "GL: Selecting Single Pass ARB YUV2RGB shader");
+ CLog::Log(LOGNOTICE, "GL: Selecting Single Pass YUV 2 RGB shader");
- if (m_pYUVShader && m_pYUVShader->CompileAndLink())
- {
- m_renderMethod = RENDER_ARB;
- UpdateVideoFilter();
- break;
- }
- else if (m_pYUVShader)
- {
- m_pYUVShader->Free();
- delete m_pYUVShader;
- m_pYUVShader = NULL;
- }
- CLog::Log(LOGERROR, "GL: Error enabling YUV2RGB ARB shader");
- m_renderMethod = -1;
- break;
- }
- default:
- {
- m_renderMethod = -1;
- CLog::Log(LOGERROR, "GL: Shaders support not present");
- break;
- }
+ if (m_pYUVShader && m_pYUVShader->CompileAndLink())
+ {
+ m_renderMethod = RENDER_GLSL;
+ UpdateVideoFilter();
+ }
+ else
+ {
+ CLog::Log(LOGERROR, "GL: Error enabling YUV2RGB GLSL shader");
}
}
@@ -961,14 +987,9 @@ bool CLinuxRendererGL::Render(DWORD flags, int renderBuffer)
break;
}
}
- else if (m_renderMethod & RENDER_ARB)
- {
- RenderSinglePass(renderBuffer, m_currentField);
- }
else
{
- RenderSoftware(renderBuffer, m_currentField);
- VerifyGLState();
+ return false;
}
AfterRenderHook(renderBuffer);
@@ -1016,51 +1037,80 @@ void CLinuxRendererGL::RenderSinglePass(int index, int field)
else
m_pYUVShader->SetNonLinStretch(pow(CDisplaySettings::GetInstance().GetPixelRatio(), g_advancedSettings.m_videoNonLinStretchRatio));
- if (field == FIELD_TOP)
+ if (field == FIELD_TOP)
m_pYUVShader->SetField(1);
else if(field == FIELD_BOT)
m_pYUVShader->SetField(0);
+ m_pYUVShader->SetMatrices(glMatrixProject.Get(), glMatrixModview.Get());
m_pYUVShader->Enable();
- glBegin(GL_QUADS);
+ GLubyte idx[4] = {0, 1, 3, 2}; //determines order of the vertices
+ GLfloat vertex[4][3];
+ GLfloat texture[3][4][2];
+
+ GLint vertLoc = m_pYUVShader->GetVertexLoc();
+ GLint Yloc = m_pYUVShader->GetYcoordLoc();
+ GLint Uloc = m_pYUVShader->GetUcoordLoc();
+ GLint Vloc = m_pYUVShader->GetVcoordLoc();
+
+ glVertexAttribPointer(vertLoc, 3, GL_FLOAT, 0, 0, vertex);
+ glVertexAttribPointer(Yloc, 2, GL_FLOAT, 0, 0, texture[0]);
+ glVertexAttribPointer(Uloc, 2, GL_FLOAT, 0, 0, texture[1]);
+ glVertexAttribPointer(Vloc, 2, GL_FLOAT, 0, 0, texture[2]);
+
+ glEnableVertexAttribArray(vertLoc);
+ glEnableVertexAttribArray(Yloc);
+ glEnableVertexAttribArray(Uloc);
+ glEnableVertexAttribArray(Vloc);
- glMultiTexCoord2fARB(GL_TEXTURE0, planes[0].rect.x1, planes[0].rect.y1);
- glMultiTexCoord2fARB(GL_TEXTURE1, planes[1].rect.x1, planes[1].rect.y1);
- glMultiTexCoord2fARB(GL_TEXTURE2, planes[2].rect.x1, planes[2].rect.y1);
- glVertex4f(m_rotatedDestCoords[0].x, m_rotatedDestCoords[0].y, 0, 1.0f );//top left
+ // Setup vertex position values
+ for(int i = 0; i < 4; i++)
+ {
+ vertex[i][0] = m_rotatedDestCoords[i].x;
+ vertex[i][1] = m_rotatedDestCoords[i].y;
+ vertex[i][2] = 0.0f;// set z to 0
+ }
- glMultiTexCoord2fARB(GL_TEXTURE0, planes[0].rect.x2, planes[0].rect.y1);
- glMultiTexCoord2fARB(GL_TEXTURE1, planes[1].rect.x2, planes[1].rect.y1);
- glMultiTexCoord2fARB(GL_TEXTURE2, planes[2].rect.x2, planes[2].rect.y1);
- glVertex4f(m_rotatedDestCoords[1].x, m_rotatedDestCoords[1].y, 0, 1.0f );//top right
+ // Setup texture coordinates
+ for (int i=0; i<3; i++)
+ {
+ // bottom left
+ texture[i][0][0] = planes[i].rect.x1;
+ texture[i][0][1] = planes[i].rect.y1;
- glMultiTexCoord2fARB(GL_TEXTURE0, planes[0].rect.x2, planes[0].rect.y2);
- glMultiTexCoord2fARB(GL_TEXTURE1, planes[1].rect.x2, planes[1].rect.y2);
- glMultiTexCoord2fARB(GL_TEXTURE2, planes[2].rect.x2, planes[2].rect.y2);
- glVertex4f(m_rotatedDestCoords[2].x, m_rotatedDestCoords[2].y, 0, 1.0f );//bottom right
+ // bottom right
+ texture[i][1][0] = planes[i].rect.x2;
+ texture[i][1][1] = planes[i].rect.y1;
- glMultiTexCoord2fARB(GL_TEXTURE0, planes[0].rect.x1, planes[0].rect.y2);
- glMultiTexCoord2fARB(GL_TEXTURE1, planes[1].rect.x1, planes[1].rect.y2);
- glMultiTexCoord2fARB(GL_TEXTURE2, planes[2].rect.x1, planes[2].rect.y2);
- glVertex4f(m_rotatedDestCoords[3].x, m_rotatedDestCoords[3].y, 0, 1.0f );//bottom left
+ // top right
+ texture[i][2][0] = planes[i].rect.x2;
+ texture[i][2][1] = planes[i].rect.y2;
- glEnd();
+ // top left
+ texture[i][3][0] = planes[i].rect.x1;
+ texture[i][3][1] = planes[i].rect.y2;
+ }
+
+ glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_BYTE, idx);
VerifyGLState();
m_pYUVShader->Disable();
VerifyGLState();
- glActiveTextureARB(GL_TEXTURE1);
- glDisable(m_textureTarget);
+ glDisableVertexAttribArray(vertLoc);
+ glDisableVertexAttribArray(Yloc);
+ glDisableVertexAttribArray(Uloc);
+ glDisableVertexAttribArray(Vloc);
- glActiveTextureARB(GL_TEXTURE2);
+ glActiveTexture(GL_TEXTURE1);
glDisable(m_textureTarget);
- glActiveTextureARB(GL_TEXTURE0);
+ glActiveTexture(GL_TEXTURE2);
glDisable(m_textureTarget);
- glMatrixMode(GL_MODELVIEW);
+ glActiveTexture(GL_TEXTURE0);
+ glDisable(m_textureTarget);
VerifyGLState();
}
@@ -1128,9 +1178,10 @@ void CLinuxRendererGL::RenderToFBO(int index, int field, bool weave /*= false*/)
m_pYUVShader->SetWidth(planes[0].texwidth);
m_pYUVShader->SetHeight(planes[0].texheight);
m_pYUVShader->SetNonLinStretch(1.0);
- if (field == FIELD_TOP)
+
+ if (field == FIELD_TOP)
m_pYUVShader->SetField(1);
- else if(field == FIELD_BOT)
+ else if (field == FIELD_BOT)
m_pYUVShader->SetField(0);
VerifyGLState();
@@ -1150,13 +1201,15 @@ void CLinuxRendererGL::RenderToFBO(int index, int field, bool weave /*= false*/)
glViewport(0, 0, m_sourceWidth, m_sourceHeight);
glScissor (0, 0, m_sourceWidth, m_sourceHeight);
+ m_pYUVShader->SetMatrices(glMatrixProject.Get(), glMatrixModview.Get());
if (!m_pYUVShader->Enable())
{
CLog::Log(LOGERROR, "GL: Error enabling YUV shader");
}
- m_fbo.width = planes[0].rect.x2 - planes[0].rect.x1;
+ m_fbo.width = planes[0].rect.x2 - planes[0].rect.x1;
m_fbo.height = planes[0].rect.y2 - planes[0].rect.y1;
+
if (m_textureTarget == GL_TEXTURE_2D)
{
m_fbo.width *= planes[0].texwidth;
@@ -1168,29 +1221,63 @@ void CLinuxRendererGL::RenderToFBO(int index, int field, bool weave /*= false*/)
m_fbo.height *= 2;
// 1st Pass to video frame size
- glBegin(GL_QUADS);
+ GLubyte idx[4] = {0, 1, 3, 2}; //determines order of the vertices
+ GLfloat vertex[4][3];
+ GLfloat texture[3][4][2];
+
+ GLint vertLoc = m_pYUVShader->GetVertexLoc();
+ GLint Yloc = m_pYUVShader->GetYcoordLoc();
+ GLint Uloc = m_pYUVShader->GetUcoordLoc();
+ GLint Vloc = m_pYUVShader->GetVcoordLoc();
+
+ glVertexAttribPointer(vertLoc, 3, GL_FLOAT, 0, 0, vertex);
+ glVertexAttribPointer(Yloc, 2, GL_FLOAT, 0, 0, texture[0]);
+ glVertexAttribPointer(Uloc, 2, GL_FLOAT, 0, 0, texture[1]);
+ glVertexAttribPointer(Vloc, 2, GL_FLOAT, 0, 0, texture[2]);
+
+ glEnableVertexAttribArray(vertLoc);
+ glEnableVertexAttribArray(Yloc);
+ glEnableVertexAttribArray(Uloc);
+ glEnableVertexAttribArray(Vloc);
+
+ // Setup vertex position values
+ vertex[0][0] = 0.0f;
+ vertex[0][1] = 0.0f;
+ vertex[0][2] = 0.0f;
+
+ vertex[1][0] = m_fbo.width;
+ vertex[1][1] = 0.0f;
+ vertex[1][2] = 0.0f;
- glMultiTexCoord2fARB(GL_TEXTURE0, planes[0].rect.x1, planes[0].rect.y1);
- glMultiTexCoord2fARB(GL_TEXTURE1, planes[1].rect.x1, planes[1].rect.y1);
- glMultiTexCoord2fARB(GL_TEXTURE2, planes[2].rect.x1, planes[2].rect.y1);
- glVertex2f(0.0f , 0.0f);
+ vertex[2][0] = m_fbo.width;
+ vertex[2][1] = m_fbo.height;
+ vertex[2][2] = 0.0f;
- glMultiTexCoord2fARB(GL_TEXTURE0, planes[0].rect.x2, planes[0].rect.y1);
- glMultiTexCoord2fARB(GL_TEXTURE1, planes[1].rect.x2, planes[1].rect.y1);
- glMultiTexCoord2fARB(GL_TEXTURE2, planes[2].rect.x2, planes[2].rect.y1);
- glVertex2f(m_fbo.width, 0.0f);
+ vertex[3][0] = 0.0f;
+ vertex[3][1] = m_fbo.height;
+ vertex[3][2] = 0.0f;
- glMultiTexCoord2fARB(GL_TEXTURE0, planes[0].rect.x2, planes[0].rect.y2);
- glMultiTexCoord2fARB(GL_TEXTURE1, planes[1].rect.x2, planes[1].rect.y2);
- glMultiTexCoord2fARB(GL_TEXTURE2, planes[2].rect.x2, planes[2].rect.y2);
- glVertex2f(m_fbo.width, m_fbo.height);
+ // Setup texture coordinates
+ for (int i=0; i<3; i++)
+ {
+ // top left
+ texture[i][0][0] = planes[i].rect.x1;
+ texture[i][0][1] = planes[i].rect.y1;
+
+ // top right
+ texture[i][1][0] = planes[i].rect.x2;
+ texture[i][1][1] = planes[i].rect.y1;
- glMultiTexCoord2fARB(GL_TEXTURE0, planes[0].rect.x1, planes[0].rect.y2);
- glMultiTexCoord2fARB(GL_TEXTURE1, planes[1].rect.x1, planes[1].rect.y2);
- glMultiTexCoord2fARB(GL_TEXTURE2, planes[2].rect.x1, planes[2].rect.y2);
- glVertex2f(0.0f , m_fbo.height);
+ // bottom right
+ texture[i][2][0] = planes[i].rect.x2;
+ texture[i][2][1] = planes[i].rect.y2;
+
+ // bottom left
+ texture[i][3][0] = planes[i].rect.x1;
+ texture[i][3][1] = planes[i].rect.y2;
+ }
- glEnd();
+ glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_BYTE, idx);
VerifyGLState();
m_pYUVShader->Disable();
@@ -1219,57 +1306,78 @@ void CLinuxRendererGL::RenderFromFBO()
VerifyGLState();
// Use regular normalized texture coordinates
-
// 2nd Pass to screen size with optional video filter
- if (m_pVideoFilterShader)
+ if (!m_pVideoFilterShader)
{
- GLint filter;
- if (!m_pVideoFilterShader->GetTextureFilter(filter))
- filter = m_scalingMethod == VS_SCALINGMETHOD_NEAREST ? GL_NEAREST : GL_LINEAR;
+ CLog::Log(LOGERROR, "CLinuxRendererGL::RenderFromFBO - no videofilter shader");
+ return;
+ }
- m_fbo.fbo.SetFiltering(GL_TEXTURE_2D, filter);
- m_pVideoFilterShader->SetSourceTexture(0);
- m_pVideoFilterShader->SetWidth(m_sourceWidth);
- m_pVideoFilterShader->SetHeight(m_sourceHeight);
+ GLint filter;
+ if (!m_pVideoFilterShader->GetTextureFilter(filter))
+ filter = m_scalingMethod == VS_SCALINGMETHOD_NEAREST ? GL_NEAREST : GL_LINEAR;
- //disable non-linear stretch when a dvd menu is shown, parts of the menu are rendered through the overlay renderer
- //having non-linear stretch on breaks the alignment
- if (g_application.m_pPlayer->IsInMenu())
- m_pVideoFilterShader->SetNonLinStretch(1.0);
- else
- m_pVideoFilterShader->SetNonLinStretch(pow(CDisplaySettings::GetInstance().GetPixelRatio(), g_advancedSettings.m_videoNonLinStretchRatio));
+ m_fbo.fbo.SetFiltering(GL_TEXTURE_2D, filter);
+ m_pVideoFilterShader->SetSourceTexture(0);
+ m_pVideoFilterShader->SetWidth(m_sourceWidth);
+ m_pVideoFilterShader->SetHeight(m_sourceHeight);
- m_pVideoFilterShader->Enable();
- }
+ //disable non-linear stretch when a dvd menu is shown, parts of the menu are rendered through the overlay renderer
+ //having non-linear stretch on breaks the alignment
+ if (g_application.m_pPlayer->IsInMenu())
+ m_pVideoFilterShader->SetNonLinStretch(1.0);
else
- {
- GLint filter = m_scalingMethod == VS_SCALINGMETHOD_NEAREST ? GL_NEAREST : GL_LINEAR;
- m_fbo.fbo.SetFiltering(GL_TEXTURE_2D, filter);
- glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
- }
+ m_pVideoFilterShader->SetNonLinStretch(pow(CDisplaySettings::GetInstance().GetPixelRatio(), g_advancedSettings.m_videoNonLinStretchRatio));
+
+ m_pVideoFilterShader->SetMatrices(glMatrixProject.Get(), glMatrixModview.Get());
+ m_pVideoFilterShader->Enable();
VerifyGLState();
float imgwidth = m_fbo.width / m_sourceWidth;
float imgheight = m_fbo.height / m_sourceHeight;
- glBegin(GL_QUADS);
+ GLubyte idx[4] = {0, 1, 3, 2}; //determines order of the vertices
+ GLfloat vertex[4][3];
+ GLfloat texture[4][2];
- glMultiTexCoord2fARB(GL_TEXTURE0, 0.0f, 0.0f);
- glVertex4f(m_rotatedDestCoords[0].x, m_rotatedDestCoords[0].y, 0, 1.0f );
+ GLint vertLoc = m_pVideoFilterShader->GetVertexLoc();
+ GLint loc = m_pVideoFilterShader->GetCoordLoc();
- glMultiTexCoord2fARB(GL_TEXTURE0, imgwidth, 0.0f);
- glVertex4f(m_rotatedDestCoords[1].x, m_rotatedDestCoords[1].y, 0, 1.0f );
+ glVertexAttribPointer(vertLoc, 3, GL_FLOAT, 0, 0, vertex);
+ glVertexAttribPointer(loc, 2, GL_FLOAT, 0, 0, texture);
- glMultiTexCoord2fARB(GL_TEXTURE0, imgwidth, imgheight);
- glVertex4f(m_rotatedDestCoords[2].x, m_rotatedDestCoords[2].y, 0, 1.0f );
-
- glMultiTexCoord2fARB(GL_TEXTURE0, 0.0f, imgheight);
- glVertex4f(m_rotatedDestCoords[3].x, m_rotatedDestCoords[3].y, 0, 1.0f );
+ glEnableVertexAttribArray(vertLoc);
+ glEnableVertexAttribArray(loc);
+
+ // Setup vertex position values
+ vertex[0][0] = m_rotatedDestCoords[0].x;
+ vertex[0][1] = m_rotatedDestCoords[0].y;
+ vertex[0][2] = 0.0f;
+
+ vertex[1][0] = m_rotatedDestCoords[1].x;
+ vertex[1][1] = m_rotatedDestCoords[1].y;
+ vertex[1][2] = 0.0f;
+
+ vertex[2][0] = m_rotatedDestCoords[2].x;
+ vertex[2][1] = m_rotatedDestCoords[2].y;
+ vertex[2][2] = 0.0f;
- glEnd();
+ vertex[3][0] = m_rotatedDestCoords[3].x;
+ vertex[3][1] = m_rotatedDestCoords[3].y;
+ vertex[3][2] = 0.0f;
+ texture[0][0] = 0.0f;
+ texture[0][1] = 0.0f;
+ texture[1][0] = imgwidth;
+ texture[1][1] = 0.0f;
+ texture[2][0] = imgwidth;
+ texture[2][1] = imgheight;
+ texture[3][0] = 0.0f;
+ texture[3][1] = imgheight;
+
+ glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_BYTE, idx);
VerifyGLState();
if (m_pVideoFilterShader)
@@ -1320,97 +1428,78 @@ void CLinuxRendererGL::RenderRGB(int index, int field)
// make sure we know the correct texture size
GetPlaneTextureSize(plane);
- // Try some clamping or wrapping
- glTexParameteri(m_textureTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameteri(m_textureTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
-
- if (m_pVideoFilterShader)
- {
- GLint filter;
- if (!m_pVideoFilterShader->GetTextureFilter(filter))
- filter = m_scalingMethod == VS_SCALINGMETHOD_NEAREST ? GL_NEAREST : GL_LINEAR;
-
- glTexParameteri(m_textureTarget, GL_TEXTURE_MAG_FILTER, filter);
- glTexParameteri(m_textureTarget, GL_TEXTURE_MIN_FILTER, filter);
- m_pVideoFilterShader->SetSourceTexture(0);
- m_pVideoFilterShader->SetWidth(m_sourceWidth);
- m_pVideoFilterShader->SetHeight(m_sourceHeight);
-
- //disable non-linear stretch when a dvd menu is shown, parts of the menu are rendered through the overlay renderer
- //having non-linear stretch on breaks the alignment
- if (g_application.m_pPlayer->IsInMenu())
- m_pVideoFilterShader->SetNonLinStretch(1.0);
- else
- m_pVideoFilterShader->SetNonLinStretch(pow(CDisplaySettings::GetInstance().GetPixelRatio(), g_advancedSettings.m_videoNonLinStretchRatio));
-
- m_pVideoFilterShader->Enable();
- }
- else
+ if (!m_pVideoFilterShader)
{
- GLint filter = m_scalingMethod == VS_SCALINGMETHOD_NEAREST ? GL_NEAREST : GL_LINEAR;
- glTexParameteri(m_textureTarget, GL_TEXTURE_MAG_FILTER, filter);
- glTexParameteri(m_textureTarget, GL_TEXTURE_MIN_FILTER, filter);
+ CLog::Log(LOGERROR, "CLinuxRendererGL::RenderRGB - no videofilter shader");
+ return;
}
- glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
- VerifyGLState();
+ GLint filter;
+ if (!m_pVideoFilterShader->GetTextureFilter(filter))
+ filter = m_scalingMethod == VS_SCALINGMETHOD_NEAREST ? GL_NEAREST : GL_LINEAR;
- glBegin(GL_QUADS);
- if (m_textureTarget==GL_TEXTURE_2D)
- {
- glTexCoord2f(plane.rect.x1, plane.rect.y1); glVertex2f(m_rotatedDestCoords[0].x, m_rotatedDestCoords[0].y);
- glTexCoord2f(plane.rect.x2, plane.rect.y1); glVertex2f(m_rotatedDestCoords[1].x, m_rotatedDestCoords[1].y);
- glTexCoord2f(plane.rect.x2, plane.rect.y2); glVertex2f(m_rotatedDestCoords[2].x, m_rotatedDestCoords[2].y);
- glTexCoord2f(plane.rect.x1, plane.rect.y2); glVertex2f(m_rotatedDestCoords[3].x, m_rotatedDestCoords[3].y);
- }
+ glTexParameteri(m_textureTarget, GL_TEXTURE_MAG_FILTER, filter);
+ glTexParameteri(m_textureTarget, GL_TEXTURE_MIN_FILTER, filter);
+ m_pVideoFilterShader->SetSourceTexture(0);
+ m_pVideoFilterShader->SetWidth(m_sourceWidth);
+ m_pVideoFilterShader->SetHeight(m_sourceHeight);
+
+ //disable non-linear stretch when a dvd menu is shown, parts of the menu are rendered through the overlay renderer
+ //having non-linear stretch on breaks the alignment
+ if (g_application.m_pPlayer->IsInMenu())
+ m_pVideoFilterShader->SetNonLinStretch(1.0);
else
- {
- glTexCoord2f(plane.rect.x1, plane.rect.y1); glVertex4f(m_rotatedDestCoords[0].x, m_rotatedDestCoords[0].y, 0.0f, 0.0f);
- glTexCoord2f(plane.rect.x2, plane.rect.y1); glVertex4f(m_rotatedDestCoords[1].x, m_rotatedDestCoords[1].y, 1.0f, 0.0f);
- glTexCoord2f(plane.rect.x2, plane.rect.y2); glVertex4f(m_rotatedDestCoords[2].x, m_rotatedDestCoords[2].y, 1.0f, 1.0f);
- glTexCoord2f(plane.rect.x1, plane.rect.y2); glVertex4f(m_rotatedDestCoords[3].x, m_rotatedDestCoords[3].y, 0.0f, 1.0f);
- }
- glEnd();
- VerifyGLState();
+ m_pVideoFilterShader->SetNonLinStretch(pow(CDisplaySettings::GetInstance().GetPixelRatio(), g_advancedSettings.m_videoNonLinStretchRatio));
- if (m_pVideoFilterShader)
- m_pVideoFilterShader->Disable();
+ m_pVideoFilterShader->SetMatrices(glMatrixProject.Get(), glMatrixModview.Get());
+ m_pVideoFilterShader->Enable();
- glBindTexture (m_textureTarget, 0);
- glDisable(m_textureTarget);
-}
+ GLubyte idx[4] = {0, 1, 3, 2}; //determines order of the vertices
+ GLfloat vertex[4][3];
+ GLfloat texture[4][2];
-void CLinuxRendererGL::RenderSoftware(int index, int field)
-{
- // used for textures uploaded from rgba or CVPixelBuffers.
- YUVPLANE (&planes)[YuvImage::MAX_PLANES] = m_buffers[index].fields[field];
+ GLint vertLoc = m_pVideoFilterShader->GetVertexLoc();
+ GLint loc = m_pVideoFilterShader->GetCoordLoc();
- glDisable(GL_DEPTH_TEST);
+ glVertexAttribPointer(vertLoc, 3, GL_FLOAT, 0, 0, vertex);
+ glVertexAttribPointer(loc, 2, GL_FLOAT, 0, 0, texture);
- glEnable(m_textureTarget);
- glActiveTextureARB(GL_TEXTURE0);
- glBindTexture(m_textureTarget, planes[0].id);
- glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+ glEnableVertexAttribArray(vertLoc);
+ glEnableVertexAttribArray(loc);
- glBegin(GL_QUADS);
- glTexCoord2f(planes[0].rect.x1, planes[0].rect.y1);
- glVertex4f(m_rotatedDestCoords[0].x, m_rotatedDestCoords[0].y, 0, 1.0f );
+ // Setup vertex position values
+ vertex[0][0] = m_rotatedDestCoords[0].x;
+ vertex[0][1] = m_rotatedDestCoords[0].y;
+ vertex[0][2] = 0.0f;
- glTexCoord2f(planes[0].rect.x2, planes[0].rect.y1);
- glVertex4f(m_rotatedDestCoords[1].x, m_rotatedDestCoords[1].y, 0, 1.0f);
+ vertex[1][0] = m_rotatedDestCoords[1].x;
+ vertex[1][1] = m_rotatedDestCoords[1].y;
+ vertex[1][2] = 0.0f;
- glTexCoord2f(planes[0].rect.x2, planes[0].rect.y2);
- glVertex4f(m_rotatedDestCoords[2].x, m_rotatedDestCoords[2].y, 0, 1.0f);
+ vertex[2][0] = m_rotatedDestCoords[2].x;
+ vertex[2][1] = m_rotatedDestCoords[2].y;
+ vertex[2][2] = 0.0f;
- glTexCoord2f(planes[0].rect.x1, planes[0].rect.y2);
- glVertex4f(m_rotatedDestCoords[3].x, m_rotatedDestCoords[3].y, 0, 1.0f);
+ vertex[3][0] = m_rotatedDestCoords[3].x;
+ vertex[3][1] = m_rotatedDestCoords[3].y;
+ vertex[3][2] = 0.0f;
- glEnd();
+ texture[0][0] = plane.rect.x1;
+ texture[0][1] = plane.rect.y1;
+ texture[1][0] = plane.rect.x2;
+ texture[1][1] = plane.rect.y1;
+ texture[2][0] = plane.rect.x2;
+ texture[2][1] = plane.rect.y2;
+ texture[3][0] = plane.rect.x1;
+ texture[3][1] = plane.rect.y2;
+ glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_BYTE, idx);
VerifyGLState();
+ m_pVideoFilterShader->Disable();
+
+ glBindTexture(m_textureTarget, 0);
glDisable(m_textureTarget);
- VerifyGLState();
}
bool CLinuxRendererGL::RenderCapture(CRenderCapture* capture)
@@ -2366,16 +2455,16 @@ bool CLinuxRendererGL::Supports(ESCALINGMETHOD method)
m_format != AV_PIX_FMT_UYVY422)
return true;
- if(method == VS_SCALINGMETHOD_LINEAR
- || method == VS_SCALINGMETHOD_AUTO)
+ if (method == VS_SCALINGMETHOD_LINEAR ||
+ method == VS_SCALINGMETHOD_AUTO)
return true;
- if(method == VS_SCALINGMETHOD_CUBIC
- || method == VS_SCALINGMETHOD_LANCZOS2
- || method == VS_SCALINGMETHOD_SPLINE36_FAST
- || method == VS_SCALINGMETHOD_LANCZOS3_FAST
- || method == VS_SCALINGMETHOD_SPLINE36
- || method == VS_SCALINGMETHOD_LANCZOS3)
+ if (method == VS_SCALINGMETHOD_CUBIC ||
+ method == VS_SCALINGMETHOD_LANCZOS2 ||
+ method == VS_SCALINGMETHOD_SPLINE36_FAST ||
+ method == VS_SCALINGMETHOD_LANCZOS3_FAST ||
+ method == VS_SCALINGMETHOD_SPLINE36 ||
+ method == VS_SCALINGMETHOD_LANCZOS3)
{
// if scaling is below level, avoid hq scaling
float scaleX = fabs(((float)m_sourceWidth - m_destRect.Width())/m_sourceWidth)*100;
diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/LinuxRendererGL.h b/xbmc/cores/VideoPlayer/VideoRenderers/LinuxRendererGL.h
index 8a6a0684d6..2de14acfb7 100644
--- a/xbmc/cores/VideoPlayer/VideoRenderers/LinuxRendererGL.h
+++ b/xbmc/cores/VideoPlayer/VideoRenderers/LinuxRendererGL.h
@@ -40,7 +40,7 @@
class CRenderCapture;
class CBaseTexture;
-namespace Shaders { class BaseYUV2RGBShader; }
+namespace Shaders { class BaseYUV2RGBGLSLShader; }
namespace Shaders { class BaseVideoFilterShader; }
struct DRAWRECT
@@ -158,7 +158,6 @@ protected:
void RenderToFBO(int renderBuffer, int field, bool weave = false);
void RenderFromFBO();
void RenderSinglePass(int renderBuffer, int field); // single pass glsl renderer
- void RenderSoftware(int renderBuffer, int field); // single pass s/w yuv2rgb renderer
void RenderRGB(int renderBuffer, int field); // render using vdpau/vaapi hardware
void RenderProgressiveWeave(int renderBuffer, int field); // render using vdpau hardware
@@ -227,7 +226,7 @@ protected:
void GetPlaneTextureSize(YUVPLANE& plane);
- Shaders::BaseYUV2RGBShader *m_pYUVShader;
+ Shaders::BaseYUV2RGBGLSLShader *m_pYUVShader;
Shaders::BaseVideoFilterShader *m_pVideoFilterShader;
ESCALINGMETHOD m_scalingMethod;
ESCALINGMETHOD m_scalingMethodGui;
diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/CMakeLists.txt b/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/CMakeLists.txt
index 49616e9751..ab6b1bc0dc 100644
--- a/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/CMakeLists.txt
+++ b/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/CMakeLists.txt
@@ -27,10 +27,10 @@ if(OPENGLES_FOUND AND (CORE_PLATFORM_NAME_LC STREQUAL android OR
CORE_PLATFORM_NAME_LC STREQUAL imx OR
CORE_PLATFORM_NAME_LC STREQUAL mir OR
CORE_PLATFORM_NAME_LC STREQUAL wayland))
- list(APPEND SOURCES GLSLOutput.cpp
+ list(APPEND SOURCES GLSLOutputGLES.cpp
VideoFilterShaderGLES.cpp
YUV2RGBShaderGLES.cpp)
- list(APPEND HEADERS GLSLOutput.h
+ list(APPEND HEADERS GLSLOutputGLES.h
VideoFilterShaderGLES.h
YUV2RGBShaderGLES.h)
endif()
diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/GLSLOutput.cpp b/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/GLSLOutput.cpp
index c01bf30d6e..3718bc8fe3 100644
--- a/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/GLSLOutput.cpp
+++ b/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/GLSLOutput.cpp
@@ -62,10 +62,8 @@ std::string GLSLOutput::GetDefines()
defines += "#define XBMC_DITHER\n";
if (m_fullRange)
defines += "#define XBMC_FULLRANGE\n";
-#ifdef HAS_GL
if (m_3DLUT)
defines += "#define KODI_3DLUT\n";
-#endif //HAS_GL
return defines;
}
@@ -84,10 +82,8 @@ void GLSLOutput::OnCompiledAndLinked(GLuint programHandle)
// 3DLUT
if (m_3DLUT)
{
-#ifdef HAS_GL
m_hCLUT = glGetUniformLocation(programHandle, "m_CLUT");
m_hCLUTSize = glGetUniformLocation(programHandle, "m_CLUTsize");
-#endif //HAS_GL
}
if (m_dither)
@@ -105,18 +101,14 @@ void GLSLOutput::OnCompiledAndLinked(GLuint programHandle)
glActiveTexture(GL_TEXTURE0 + m_uDither);
glBindTexture(GL_TEXTURE_2D, m_tDitherTex);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
-#if defined(HAS_GL)
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
-#endif
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
-#if defined(HAS_GL)
// load dither texture data
glTexImage2D(GL_TEXTURE_2D, 0, GL_R16, dither_size, dither_size, 0, GL_RED, GL_UNSIGNED_SHORT, dither_matrix);
-#endif
}
glActiveTexture(GL_TEXTURE0);
@@ -148,7 +140,6 @@ bool GLSLOutput::OnEnabled()
if (m_3DLUT)
{
-#ifdef HAS_GL
// set texture units
glUniform1i(m_hCLUT, m_uCLUT);
glUniform1f(m_hCLUTSize, m_uCLUTSize);
@@ -159,7 +150,6 @@ bool GLSLOutput::OnEnabled()
glBindTexture(GL_TEXTURE_3D, m_tCLUTTex);
glActiveTexture(GL_TEXTURE0);
VerifyGLState();
-#endif //HAS_GL
}
VerifyGLState();
@@ -176,10 +166,8 @@ void GLSLOutput::OnDisabled()
}
if (m_3DLUT)
{
-#ifdef HAS_GL
glActiveTexture(GL_TEXTURE0 + m_uCLUT);
glDisable(GL_TEXTURE_3D);
-#endif //HAS_GL
}
glActiveTexture(GL_TEXTURE0);
VerifyGLState();
diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/GLSLOutputGLES.cpp b/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/GLSLOutputGLES.cpp
new file mode 100644
index 0000000000..8a2798db9f
--- /dev/null
+++ b/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/GLSLOutputGLES.cpp
@@ -0,0 +1,200 @@
+/*
+ * Copyright (c) 2007 d4rk
+ * Copyright (C) 2007-2015 Team XBMC
+ * Copyright (C) 2015 Lauri Mylläri
+ * http://xbmc.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with XBMC; see the file COPYING. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "system_gl.h"
+#include "utils/log.h"
+
+#include "GLSLOutputGLES.h"
+#include "dither.h"
+
+using namespace Shaders;
+
+GLSLOutput::GLSLOutput(int texunit, bool useDithering, unsigned int ditherDepth, bool fullrange, GLuint clutTex, int clutSize)
+{
+ // set member variable initial values
+ m_1stTexUnit = texunit;
+ m_uDither = m_1stTexUnit+0;
+ m_uCLUT = m_1stTexUnit+1;
+
+ // textures
+ m_tDitherTex = 0;
+ m_tCLUTTex = clutTex;
+
+ // shader attribute handles
+ m_hDither = -1;
+ m_hDitherQuant = -1;
+ m_hDitherSize = -1;
+ m_hCLUT = -1;
+ m_hCLUTSize = -1;
+
+ m_dither = useDithering;
+ m_ditherDepth = ditherDepth;
+ m_fullRange = fullrange;
+ // make sure CMS is enabled - this allows us to keep the texture
+ // around to quickly switch between CMS on and off
+ m_3DLUT = clutTex > 0;
+ m_uCLUTSize = clutSize;
+}
+
+std::string GLSLOutput::GetDefines()
+{
+ std::string defines;
+ if (m_dither)
+ defines += "#define XBMC_DITHER\n";
+ if (m_fullRange)
+ defines += "#define XBMC_FULLRANGE\n";
+#ifdef HAS_GL
+ if (m_3DLUT)
+ defines += "#define KODI_3DLUT\n";
+#endif //HAS_GL
+ return defines;
+}
+
+void GLSLOutput::OnCompiledAndLinked(GLuint programHandle)
+{
+ FreeTextures();
+
+ // get uniform locations
+ // dithering
+ if (m_dither)
+ {
+ m_hDither = glGetUniformLocation(programHandle, "m_dither");
+ m_hDitherQuant = glGetUniformLocation(programHandle, "m_ditherquant");
+ m_hDitherSize = glGetUniformLocation(programHandle, "m_dithersize");
+ }
+ // 3DLUT
+ if (m_3DLUT)
+ {
+#ifdef HAS_GL
+ m_hCLUT = glGetUniformLocation(programHandle, "m_CLUT");
+ m_hCLUTSize = glGetUniformLocation(programHandle, "m_CLUTsize");
+#endif //HAS_GL
+ }
+
+ if (m_dither)
+ {
+ //! @todo create a dither pattern
+
+ // create a dither texture
+ glGenTextures(1, &m_tDitherTex);
+ if ( m_tDitherTex <= 0 )
+ {
+ CLog::Log(LOGERROR, "Error creating dither texture");
+ return;
+ }
+ // bind and set texture parameters
+ glActiveTexture(GL_TEXTURE0 + m_uDither);
+ glBindTexture(GL_TEXTURE_2D, m_tDitherTex);
+ glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+#if defined(HAS_GL)
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
+#endif
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+
+#if defined(HAS_GL)
+ // load dither texture data
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_R16, dither_size, dither_size, 0, GL_RED, GL_UNSIGNED_SHORT, dither_matrix);
+#endif
+ }
+
+ glActiveTexture(GL_TEXTURE0);
+
+ VerifyGLState();
+}
+
+bool GLSLOutput::OnEnabled()
+{
+
+ if (m_dither)
+ {
+ // set texture units
+ glUniform1i(m_hDither, m_uDither);
+ VerifyGLState();
+
+ // bind textures
+ glActiveTexture(GL_TEXTURE0 + m_uDither);
+ glBindTexture(GL_TEXTURE_2D, m_tDitherTex);
+ glActiveTexture(GL_TEXTURE0);
+ VerifyGLState();
+
+ // dither settings
+ glUniform1f(m_hDitherQuant, (1<<m_ditherDepth)-1.0);
+ VerifyGLState();
+ glUniform2f(m_hDitherSize, dither_size, dither_size);
+ VerifyGLState();
+ }
+
+ if (m_3DLUT)
+ {
+#ifdef HAS_GL
+ // set texture units
+ glUniform1i(m_hCLUT, m_uCLUT);
+ glUniform1f(m_hCLUTSize, m_uCLUTSize);
+ VerifyGLState();
+
+ // bind textures
+ glActiveTexture(GL_TEXTURE0 + m_uCLUT);
+ glBindTexture(GL_TEXTURE_3D, m_tCLUTTex);
+ glActiveTexture(GL_TEXTURE0);
+ VerifyGLState();
+#endif //HAS_GL
+ }
+
+ VerifyGLState();
+ return true;
+}
+
+void GLSLOutput::OnDisabled()
+{
+ // disable textures
+ if (m_dither)
+ {
+ glActiveTexture(GL_TEXTURE0 + m_uDither);
+ glDisable(GL_TEXTURE_2D);
+ }
+ if (m_3DLUT)
+ {
+#ifdef HAS_GL
+ glActiveTexture(GL_TEXTURE0 + m_uCLUT);
+ glDisable(GL_TEXTURE_3D);
+#endif //HAS_GL
+ }
+ glActiveTexture(GL_TEXTURE0);
+ VerifyGLState();
+}
+
+void GLSLOutput::Free()
+{
+ FreeTextures();
+}
+
+void GLSLOutput::FreeTextures()
+{
+ if (m_tDitherTex)
+ {
+ glDeleteTextures(1, &m_tDitherTex);
+ m_tDitherTex = 0;
+ }
+}
diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/GLSLOutputGLES.h b/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/GLSLOutputGLES.h
new file mode 100644
index 0000000000..047aba0361
--- /dev/null
+++ b/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/GLSLOutputGLES.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2007-2015 Team XBMC
+ * Copyright (C) 2015 Lauri Mylläri
+ * http://xbmc.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with XBMC; see the file COPYING. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ */
+#pragma once
+
+#include "system.h"
+#include "utils/GLUtils.h"
+
+namespace Shaders
+{
+ class GLSLOutput
+ {
+ public:
+ // take the 1st available texture unit as a parameter
+ GLSLOutput(
+ int texunit,
+ bool useDithering,
+ unsigned int ditherDepth,
+ bool fullrange,
+ GLuint clutTex,
+ int clutSize);
+ std::string GetDefines();
+ void OnCompiledAndLinked(GLuint programHandle);
+ bool OnEnabled();
+ void OnDisabled();
+ void Free();
+
+ private:
+ void FreeTextures();
+
+ bool m_dither;
+ unsigned int m_ditherDepth;
+ bool m_fullRange;
+ bool m_3DLUT;
+ // first texture unit available to us
+ int m_1stTexUnit;
+ int m_uDither;
+ int m_uCLUT;
+ int m_uCLUTSize;
+
+ // defines
+
+ // attribute locations
+ GLint m_hDither;
+ GLint m_hDitherQuant;
+ GLint m_hDitherSize;
+ GLint m_hCLUT;
+ GLint m_hCLUTSize;
+
+ // textures
+ GLuint m_tDitherTex;
+ GLuint m_tCLUTTex;
+ };
+}
diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/VideoFilterShaderGL.cpp b/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/VideoFilterShaderGL.cpp
index 8db8e9a1cd..7d670f0128 100644
--- a/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/VideoFilterShaderGL.cpp
+++ b/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/VideoFilterShaderGL.cpp
@@ -30,12 +30,8 @@
#include "ConvolutionKernels.h"
#include "windowing/WindowingFactory.h"
-#if defined(HAS_GL)
- #define USE1DTEXTURE
- #define TEXTARGET GL_TEXTURE_1D
-#else
- #define TEXTARGET GL_TEXTURE_2D
-#endif
+#define USE1DTEXTURE
+#define TEXTARGET GL_TEXTURE_1D
using namespace Shaders;
@@ -52,30 +48,22 @@ BaseVideoFilterShader::BaseVideoFilterShader()
m_stepY = 0;
m_sourceTexUnit = 0;
m_hSourceTex = 0;
-
m_stretch = 0.0f;
- std::string shaderv =
- "varying vec2 cord;"
- "void main()"
- "{"
- "cord = vec2(gl_TextureMatrix[0] * gl_MultiTexCoord0);"
- "gl_Position = ftransform();"
- "gl_FrontColor = gl_Color;"
- "}";
- VertexShader()->SetSource(shaderv);
-
- std::string shaderp =
- "uniform sampler2D img;"
- "varying vec2 cord;"
- "void main()"
- "{"
- "gl_FragColor.rgb = texture2D(img, cord).rgb;"
- "gl_FragColor.a = gl_Color.a;"
- "}";
- PixelShader()->SetSource(shaderp);
+ VertexShader()->LoadSource("gl_videofilter_vertex.glsl");
+
+ PixelShader()->LoadSource("gl_videofilter_frag.glsl");
+}
+
+BaseVideoFilterShader::~BaseVideoFilterShader()
+{
+ Free();
}
+//////////////////////////////////////////////////////////////////////
+// ConvolutionFilterShader - base class for video filter shaders
+//////////////////////////////////////////////////////////////////////
+
ConvolutionFilterShader::ConvolutionFilterShader(ESCALINGMETHOD method, bool stretch, GLSLOutput *output)
{
m_method = method;
@@ -84,34 +72,28 @@ ConvolutionFilterShader::ConvolutionFilterShader(ESCALINGMETHOD method, bool str
std::string shadername;
std::string defines;
-#if defined(HAS_GL)
m_floattex = g_Windowing.IsExtSupported("GL_ARB_texture_float");
-#elif HAS_GLES >= 2
- m_floattex = false;
-#endif
if (m_method == VS_SCALINGMETHOD_CUBIC ||
m_method == VS_SCALINGMETHOD_LANCZOS2 ||
m_method == VS_SCALINGMETHOD_SPLINE36_FAST ||
m_method == VS_SCALINGMETHOD_LANCZOS3_FAST)
{
- shadername = "convolution-4x4.glsl";
-#if defined(HAS_GL)
+ shadername = "gl_convolution-4x4.glsl";
+
if (m_floattex)
m_internalformat = GL_RGBA16F_ARB;
else
-#endif
m_internalformat = GL_RGBA;
}
else if (m_method == VS_SCALINGMETHOD_SPLINE36 ||
m_method == VS_SCALINGMETHOD_LANCZOS3)
{
- shadername = "convolution-6x6.glsl";
-#if defined(HAS_GL)
+ shadername = "gl_convolution-6x6.glsl";
+
if (m_floattex)
m_internalformat = GL_RGB16F_ARB;
else
-#endif
m_internalformat = GL_RGB;
}
@@ -141,7 +123,7 @@ ConvolutionFilterShader::ConvolutionFilterShader(ESCALINGMETHOD method, bool str
CLog::Log(LOGDEBUG, "GL: ConvolutionFilterShader: using %s defines:\n%s", shadername.c_str(), defines.c_str());
PixelShader()->LoadSource(shadername, defines);
- PixelShader()->AppendSource("output.glsl");
+ PixelShader()->AppendSource("gl_output.glsl");
}
ConvolutionFilterShader::~ConvolutionFilterShader()
@@ -153,9 +135,13 @@ void ConvolutionFilterShader::OnCompiledAndLinked()
{
// obtain shader attribute handles on successful compilation
m_hSourceTex = glGetUniformLocation(ProgramHandle(), "img");
- m_hStepXY = glGetUniformLocation(ProgramHandle(), "stepxy");
- m_hKernTex = glGetUniformLocation(ProgramHandle(), "kernelTex");
- m_hStretch = glGetUniformLocation(ProgramHandle(), "m_stretch");
+ m_hStepXY = glGetUniformLocation(ProgramHandle(), "stepxy");
+ m_hKernTex = glGetUniformLocation(ProgramHandle(), "kernelTex");
+ m_hStretch = glGetUniformLocation(ProgramHandle(), "m_stretch");
+ m_hProj = glGetUniformLocation(ProgramHandle(), "m_proj");
+ m_hModel = glGetUniformLocation(ProgramHandle(), "m_model");
+ m_hVertex = glGetAttribLocation(ProgramHandle(), "m_attrpos");
+ m_hCoord = glGetAttribLocation(ProgramHandle(), "m_attrcord");
CConvolutionKernel kernel(m_method, 256);
@@ -222,6 +208,10 @@ bool ConvolutionFilterShader::OnEnabled()
glUniform1i(m_hKernTex, 2);
glUniform2f(m_hStepXY, m_stepX, m_stepY);
glUniform1f(m_hStretch, m_stretch);
+
+ glUniformMatrix4fv(m_hProj, 1, GL_FALSE, m_proj);
+ glUniformMatrix4fv(m_hModel, 1, GL_FALSE, m_model);
+
VerifyGLState();
if (m_glslOutput) m_glslOutput->OnEnabled();
return true;
@@ -241,33 +231,53 @@ void ConvolutionFilterShader::Free()
BaseVideoFilterShader::Free();
}
+//////////////////////////////////////////////////////////////////////
+// StretchFilterShader - base class for video filter shaders
+//////////////////////////////////////////////////////////////////////
+
StretchFilterShader::StretchFilterShader()
{
- PixelShader()->LoadSource("stretch.glsl");
+ PixelShader()->LoadSource("gl_stretch.glsl");
}
void StretchFilterShader::OnCompiledAndLinked()
{
m_hSourceTex = glGetUniformLocation(ProgramHandle(), "img");
- m_hStretch = glGetUniformLocation(ProgramHandle(), "m_stretch");
+ m_hStretch = glGetUniformLocation(ProgramHandle(), "m_stretch");
+ m_hProj = glGetUniformLocation(ProgramHandle(), "m_proj");
+ m_hModel = glGetUniformLocation(ProgramHandle(), "m_model");
+ m_hVertex = glGetAttribLocation(ProgramHandle(), "m_attrpos");
+ m_hCoord = glGetAttribLocation(ProgramHandle(), "m_attrcord");
}
bool StretchFilterShader::OnEnabled()
{
glUniform1i(m_hSourceTex, m_sourceTexUnit);
glUniform1f(m_hStretch, m_stretch);
+ glUniformMatrix4fv(m_hProj, 1, GL_FALSE, m_proj);
+ glUniformMatrix4fv(m_hModel, 1, GL_FALSE, m_model);
VerifyGLState();
return true;
}
+//////////////////////////////////////////////////////////////////////
+// DefaultFilterShader - base class for video filter shaders
+//////////////////////////////////////////////////////////////////////
+
void DefaultFilterShader::OnCompiledAndLinked()
{
m_hSourceTex = glGetUniformLocation(ProgramHandle(), "img");
+ m_hProj = glGetUniformLocation(ProgramHandle(), "m_proj");
+ m_hModel = glGetUniformLocation(ProgramHandle(), "m_model");
+ m_hVertex = glGetAttribLocation(ProgramHandle(), "m_attrpos");
+ m_hCoord = glGetAttribLocation(ProgramHandle(), "m_attrcord");
}
bool DefaultFilterShader::OnEnabled()
{
glUniform1i(m_hSourceTex, m_sourceTexUnit);
+ glUniformMatrix4fv(m_hProj, 1, GL_FALSE, m_proj);
+ glUniformMatrix4fv(m_hModel, 1, GL_FALSE, m_model);
VerifyGLState();
return true;
}
diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/VideoFilterShaderGL.h b/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/VideoFilterShaderGL.h
index b9a7eaacb0..5d821516ec 100644
--- a/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/VideoFilterShaderGL.h
+++ b/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/VideoFilterShaderGL.h
@@ -22,10 +22,7 @@
#include "system.h"
-#if defined(HAS_GL) || HAS_GLES >= 2
#include "system_gl.h"
-
-
#include "guilib/Shader.h"
#include "settings/VideoSettings.h"
#include "GLSLOutput.h"
@@ -36,13 +33,18 @@ namespace Shaders {
{
public:
BaseVideoFilterShader();
- void Free() override { CGLSLShaderProgram::Free(); }
+ virtual ~BaseVideoFilterShader();
virtual void SetSourceTexture(GLint ytex) { m_sourceTexUnit = ytex; }
virtual void SetWidth(int w) { m_width = w; m_stepX = w>0?1.0f/w:0; }
virtual void SetHeight(int h) { m_height = h; m_stepY = h>0?1.0f/h:0; }
virtual void SetNonLinStretch(float stretch) { m_stretch = stretch; }
virtual bool GetTextureFilter(GLint& filter) { return false; }
+ GLint GetVertexLoc() { return m_hVertex; }
+ GLint GetCoordLoc() { return m_hCoord; }
+
+ void SetMatrices(GLfloat *p, GLfloat *m) { m_proj = p; m_model = m; }
+
protected:
int m_width;
int m_height;
@@ -50,11 +52,17 @@ namespace Shaders {
float m_stepY;
float m_stretch;
GLint m_sourceTexUnit;
+ GLfloat *m_proj = nullptr;
+ GLfloat *m_model = nullptr;
// shader attribute handles
GLint m_hSourceTex;
GLint m_hStepXY;
GLint m_hStretch = 0;
+ GLint m_hVertex = -1;
+ GLint m_hCoord = -1;
+ GLint m_hProj = -1;
+ GLint m_hModel = -1;
};
class ConvolutionFilterShader : public BaseVideoFilterShader
@@ -100,5 +108,4 @@ namespace Shaders {
} // end namespace
-#endif
diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/VideoFilterShaderGLES.h b/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/VideoFilterShaderGLES.h
index 48520c59c2..243048264f 100644
--- a/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/VideoFilterShaderGLES.h
+++ b/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/VideoFilterShaderGLES.h
@@ -28,7 +28,7 @@
#include "guilib/Shader.h"
#include "settings/VideoSettings.h"
-#include "GLSLOutput.h"
+#include "GLSLOutputGLES.h"
namespace Shaders {
@@ -116,4 +116,3 @@ namespace Shaders {
} // end namespace
#endif
-
diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/YUV2RGBShaderGL.cpp b/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/YUV2RGBShaderGL.cpp
index 5549ff313f..38a8731d52 100644
--- a/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/YUV2RGBShaderGL.cpp
+++ b/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/YUV2RGBShaderGL.cpp
@@ -60,24 +60,15 @@ static void CalculateYUVMatrixGL(GLfloat res[4][4]
BaseYUV2RGBGLSLShader::BaseYUV2RGBGLSLShader(bool rect, unsigned flags, EShaderFormat format, bool stretch,
GLSLOutput *output)
{
- m_width = 1;
- m_height = 1;
- m_field = 0;
- m_flags = flags;
- m_format = format;
-
- m_black = 0.0f;
- m_contrast = 1.0f;
-
+ m_width = 1;
+ m_height = 1;
+ m_field = 0;
+ m_flags = flags;
+ m_format = format;
+ m_black = 0.0f;
+ m_contrast = 1.0f;
m_stretch = 0.0f;
- // shader attribute handles
- m_hYTex = -1;
- m_hUTex = -1;
- m_hVTex = -1;
- m_hStretch = -1;
- m_hStep = -1;
-
// get defines from the output stage if used
m_glslOutput = output;
if (m_glslOutput) {
@@ -120,7 +111,7 @@ BaseYUV2RGBGLSLShader::BaseYUV2RGBGLSLShader(bool rect, unsigned flags, EShaderF
else
CLog::Log(LOGERROR, "GL: BaseYUV2RGBGLSLShader - unsupported format %d", m_format);
- VertexShader()->LoadSource("yuv2rgb_vertex.glsl", m_defines);
+ VertexShader()->LoadSource("gl_yuv2rgb_vertex.glsl", m_defines);
CLog::Log(LOGDEBUG, "GL: BaseYUV2RGBGLSLShader: defines:\n%s", m_defines.c_str());
}
@@ -132,15 +123,23 @@ BaseYUV2RGBGLSLShader::~BaseYUV2RGBGLSLShader()
void BaseYUV2RGBGLSLShader::OnCompiledAndLinked()
{
- m_hYTex = glGetUniformLocation(ProgramHandle(), "m_sampY");
- m_hUTex = glGetUniformLocation(ProgramHandle(), "m_sampU");
- m_hVTex = glGetUniformLocation(ProgramHandle(), "m_sampV");
- m_hMatrix = glGetUniformLocation(ProgramHandle(), "m_yuvmat");
+ m_hYTex = glGetUniformLocation(ProgramHandle(), "m_sampY");
+ m_hUTex = glGetUniformLocation(ProgramHandle(), "m_sampU");
+ m_hVTex = glGetUniformLocation(ProgramHandle(), "m_sampV");
+ m_hMatrix = glGetUniformLocation(ProgramHandle(), "m_yuvmat");
m_hStretch = glGetUniformLocation(ProgramHandle(), "m_stretch");
- m_hStep = glGetUniformLocation(ProgramHandle(), "m_step");
+ m_hStep = glGetUniformLocation(ProgramHandle(), "m_step");
+ m_hVertex = glGetAttribLocation(ProgramHandle(), "m_attrpos");
+ m_hYcoord = glGetAttribLocation(ProgramHandle(), "m_attrcordY");
+ m_hUcoord = glGetAttribLocation(ProgramHandle(), "m_attrcordU");
+ m_hVcoord = glGetAttribLocation(ProgramHandle(), "m_attrcordV");
+ m_hProj = glGetUniformLocation(ProgramHandle(), "m_proj");
+ m_hModel = glGetUniformLocation(ProgramHandle(), "m_model");
+ m_hAlpha = glGetUniformLocation(ProgramHandle(), "m_alpha");
VerifyGLState();
- if (m_glslOutput) m_glslOutput->OnCompiledAndLinked(ProgramHandle());
+ if (m_glslOutput)
+ m_glslOutput->OnCompiledAndLinked(ProgramHandle());
}
bool BaseYUV2RGBGLSLShader::OnEnabled()
@@ -157,36 +156,26 @@ bool BaseYUV2RGBGLSLShader::OnEnabled()
CalculateYUVMatrixGL(matrix, m_flags, m_format, m_black, m_contrast, !m_convertFullRange);
glUniformMatrix4fv(m_hMatrix, 1, GL_FALSE, (GLfloat*)matrix);
+ glUniformMatrix4fv(m_hProj, 1, GL_FALSE, m_proj);
+ glUniformMatrix4fv(m_hModel, 1, GL_FALSE, m_model);
+ glUniform1f(m_hAlpha, m_alpha);
VerifyGLState();
- if (m_glslOutput) m_glslOutput->OnEnabled();
+ if (m_glslOutput)
+ m_glslOutput->OnEnabled();
return true;
}
void BaseYUV2RGBGLSLShader::OnDisabled()
{
- if (m_glslOutput) m_glslOutput->OnDisabled();
+ if (m_glslOutput)
+ m_glslOutput->OnDisabled();
}
void BaseYUV2RGBGLSLShader::Free()
{
- if (m_glslOutput) m_glslOutput->Free();
-}
-//////////////////////////////////////////////////////////////////////
-// BaseYUV2RGBGLSLShader - base class for GLSL YUV2RGB shaders
-//////////////////////////////////////////////////////////////////////
-BaseYUV2RGBARBShader::BaseYUV2RGBARBShader(unsigned flags, EShaderFormat format)
-{
- m_width = 1;
- m_height = 1;
- m_field = 0;
- m_flags = flags;
- m_format = format;
-
- // shader attribute handles
- m_hYTex = -1;
- m_hUTex = -1;
- m_hVTex = -1;
+ if (m_glslOutput)
+ m_glslOutput->Free();
}
//////////////////////////////////////////////////////////////////////
@@ -198,101 +187,7 @@ YUV2RGBProgressiveShader::YUV2RGBProgressiveShader(bool rect, unsigned flags, ES
GLSLOutput *output)
: BaseYUV2RGBGLSLShader(rect, flags, format, stretch, output)
{
- PixelShader()->LoadSource("yuv2rgb_basic.glsl", m_defines);
- PixelShader()->AppendSource("output.glsl");
-}
-
-
-//////////////////////////////////////////////////////////////////////
-// YUV2RGBBobShader - YUV2RGB with Bob deinterlacing
-//////////////////////////////////////////////////////////////////////
-
-YUV2RGBBobShader::YUV2RGBBobShader(bool rect, unsigned flags, EShaderFormat format)
- : BaseYUV2RGBGLSLShader(rect, flags, format, false)
-{
- m_hStepX = -1;
- m_hStepY = -1;
- m_hField = -1;
- PixelShader()->LoadSource("yuv2rgb_bob.glsl", m_defines);
-}
-
-void YUV2RGBBobShader::OnCompiledAndLinked()
-{
- BaseYUV2RGBGLSLShader::OnCompiledAndLinked();
- m_hStepX = glGetUniformLocation(ProgramHandle(), "m_stepX");
- m_hStepY = glGetUniformLocation(ProgramHandle(), "m_stepY");
- m_hField = glGetUniformLocation(ProgramHandle(), "m_field");
- VerifyGLState();
-}
-
-bool YUV2RGBBobShader::OnEnabled()
-{
- if(!BaseYUV2RGBGLSLShader::OnEnabled())
- return false;
-
- glUniform1i(m_hField, m_field);
- glUniform1f(m_hStepX, 1.0f / (float)m_width);
- glUniform1f(m_hStepY, 1.0f / (float)m_height);
- VerifyGLState();
- return true;
-}
-
-//////////////////////////////////////////////////////////////////////
-// YUV2RGBProgressiveShaderARB - YUV2RGB with no deinterlacing
-//////////////////////////////////////////////////////////////////////
-YUV2RGBProgressiveShaderARB::YUV2RGBProgressiveShaderARB(bool rect, unsigned flags, EShaderFormat format)
- : BaseYUV2RGBARBShader(flags, format)
-{
- m_black = 0.0f;
- m_contrast = 1.0f;
-
- std::string shaderfile;
-
- if (m_format == SHADER_YUY2)
- {
- if(rect)
- shaderfile = "yuv2rgb_basic_rect_YUY2.arb";
- else
- shaderfile = "yuv2rgb_basic_2d_YUY2.arb";
- }
- else if (m_format == SHADER_UYVY)
- {
- if(rect)
- shaderfile = "yuv2rgb_basic_rect_UYVY.arb";
- else
- shaderfile = "yuv2rgb_basic_2d_UYVY.arb";
- }
- else
- {
- if(rect)
- shaderfile = "yuv2rgb_basic_rect.arb";
- else
- shaderfile = "yuv2rgb_basic_2d.arb";
- }
-
- CLog::Log(LOGDEBUG, "GL: YUV2RGBProgressiveShaderARB: loading %s", shaderfile.c_str());
-
- PixelShader()->LoadSource(shaderfile);
-}
-
-void YUV2RGBProgressiveShaderARB::OnCompiledAndLinked()
-{
+ PixelShader()->LoadSource("gl_yuv2rgb_basic.glsl", m_defines);
+ PixelShader()->AppendSource("gl_output.glsl");
}
-bool YUV2RGBProgressiveShaderARB::OnEnabled()
-{
- GLfloat matrix[4][4];
- CalculateYUVMatrixGL(matrix, m_flags, m_format, m_black, m_contrast, !m_convertFullRange);
-
- for(int i=0;i<4;i++)
- glProgramLocalParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, i
- , matrix[0][i]
- , matrix[1][i]
- , matrix[2][i]
- , matrix[3][i]);
-
- glProgramLocalParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 4,
- 1.0 / m_width, 1.0 / m_height,
- m_width, m_height);
- return true;
-}
diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/YUV2RGBShaderGL.h b/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/YUV2RGBShaderGL.h
index e8220f2c05..bb3fcd57a4 100644
--- a/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/YUV2RGBShaderGL.h
+++ b/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/YUV2RGBShaderGL.h
@@ -40,47 +40,37 @@ void CalculateYUVMatrix(TransformMatrix &matrix
namespace Shaders {
- class BaseYUV2RGBShader : virtual public CShaderProgram
+ class BaseYUV2RGBGLSLShader : public CGLSLShaderProgram
{
public:
- BaseYUV2RGBShader() : m_convertFullRange(false) {};
- ~BaseYUV2RGBShader() override = default;
- virtual void SetField(int field) {};
- virtual void SetWidth(int width) {};
- virtual void SetHeight(int width) {};
+ BaseYUV2RGBGLSLShader(bool rect, unsigned flags, EShaderFormat format, bool stretch, GLSLOutput *output=NULL);
+ ~BaseYUV2RGBGLSLShader();
+ void Free() override;
- virtual void SetBlack(float black) {};
- virtual void SetContrast(float contrast) {};
- virtual void SetNonLinStretch(float stretch) {};
+ void SetField(int field) { m_field = field; }
+ void SetWidth(int w) { m_width = w; }
+ void SetHeight(int h) { m_height = h; }
- void SetConvertFullColorRange(bool convertFullRange) { m_convertFullRange = convertFullRange; }
-
- protected:
- bool m_convertFullRange;
- };
+ void SetBlack(float black) { m_black = black; }
+ void SetContrast(float contrast) { m_contrast = contrast; }
+ void SetNonLinStretch(float stretch) { m_stretch = stretch; }
+ void SetConvertFullColorRange(bool convertFullRange) { m_convertFullRange = convertFullRange; }
- class BaseYUV2RGBGLSLShader
- : public BaseYUV2RGBShader
- , public CGLSLShaderProgram
- {
- public:
- BaseYUV2RGBGLSLShader(bool rect, unsigned flags, EShaderFormat format, bool stretch, GLSLOutput *output=NULL);
- ~BaseYUV2RGBGLSLShader() override;
- void SetField(int field) override { m_field = field; }
- void SetWidth(int w) override { m_width = w; }
- void SetHeight(int h) override { m_height = h; }
+ GLint GetVertexLoc() { return m_hVertex; }
+ GLint GetYcoordLoc() { return m_hYcoord; }
+ GLint GetUcoordLoc() { return m_hUcoord; }
+ GLint GetVcoordLoc() { return m_hVcoord; }
- void SetBlack(float black) override { m_black = black; }
- void SetContrast(float contrast) override { m_contrast = contrast; }
- void SetNonLinStretch(float stretch) override { m_stretch = stretch; }
+ void SetMatrices(GLfloat *p, GLfloat *m) { m_proj = p; m_model = m; }
+ void SetAlpha(GLfloat alpha) { m_alpha = alpha; }
protected:
void OnCompiledAndLinked() override;
bool OnEnabled() override;
void OnDisabled() override;
- void Free() override;
+ bool m_convertFullRange;
unsigned m_flags;
EShaderFormat m_format;
int m_width;
@@ -91,55 +81,30 @@ namespace Shaders {
float m_contrast;
float m_stretch;
+ GLfloat *m_proj = nullptr;
+ GLfloat *m_model = nullptr;
+ GLfloat m_alpha = 1.0f;
+
std::string m_defines;
Shaders::GLSLOutput *m_glslOutput;
- // shader attribute handles
- GLint m_hYTex;
- GLint m_hUTex;
- GLint m_hVTex;
- GLint m_hMatrix;
- GLint m_hStretch;
- GLint m_hStep;
- };
-
- class BaseYUV2RGBARBShader
- : public BaseYUV2RGBShader
- , public CARBShaderProgram
- {
- public:
- BaseYUV2RGBARBShader(unsigned flags, EShaderFormat format);
- ~BaseYUV2RGBARBShader() override = default;
- void SetField(int field) override { m_field = field; }
- void SetWidth(int w) override { m_width = w; }
- void SetHeight(int h) override { m_height = h; }
-
- void SetBlack(float black) override { m_black = black; }
- void SetContrast(float contrast) override { m_contrast = contrast; }
-
- protected:
- unsigned m_flags;
- EShaderFormat m_format;
- int m_width;
- int m_height;
- int m_field;
-
- float m_black;
- float m_contrast;
-
- // shader attribute handles
- GLint m_hYTex;
- GLint m_hUTex;
- GLint m_hVTex;
- };
-
- class YUV2RGBProgressiveShaderARB : public BaseYUV2RGBARBShader
- {
- public:
- YUV2RGBProgressiveShaderARB(bool rect=false, unsigned flags=0, EShaderFormat format=SHADER_NONE);
- void OnCompiledAndLinked() override;
- bool OnEnabled() override;
+ // pixel shader attribute handles
+ GLint m_hYTex = -1;
+ GLint m_hUTex = -1;
+ GLint m_hVTex = -1;
+ GLint m_hMatrix = -1;
+ GLint m_hStretch = -1;
+ GLint m_hStep = -1;
+
+ // vertex shader attribute handles
+ GLint m_hVertex = -1;
+ GLint m_hYcoord = -1;
+ GLint m_hUcoord = -1;
+ GLint m_hVcoord = -1;
+ GLint m_hProj = -1;
+ GLint m_hModel = -1;
+ GLint m_hAlpha = -1;
};
class YUV2RGBProgressiveShader : public BaseYUV2RGBGLSLShader
@@ -152,18 +117,6 @@ namespace Shaders {
GLSLOutput *output=NULL);
};
- class YUV2RGBBobShader : public BaseYUV2RGBGLSLShader
- {
- public:
- YUV2RGBBobShader(bool rect=false, unsigned flags=0, EShaderFormat format=SHADER_NONE);
- void OnCompiledAndLinked() override;
- bool OnEnabled() override;
-
- GLint m_hStepX;
- GLint m_hStepY;
- GLint m_hField;
- };
-
} // end namespace
#ifndef __GNUC__
diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/YUV2RGBShaderGLES.h b/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/YUV2RGBShaderGLES.h
index ff36c3c533..d376bfb271 100644
--- a/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/YUV2RGBShaderGLES.h
+++ b/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/YUV2RGBShaderGLES.h
@@ -29,7 +29,7 @@ void CalculateYUVMatrix(TransformMatrix &matrix
, float contrast
, bool limited);
-#include "GLSLOutput.h"
+#include "GLSLOutputGLES.h"
#ifndef __GNUC__
#pragma warning( push )