diff options
12 files changed, 635 insertions, 299 deletions
diff --git a/system/shaders/yuv2rgb_basic.glsl b/system/shaders/yuv2rgb_basic.glsl index 59cac3eaa8..7141ffe68d 100644 --- a/system/shaders/yuv2rgb_basic.glsl +++ b/system/shaders/yuv2rgb_basic.glsl @@ -24,19 +24,24 @@ # define sampler2D sampler2DRect #endif +#ifdef GL_ES + precision mediump float; +#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; +#ifdef GL_ES + uniform float m_alpha; +#endif + vec2 stretch(vec2 pos) { #if (XBMC_STRETCH) @@ -67,7 +72,12 @@ vec4 process() , 1.0 ); rgb = m_yuvmat * yuv; + +#ifdef GL_ES + rgb.a = m_alpha; +#else rgb.a = gl_Color.a; +#endif #elif defined(XBMC_NV12_RRG) @@ -78,7 +88,12 @@ vec4 process() , 1.0 ); rgb = m_yuvmat * yuv; + +#ifdef GL_ES + rgb.a = m_alpha; +#else rgb.a = gl_Color.a; +#endif #elif defined(XBMC_YUY2) || defined(XBMC_UYVY) @@ -117,9 +132,14 @@ vec4 process() vec4 yuv = vec4(outY, outUV, 1.0); rgb = m_yuvmat * yuv; +#ifdef GL_ES + rgb.a = m_alpha; +#else rgb.a = gl_Color.a; #endif +#endif + return rgb; } diff --git a/system/shaders/yuv2rgb_basic_gles.glsl b/system/shaders/yuv2rgb_basic_gles.glsl deleted file mode 100644 index 82fa003b53..0000000000 --- a/system/shaders/yuv2rgb_basic_gles.glsl +++ /dev/null @@ -1,50 +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/>. - * - */ - -precision mediump float; -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 float m_alpha; -uniform mat4 m_yuvmat; - -// handles both YV12 and NV12 formats -void main() -{ - vec4 yuv, rgb; -#if defined(XBMC_NV12_RRG) - yuv.rgba = vec4( texture2D(m_sampY, m_cordY).r - , texture2D(m_sampU, m_cordU).r - , texture2D(m_sampV, m_cordV).g - , 1.0); -#else - yuv.rgba = vec4( texture2D(m_sampY, m_cordY).r - , texture2D(m_sampU, m_cordU).g - , texture2D(m_sampV, m_cordV).a - , 1.0); -#endif - - rgb = m_yuvmat * yuv; - rgb.a = m_alpha; - gl_FragColor = rgb; -} diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/LinuxRendererGL.cpp b/xbmc/cores/VideoPlayer/VideoRenderers/LinuxRendererGL.cpp index ac2f1db709..f2fdff50ce 100644 --- a/xbmc/cores/VideoPlayer/VideoRenderers/LinuxRendererGL.cpp +++ b/xbmc/cores/VideoPlayer/VideoRenderers/LinuxRendererGL.cpp @@ -32,7 +32,7 @@ #include "settings/DisplaySettings.h" #include "settings/MediaSettings.h" #include "settings/Settings.h" -#include "VideoShaders/YUV2RGBShader.h" +#include "VideoShaders/YUV2RGBShaderGL.h" #include "VideoShaders/VideoFilterShaderGL.h" #include "windowing/WindowingFactory.h" #include "guilib/Texture.h" diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/LinuxRendererGLES.cpp b/xbmc/cores/VideoPlayer/VideoRenderers/LinuxRendererGLES.cpp index 38946dd6b1..f25883ad7b 100644 --- a/xbmc/cores/VideoPlayer/VideoRenderers/LinuxRendererGLES.cpp +++ b/xbmc/cores/VideoPlayer/VideoRenderers/LinuxRendererGLES.cpp @@ -36,7 +36,7 @@ #include "settings/DisplaySettings.h" #include "settings/MediaSettings.h" #include "settings/Settings.h" -#include "VideoShaders/YUV2RGBShader.h" +#include "VideoShaders/YUV2RGBShaderGLES.h" #include "VideoShaders/VideoFilterShaderGLES.h" #include "windowing/WindowingFactory.h" #include "guilib/Texture.h" @@ -541,8 +541,8 @@ void CLinuxRendererGLES::LoadShaders(int field) CLog::Log(LOGNOTICE, "GL: Selecting Single Pass YUV 2 RGB shader"); EShaderFormat shaderFormat = GetShaderFormat(); - m_pYUVProgShader = new YUV2RGBProgressiveShader(false, m_iFlags, shaderFormat); - m_pYUVBobShader = new YUV2RGBBobShader(false, m_iFlags, shaderFormat); + m_pYUVProgShader = new YUV2RGBProgressiveShader(m_iFlags, shaderFormat); + m_pYUVBobShader = new YUV2RGBBobShader(m_iFlags, shaderFormat); if ((m_pYUVProgShader && m_pYUVProgShader->CompileAndLink()) && (m_pYUVBobShader && m_pYUVBobShader->CompileAndLink())) { diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/CMakeLists.txt b/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/CMakeLists.txt index d39a5594b7..3f02baf112 100644 --- a/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/CMakeLists.txt +++ b/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/CMakeLists.txt @@ -1,23 +1,23 @@ -set(SOURCES ConvolutionKernels.cpp) +set(SOURCES ConvolutionKernels.cpp + YUVMatrix.cpp) set(HEADERS ConvolutionKernels.h + YUVMatrix.h dither.h ShaderFormats.h) if(CORE_SYSTEM_NAME STREQUAL windows) - list(APPEND SOURCES WinVideoFilter.cpp - YUV2RGBShader.cpp) - list(APPEND HEADERS WinVideoFilter.h - YUV2RGBShader.h) + list(APPEND SOURCES WinVideoFilter.cpp) + list(APPEND HEADERS WinVideoFilter.h) endif() if(OPENGL_FOUND) - list(APPEND SOURCES VideoFilterShaderGL.cpp - GLSLOutput.cpp - YUV2RGBShader.cpp) - list(APPEND HEADERS VideoFilterShaderGL.h - GLSLOutput.h - YUV2RGBShader.h) + list(APPEND SOURCES GLSLOutput.cpp + VideoFilterShaderGL.cpp + YUV2RGBShaderGL.cpp) + list(APPEND HEADERS GLSLOutput.h + VideoFilterShaderGL.h + YUV2RGBShaderGL.h) endif() if(OPENGLES_FOUND AND (CORE_PLATFORM_NAME_LC STREQUAL android OR @@ -26,12 +26,12 @@ 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 VideoFilterShaderGLES.cpp - GLSLOutput.cpp - YUV2RGBShader.cpp) - list(APPEND HEADERS VideoFilterShaderGLES.h - GLSLOutput.h - YUV2RGBShader.h) + list(APPEND SOURCES GLSLOutput.cpp + VideoFilterShaderGLES.cpp + YUV2RGBShaderGLES.cpp) + list(APPEND HEADERS GLSLOutput.h + VideoFilterShaderGLES.h + YUV2RGBShaderGLES.h) endif() core_add_library(videoshaders) diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/WinVideoFilter.cpp b/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/WinVideoFilter.cpp index ce79623b62..3eaa59ac11 100644 --- a/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/WinVideoFilter.cpp +++ b/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/WinVideoFilter.cpp @@ -28,7 +28,7 @@ #include "VideoRenderers/WinRenderBuffer.h" #include "windowing/WindowingFactory.h" #include "WinVideoFilter.h" -#include "YUV2RGBShader.h" +#include "YUVMatrix.h" #include <DirectXPackedVector.h> #include <map> diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/YUV2RGBShader.cpp b/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/YUV2RGBShaderGL.cpp index 70a7a329b7..5549ff313f 100644 --- a/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/YUV2RGBShader.cpp +++ b/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/YUV2RGBShaderGL.cpp @@ -21,153 +21,16 @@ #include "system.h" #include "../RenderFlags.h" -#include "YUV2RGBShader.h" +#include "YUV2RGBShaderGL.h" +#include "YUVMatrix.h" #include "settings/AdvancedSettings.h" #include "guilib/TransformMatrix.h" #include "utils/log.h" -#if defined(HAS_GL) || defined(HAS_GLES) #include "utils/GLUtils.h" -#endif #include <string> #include <sstream> -// http://www.martinreddy.net/gfx/faqs/colorconv.faq - -// -// Transformation matrixes for different colorspaces. -// -static float yuv_coef_bt601[4][4] = -{ - { 1.0f, 1.0f, 1.0f, 0.0f }, - { 0.0f, -0.344f, 1.773f, 0.0f }, - { 1.403f, -0.714f, 0.0f, 0.0f }, - { 0.0f, 0.0f, 0.0f, 0.0f } -}; - -static float yuv_coef_bt709[4][4] = -{ - { 1.0f, 1.0f, 1.0f, 0.0f }, - { 0.0f, -0.1870f, 1.8556f, 0.0f }, - { 1.5701f, -0.4664f, 0.0f, 0.0f }, - { 0.0f, 0.0f, 0.0f, 0.0f } -}; - -static float yuv_coef_bt2020[4][4] = -{ - { 1.0f, 1.0f, 1.0f, 0.0f }, - { 0.0f, -0.1645f, 1.8814f, 0.0f }, - { 1.4745f, -0.5713f, 0.0f, 0.0f }, - { 0.0f, 0.0f, 0.0f, 0.0f } -}; - -static float yuv_coef_ebu[4][4] = -{ - { 1.0f, 1.0f, 1.0f, 0.0f }, - { 0.0f, -0.3960f, 2.029f, 0.0f }, - { 1.140f, -0.581f, 0.0f, 0.0f }, - { 0.0f, 0.0f, 0.0f, 0.0f } -}; - -static float yuv_coef_smtp240m[4][4] = -{ - { 1.0f, 1.0f, 1.0f, 0.0f }, - { 0.0f, -0.2253f, 1.8270f, 0.0f }, - { 1.5756f, -0.5000f, 0.0f, 0.0f }, - { 0.0f, 0.0f, 0.0f, 0.0f } -}; - -static float** PickYUVConversionMatrix(unsigned flags) -{ - // Pick the matrix. - - switch(CONF_FLAGS_YUVCOEF_MASK(flags)) - { - case CONF_FLAGS_YUVCOEF_240M: - return reinterpret_cast<float**>(yuv_coef_smtp240m); - case CONF_FLAGS_YUVCOEF_BT2020: - return reinterpret_cast<float**>(yuv_coef_bt2020); - case CONF_FLAGS_YUVCOEF_BT709: - return reinterpret_cast<float**>(yuv_coef_bt709); - case CONF_FLAGS_YUVCOEF_BT601: - return reinterpret_cast<float**>(yuv_coef_bt601); - case CONF_FLAGS_YUVCOEF_EBU: - return reinterpret_cast<float**>(yuv_coef_ebu); - } - - return reinterpret_cast<float**>(yuv_coef_bt601); -} - -void CalculateYUVMatrix(TransformMatrix &matrix - , unsigned int flags - , EShaderFormat format - , float black - , float contrast - , bool limited) -{ - TransformMatrix coef; - - matrix *= TransformMatrix::CreateScaler(contrast, contrast, contrast); - matrix *= TransformMatrix::CreateTranslation(black, black, black); - - float (*conv)[4] = (float (*)[4])PickYUVConversionMatrix(flags); - for(int row = 0; row < 3; row++) - for(int col = 0; col < 4; col++) - coef.m[row][col] = conv[col][row]; - coef.identity = false; - - if (limited) - { - matrix *= TransformMatrix::CreateTranslation(+ 16.0f / 255 - , + 16.0f / 255 - , + 16.0f / 255); - matrix *= TransformMatrix::CreateScaler((235 - 16) / 255.0f - , (235 - 16) / 255.0f - , (235 - 16) / 255.0f); - } - - matrix *= coef; - matrix *= TransformMatrix::CreateTranslation(0.0, -0.5, -0.5); - - if (!(flags & CONF_FLAGS_YUV_FULLRANGE)) - { - matrix *= TransformMatrix::CreateScaler(255.0f / (235 - 16) - , 255.0f / (240 - 16) - , 255.0f / (240 - 16)); - matrix *= TransformMatrix::CreateTranslation(- 16.0f / 255 - , - 16.0f / 255 - , - 16.0f / 255); - } - - int effectiveBpp; - switch (format) - { - case SHADER_YV12_9: - effectiveBpp = 9; - break; - case SHADER_YV12_10: - effectiveBpp = 10; - break; - case SHADER_YV12_12: - effectiveBpp = 12; - break; - case SHADER_YV12_14: - effectiveBpp = 14; - break; - default: - effectiveBpp = 0; - } - - if (effectiveBpp > 8 && effectiveBpp < 16) - { - // Convert range to 2 bytes - float scale = 65535.0f / ((1 << effectiveBpp) - 1); - matrix *= TransformMatrix::CreateScaler(scale, scale, scale); - } -} - -#if defined(HAS_GL) || HAS_GLES >= 2 - using namespace Shaders; static void CalculateYUVMatrixGL(GLfloat res[4][4] @@ -221,7 +84,6 @@ BaseYUV2RGBGLSLShader::BaseYUV2RGBGLSLShader(bool rect, unsigned flags, EShaderF m_defines += m_glslOutput->GetDefines(); } -#ifdef HAS_GL if(rect) m_defines += "#define XBMC_texture_rectangle 1\n"; else @@ -259,27 +121,6 @@ BaseYUV2RGBGLSLShader::BaseYUV2RGBGLSLShader(bool rect, unsigned flags, EShaderF CLog::Log(LOGERROR, "GL: BaseYUV2RGBGLSLShader - unsupported format %d", m_format); VertexShader()->LoadSource("yuv2rgb_vertex.glsl", m_defines); -#elif HAS_GLES >= 2 - m_hVertex = -1; - m_hYcoord = -1; - m_hUcoord = -1; - m_hVcoord = -1; - m_hProj = -1; - m_hModel = -1; - m_hAlpha = -1; - if (m_format == SHADER_YV12) - m_defines += "#define XBMC_YV12\n"; - else if (m_format == SHADER_NV12) - m_defines += "#define XBMC_NV12\n"; - else if (m_format == SHADER_NV12_RRG) - m_defines += "#define XBMC_NV12_RRG\n"; - else if (m_format == SHADER_YV12) - m_defines += "#define XBMC_YV12\n"; - else - CLog::Log(LOGERROR, "GL: BaseYUV2RGBGLSLShader - unsupported format %d", m_format); - - VertexShader()->LoadSource("yuv2rgb_vertex_gles.glsl", m_defines); -#endif CLog::Log(LOGDEBUG, "GL: BaseYUV2RGBGLSLShader: defines:\n%s", m_defines.c_str()); } @@ -291,15 +132,6 @@ BaseYUV2RGBGLSLShader::~BaseYUV2RGBGLSLShader() void BaseYUV2RGBGLSLShader::OnCompiledAndLinked() { -#if HAS_GLES >= 2 - 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"); -#endif m_hYTex = glGetUniformLocation(ProgramHandle(), "m_sampY"); m_hUTex = glGetUniformLocation(ProgramHandle(), "m_sampU"); m_hVTex = glGetUniformLocation(ProgramHandle(), "m_sampV"); @@ -325,11 +157,7 @@ bool BaseYUV2RGBGLSLShader::OnEnabled() CalculateYUVMatrixGL(matrix, m_flags, m_format, m_black, m_contrast, !m_convertFullRange); glUniformMatrix4fv(m_hMatrix, 1, GL_FALSE, (GLfloat*)matrix); -#if HAS_GLES >= 2 - glUniformMatrix4fv(m_hProj, 1, GL_FALSE, m_proj); - glUniformMatrix4fv(m_hModel, 1, GL_FALSE, m_model); - glUniform1f(m_hAlpha, m_alpha); -#endif + VerifyGLState(); if (m_glslOutput) m_glslOutput->OnEnabled(); return true; @@ -347,7 +175,6 @@ void BaseYUV2RGBGLSLShader::Free() ////////////////////////////////////////////////////////////////////// // BaseYUV2RGBGLSLShader - base class for GLSL YUV2RGB shaders ////////////////////////////////////////////////////////////////////// -#if defined(HAS_GL) // No ARB Shader when using GLES2.0 BaseYUV2RGBARBShader::BaseYUV2RGBARBShader(unsigned flags, EShaderFormat format) { m_width = 1; @@ -361,7 +188,6 @@ BaseYUV2RGBARBShader::BaseYUV2RGBARBShader(unsigned flags, EShaderFormat format) m_hUTex = -1; m_hVTex = -1; } -#endif ////////////////////////////////////////////////////////////////////// // YUV2RGBProgressiveShader - YUV2RGB with no deinterlacing @@ -372,12 +198,8 @@ YUV2RGBProgressiveShader::YUV2RGBProgressiveShader(bool rect, unsigned flags, ES GLSLOutput *output) : BaseYUV2RGBGLSLShader(rect, flags, format, stretch, output) { -#ifdef HAS_GL PixelShader()->LoadSource("yuv2rgb_basic.glsl", m_defines); PixelShader()->AppendSource("output.glsl"); -#elif HAS_GLES >= 2 - PixelShader()->LoadSource("yuv2rgb_basic_gles.glsl", m_defines); -#endif } @@ -391,11 +213,7 @@ YUV2RGBBobShader::YUV2RGBBobShader(bool rect, unsigned flags, EShaderFormat form m_hStepX = -1; m_hStepY = -1; m_hField = -1; -#ifdef HAS_GL PixelShader()->LoadSource("yuv2rgb_bob.glsl", m_defines); -#elif HAS_GLES >= 2 - PixelShader()->LoadSource("yuv2rgb_bob_gles.glsl", m_defines); -#endif } void YUV2RGBBobShader::OnCompiledAndLinked() @@ -422,7 +240,6 @@ bool YUV2RGBBobShader::OnEnabled() ////////////////////////////////////////////////////////////////////// // YUV2RGBProgressiveShaderARB - YUV2RGB with no deinterlacing ////////////////////////////////////////////////////////////////////// -#if defined(HAS_GL) // No ARB Shader when using GLES2.0 YUV2RGBProgressiveShaderARB::YUV2RGBProgressiveShaderARB(bool rect, unsigned flags, EShaderFormat format) : BaseYUV2RGBARBShader(flags, format) { @@ -479,5 +296,3 @@ bool YUV2RGBProgressiveShaderARB::OnEnabled() m_width, m_height); return true; } -#endif -#endif // HAS_GL diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/YUV2RGBShader.h b/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/YUV2RGBShaderGL.h index 4e0b4817ea..e8220f2c05 100644 --- a/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/YUV2RGBShader.h +++ b/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/YUV2RGBShaderGL.h @@ -29,8 +29,6 @@ void CalculateYUVMatrix(TransformMatrix &matrix , float contrast , bool limited); -#if defined(HAS_GL) || HAS_GLES >= 2 - #include "GLSLOutput.h" #ifndef __GNUC__ @@ -54,15 +52,7 @@ namespace Shaders { virtual void SetBlack(float black) {}; virtual void SetContrast(float contrast) {}; virtual void SetNonLinStretch(float stretch) {}; -#if HAS_GLES >= 2 - virtual GLint GetVertexLoc() { return 0; }; - virtual GLint GetYcoordLoc() { return 0; }; - virtual GLint GetUcoordLoc() { return 0; }; - virtual GLint GetVcoordLoc() { return 0; }; - - virtual void SetMatrices(GLfloat *p, GLfloat *m) {}; - virtual void SetAlpha(GLfloat alpha) {}; -#endif + void SetConvertFullColorRange(bool convertFullRange) { m_convertFullRange = convertFullRange; } protected: @@ -84,15 +74,6 @@ namespace Shaders { void SetBlack(float black) override { m_black = black; } void SetContrast(float contrast) override { m_contrast = contrast; } void SetNonLinStretch(float stretch) override { m_stretch = stretch; } -#if HAS_GLES >= 2 - GLint GetVertexLoc() override { return m_hVertex; } - GLint GetYcoordLoc() override { return m_hYcoord; } - GLint GetUcoordLoc() override { return m_hUcoord; } - GLint GetVcoordLoc() override { return m_hVcoord; } - - void SetMatrices(GLfloat *p, GLfloat *m) override { m_proj = p; m_model = m; } - void SetAlpha(GLfloat alpha) override { m_alpha = alpha; } -#endif protected: void OnCompiledAndLinked() override; @@ -121,22 +102,8 @@ namespace Shaders { GLint m_hMatrix; GLint m_hStretch; GLint m_hStep; -#if HAS_GLES >= 2 - GLint m_hVertex; - GLint m_hYcoord; - GLint m_hUcoord; - GLint m_hVcoord; - GLint m_hProj; - GLint m_hModel; - GLint m_hAlpha; - - GLfloat *m_proj; - GLfloat *m_model; - GLfloat m_alpha; -#endif }; -#if defined(HAS_GL) // No ARB Shader when using GLES2.0 class BaseYUV2RGBARBShader : public BaseYUV2RGBShader , public CARBShaderProgram @@ -174,7 +141,6 @@ namespace Shaders { void OnCompiledAndLinked() override; bool OnEnabled() override; }; -#endif class YUV2RGBProgressiveShader : public BaseYUV2RGBGLSLShader { @@ -203,4 +169,3 @@ namespace Shaders { #ifndef __GNUC__ #pragma warning( pop ) #endif -#endif diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/YUV2RGBShaderGLES.cpp b/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/YUV2RGBShaderGLES.cpp new file mode 100644 index 0000000000..69dd780c58 --- /dev/null +++ b/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/YUV2RGBShaderGLES.cpp @@ -0,0 +1,238 @@ +/* + * Copyright (c) 2007 d4rk + * Copyright (C) 2007-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/>. + * + */ + +#include "system.h" +#include "../RenderFlags.h" +#include "YUV2RGBShaderGLES.h" +#include "YUVMatrix.h" +#include "settings/AdvancedSettings.h" +#include "guilib/TransformMatrix.h" +#include "utils/log.h" +#include "utils/GLUtils.h" + +#include <string> +#include <sstream> + +using namespace Shaders; + +static void CalculateYUVMatrixGL(GLfloat res[4][4] + , unsigned int flags + , EShaderFormat format + , float black + , float contrast + , bool limited) +{ + TransformMatrix matrix; + CalculateYUVMatrix(matrix, flags, format, black, contrast, limited); + + for(int row = 0; row < 3; row++) + for(int col = 0; col < 4; col++) + res[col][row] = matrix.m[row][col]; + + res[0][3] = 0.0f; + res[1][3] = 0.0f; + res[2][3] = 0.0f; + res[3][3] = 1.0f; +} + +////////////////////////////////////////////////////////////////////// +// BaseYUV2RGBGLSLShader - base class for GLSL YUV2RGB shaders +////////////////////////////////////////////////////////////////////// + +BaseYUV2RGBGLSLShader::BaseYUV2RGBGLSLShader(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_stretch = 0.0f; + + // shader attribute handles + m_hYTex = -1; + m_hUTex = -1; + m_hVTex = -1; + m_hMatrix = -1; + m_hStretch = -1; + m_hStep = -1; + + m_hVertex = -1; + m_hYcoord = -1; + m_hUcoord = -1; + m_hVcoord = -1; + m_hProj = -1; + m_hModel = -1; + m_hAlpha = -1; + + m_proj = nullptr; + m_model = nullptr; + m_alpha = 1.0; + + // get defines from the output stage if used + m_glslOutput = output; + if (m_glslOutput) + m_defines += m_glslOutput->GetDefines(); + + // not supported on GLES 2.0 + m_defines += "#define XBMC_texture_rectangle 0\n"; + m_defines += "#define XBMC_texture_rectangle_hack 0\n"; + + //don't compile in stretch support when it's not needed + if (stretch) + m_defines += "#define XBMC_STRETCH 1\n"; + else + m_defines += "#define XBMC_STRETCH 0\n"; + + if (m_format == SHADER_YV12 || + m_format == SHADER_YV12_9 || + m_format == SHADER_YV12_10 || + m_format == SHADER_YV12_12 || + m_format == SHADER_YV12_14 || + m_format == SHADER_YV12_16) + m_defines += "#define XBMC_YV12\n"; + else if (m_format == SHADER_NV12) + m_defines += "#define XBMC_NV12\n"; + else if (m_format == SHADER_YUY2) + m_defines += "#define XBMC_YUY2\n"; + else if (m_format == SHADER_UYVY) + m_defines += "#define XBMC_UYVY\n"; + else if (m_format == SHADER_NV12_RRG) + m_defines += "#define XBMC_NV12_RRG\n"; + else if (m_format == SHADER_YV12) + m_defines += "#define XBMC_YV12\n"; + else + CLog::Log(LOGERROR, "GL: BaseYUV2RGBGLSLShader - unsupported format %d", m_format); + + VertexShader()->LoadSource("yuv2rgb_vertex_gles.glsl", m_defines); + + CLog::Log(LOGDEBUG, "GL: BaseYUV2RGBGLSLShader: defines:\n%s", m_defines.c_str()); +} + +BaseYUV2RGBGLSLShader::~BaseYUV2RGBGLSLShader() +{ + delete m_glslOutput; +} + +void BaseYUV2RGBGLSLShader::OnCompiledAndLinked() +{ + 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"); + 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"); + VerifyGLState(); + + if (m_glslOutput) m_glslOutput->OnCompiledAndLinked(ProgramHandle()); +} + +bool BaseYUV2RGBGLSLShader::OnEnabled() +{ + // set shader attributes once enabled + glUniform1i(m_hYTex, 0); + glUniform1i(m_hUTex, 1); + glUniform1i(m_hVTex, 2); + glUniform1f(m_hStretch, m_stretch); + glUniform2f(m_hStep, 1.0 / m_width, 1.0 / m_height); + + GLfloat matrix[4][4]; + // keep video levels + 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(); + return true; +} + +void BaseYUV2RGBGLSLShader::OnDisabled() +{ + if (m_glslOutput) m_glslOutput->OnDisabled(); +} + +void BaseYUV2RGBGLSLShader::Free() +{ + if (m_glslOutput) m_glslOutput->Free(); +} + +////////////////////////////////////////////////////////////////////// +// YUV2RGBProgressiveShader - YUV2RGB with no deinterlacing +// Use for weave deinterlacing / progressive +////////////////////////////////////////////////////////////////////// + +YUV2RGBProgressiveShader::YUV2RGBProgressiveShader(unsigned flags, EShaderFormat format, bool stretch, + GLSLOutput *output) + : BaseYUV2RGBGLSLShader(flags, format, stretch, output) +{ + PixelShader()->LoadSource("yuv2rgb_basic.glsl", m_defines); + PixelShader()->AppendSource("output.glsl"); +} + + +////////////////////////////////////////////////////////////////////// +// YUV2RGBBobShader - YUV2RGB with Bob deinterlacing +////////////////////////////////////////////////////////////////////// + +YUV2RGBBobShader::YUV2RGBBobShader(unsigned flags, EShaderFormat format) + : BaseYUV2RGBGLSLShader(flags, format, false) +{ + m_hStepX = -1; + m_hStepY = -1; + m_hField = -1; + + PixelShader()->LoadSource("yuv2rgb_bob_gles.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; +} diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/YUV2RGBShaderGLES.h b/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/YUV2RGBShaderGLES.h new file mode 100644 index 0000000000..ff36c3c533 --- /dev/null +++ b/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/YUV2RGBShaderGLES.h @@ -0,0 +1,160 @@ +/* + * Copyright (C) 2007-2015 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/>. + * + */ +#pragma once + +#include "guilib/TransformMatrix.h" +#include "ShaderFormats.h" + +void CalculateYUVMatrix(TransformMatrix &matrix + , unsigned int flags + , EShaderFormat format + , float black + , float contrast + , bool limited); + +#include "GLSLOutput.h" + +#ifndef __GNUC__ +#pragma warning( push ) +#pragma warning( disable : 4250 ) +#endif + +#include "guilib/Shader.h" + +namespace Shaders { + + class BaseYUV2RGBShader : virtual public CShaderProgram + { + public: + BaseYUV2RGBShader() : m_convertFullRange(false) {}; + ~BaseYUV2RGBShader() override = default; + virtual void SetField(int field) {}; + virtual void SetWidth(int width) {}; + virtual void SetHeight(int width) {}; + + virtual void SetBlack(float black) {}; + virtual void SetContrast(float contrast) {}; + virtual void SetNonLinStretch(float stretch) {}; + + virtual GLint GetVertexLoc() { return 0; }; + virtual GLint GetYcoordLoc() { return 0; }; + virtual GLint GetUcoordLoc() { return 0; }; + virtual GLint GetVcoordLoc() { return 0; }; + + virtual void SetMatrices(GLfloat *p, GLfloat *m) {}; + virtual void SetAlpha(GLfloat alpha) {}; + + void SetConvertFullColorRange(bool convertFullRange) { m_convertFullRange = convertFullRange; } + + protected: + bool m_convertFullRange; + }; + + + class BaseYUV2RGBGLSLShader + : public BaseYUV2RGBShader + , public CGLSLShaderProgram + { + public: + BaseYUV2RGBGLSLShader(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; } + + void SetBlack(float black) override { m_black = black; } + void SetContrast(float contrast) override { m_contrast = contrast; } + void SetNonLinStretch(float stretch) override { m_stretch = stretch; } + + GLint GetVertexLoc() override { return m_hVertex; } + GLint GetYcoordLoc() override { return m_hYcoord; } + GLint GetUcoordLoc() override { return m_hUcoord; } + GLint GetVcoordLoc() override { return m_hVcoord; } + + void SetMatrices(GLfloat *p, GLfloat *m) override { m_proj = p; m_model = m; } + void SetAlpha(GLfloat alpha) override { m_alpha = alpha; } + + protected: + void OnCompiledAndLinked() override; + bool OnEnabled() override; + void OnDisabled() override; + void Free() override; + + unsigned m_flags; + EShaderFormat m_format; + int m_width; + int m_height; + int m_field; + + float m_black; + float m_contrast; + float m_stretch; + + 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; + + GLint m_hVertex; + GLint m_hYcoord; + GLint m_hUcoord; + GLint m_hVcoord; + GLint m_hProj; + GLint m_hModel; + GLint m_hAlpha; + + GLfloat *m_proj; + GLfloat *m_model; + GLfloat m_alpha; + }; + + class YUV2RGBProgressiveShader : public BaseYUV2RGBGLSLShader + { + public: + YUV2RGBProgressiveShader(unsigned flags=0, + EShaderFormat format=SHADER_NONE, + bool stretch = false, + GLSLOutput *output=NULL); + }; + + class YUV2RGBBobShader : public BaseYUV2RGBGLSLShader + { + public: + YUV2RGBBobShader(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__ +#pragma warning( pop ) +#endif diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/YUVMatrix.cpp b/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/YUVMatrix.cpp new file mode 100644 index 0000000000..fd3e61c147 --- /dev/null +++ b/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/YUVMatrix.cpp @@ -0,0 +1,158 @@ +/* + * Copyright (c) 2007 d4rk + * Copyright (C) 2007-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/>. + * + */ + +#include "system.h" +#include "../RenderFlags.h" +#include "YUVMatrix.h" + +// http://www.martinreddy.net/gfx/faqs/colorconv.faq + +// +// Transformation matrixes for different colorspaces. +// +static float yuv_coef_bt601[4][4] = +{ + { 1.0f, 1.0f, 1.0f, 0.0f }, + { 0.0f, -0.344f, 1.773f, 0.0f }, + { 1.403f, -0.714f, 0.0f, 0.0f }, + { 0.0f, 0.0f, 0.0f, 0.0f } +}; + +static float yuv_coef_bt709[4][4] = +{ + { 1.0f, 1.0f, 1.0f, 0.0f }, + { 0.0f, -0.1870f, 1.8556f, 0.0f }, + { 1.5701f, -0.4664f, 0.0f, 0.0f }, + { 0.0f, 0.0f, 0.0f, 0.0f } +}; + +static float yuv_coef_bt2020[4][4] = +{ + { 1.0f, 1.0f, 1.0f, 0.0f }, + { 0.0f, -0.1645f, 1.8814f, 0.0f }, + { 1.4745f, -0.5713f, 0.0f, 0.0f }, + { 0.0f, 0.0f, 0.0f, 0.0f } +}; + +static float yuv_coef_ebu[4][4] = +{ + { 1.0f, 1.0f, 1.0f, 0.0f }, + { 0.0f, -0.3960f, 2.029f, 0.0f }, + { 1.140f, -0.581f, 0.0f, 0.0f }, + { 0.0f, 0.0f, 0.0f, 0.0f } +}; + +static float yuv_coef_smtp240m[4][4] = +{ + { 1.0f, 1.0f, 1.0f, 0.0f }, + { 0.0f, -0.2253f, 1.8270f, 0.0f }, + { 1.5756f, -0.5000f, 0.0f, 0.0f }, + { 0.0f, 0.0f, 0.0f, 0.0f } +}; + +static float** PickYUVConversionMatrix(unsigned flags) +{ + // Pick the matrix. + + switch(CONF_FLAGS_YUVCOEF_MASK(flags)) + { + case CONF_FLAGS_YUVCOEF_240M: + return reinterpret_cast<float**>(yuv_coef_smtp240m); + case CONF_FLAGS_YUVCOEF_BT2020: + return reinterpret_cast<float**>(yuv_coef_bt2020); + case CONF_FLAGS_YUVCOEF_BT709: + return reinterpret_cast<float**>(yuv_coef_bt709); + case CONF_FLAGS_YUVCOEF_BT601: + return reinterpret_cast<float**>(yuv_coef_bt601); + case CONF_FLAGS_YUVCOEF_EBU: + return reinterpret_cast<float**>(yuv_coef_ebu); + } + + return reinterpret_cast<float**>(yuv_coef_bt601); +} + +void CalculateYUVMatrix(TransformMatrix &matrix + , unsigned int flags + , EShaderFormat format + , float black + , float contrast + , bool limited) +{ + TransformMatrix coef; + + matrix *= TransformMatrix::CreateScaler(contrast, contrast, contrast); + matrix *= TransformMatrix::CreateTranslation(black, black, black); + + float (*conv)[4] = (float (*)[4])PickYUVConversionMatrix(flags); + for(int row = 0; row < 3; row++) + for(int col = 0; col < 4; col++) + coef.m[row][col] = conv[col][row]; + coef.identity = false; + + if (limited) + { + matrix *= TransformMatrix::CreateTranslation(+ 16.0f / 255 + , + 16.0f / 255 + , + 16.0f / 255); + matrix *= TransformMatrix::CreateScaler((235 - 16) / 255.0f + , (235 - 16) / 255.0f + , (235 - 16) / 255.0f); + } + + matrix *= coef; + matrix *= TransformMatrix::CreateTranslation(0.0, -0.5, -0.5); + + if (!(flags & CONF_FLAGS_YUV_FULLRANGE)) + { + matrix *= TransformMatrix::CreateScaler(255.0f / (235 - 16) + , 255.0f / (240 - 16) + , 255.0f / (240 - 16)); + matrix *= TransformMatrix::CreateTranslation(- 16.0f / 255 + , - 16.0f / 255 + , - 16.0f / 255); + } + + int effectiveBpp; + switch (format) + { + case SHADER_YV12_9: + effectiveBpp = 9; + break; + case SHADER_YV12_10: + effectiveBpp = 10; + break; + case SHADER_YV12_12: + effectiveBpp = 12; + break; + case SHADER_YV12_14: + effectiveBpp = 14; + break; + default: + effectiveBpp = 0; + } + + if (effectiveBpp > 8 && effectiveBpp < 16) + { + // Convert range to 2 bytes + float scale = 65535.0f / ((1 << effectiveBpp) - 1); + matrix *= TransformMatrix::CreateScaler(scale, scale, scale); + } +} diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/YUVMatrix.h b/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/YUVMatrix.h new file mode 100644 index 0000000000..5ecffd7539 --- /dev/null +++ b/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/YUVMatrix.h @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2007-2015 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/>. + * + */ +#pragma once + +#include "guilib/TransformMatrix.h" +#include "ShaderFormats.h" + +void CalculateYUVMatrix(TransformMatrix &matrix + , unsigned int flags + , EShaderFormat format + , float black + , float contrast + , bool limited); |