diff options
author | bobo1on1 <bobo1on1@svn> | 2010-07-10 11:44:25 +0000 |
---|---|---|
committer | bobo1on1 <bobo1on1@svn> | 2010-07-10 11:44:25 +0000 |
commit | aef0b1901d59ccfa172a8069ee1ef38c0b4c0bdf (patch) | |
tree | 61644739e513802badbd3a36b0518f65b6d3fe7a | |
parent | 57ec3a8656a315bb63fec8e50bc2a368f7607426 (diff) |
added: YUY2 to rgb conversion with shaders
removed: double upload for YUY2
git-svn-id: https://xbmc.svn.sourceforge.net/svnroot/xbmc/trunk@31688 568bbfeb-2a22-0410-94d2-cc84cf5bfa90
-rw-r--r-- | guilib/Shader.cpp | 5 | ||||
-rw-r--r-- | system/shaders/yuv2rgb_basic.glsl | 39 | ||||
-rw-r--r-- | system/shaders/yuv2rgb_basic_2d_YUY2.arb | 51 | ||||
-rw-r--r-- | system/shaders/yuv2rgb_basic_rect_YUY2.arb | 45 | ||||
-rw-r--r-- | xbmc/cores/VideoRenderers/LinuxRendererGL.cpp | 129 | ||||
-rw-r--r-- | xbmc/cores/VideoRenderers/LinuxRendererGL.h | 2 | ||||
-rw-r--r-- | xbmc/cores/VideoRenderers/VideoShaders/YUV2RGBShader.cpp | 32 | ||||
-rw-r--r-- | xbmc/cores/VideoRenderers/VideoShaders/YUV2RGBShader.h | 1 |
8 files changed, 215 insertions, 89 deletions
diff --git a/guilib/Shader.cpp b/guilib/Shader.cpp index abdf5d441b..ee2aa83977 100644 --- a/guilib/Shader.cpp +++ b/guilib/Shader.cpp @@ -251,7 +251,10 @@ bool CARBPixelShader::Compile() glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB, &err); if (err>0) { - CLog::Log(LOGERROR, "GL: Error compiling ARB pixel shader"); + const char* errStr = (const char*)glGetString(GL_PROGRAM_ERROR_STRING_ARB); + if (!errStr) + errStr = "NULL"; + CLog::Log(LOGERROR, "GL: Error compiling ARB pixel shader, GL_PROGRAM_ERROR_STRING_ARB = %s", errStr); m_compiled = false; } else diff --git a/system/shaders/yuv2rgb_basic.glsl b/system/shaders/yuv2rgb_basic.glsl index 0cbd1f8c74..31f07ee3db 100644 --- a/system/shaders/yuv2rgb_basic.glsl +++ b/system/shaders/yuv2rgb_basic.glsl @@ -11,6 +11,8 @@ varying vec2 m_cordY; varying vec2 m_cordU; varying vec2 m_cordV; +uniform vec2 m_step; + uniform mat4 m_yuvmat; uniform float m_stretch; @@ -30,6 +32,8 @@ vec2 stretch(vec2 pos) void main() { +#ifndef XBMC_YUY2 + vec4 yuv, rgb; yuv.rgba = vec4( texture2D(m_sampY, stretch(m_cordY)).r , texture2D(m_sampU, stretch(m_cordU)).g @@ -39,4 +43,39 @@ void main() rgb = m_yuvmat * yuv; rgb.a = gl_Color.a; gl_FragColor = rgb; + +#else + +#if(XBMC_texture_rectangle) + vec2 stepxy = vec2(1.0, 1.0); + vec2 pos = stretch(vec2(m_cordY.x * 0.5 - 0.25, m_cordY.y)); + vec2 f = fract(pos); +#else + vec2 stepxy = vec2(m_step.x * 2.0, m_step.y); + vec2 pos = stretch(vec2(m_cordY.x - stepxy.x * 0.25, m_cordY.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 + ( 0.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*/ + float leftY = mix(c1.b, c1.r, f.x * 2.0); + float rightY = mix(c1.r, c2.b, f.x * 2.0 - 1.0); + float outY = mix(leftY, rightY, step(0.5, f.x)); + + //interpolate UV + vec2 outUV = mix(c1.ga, c2.ga, f.x); + + vec4 yuv = vec4(outY, outUV, 1.0); + vec4 rgb = m_yuvmat * yuv; + + gl_FragColor = rgb; + gl_FragColor.a = gl_Color.a; + +#endif } diff --git a/system/shaders/yuv2rgb_basic_2d_YUY2.arb b/system/shaders/yuv2rgb_basic_2d_YUY2.arb new file mode 100644 index 0000000000..65f1a38c03 --- /dev/null +++ b/system/shaders/yuv2rgb_basic_2d_YUY2.arb @@ -0,0 +1,51 @@ +!!ARBfp1.0 +PARAM yuvmat[4] = { program.local[0..3] }; +#stepx, stepy, width, height +PARAM dims[1] = { program.local[4] }; +TEMP stepY; +TEMP f; +TEMP pos; +MUL stepY.x, dims[0].x, 2.0; +MOV stepY.y, dims[0].y; +RCP f.x , stepY.x; +RCP f.y , stepY.y; +MAD pos.x , stepY.x, -0.25, fragment.texcoord[0].x; +MOV pos.y , fragment.texcoord[0].y; +MUL f , pos, f; +FRC f , f; + +TEMP c1pos; +TEMP c2pos; +SUB c1pos.x, -0.5, f.x; +SUB c2pos.x, 0.5, f.x; +MAD c1pos.x, c1pos.x, stepY.x, pos.x; +MAD c2pos.x, c2pos.x, stepY.x, pos.x; +MOV c1pos.y, pos.y; +MOV c2pos.y, pos.y; + +TEMP c1; +TEMP c2; +TEX c1, c1pos, texture[0], 2D; +TEX c2, c2pos, texture[0], 2D; + +TEMP cint; +MUL cint.x, f.x, 2.0; +MAD cint.y, f.x, 2.0, -1.0; +SGE cint.z, f.x, 0.5; + +TEMP yuv; +LRP yuv.g, cint.x, c1.r , c1.b; +LRP yuv.b, cint.y, c2.b , c1.r; +LRP yuv.r, cint.z, yuv.b, yuv.g; + +LRP yuv.g, f.x , c2.g , c1.g; +LRP yuv.b, f.x , c2.a , c1.a; + +TEMP rgb; +DPH rgb.r, yuv, yuvmat[0]; +DPH rgb.g, yuv, yuvmat[1]; +DPH rgb.b, yuv, yuvmat[2]; +MOV rgb.a, fragment.color.a; +MOV result.color, rgb; + +END diff --git a/system/shaders/yuv2rgb_basic_rect_YUY2.arb b/system/shaders/yuv2rgb_basic_rect_YUY2.arb new file mode 100644 index 0000000000..42dd4e89fe --- /dev/null +++ b/system/shaders/yuv2rgb_basic_rect_YUY2.arb @@ -0,0 +1,45 @@ +!!ARBfp1.0 +PARAM yuvmat[4] = { program.local[0..3] }; +#stepx, stepy, width, height +PARAM dims[1] = { program.local[4] }; +TEMP f; +TEMP pos; +MAD pos.x , fragment.texcoord[0].x, 0.5, -0.25; +MOV pos.y , fragment.texcoord[0].y; +FRC f , pos; + +TEMP c1pos; +TEMP c2pos; +SUB c1pos.x, -0.5, f.x; +SUB c2pos.x, 0.5, f.x; +ADD c1pos.x, c1pos.x, pos.x; +ADD c2pos.x, c2pos.x, pos.x; +MOV c1pos.y, pos.y; +MOV c2pos.y, pos.y; + +TEMP c1; +TEMP c2; +TEX c1, c1pos, texture[0], RECT; +TEX c2, c2pos, texture[0], RECT; + +TEMP cint; +MUL cint.x, f.x, 2.0; +MAD cint.y, f.x, 2.0, -1.0; +SGE cint.z, f.x, 0.5; + +TEMP yuv; +LRP yuv.g, cint.x, c1.r , c1.b; +LRP yuv.b, cint.y, c2.b , c1.r; +LRP yuv.r, cint.z, yuv.b, yuv.g; + +LRP yuv.g, f.x , c2.g , c1.g; +LRP yuv.b, f.x , c2.a , c1.a; + +TEMP rgb; +DPH rgb.r, yuv, yuvmat[0]; +DPH rgb.g, yuv, yuvmat[1]; +DPH rgb.b, yuv, yuvmat[2]; +MOV rgb.a, fragment.color.a; +MOV result.color, rgb; + +END diff --git a/xbmc/cores/VideoRenderers/LinuxRendererGL.cpp b/xbmc/cores/VideoRenderers/LinuxRendererGL.cpp index fdf347699c..3708f80eb1 100644 --- a/xbmc/cores/VideoRenderers/LinuxRendererGL.cpp +++ b/xbmc/cores/VideoRenderers/LinuxRendererGL.cpp @@ -475,16 +475,13 @@ void CLinuxRendererGL::CalculateTextureSourceRects(int source, int num_planes) void CLinuxRendererGL::LoadPlane( YUVPLANE& plane, int type, unsigned flipindex , unsigned width, unsigned height - , int stride, void* data, GLuint pbo/*= 0*/ ) + , int stride, void* data ) { if(plane.flipindex == flipindex) return; - if (plane.pbo && !pbo) - pbo = plane.pbo; - - if(pbo) - glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, pbo); + if(plane.pbo) + glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, plane.pbo); glPixelStorei(GL_UNPACK_ROW_LENGTH, stride); glBindTexture(m_textureTarget, plane.id); @@ -505,7 +502,7 @@ void CLinuxRendererGL::LoadPlane( YUVPLANE& plane, int type, unsigned flipindex glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); glBindTexture(m_textureTarget, 0); - if(pbo) + if(plane.pbo) glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0); plane.flipindex = flipindex; @@ -1322,7 +1319,6 @@ void CLinuxRendererGL::Render(DWORD flags, int renderBuffer) void CLinuxRendererGL::RenderSinglePass(int index, int field) { - YV12Image &im = m_buffers[index].image; YUVFIELDS &fields = m_buffers[index].fields; YUVPLANES &planes = fields[field]; @@ -1359,8 +1355,8 @@ void CLinuxRendererGL::RenderSinglePass(int index, int field) m_pYUVShader->SetBlack(g_settings.m_currentVideoSettings.m_Brightness * 0.01f - 0.5f); m_pYUVShader->SetContrast(g_settings.m_currentVideoSettings.m_Contrast * 0.02f); m_pYUVShader->SetNonLinStretch(pow(m_pixelRatio, g_advancedSettings.m_videoNonLinStretchRatio)); - m_pYUVShader->SetWidth(im.width); - m_pYUVShader->SetHeight(im.height); + m_pYUVShader->SetWidth(planes[0].texwidth); + m_pYUVShader->SetHeight(planes[0].texheight); if (field == FIELD_ODD) m_pYUVShader->SetField(1); else if(field == FIELD_EVEN) @@ -1412,7 +1408,6 @@ void CLinuxRendererGL::RenderSinglePass(int index, int field) void CLinuxRendererGL::RenderMultiPass(int index, int field) { - YV12Image &im = m_buffers[index].image; YUVPLANES &planes = m_buffers[index].fields[field]; // set scissors if we are not in fullscreen video @@ -1460,8 +1455,8 @@ void CLinuxRendererGL::RenderMultiPass(int index, int field) m_pYUVShader->SetBlack(g_settings.m_currentVideoSettings.m_Brightness * 0.01f - 0.5f); m_pYUVShader->SetContrast(g_settings.m_currentVideoSettings.m_Contrast * 0.02f); - m_pYUVShader->SetWidth(im.width); - m_pYUVShader->SetHeight(im.height); + m_pYUVShader->SetWidth(planes[0].texwidth); + m_pYUVShader->SetHeight(planes[0].texheight); if (field == FIELD_ODD) m_pYUVShader->SetField(1); else if(field == FIELD_EVEN) @@ -2423,52 +2418,27 @@ void CLinuxRendererGL::UploadYUY2Texture(int source) glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - //YUY2 is YUYV packed - //we upload it here as GL_LUMINANCE_ALPHA so we can get the Y plane on the luminance if (deinterlacing) { - // Load Y fields - LoadPlane( fields[FIELD_ODD][0] , GL_LUMINANCE_ALPHA, buf.flipindex - , im->width, im->height >> 1 - , im->stride[0], im->plane[0] ); + // Load YUYV fields + LoadPlane( fields[FIELD_ODD][0], GL_BGRA, buf.flipindex + , im->width / 2, im->height >> 1 + , im->stride[0] / 2, im->plane[0] ); - LoadPlane( fields[FIELD_EVEN][0], GL_LUMINANCE_ALPHA, buf.flipindex - , im->width, im->height >> 1 - , im->stride[0], im->plane[0] + im->stride[0]) ; + LoadPlane( fields[FIELD_EVEN][0], GL_BGRA, buf.flipindex + , im->width / 2, im->height >> 1 + , im->stride[0] / 2, im->plane[0] + im->stride[0]) ; } else { - // Load Y plane - LoadPlane( fields[FIELD_FULL][0], GL_LUMINANCE_ALPHA, buf.flipindex - , im->width, im->height - , im->stride[0] / 2, im->plane[0] ); + // Load YUYV plane + LoadPlane( fields[FIELD_FULL][0], GL_BGRA, buf.flipindex + , im->width / 2, im->height + , im->stride[0] / 4, im->plane[0] ); } VerifyGLState(); - glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - - //YUY2 is YUYV packed - //we upload it here as GL_BRGA so we can get U on red and V on alpha - //it's uploaded to the texture of plane 1, but loaded from the buffer/pbo of plane 0 - if (deinterlacing) - { - // Load Even UV Fields - LoadPlane( fields[FIELD_ODD][1], GL_BGRA, buf.flipindex - , im->width >> im->cshift_x, im->height >> (im->cshift_y + 1) - , im->stride[0] / 2, im->plane[0], fields[FIELD_ODD][0].pbo ); - - // Load Odd UV Fields - LoadPlane( fields[FIELD_EVEN][1], GL_BGRA, buf.flipindex - , im->width >> im->cshift_x, im->height >> (im->cshift_y + 1) - , im->stride[0] / 2, im->plane[0] + im->stride[0], fields[FIELD_EVEN][0].pbo ); - } - else - { - LoadPlane( fields[FIELD_FULL][1], GL_BGRA, buf.flipindex - , im->width >> im->cshift_x, im->height - , im->stride[0] / 4, im->plane[0], fields[FIELD_FULL][0].pbo ); - } SetEvent(m_eventTexturesDone[source]); CalculateTextureSourceRects(source, 3); @@ -2489,17 +2459,15 @@ void CLinuxRendererGL::DeleteYUY2Texture(int index) g_graphicsContext.BeginPaint(); //FIXME for(int f = 0;f<MAX_FIELDS;f++) { - for(int p = 0;p<2;p++) + if( fields[f][0].id ) { - if( fields[f][p].id ) + if (glIsTexture(fields[f][0].id)) { - if (glIsTexture(fields[f][p].id)) - { - glDeleteTextures(1, &fields[f][p].id); - } - fields[f][p].id = 0; + glDeleteTextures(1, &fields[f][0].id); } + fields[f][0].id = 0; } + fields[f][1].id = 0; fields[f][2].id = 0; } g_graphicsContext.EndPaint(); @@ -2538,7 +2506,7 @@ bool CLinuxRendererGL::CreateYUY2Texture(int index) im.height = m_sourceHeight; im.width = m_sourceWidth; - im.cshift_x = 1; + im.cshift_x = 0; im.cshift_y = 0; im.stride[0] = im.width * 2; @@ -2575,15 +2543,13 @@ bool CLinuxRendererGL::CreateYUY2Texture(int index) glEnable(m_textureTarget); for(int f = 0;f<MAX_FIELDS;f++) { - for(int p = 0;p<2;p++) + if (!glIsTexture(fields[f][0].id)) { - if (!glIsTexture(fields[f][p].id)) - { - glGenTextures(1, &fields[f][p].id); - VerifyGLState(); - } - fields[f][p].pbo = pbo[0]; + glGenTextures(1, &fields[f][0].id); + VerifyGLState(); } + fields[f][0].pbo = pbo[0]; + fields[f][1].id = fields[f][0].id; fields[f][2].id = fields[f][1].id; } @@ -2596,7 +2562,7 @@ bool CLinuxRendererGL::CreateYUY2Texture(int index) planes[0].texwidth = im.width; planes[0].texheight = im.height >> fieldshift; - planes[1].texwidth = planes[0].texwidth >> im.cshift_x; + planes[1].texwidth = planes[0].texwidth; planes[1].texheight = planes[0].texheight; planes[2].texwidth = planes[1].texwidth; @@ -2611,25 +2577,19 @@ bool CLinuxRendererGL::CreateYUY2Texture(int index) } } - for(int p = 0; p < 2; p++) - { - YUVPLANE &plane = planes[p]; - if (plane.texwidth * plane.texheight == 0) - continue; + YUVPLANE &plane = planes[0]; + if (plane.texwidth * plane.texheight == 0) + continue; - glBindTexture(m_textureTarget, plane.id); + glBindTexture(m_textureTarget, plane.id); - if (p == 0) - glTexImage2D(m_textureTarget, 0, GL_LUMINANCE_ALPHA, plane.texwidth, plane.texheight, 0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, NULL); - else - glTexImage2D(m_textureTarget, 0, GL_RGBA, plane.texwidth, plane.texheight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + glTexImage2D(m_textureTarget, 0, GL_RGBA, plane.texwidth / 2, plane.texheight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); - glTexParameteri(m_textureTarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(m_textureTarget, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(m_textureTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(m_textureTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - VerifyGLState(); - } + glTexParameteri(m_textureTarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(m_textureTarget, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(m_textureTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(m_textureTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + VerifyGLState(); } glDisable(m_textureTarget); SetEvent(m_eventTexturesDone[index]); @@ -2751,8 +2711,11 @@ bool CLinuxRendererGL::Supports(EINTERLACEMETHOD method) bool CLinuxRendererGL::Supports(ESCALINGMETHOD method) { - if(method == VS_SCALINGMETHOD_NEAREST - || method == VS_SCALINGMETHOD_LINEAR + //nearest neighbor doesn't work on YUY2 + if (method == VS_SCALINGMETHOD_NEAREST && CONF_FLAGS_FORMAT_MASK(m_iFlags) != CONF_FLAGS_FORMAT_YUY2) + return true; + + if(method == VS_SCALINGMETHOD_LINEAR || method == VS_SCALINGMETHOD_AUTO) return true; diff --git a/xbmc/cores/VideoRenderers/LinuxRendererGL.h b/xbmc/cores/VideoRenderers/LinuxRendererGL.h index abb44e7e3d..59ee80174c 100644 --- a/xbmc/cores/VideoRenderers/LinuxRendererGL.h +++ b/xbmc/cores/VideoRenderers/LinuxRendererGL.h @@ -271,7 +271,7 @@ protected: void LoadPlane( YUVPLANE& plane, int type, unsigned flipindex , unsigned width, unsigned height - , int stride, void* data, GLuint pbo = 0 ); + , int stride, void* data ); Shaders::BaseYUV2RGBShader *m_pYUVShader; Shaders::BaseVideoFilterShader *m_pVideoFilterShader; diff --git a/xbmc/cores/VideoRenderers/VideoShaders/YUV2RGBShader.cpp b/xbmc/cores/VideoRenderers/VideoShaders/YUV2RGBShader.cpp index a1af043dca..e181f601d0 100644 --- a/xbmc/cores/VideoRenderers/VideoShaders/YUV2RGBShader.cpp +++ b/xbmc/cores/VideoRenderers/VideoShaders/YUV2RGBShader.cpp @@ -157,6 +157,7 @@ BaseYUV2RGBGLSLShader::BaseYUV2RGBGLSLShader(bool rect, unsigned flags, bool str m_hUTex = -1; m_hVTex = -1; m_hStretch = -1; + m_hStep = -1; #ifdef HAS_GL if(rect) @@ -175,6 +176,13 @@ BaseYUV2RGBGLSLShader::BaseYUV2RGBGLSLShader(bool rect, unsigned flags, bool str else m_defines += "#define XBMC_STRETCH 0\n"; + if (CONF_FLAGS_FORMAT_MASK(flags) == CONF_FLAGS_FORMAT_YV12) + m_defines += "#define XBMC_YV12\n"; + else if (CONF_FLAGS_FORMAT_MASK(flags) == CONF_FLAGS_FORMAT_NV12) + m_defines += "#define XBMC_NV12\n"; + else if (CONF_FLAGS_FORMAT_MASK(flags) == CONF_FLAGS_FORMAT_YUY2) + m_defines += "#define XBMC_YUY2\n"; + VertexShader()->LoadSource("yuv2rgb_vertex.glsl", m_defines); #elif HAS_GLES == 2 m_hVertex = -1; @@ -205,6 +213,7 @@ void BaseYUV2RGBGLSLShader::OnCompiledAndLinked() 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(); } @@ -215,6 +224,7 @@ bool BaseYUV2RGBGLSLShader::OnEnabled() 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]; CalculateYUVMatrixGL(matrix, m_flags, m_black, m_contrast); @@ -310,11 +320,21 @@ YUV2RGBProgressiveShaderARB::YUV2RGBProgressiveShaderARB(bool rect, unsigned fla { m_black = 0.0f; m_contrast = 1.0f; - if(rect) - PixelShader()->LoadSource("yuv2rgb_basic_rect.arb"); - else - PixelShader()->LoadSource("yuv2rgb_basic_2d.arb"); + if (CONF_FLAGS_FORMAT_MASK(flags) == CONF_FLAGS_FORMAT_YUY2) + { + if(rect) + PixelShader()->LoadSource("yuv2rgb_basic_rect_YUY2.arb"); + else + PixelShader()->LoadSource("yuv2rgb_basic_2d_YUY2.arb"); + } + else + { + if(rect) + PixelShader()->LoadSource("yuv2rgb_basic_rect.arb"); + else + PixelShader()->LoadSource("yuv2rgb_basic_2d.arb"); + } } void YUV2RGBProgressiveShaderARB::OnCompiledAndLinked() @@ -332,6 +352,10 @@ bool YUV2RGBProgressiveShaderARB::OnEnabled() , 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; } #endif diff --git a/xbmc/cores/VideoRenderers/VideoShaders/YUV2RGBShader.h b/xbmc/cores/VideoRenderers/VideoShaders/YUV2RGBShader.h index 521f99c6bd..c662eb01ec 100644 --- a/xbmc/cores/VideoRenderers/VideoShaders/YUV2RGBShader.h +++ b/xbmc/cores/VideoRenderers/VideoShaders/YUV2RGBShader.h @@ -109,6 +109,7 @@ namespace Shaders { GLint m_hVTex; GLint m_hMatrix; GLint m_hStretch; + GLint m_hStep; #if HAS_GLES == 2 GLint m_hVertex; GLint m_hYcoord; |