From c4c88062582ca87d6df4e48aa4cf79a5adb3301c Mon Sep 17 00:00:00 2001
From: Rainer Hochecker <fernetmenta@online.de>
Date: Wed, 27 Sep 2017 08:05:54 +0200
Subject: VideoPlayer: OpenGL - drop fixed function pipeline

---
 system/shaders/gl_convolution-4x4.glsl             | 113 ++++
 system/shaders/gl_convolution-6x6.glsl             | 124 ++++
 system/shaders/gl_output.glsl                      |  58 ++
 system/shaders/gl_streatch.glsl                    |  40 ++
 system/shaders/gl_videofilter_frag.glsl            |  30 +
 system/shaders/gl_videofilter_vertex.glsl          |  34 ++
 system/shaders/gl_yuv2rgb_basic.glsl               | 122 ++++
 system/shaders/gl_yuv2rgb_vertex.glsl              |  38 ++
 system/shaders/yuv2rgb_vertex.glsl                 |  38 --
 .../VideoPlayer/VideoRenderers/BaseRenderer.cpp    |   1 -
 .../VideoPlayer/VideoRenderers/BaseRenderer.h      |   1 -
 .../VideoPlayer/VideoRenderers/LinuxRendererGL.cpp | 655 ++++++++++++---------
 .../VideoPlayer/VideoRenderers/LinuxRendererGL.h   |   5 +-
 .../VideoRenderers/VideoShaders/CMakeLists.txt     |   4 +-
 .../VideoRenderers/VideoShaders/GLSLOutput.cpp     |  12 -
 .../VideoRenderers/VideoShaders/GLSLOutputGLES.cpp | 200 +++++++
 .../VideoRenderers/VideoShaders/GLSLOutputGLES.h   |  71 +++
 .../VideoShaders/VideoFilterShaderGL.cpp           |  94 +--
 .../VideoShaders/VideoFilterShaderGL.h             |  17 +-
 .../VideoShaders/VideoFilterShaderGLES.h           |   3 +-
 .../VideoShaders/YUV2RGBShaderGL.cpp               | 171 ++----
 .../VideoRenderers/VideoShaders/YUV2RGBShaderGL.h  | 123 ++--
 .../VideoShaders/YUV2RGBShaderGLES.h               |   2 +-
 23 files changed, 1343 insertions(+), 613 deletions(-)
 create mode 100644 system/shaders/gl_convolution-4x4.glsl
 create mode 100644 system/shaders/gl_convolution-6x6.glsl
 create mode 100644 system/shaders/gl_output.glsl
 create mode 100644 system/shaders/gl_streatch.glsl
 create mode 100644 system/shaders/gl_videofilter_frag.glsl
 create mode 100644 system/shaders/gl_videofilter_vertex.glsl
 create mode 100644 system/shaders/gl_yuv2rgb_basic.glsl
 create mode 100644 system/shaders/gl_yuv2rgb_vertex.glsl
 delete mode 100644 system/shaders/yuv2rgb_vertex.glsl
 create mode 100644 xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/GLSLOutputGLES.cpp
 create mode 100644 xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/GLSLOutputGLES.h

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/gl_yuv2rgb_vertex.glsl b/system/shaders/gl_yuv2rgb_vertex.glsl
new file mode 100644
index 0000000000..cdf3c56a71
--- /dev/null
+++ b/system/shaders/gl_yuv2rgb_vertex.glsl
@@ -0,0 +1,38 @@
+/*
+ *      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/>.
+ *
+ */
+
+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 ()
+{
+  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/system/shaders/yuv2rgb_vertex.glsl b/system/shaders/yuv2rgb_vertex.glsl
deleted file mode 100644
index 2225040f9c..0000000000
--- a/system/shaders/yuv2rgb_vertex.glsl
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- *      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/>.
- *
- */
-
-varying vec2 m_cordY;
-varying vec2 m_cordU;
-varying vec2 m_cordV;
-
-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;
-}
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 )
-- 
cgit v1.2.3