Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

weave with shader

  • Loading branch information...
commit 975d03b504b51d81acd627489255d9a2d70f7e46 1 parent 44fef67
@FernetMenta authored
View
31 system/shaders/yuv2rgb_basic.glsl
@@ -32,12 +32,21 @@ varying vec2 m_cordY;
varying vec2 m_cordU;
varying vec2 m_cordV;
+uniform sampler2D m_sampY2;
+uniform sampler2D m_sampU2;
+uniform sampler2D m_sampV2;
+varying vec2 m_cordY2;
+varying vec2 m_cordU2;
+varying vec2 m_cordV2;
+
uniform vec2 m_step;
uniform mat4 m_yuvmat;
uniform float m_stretch;
+uniform int m_weave;
+
vec2 stretch(vec2 pos)
{
#if (XBMC_STRETCH)
@@ -73,14 +82,24 @@ void main()
#elif defined(XBMC_VDPAU_NV12)
vec4 yuv, rgb;
- 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 );
-
+
+ if (mod(gl_FragCoord.y, 2.0) < 1.0 || (m_weave == 0))
+ {
+ 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 );
+ }
+ else
+ {
+ yuv.rgba = vec4( texture2D(m_sampY2, stretch(m_cordY2)).r
+ , texture2D(m_sampU2, stretch(m_cordU2)).r
+ , texture2D(m_sampV2, stretch(m_cordV2)).g
+ , 1.0 );
+ }
@elupus
elupus added a note

This will slow down the normal shader in the non weave case. This should be a #if()

@FernetMenta Owner

ok.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
rgb = m_yuvmat * yuv;
rgb.a = gl_Color.a;
- gl_FragColor = rgb;
+ gl_FragColor = rgb;
#elif defined(XBMC_YUY2) || defined(XBMC_UYVY)
View
6 system/shaders/yuv2rgb_vertex.glsl
@@ -22,6 +22,9 @@
varying vec2 m_cordY;
varying vec2 m_cordU;
varying vec2 m_cordV;
+varying vec2 m_cordY2;
+varying vec2 m_cordU2;
+varying vec2 m_cordV2;
void main()
{
@@ -33,6 +36,9 @@ void main()
m_cordY = vec2(gl_TextureMatrix[0] * gl_MultiTexCoord0);
m_cordU = vec2(gl_TextureMatrix[1] * gl_MultiTexCoord1);
m_cordV = vec2(gl_TextureMatrix[2] * gl_MultiTexCoord2);
+ m_cordY2 = vec2(gl_TextureMatrix[3] * gl_MultiTexCoord3);
+ m_cordU2 = vec2(gl_TextureMatrix[4] * gl_MultiTexCoord4);
+ m_cordV2 = vec2(gl_TextureMatrix[5] * gl_MultiTexCoord5);
#endif
gl_Position = ftransform();
gl_FrontColor = gl_Color;
View
441 xbmc/cores/VideoRenderers/LinuxRendererGL.cpp
@@ -693,14 +693,7 @@ void CLinuxRendererGL::RenderUpdate(bool clear, DWORD flags, DWORD alpha)
else if(m_format == RENDER_FMT_VDPAU_420
&& !(flags & (RENDER_FLAG_TOP | RENDER_FLAG_BOT)))
{
- glDisable(GL_BLEND);
- glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
- Render(flags | RENDER_FLAG_TOP, index);
-
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glColor4f(1.0f, 1.0f, 1.0f, 128 / 255.0f);
- Render(flags | RENDER_FLAG_BOT , index);
+ Render(RENDER_FLAG_TOP, index, true, RENDER_FLAG_BOT, index);
@elupus
elupus added a note

Hmm.. This is the blend case.. Not weave, so shouldn't be changed.

@FernetMenta Owner

This is actually the case when vdpau interop yuv want's to output a progressive frame. As notes earlier, it only exposes fields, not a complete frame.

@elupus
elupus added a note

That may as well be, but we should not break blend in the non vdpau case.

@FernetMenta Owner

Sure, this is why I check for vdpau format in line 693.

@elupus
elupus added a note

Oh, right.. i missed that this was a diff against your interop branch. Thought that removed the code for normal blend.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
}
else
{
@@ -983,7 +976,7 @@ void CLinuxRendererGL::UpdateVideoFilter()
m_renderQuality = RQ_SINGLEPASS;
}
-void CLinuxRendererGL::LoadShaders(int field)
+void CLinuxRendererGL::LoadShaders()
{
if (m_format == RENDER_FMT_VDPAU)
{
@@ -1209,7 +1202,7 @@ void CLinuxRendererGL::UnInit()
m_bConfigured = false;
}
-void CLinuxRendererGL::Render(DWORD flags, int renderBuffer)
+void CLinuxRendererGL::Render(DWORD flags, int renderBuffer, bool weave /*= false*/, DWORD flags2 /*= 0*/, int renderBuffer2 /*= 0*/)
{
// obtain current field, if interlaced
if( flags & RENDER_FLAG_TOP)
@@ -1221,6 +1214,15 @@ void CLinuxRendererGL::Render(DWORD flags, int renderBuffer)
else
m_currentField = FIELD_FULL;
+ int field2;
+ if (weave)
+ {
+ if (flags2 & RENDER_FLAG_TOP)
+ field2 = FIELD_TOP;
+ else
+ field2 = FIELD_BOT;
+ }
+
// call texture load function
m_skipRender = false;
(this->*m_textureUpload)(renderBuffer);
@@ -1234,19 +1236,22 @@ void CLinuxRendererGL::Render(DWORD flags, int renderBuffer)
{
case RQ_LOW:
case RQ_SINGLEPASS:
- RenderSinglePass(renderBuffer, m_currentField);
+ if (weave)
+ RenderSinglePassWeave(renderBuffer, m_currentField, renderBuffer2, field2);
+ else
+ RenderSinglePass(renderBuffer, m_currentField, false, renderBuffer2, field2);
VerifyGLState();
break;
case RQ_MULTIPASS:
- RenderMultiPass(renderBuffer, m_currentField);
+ RenderMultiPass(renderBuffer, m_currentField, weave, renderBuffer2, field2);
VerifyGLState();
break;
}
}
else if (m_renderMethod & RENDER_ARB)
{
- RenderSinglePass(renderBuffer, m_currentField);
+ RenderSinglePass(renderBuffer, m_currentField, false, 0, 0);
}
#ifdef HAVE_LIBVDPAU
else if (m_renderMethod & RENDER_VDPAU)
@@ -1277,15 +1282,18 @@ void CLinuxRendererGL::Render(DWORD flags, int renderBuffer)
}
}
-void CLinuxRendererGL::RenderSinglePass(int index, int field)
+void CLinuxRendererGL::RenderSinglePass(int index, int field, bool weave, int index2, int field2)
{
YUVFIELDS &fields = m_buffers[index].fields;
YUVPLANES &planes = fields[field];
+ YUVFIELDS &fields2 = m_buffers[index2].fields;
+ YUVPLANES &planes2 = fields2[field2];
+
@elupus
elupus added a note

What is index2 good for? Both fields are in same index?

@FernetMenta Owner

This is for the WeaveX2 method. It duplicated frame rate by inseting a frame combining one field of previous frame with one filed of current frame.

@elupus
elupus added a note

Ah. multipass would be simpler.

@elupus
elupus added a note

That came out harsh.. Multipass would be much slower.. so it's probably a good idea to add this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
if (m_reloadShaders)
{
m_reloadShaders = 0;
- LoadShaders(field);
+ LoadShaders();
}
glDisable(GL_DEPTH_TEST);
@@ -1305,6 +1313,24 @@ void CLinuxRendererGL::RenderSinglePass(int index, int field)
glEnable(m_textureTarget);
glBindTexture(m_textureTarget, planes[2].id);
+ if (weave)
+ {
+ // Y2
+ glActiveTextureARB(GL_TEXTURE3);
+ glEnable(m_textureTarget);
+ glBindTexture(m_textureTarget, planes2[0].id);
+
+ // U2
+ glActiveTextureARB(GL_TEXTURE4);
+ glEnable(m_textureTarget);
+ glBindTexture(m_textureTarget, planes2[1].id);
+
+ // V2
+ glActiveTextureARB(GL_TEXTURE5);
+ glEnable(m_textureTarget);
+ glBindTexture(m_textureTarget, planes2[2].id);
+ }
+
glActiveTextureARB(GL_TEXTURE0);
VerifyGLState();
@@ -1320,10 +1346,16 @@ void CLinuxRendererGL::RenderSinglePass(int index, int field)
else
m_pYUVShader->SetNonLinStretch(pow(g_settings.m_fPixelRatio, g_advancedSettings.m_videoNonLinStretchRatio));
- if (field == FIELD_TOP)
- m_pYUVShader->SetField(1);
- else if(field == FIELD_BOT)
- m_pYUVShader->SetField(0);
+ if (!weave)
+ {
+ if (field == FIELD_TOP)
+ m_pYUVShader->SetField(1);
+ else if(field == FIELD_BOT)
+ m_pYUVShader->SetField(0);
+ m_pYUVShader->SetWeave(0);
+ }
+ else
+ m_pYUVShader->SetWeave(1);
m_pYUVShader->Enable();
@@ -1332,21 +1364,45 @@ void CLinuxRendererGL::RenderSinglePass(int index, int field)
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);
+ if (weave)
+ {
+ glMultiTexCoord2fARB(GL_TEXTURE3, planes2[0].rect.x1, planes2[0].rect.y1);
+ glMultiTexCoord2fARB(GL_TEXTURE4, planes2[1].rect.x1, planes2[1].rect.y1);
+ glMultiTexCoord2fARB(GL_TEXTURE5, planes2[2].rect.x1, planes2[2].rect.y1);
+ }
glVertex4f(m_destRect.x1, m_destRect.y1, 0, 1.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);
+ if (weave)
+ {
+ glMultiTexCoord2fARB(GL_TEXTURE3, planes2[0].rect.x2, planes2[0].rect.y1);
+ glMultiTexCoord2fARB(GL_TEXTURE4, planes2[1].rect.x2, planes2[1].rect.y1);
+ glMultiTexCoord2fARB(GL_TEXTURE5, planes2[2].rect.x2, planes2[2].rect.y1);
+ }
glVertex4f(m_destRect.x2, m_destRect.y1, 0, 1.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);
+ if (weave)
+ {
+ glMultiTexCoord2fARB(GL_TEXTURE3, planes2[0].rect.x2, planes2[0].rect.y2);
+ glMultiTexCoord2fARB(GL_TEXTURE4, planes2[1].rect.x2, planes2[1].rect.y2);
+ glMultiTexCoord2fARB(GL_TEXTURE5, planes2[2].rect.x2, planes2[2].rect.y2);
+ }
glVertex4f(m_destRect.x2, m_destRect.y2, 0, 1.0f);
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);
+ if (weave)
+ {
+ glMultiTexCoord2fARB(GL_TEXTURE3, planes2[0].rect.x1, planes2[0].rect.y2);
+ glMultiTexCoord2fARB(GL_TEXTURE4, planes2[1].rect.x1, planes2[1].rect.y2);
+ glMultiTexCoord2fARB(GL_TEXTURE5, planes2[2].rect.x1, planes2[2].rect.y2);
+ }
glVertex4f(m_destRect.x1, m_destRect.y2, 0, 1.0f);
glEnd();
@@ -1355,6 +1411,18 @@ void CLinuxRendererGL::RenderSinglePass(int index, int field)
m_pYUVShader->Disable();
VerifyGLState();
+ if (weave)
+ {
+ glActiveTextureARB(GL_TEXTURE4);
+ glDisable(m_textureTarget);
+
+ glActiveTextureARB(GL_TEXTURE5);
+ glDisable(m_textureTarget);
+
+ glActiveTextureARB(GL_TEXTURE3);
+ glDisable(m_textureTarget);
+ }
+
glActiveTextureARB(GL_TEXTURE1);
glDisable(m_textureTarget);
@@ -1369,14 +1437,274 @@ void CLinuxRendererGL::RenderSinglePass(int index, int field)
VerifyGLState();
}
-void CLinuxRendererGL::RenderMultiPass(int index, int field)
+void CLinuxRendererGL::RenderSinglePassWeave(int index, int field, int index2, int field2)
@elupus
elupus added a note

This is somewhat confusingly named. It's not really rendering weaved to screen. How about RenderProgressiveFields?

@FernetMenta Owner

Yes, I don't like the name either. It can do the weave in terms of WeaveX2 or just combine the fields of a progressive, but not necessarily single pass. Maybe this method completely goes away (see other comment: RenderToFBO / RenderFromFBO)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
{
+ bool scaleUp = (int)m_sourceHeight < g_graphicsContext.GetHeight() && (int)m_sourceWidth < g_graphicsContext.GetWidth();
+ if (!scaleUp)
+ {
+ RenderSinglePass(index, field, true, index2, field2);
+ return;
+ }
+
+ if (!m_fbo.Initialize())
+ {
+ CLog::Log(LOGERROR, "GL: Error initializing FBO");
+ return;
+ }
+
+ if (!m_fbo.CreateAndBindToTexture(GL_TEXTURE_2D, m_sourceWidth, m_sourceHeight, GL_RGBA))
+ {
+ CLog::Log(LOGERROR, "GL: Error creating texture and binding to FBO");
+ return;
+ }
+
+ if (m_reloadShaders)
+ {
+ m_reloadShaders = 0;
+ LoadShaders();
+ }
+
+ if (!m_pVideoFilterShader)
+ {
+ m_pVideoFilterShader = new StretchFilterShader();
+ if (!m_pVideoFilterShader->CompileAndLink())
+ {
+ CLog::Log(LOGERROR, "GL: Error compiling and linking video filter shader");
+ return;
+ }
+ }
+
YUVPLANES &planes = m_buffers[index].fields[field];
+ YUVPLANES &planes2 = m_buffers[index2].fields[field2];
+
+ glDisable(GL_DEPTH_TEST);
+
+ // Y
+ glActiveTextureARB(GL_TEXTURE0);
+ glEnable(m_textureTarget);
+ glBindTexture(m_textureTarget, planes[0].id);
+ VerifyGLState();
+
+ // U
+ glActiveTextureARB(GL_TEXTURE1);
+ glEnable(m_textureTarget);
+ glBindTexture(m_textureTarget, planes[1].id);
+ VerifyGLState();
+
+ // V
+ glActiveTextureARB(GL_TEXTURE2);
+ glEnable(m_textureTarget);
+ glBindTexture(m_textureTarget, planes[2].id);
+ VerifyGLState();
+
+ // Y2
+ glActiveTextureARB(GL_TEXTURE3);
+ glEnable(m_textureTarget);
+ glBindTexture(m_textureTarget, planes2[0].id);
+ VerifyGLState();
+
+ // U2
+ glActiveTextureARB(GL_TEXTURE4);
+ glEnable(m_textureTarget);
+ glBindTexture(m_textureTarget, planes2[1].id);
+ VerifyGLState();
+
+ // V2
+ glActiveTextureARB(GL_TEXTURE5);
+ glEnable(m_textureTarget);
+ glBindTexture(m_textureTarget, planes2[2].id);
+ VerifyGLState();
+
+ glActiveTextureARB(GL_TEXTURE0);
+ VerifyGLState();
+
+ // make sure the yuv shader is loaded and ready to go
+ if (!m_pYUVShader || (!m_pYUVShader->OK()))
+ {
+ CLog::Log(LOGERROR, "GL: YUV shader not active, cannot do multipass render");
+ return;
+ }
+
+ m_fbo.BeginRender();
+ VerifyGLState();
+
+ 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(planes[0].texwidth);
+ m_pYUVShader->SetHeight(planes[0].texheight);
+ m_pYUVShader->SetNonLinStretch(1.0);
+ m_pYUVShader->SetWeave(1);
+
+ VerifyGLState();
+
+ glPushAttrib(GL_VIEWPORT_BIT);
+ glPushAttrib(GL_SCISSOR_BIT);
+ glMatrixMode(GL_MODELVIEW);
+ glPushMatrix();
+ glLoadIdentity();
+ VerifyGLState();
+
+ glMatrixMode(GL_PROJECTION);
+ glPushMatrix();
+ glLoadIdentity();
+ VerifyGLState();
+ gluOrtho2D(0, m_sourceWidth, 0, m_sourceHeight);
+ glViewport(0, 0, m_sourceWidth, m_sourceHeight);
+ glScissor (0, 0, m_sourceWidth, m_sourceHeight);
+ glMatrixMode(GL_MODELVIEW);
+ VerifyGLState();
+
+ if (!m_pYUVShader->Enable())
+ {
+ CLog::Log(LOGERROR, "GL: Error enabling YUV shader");
+ }
+
+ float imgwidth = planes[0].rect.x2 - planes[0].rect.x1;
+ float imgheight = planes[0].rect.y2 - planes[0].rect.y1;
+ if (m_textureTarget == GL_TEXTURE_2D)
+ {
+ imgwidth *= planes[0].texwidth;
+ imgheight *= planes[0].texheight;
+ }
+ imgwidth *= planes[0].pixpertex_x;
+ imgheight *= planes[0].pixpertex_y;
+
+ // 1st Pass to video frame size
+ glBegin(GL_QUADS);
+
+ 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);
+ glMultiTexCoord2fARB(GL_TEXTURE3, planes2[0].rect.x1, planes2[0].rect.y1);
+ glMultiTexCoord2fARB(GL_TEXTURE4, planes2[1].rect.x1, planes2[1].rect.y1);
+ glMultiTexCoord2fARB(GL_TEXTURE5, planes2[2].rect.x1, planes2[2].rect.y1);
+ glVertex2f(0.0f , 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);
+ glMultiTexCoord2fARB(GL_TEXTURE3, planes2[0].rect.x2, planes2[0].rect.y1);
+ glMultiTexCoord2fARB(GL_TEXTURE4, planes2[1].rect.x2, planes2[1].rect.y1);
+ glMultiTexCoord2fARB(GL_TEXTURE5, planes2[2].rect.x2, planes2[2].rect.y1);
+ glVertex2f(imgwidth, 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);
+ glMultiTexCoord2fARB(GL_TEXTURE3, planes2[0].rect.x2, planes2[0].rect.y2);
+ glMultiTexCoord2fARB(GL_TEXTURE4, planes2[1].rect.x2, planes2[1].rect.y2);
+ glMultiTexCoord2fARB(GL_TEXTURE5, planes2[2].rect.x2, planes2[2].rect.y2);
+ glVertex2f(imgwidth, imgheight);
+
+ 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);
+ glMultiTexCoord2fARB(GL_TEXTURE3, planes2[0].rect.x1, planes2[0].rect.y2);
+ glMultiTexCoord2fARB(GL_TEXTURE4, planes2[1].rect.x1, planes2[1].rect.y2);
+ glMultiTexCoord2fARB(GL_TEXTURE5, planes2[2].rect.x1, planes2[2].rect.y2);
+ glVertex2f(0.0f , imgheight);
+
+ glEnd();
+ VerifyGLState();
+
+ m_pYUVShader->Disable();
+
+ glMatrixMode(GL_MODELVIEW);
+ glPopMatrix(); // pop modelview
+ glMatrixMode(GL_PROJECTION);
+ glPopMatrix(); // pop projection
+ glPopAttrib(); // pop scissor
+ glPopAttrib(); // pop viewport
+ glMatrixMode(GL_MODELVIEW);
+ VerifyGLState();
+
+ m_fbo.EndRender();
+
+ glActiveTextureARB(GL_TEXTURE4);
+ glDisable(m_textureTarget);
+ glActiveTextureARB(GL_TEXTURE5);
+ glDisable(m_textureTarget);
+ glActiveTextureARB(GL_TEXTURE3);
+ glDisable(m_textureTarget);
+
+ glActiveTextureARB(GL_TEXTURE1);
+ glDisable(m_textureTarget);
+ glActiveTextureARB(GL_TEXTURE2);
+ glDisable(m_textureTarget);
+ glActiveTextureARB(GL_TEXTURE0);
+ glDisable(m_textureTarget);
+
+ glEnable(GL_TEXTURE_2D);
+ glBindTexture(GL_TEXTURE_2D, m_fbo.Texture());
+ VerifyGLState();
+
+ if (m_pVideoFilterShader)
+ {
@elupus
elupus added a note

Everything below here is duplicate from MultipassRender right? So should be factored out.

@FernetMenta Owner

Yep, below and above. Maybe this can be split into RenderToFBO and RenderFromFBO

@elupus
elupus added a note

Yea that sounds good. Please try to do that as a separate commit before this one.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+ GLint filter;
+ if (!m_pVideoFilterShader->GetTextureFilter(filter))
+ filter = m_scalingMethod == VS_SCALINGMETHOD_NEAREST ? GL_NEAREST : GL_LINEAR;
+
+ m_fbo.SetFiltering(GL_TEXTURE_2D, 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 && g_application.m_pPlayer->IsInMenu())
+ m_pVideoFilterShader->SetNonLinStretch(1.0);
+ else
+ m_pVideoFilterShader->SetNonLinStretch(pow(g_settings.m_fPixelRatio, g_advancedSettings.m_videoNonLinStretchRatio));
+
+ m_pVideoFilterShader->Enable();
+ }
+ else
+ {
+ GLint filter = m_scalingMethod == VS_SCALINGMETHOD_NEAREST ? GL_NEAREST : GL_LINEAR;
+ m_fbo.SetFiltering(GL_TEXTURE_2D, filter);
+ }
+
+ VerifyGLState();
+
+ imgwidth /= m_sourceWidth;
+ imgheight /= m_sourceHeight;
+
+ glBegin(GL_QUADS);
+
+ glMultiTexCoord2fARB(GL_TEXTURE0, 0.0f , 0.0f);
+ glVertex4f(m_destRect.x1, m_destRect.y1, 0, 1.0f );
+
+ glMultiTexCoord2fARB(GL_TEXTURE0, imgwidth, 0.0f);
+ glVertex4f(m_destRect.x2, m_destRect.y1, 0, 1.0f);
+
+ glMultiTexCoord2fARB(GL_TEXTURE0, imgwidth, imgheight);
+ glVertex4f(m_destRect.x2, m_destRect.y2, 0, 1.0f);
+
+ glMultiTexCoord2fARB(GL_TEXTURE0, 0.0f , imgheight);
+ glVertex4f(m_destRect.x1, m_destRect.y2, 0, 1.0f);
+
+ glEnd();
+
+ VerifyGLState();
+
+ if (m_pVideoFilterShader)
+ m_pVideoFilterShader->Disable();
+
+ VerifyGLState();
+
+ glDisable(m_textureTarget);
+ VerifyGLState();
+}
+
+void CLinuxRendererGL::RenderMultiPass(int index, int field, bool weave, int index2, int field2)
+{
+ YUVPLANES &planes = m_buffers[index].fields[field];
+ YUVPLANES &planes2 = m_buffers[index2].fields[field2];
if (m_reloadShaders)
{
m_reloadShaders = 0;
- LoadShaders(m_currentField);
+ LoadShaders();
}
glDisable(GL_DEPTH_TEST);
@@ -1399,6 +1727,27 @@ void CLinuxRendererGL::RenderMultiPass(int index, int field)
glBindTexture(m_textureTarget, planes[2].id);
VerifyGLState();
+ if (weave)
+ {
+ // Y2
+ glActiveTextureARB(GL_TEXTURE3);
+ glEnable(m_textureTarget);
+ glBindTexture(m_textureTarget, planes2[0].id);
+ VerifyGLState();
+
+ // U2
+ glActiveTextureARB(GL_TEXTURE4);
+ glEnable(m_textureTarget);
+ glBindTexture(m_textureTarget, planes2[1].id);
+ VerifyGLState();
+
+ // V2
+ glActiveTextureARB(GL_TEXTURE5);
+ glEnable(m_textureTarget);
+ glBindTexture(m_textureTarget, planes2[2].id);
+ VerifyGLState();
+ }
+
glActiveTextureARB(GL_TEXTURE0);
VerifyGLState();
@@ -1417,10 +1766,17 @@ void CLinuxRendererGL::RenderMultiPass(int index, int field)
m_pYUVShader->SetWidth(planes[0].texwidth);
m_pYUVShader->SetHeight(planes[0].texheight);
m_pYUVShader->SetNonLinStretch(1.0);
- if (field == FIELD_TOP)
- m_pYUVShader->SetField(1);
- else if(field == FIELD_BOT)
- m_pYUVShader->SetField(0);
+
+ if (!weave)
+ {
+ if (field == FIELD_TOP)
+ m_pYUVShader->SetField(1);
+ else if(field == FIELD_BOT)
+ m_pYUVShader->SetField(0);
+ m_pYUVShader->SetWeave(0);
+ }
+ else
+ m_pYUVShader->SetWeave(1);
VerifyGLState();
@@ -1463,21 +1819,46 @@ void CLinuxRendererGL::RenderMultiPass(int index, int field)
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);
+ if (weave)
+ {
+ glMultiTexCoord2fARB(GL_TEXTURE3, planes2[0].rect.x1, planes2[0].rect.y1);
+ glMultiTexCoord2fARB(GL_TEXTURE4, planes2[1].rect.x1, planes2[1].rect.y1);
+ glMultiTexCoord2fARB(GL_TEXTURE5, planes2[2].rect.x1, planes2[2].rect.y1);
+ }
+
glVertex2f(0.0f , 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);
+ if (weave)
+ {
+ glMultiTexCoord2fARB(GL_TEXTURE3, planes2[0].rect.x2, planes2[0].rect.y1);
+ glMultiTexCoord2fARB(GL_TEXTURE4, planes2[1].rect.x2, planes2[1].rect.y1);
+ glMultiTexCoord2fARB(GL_TEXTURE5, planes2[2].rect.x2, planes2[2].rect.y1);
+ }
glVertex2f(imgwidth, 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);
+ if (weave)
+ {
+ glMultiTexCoord2fARB(GL_TEXTURE3, planes2[0].rect.x2, planes2[0].rect.y2);
+ glMultiTexCoord2fARB(GL_TEXTURE4, planes2[1].rect.x2, planes2[1].rect.y2);
+ glMultiTexCoord2fARB(GL_TEXTURE5, planes2[2].rect.x2, planes2[2].rect.y2);
+ }
glVertex2f(imgwidth, imgheight);
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);
+ if (weave)
+ {
+ glMultiTexCoord2fARB(GL_TEXTURE3, planes2[0].rect.x1, planes2[0].rect.y2);
+ glMultiTexCoord2fARB(GL_TEXTURE4, planes2[1].rect.x1, planes2[1].rect.y2);
+ glMultiTexCoord2fARB(GL_TEXTURE5, planes2[2].rect.x1, planes2[2].rect.y2);
+ }
glVertex2f(0.0f , imgheight);
glEnd();
@@ -1496,6 +1877,16 @@ void CLinuxRendererGL::RenderMultiPass(int index, int field)
m_fbo.EndRender();
+ if (weave)
+ {
+ glActiveTextureARB(GL_TEXTURE4);
+ glDisable(m_textureTarget);
+ glActiveTextureARB(GL_TEXTURE5);
+ glDisable(m_textureTarget);
+ glActiveTextureARB(GL_TEXTURE3);
+ glDisable(m_textureTarget);
+ }
+
glActiveTextureARB(GL_TEXTURE1);
glDisable(m_textureTarget);
glActiveTextureARB(GL_TEXTURE2);
View
9 xbmc/cores/VideoRenderers/LinuxRendererGL.h
@@ -172,7 +172,7 @@ class CLinuxRendererGL : public CBaseRenderer
virtual std::vector<ERenderFormat> SupportedFormats() { return m_formats; }
protected:
- virtual void Render(DWORD flags, int renderBuffer);
+ virtual void Render(DWORD flags, int renderBuffer, bool weave = false, DWORD flags2 = 0, int renderBuffer2 = 0);
@elupus
elupus added a note

weave is impllied of flags contain TOP and BOTTOM field at the same time.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
void ClearBackBuffer();
void DrawBlackBars();
@@ -180,7 +180,7 @@ class CLinuxRendererGL : public CBaseRenderer
virtual void ManageTextures();
int NextYV12Texture();
virtual bool ValidateRenderTarget();
- virtual void LoadShaders(int field=FIELD_FULL);
+ virtual void LoadShaders();
void SetTextureFilter(GLenum method);
void UpdateVideoFilter();
@@ -229,8 +229,9 @@ class CLinuxRendererGL : public CBaseRenderer
void CalculateTextureSourceRects(int source, int num_planes);
// renderers
- void RenderMultiPass(int renderBuffer, int field); // multi pass glsl renderer
- void RenderSinglePass(int renderBuffer, int field); // single pass glsl renderer
+ void RenderMultiPass(int renderBuffer, int field, bool weave, int index, int field2); // multi pass glsl renderer
+ void RenderSinglePass(int renderBuffer, int field, bool weave, int index2, int field2); // single pass glsl renderer
+ void RenderSinglePassWeave(int index, int field, int index2, int field2);
void RenderSoftware(int renderBuffer, int field); // single pass s/w yuv2rgb renderer
void RenderVDPAU(int renderBuffer, int field); // render using vdpau hardware
void RenderVDPAUYV12(int renderBuffer, int field); // render using vdpau hardware
View
12 xbmc/cores/VideoRenderers/VideoShaders/YUV2RGBShader.cpp
@@ -173,6 +173,7 @@ BaseYUV2RGBGLSLShader::BaseYUV2RGBGLSLShader(bool rect, unsigned flags, ERenderF
m_hVTex = -1;
m_hStretch = -1;
m_hStep = -1;
+ m_hWeave = 0;
#ifdef HAS_GL
if(rect)
@@ -236,9 +237,13 @@ void BaseYUV2RGBGLSLShader::OnCompiledAndLinked()
m_hYTex = glGetUniformLocation(ProgramHandle(), "m_sampY");
m_hUTex = glGetUniformLocation(ProgramHandle(), "m_sampU");
m_hVTex = glGetUniformLocation(ProgramHandle(), "m_sampV");
+ m_hYTex2 = glGetUniformLocation(ProgramHandle(), "m_sampY2");
+ m_hUTex2 = glGetUniformLocation(ProgramHandle(), "m_sampU2");
+ m_hVTex2 = glGetUniformLocation(ProgramHandle(), "m_sampV2");
m_hMatrix = glGetUniformLocation(ProgramHandle(), "m_yuvmat");
m_hStretch = glGetUniformLocation(ProgramHandle(), "m_stretch");
m_hStep = glGetUniformLocation(ProgramHandle(), "m_step");
+ m_hWeave = glGetUniformLocation(ProgramHandle(), "m_weave");
VerifyGLState();
}
@@ -248,8 +253,12 @@ bool BaseYUV2RGBGLSLShader::OnEnabled()
glUniform1i(m_hYTex, 0);
glUniform1i(m_hUTex, 1);
glUniform1i(m_hVTex, 2);
+ glUniform1i(m_hYTex2, 3);
+ glUniform1i(m_hUTex2, 4);
+ glUniform1i(m_hVTex2, 5);
glUniform1f(m_hStretch, m_stretch);
glUniform2f(m_hStep, 1.0 / m_width, 1.0 / m_height);
+ glUniform1i(m_hWeave, m_weave);
GLfloat matrix[4][4];
CalculateYUVMatrixGL(matrix, m_flags, m_format, m_black, m_contrast);
@@ -280,6 +289,9 @@ BaseYUV2RGBARBShader::BaseYUV2RGBARBShader(unsigned flags, ERenderFormat format)
m_hYTex = -1;
m_hUTex = -1;
m_hVTex = -1;
+ m_hYTex2 = -1;
+ m_hUTex2 = -1;
+ m_hVTex2 = -1;
}
#endif
View
10 xbmc/cores/VideoRenderers/VideoShaders/YUV2RGBShader.h
@@ -54,6 +54,7 @@ namespace Shaders {
virtual void SetBlack(float black) {};
virtual void SetContrast(float contrast) {};
virtual void SetNonLinStretch(float stretch){};
+ virtual void SetWeave(int weave){};
#if HAS_GLES == 2
virtual GLint GetVertexLoc() { return 0; };
virtual GLint GetYcoordLoc() { return 0; };
@@ -80,6 +81,7 @@ namespace Shaders {
virtual void SetBlack(float black) { m_black = black; }
virtual void SetContrast(float contrast) { m_contrast = contrast; }
virtual void SetNonLinStretch(float stretch) { m_stretch = stretch; }
+ virtual void SetWeave(int weave) { m_weave = weave; }
#if HAS_GLES == 2
virtual GLint GetVertexLoc() { return m_hVertex; }
virtual GLint GetYcoordLoc() { return m_hYcoord; }
@@ -103,6 +105,7 @@ namespace Shaders {
float m_black;
float m_contrast;
float m_stretch;
+ int m_weave;
string m_defines;
@@ -110,9 +113,13 @@ namespace Shaders {
GLint m_hYTex;
GLint m_hUTex;
GLint m_hVTex;
+ GLint m_hYTex2;
+ GLint m_hUTex2;
+ GLint m_hVTex2;
GLint m_hMatrix;
GLint m_hStretch;
GLint m_hStep;
+ GLint m_hWeave;
#if HAS_GLES == 2
GLint m_hVertex;
GLint m_hYcoord;
@@ -157,6 +164,9 @@ namespace Shaders {
GLint m_hYTex;
GLint m_hUTex;
GLint m_hVTex;
+ GLint m_hYTex2;
+ GLint m_hUTex2;
+ GLint m_hVTex2;
};
class YUV2RGBProgressiveShaderARB : public BaseYUV2RGBARBShader
Please sign in to comment.
Something went wrong with that request. Please try again.