diff options
author | CrystalPT <CrystalPT@svn> | 2010-08-03 01:16:18 +0000 |
---|---|---|
committer | CrystalPT <CrystalPT@svn> | 2010-08-03 01:16:18 +0000 |
commit | d31b7bfe061e7e1232344168ae9e0e48c6323381 (patch) | |
tree | 1f844ed2aacbf3e8e2b6f405f15c625ae766acfa | |
parent | 94e7088d6a2da5d66c33e561a00ad8453b97a4ad (diff) |
[WIN32] changed: always place the YUV buffers for dvdplayer in system memory and copy to video memory before running the shaders.
Not less efficient, we're explicitely doing the copy instead of letting D3D do it for us.
Helps with auto refresh rate: the textures don't need to be released on device loss, meaning they can be locked for dvdplayer wihtout interfering.
Hopefully also helps with ticket #9476.
git-svn-id: https://xbmc.svn.sourceforge.net/svnroot/xbmc/trunk@32438 568bbfeb-2a22-0410-94d2-cc84cf5bfa90
-rw-r--r-- | guilib/D3DResource.cpp | 4 | ||||
-rw-r--r-- | xbmc/cores/VideoRenderers/VideoShaders/WinVideoFilter.cpp | 108 | ||||
-rw-r--r-- | xbmc/cores/VideoRenderers/VideoShaders/WinVideoFilter.h | 13 | ||||
-rw-r--r-- | xbmc/cores/VideoRenderers/WinRenderer.cpp | 67 | ||||
-rw-r--r-- | xbmc/cores/VideoRenderers/WinRenderer.h | 10 |
5 files changed, 104 insertions, 98 deletions
diff --git a/guilib/D3DResource.cpp b/guilib/D3DResource.cpp index 8e757aec94..b2ac1164f5 100644 --- a/guilib/D3DResource.cpp +++ b/guilib/D3DResource.cpp @@ -123,7 +123,9 @@ void CD3DTexture::SaveTexture() { delete[] m_data; m_data = NULL; - if (!(m_usage & D3DUSAGE_RENDERTARGET) && !(m_usage & D3DUSAGE_DEPTHSTENCIL)) + if(!(m_usage & D3DUSAGE_RENDERTARGET) + && !(m_usage & D3DUSAGE_DEPTHSTENCIL) + && !(m_pool == D3DPOOL_DEFAULT && (m_usage & D3DUSAGE_DYNAMIC) == 0)) { D3DLOCKED_RECT lr; if (LockRect( 0, &lr, NULL, D3DLOCK_READONLY )) diff --git a/xbmc/cores/VideoRenderers/VideoShaders/WinVideoFilter.cpp b/xbmc/cores/VideoRenderers/VideoShaders/WinVideoFilter.cpp index d1037280f7..0aabc6c9bc 100644 --- a/xbmc/cores/VideoRenderers/VideoShaders/WinVideoFilter.cpp +++ b/xbmc/cores/VideoRenderers/VideoShaders/WinVideoFilter.cpp @@ -194,7 +194,7 @@ bool CWinShader::Execute() //================================================================================== -bool CYUV2RGBShader::Create(bool singlepass) +bool CYUV2RGBShader::Create(bool singlepass, unsigned int sourceWidth, unsigned int sourceHeight) { ReleaseInternal(); @@ -212,24 +212,35 @@ bool CYUV2RGBShader::Create(bool singlepass) CLog::Log(LOGERROR, __FUNCTION__": Failed to load shader %s.", effectString.c_str()); return false; } + + m_sourceWidth = sourceWidth; + m_sourceHeight = sourceHeight; + + if(!m_YUVPlanes[0].Create(m_sourceWidth , m_sourceHeight , 1, 0, D3DFMT_L8, D3DPOOL_DEFAULT) + || !m_YUVPlanes[1].Create(m_sourceWidth / 2, m_sourceHeight / 2, 1, 0, D3DFMT_L8, D3DPOOL_DEFAULT) + || !m_YUVPlanes[2].Create(m_sourceWidth / 2, m_sourceHeight / 2, 1, 0, D3DFMT_L8, D3DPOOL_DEFAULT)) + { + CLog::Log(LOGERROR, __FUNCTION__": Failed to create YUV planes."); + return false; + } + return true; } -void CYUV2RGBShader::Render(unsigned int sourceWidth, unsigned int sourceHeight, - CRect sourceRect, CRect destRect, +void CYUV2RGBShader::Render(CRect sourceRect, CRect destRect, float contrast, float brightness, unsigned int flags, YUVBuffer* YUVbuf) { - PrepareParameters(sourceWidth, sourceHeight, sourceRect, destRect, + PrepareParameters(sourceRect, destRect, contrast, brightness, flags); - SetShaderParameters(m_matrix.Matrix(), YUVbuf, sourceWidth); + UploadToGPU(YUVbuf); + SetShaderParameters(); Execute(); } -void CYUV2RGBShader::PrepareParameters(unsigned int sourceWidth, unsigned int sourceHeight, - CRect sourceRect, +void CYUV2RGBShader::PrepareParameters(CRect sourceRect, CRect destRect, float contrast, float brightness, @@ -238,11 +249,8 @@ void CYUV2RGBShader::PrepareParameters(unsigned int sourceWidth, unsigned int so //See RGB renderer for comment on this #define CHROMAOFFSET_HORIZ 0.25f - if (m_sourceWidth != sourceWidth || m_sourceHeight != sourceHeight - || m_sourceRect != sourceRect || m_destRect != destRect) + if (m_sourceRect != sourceRect || m_destRect != destRect) { - m_sourceWidth = sourceWidth; - m_sourceHeight = sourceHeight; m_sourceRect = sourceRect; m_destRect = destRect; @@ -251,31 +259,31 @@ void CYUV2RGBShader::PrepareParameters(unsigned int sourceWidth, unsigned int so v[0].x = destRect.x1; v[0].y = destRect.y1; - v[0].tu = sourceRect.x1 / sourceWidth; - v[0].tv = sourceRect.y1 / sourceHeight; - v[0].tu2 = v[0].tu3 = (sourceRect.x1 / 2.0f + CHROMAOFFSET_HORIZ) / (sourceWidth>>1); - v[0].tv2 = v[0].tv3 = (sourceRect.y1 / 2.0f + CHROMAOFFSET_HORIZ) / (sourceHeight>>1); + v[0].tu = sourceRect.x1 / m_sourceWidth; + v[0].tv = sourceRect.y1 / m_sourceHeight; + v[0].tu2 = v[0].tu3 = (sourceRect.x1 / 2.0f + CHROMAOFFSET_HORIZ) / (m_sourceWidth>>1); + v[0].tv2 = v[0].tv3 = (sourceRect.y1 / 2.0f + CHROMAOFFSET_HORIZ) / (m_sourceHeight>>1); v[1].x = destRect.x2; v[1].y = destRect.y1; - v[1].tu = sourceRect.x2 / sourceWidth; - v[1].tv = sourceRect.y1 / sourceHeight; - v[1].tu2 = v[1].tu3 = (sourceRect.x2 / 2.0f + CHROMAOFFSET_HORIZ) / (sourceWidth>>1); - v[1].tv2 = v[1].tv3 = (sourceRect.y1 / 2.0f + CHROMAOFFSET_HORIZ) / (sourceHeight>>1); + v[1].tu = sourceRect.x2 / m_sourceWidth; + v[1].tv = sourceRect.y1 / m_sourceHeight; + v[1].tu2 = v[1].tu3 = (sourceRect.x2 / 2.0f + CHROMAOFFSET_HORIZ) / (m_sourceWidth>>1); + v[1].tv2 = v[1].tv3 = (sourceRect.y1 / 2.0f + CHROMAOFFSET_HORIZ) / (m_sourceHeight>>1); v[2].x = destRect.x2; v[2].y = destRect.y2; - v[2].tu = sourceRect.x2 / sourceWidth; - v[2].tv = sourceRect.y2 / sourceHeight; - v[2].tu2 = v[2].tu3 = (sourceRect.x2 / 2.0f + CHROMAOFFSET_HORIZ) / (sourceWidth>>1); - v[2].tv2 = v[2].tv3 = (sourceRect.y2 / 2.0f + CHROMAOFFSET_HORIZ) / (sourceHeight>>1); + v[2].tu = sourceRect.x2 / m_sourceWidth; + v[2].tv = sourceRect.y2 / m_sourceHeight; + v[2].tu2 = v[2].tu3 = (sourceRect.x2 / 2.0f + CHROMAOFFSET_HORIZ) / (m_sourceWidth>>1); + v[2].tv2 = v[2].tv3 = (sourceRect.y2 / 2.0f + CHROMAOFFSET_HORIZ) / (m_sourceHeight>>1); v[3].x = destRect.x1; v[3].y = destRect.y2; - v[3].tu = sourceRect.x1 / sourceWidth; - v[3].tv = sourceRect.y2 / sourceHeight; - v[3].tu2 = v[3].tu3 = (sourceRect.x1 / 2.0f + CHROMAOFFSET_HORIZ) / (sourceWidth>>1); - v[3].tv2 = v[3].tv3 = (sourceRect.y2 / 2.0f + CHROMAOFFSET_HORIZ) / (sourceHeight>>1); + v[3].tu = sourceRect.x1 / m_sourceWidth; + v[3].tv = sourceRect.y2 / m_sourceHeight; + v[3].tu2 = v[3].tu3 = (sourceRect.x1 / 2.0f + CHROMAOFFSET_HORIZ) / (m_sourceWidth>>1); + v[3].tv2 = v[3].tv3 = (sourceRect.y2 / 2.0f + CHROMAOFFSET_HORIZ) / (m_sourceHeight>>1); // -0.5 offset to compensate for D3D rasterization // set z and rhw @@ -294,13 +302,49 @@ void CYUV2RGBShader::PrepareParameters(unsigned int sourceWidth, unsigned int so flags); } -void CYUV2RGBShader::SetShaderParameters(D3DXMATRIX* matrix, YUVBuffer* YUVbuf, unsigned int sourceWidth) +void CYUV2RGBShader::SetShaderParameters() { - m_effect.SetMatrix( "g_ColorMatrix", matrix); + m_effect.SetMatrix( "g_ColorMatrix", m_matrix.Matrix()); m_effect.SetTechnique( "YUV2RGB_T" ); - m_effect.SetTexture( "g_YTexture", YUVbuf->planes[0].texture ) ; - m_effect.SetTexture( "g_UTexture", YUVbuf->planes[1].texture ) ; - m_effect.SetTexture( "g_VTexture", YUVbuf->planes[2].texture ) ; + m_effect.SetTexture( "g_YTexture", m_YUVPlanes[0] ) ; + m_effect.SetTexture( "g_UTexture", m_YUVPlanes[1] ) ; + m_effect.SetTexture( "g_VTexture", m_YUVPlanes[2] ) ; +} + +void CYUV2RGBShader::ReleaseInternal() +{ + for(unsigned i = 0; i < MAX_PLANES; i++) + { + if (m_YUVPlanes[i].Get()) + m_YUVPlanes[i].Release(); + } +} + +bool CYUV2RGBShader::UploadToGPU(YUVBuffer* YUVbuf) +{ + const RECT rect = { 0, 0, m_sourceWidth, m_sourceHeight }; + const RECT recthalf = { 0, 0, m_sourceWidth / 2, m_sourceHeight / 2}; + const POINT point = { 0, 0 }; + + for (int i = 0; i<3; i++) + { + IDirect3DSurface9 *src, *dest; + if(FAILED(YUVbuf->planes[i].texture.Get()->GetSurfaceLevel(0, &src))) + CLog::Log(LOGERROR, __FUNCTION__": Failed to retrieve level 0 surface for source YUV plane %d", i); + if (FAILED(m_YUVPlanes[i].Get()->GetSurfaceLevel(0, &dest))) + CLog::Log(LOGERROR, __FUNCTION__": Failed to retrieve level 0 surface for destination YUV plane %d", i); + + if (FAILED(g_Windowing.Get3DDevice()->UpdateSurface(src, i == 0 ? &rect : &recthalf, dest, &point))) + { + CLog::Log(LOGERROR, __FUNCTION__": Failed to copy plane %d from sysmem to vidmem.", i); + src->Release(); + dest->Release(); + return false; + } + src->Release(); + dest->Release(); + } + return true; } //================================================================================== diff --git a/xbmc/cores/VideoRenderers/VideoShaders/WinVideoFilter.h b/xbmc/cores/VideoRenderers/VideoShaders/WinVideoFilter.h index cccf0fe787..bcf48c489d 100644 --- a/xbmc/cores/VideoRenderers/VideoShaders/WinVideoFilter.h +++ b/xbmc/cores/VideoRenderers/VideoShaders/WinVideoFilter.h @@ -75,9 +75,8 @@ private: class CYUV2RGBShader : public CWinShader { public: - virtual bool Create(bool singlepass); - virtual void Render(unsigned int sourceWidth, unsigned int sourceHeight, - CRect sourceRect, + virtual bool Create(bool singlepass, unsigned int sourceWidth, unsigned int sourceHeight); + virtual void Render(CRect sourceRect, CRect destRect, float contrast, float brightness, @@ -85,18 +84,20 @@ public: YUVBuffer* YUVbuf); protected: - virtual void PrepareParameters(unsigned int sourceWidth, unsigned int sourceHeight, - CRect sourceRect, + virtual void PrepareParameters(CRect sourceRect, CRect destRect, float contrast, float brightness, unsigned int flags); - virtual void SetShaderParameters(D3DXMATRIX* matrix, YUVBuffer* YUVbuf, unsigned int sourceWidth); + virtual void SetShaderParameters(); + virtual void ReleaseInternal(); + virtual bool UploadToGPU(YUVBuffer* YUVbuf); private: CYUV2RGBMatrix m_matrix; unsigned int m_sourceWidth, m_sourceHeight; CRect m_sourceRect, m_destRect; + CD3DTexture m_YUVPlanes[3]; struct CUSTOMVERTEX { FLOAT x, y, z; diff --git a/xbmc/cores/VideoRenderers/WinRenderer.cpp b/xbmc/cores/VideoRenderers/WinRenderer.cpp index a0935397f7..b3cf6537d6 100644 --- a/xbmc/cores/VideoRenderers/WinRenderer.cpp +++ b/xbmc/cores/VideoRenderers/WinRenderer.cpp @@ -562,7 +562,7 @@ void CWinRenderer::UpdatePSVideoFilter() if (m_bUseHQScaler) { m_colorShader = new CYUV2RGBShader(); - if (!m_colorShader->Create(false)) + if (!m_colorShader->Create(false, m_sourceWidth, m_sourceHeight)) { m_IntermediateTarget.Release(); m_IntermediateStencilSurface.Release(); @@ -575,7 +575,7 @@ void CWinRenderer::UpdatePSVideoFilter() if (!m_bUseHQScaler) //fallback from HQ scalers and multipass creation above { m_colorShader = new CYUV2RGBShader(); - if (!m_colorShader->Create(true)) + if (!m_colorShader->Create(true, m_sourceWidth, m_sourceHeight)) SAFE_RELEASE(m_colorShader); // we're in big trouble - should fallback on D3D accelerated or sw method } @@ -765,11 +765,11 @@ void CWinRenderer::Stage1(DWORD flags) { if (!m_bUseHQScaler) { - m_colorShader->Render(m_sourceWidth, m_sourceHeight, m_sourceRect, m_destRect, - g_settings.m_currentVideoSettings.m_Contrast, - g_settings.m_currentVideoSettings.m_Brightness, - m_flags, - (YUVBuffer*)m_VideoBuffers[m_iYV12RenderBuffer]); + m_colorShader->Render(m_sourceRect, m_destRect, + g_settings.m_currentVideoSettings.m_Contrast, + g_settings.m_currentVideoSettings.m_Brightness, + m_flags, + (YUVBuffer*)m_VideoBuffers[m_iYV12RenderBuffer]); } else { @@ -786,11 +786,11 @@ void CWinRenderer::Stage1(DWORD flags) CRect srcRect(0.0f, 0.0f, m_sourceWidth, m_sourceHeight); CRect rtRect(0.0f, 0.0f, m_sourceWidth, m_sourceHeight); - m_colorShader->Render(m_sourceWidth, m_sourceHeight, srcRect, rtRect, - g_settings.m_currentVideoSettings.m_Contrast, - g_settings.m_currentVideoSettings.m_Brightness, - m_flags, - (YUVBuffer*)m_VideoBuffers[m_iYV12RenderBuffer]); + m_colorShader->Render(srcRect, rtRect, + g_settings.m_currentVideoSettings.m_Contrast, + g_settings.m_currentVideoSettings.m_Brightness, + m_flags, + (YUVBuffer*)m_VideoBuffers[m_iYV12RenderBuffer]); // Restore the render target pD3DDevice->SetRenderTarget(0, oldRT); @@ -890,14 +890,7 @@ bool CWinRenderer::CreateYV12Texture(int index) { YUVBuffer *buf = new YUVBuffer(); - BufferMemoryType memoryType; - - if (m_renderMethod == RENDER_SW) - memoryType = SystemMemory; // Need the textures in system memory for quick read and write - else - memoryType = DontCare; - - if (!buf->Create(memoryType, m_sourceWidth, m_sourceHeight)) + if (!buf->Create(m_sourceWidth, m_sourceHeight)) { CLog::Log(LOGERROR, __FUNCTION__" - Unable to create YV12 video texture %i", index); return false; @@ -995,40 +988,14 @@ YUVBuffer::~YUVBuffer() Release(); } -bool YUVBuffer::Create(BufferMemoryType memoryType, unsigned int width, unsigned int height) +bool YUVBuffer::Create(unsigned int width, unsigned int height) { - m_memoryType = memoryType; m_width = width; m_height = height; - D3DPOOL pool; - DWORD usage; - - switch(m_memoryType) - { - case DontCare: - pool = g_Windowing.DefaultD3DPool(); - usage = g_Windowing.DefaultD3DUsage(); - break; - - case SystemMemory: - pool = D3DPOOL_SYSTEMMEM; - usage = 0; - break; - - case VideoMemory: - pool = D3DPOOL_DEFAULT; - usage = D3DUSAGE_DYNAMIC; - break; - - default: - CLog::Log(LOGERROR, __FUNCTION__" - unknown memory type %d", m_memoryType); - return false; - } - - if ( !planes[PLANE_Y].texture.Create(m_width , m_height , 1, usage, D3DFMT_L8, pool) - || !planes[PLANE_U].texture.Create(m_width / 2, m_height / 2, 1, usage, D3DFMT_L8, pool) - || !planes[PLANE_V].texture.Create(m_width / 2, m_height / 2, 1, usage, D3DFMT_L8, pool)) + if ( !planes[PLANE_Y].texture.Create(m_width , m_height , 1, 0, D3DFMT_L8, D3DPOOL_SYSTEMMEM) + || !planes[PLANE_U].texture.Create(m_width / 2, m_height / 2, 1, 0, D3DFMT_L8, D3DPOOL_SYSTEMMEM) + || !planes[PLANE_V].texture.Create(m_width / 2, m_height / 2, 1, 0, D3DFMT_L8, D3DPOOL_SYSTEMMEM)) return false; return true; diff --git a/xbmc/cores/VideoRenderers/WinRenderer.h b/xbmc/cores/VideoRenderers/WinRenderer.h index 0971d25a99..f515114389 100644 --- a/xbmc/cores/VideoRenderers/WinRenderer.h +++ b/xbmc/cores/VideoRenderers/WinRenderer.h @@ -120,13 +120,6 @@ enum RenderMethod #define FIELD_ODD 1 #define FIELD_EVEN 2 -enum BufferMemoryType -{ - DontCare, - SystemMemory, - VideoMemory -}; - struct SVideoBuffer { virtual ~SVideoBuffer() {} @@ -146,7 +139,7 @@ struct SVideoPlane struct YUVBuffer : SVideoBuffer { ~YUVBuffer(); - bool Create(BufferMemoryType memoryType, unsigned int width, unsigned int height); + bool Create(unsigned int width, unsigned int height); virtual void Release(); virtual void StartDecode(); virtual void StartRender(); @@ -155,7 +148,6 @@ struct YUVBuffer : SVideoBuffer SVideoPlane planes[MAX_PLANES]; private: - BufferMemoryType m_memoryType; unsigned int m_width; unsigned int m_height; }; |