diff options
author | Anton Fedchin <afedchin@ruswizards.com> | 2016-01-08 22:19:20 +0300 |
---|---|---|
committer | Anton Fedchin <anightik@gmail.com> | 2016-02-08 11:19:33 +0300 |
commit | 9ac0c0e2c9ce53ddc094b33307c0bc29955ff4d2 (patch) | |
tree | d9871e8171625306ff857e43c6a6d6f314487cef | |
parent | 3f1fbbe081c643cc2e80b57cef7a593ab9d39c7c (diff) |
[win32] WinRenderer: Fixed rotated videos.
-rw-r--r-- | xbmc/cores/VideoRenderers/DXVAHD.cpp | 14 | ||||
-rw-r--r-- | xbmc/cores/VideoRenderers/VideoShaders/WinVideoFilter.cpp | 29 | ||||
-rw-r--r-- | xbmc/cores/VideoRenderers/VideoShaders/WinVideoFilter.h | 7 | ||||
-rw-r--r-- | xbmc/cores/VideoRenderers/WinRenderer.cpp | 141 | ||||
-rw-r--r-- | xbmc/guilib/D3DResource.cpp | 37 | ||||
-rw-r--r-- | xbmc/guilib/D3DResource.h | 6 | ||||
-rw-r--r-- | xbmc/guilib/Geometry.h | 7 | ||||
-rw-r--r-- | xbmc/rendering/dx/RenderSystemDX.h | 1 | ||||
-rw-r--r-- | xbmc/win32/WIN32Util.cpp | 79 | ||||
-rw-r--r-- | xbmc/win32/WIN32Util.h | 2 |
10 files changed, 213 insertions, 110 deletions
diff --git a/xbmc/cores/VideoRenderers/DXVAHD.cpp b/xbmc/cores/VideoRenderers/DXVAHD.cpp index 98850d8f3e..247d1a6308 100644 --- a/xbmc/cores/VideoRenderers/DXVAHD.cpp +++ b/xbmc/cores/VideoRenderers/DXVAHD.cpp @@ -588,20 +588,6 @@ bool CProcessorHD::Render(CRect src, CRect dst, ID3D11Resource* target, ID3D11Vi bool progressive = deinterlace_mode == VS_DEINTERLACEMODE_OFF; - ID3D11Texture2D* targetTex = nullptr; - hr = target->QueryInterface(__uuidof(ID3D11Texture2D), reinterpret_cast<void**>(&targetTex)); - if (FAILED(hr)) - { - CLog::Log(LOGERROR, __FUNCTION__" - failed getting target texture with error %x", hr); - return false; - } - - D3D11_TEXTURE2D_DESC desc; - targetTex->GetDesc(&desc); - targetTex->Release(); - - CRect rectTarget(0, 0, float(desc.Width), float(desc.Height)); - CWIN32Util::CropSource(src, dst, rectTarget); RECT sourceRECT = { src.x1, src.y1, src.x2, src.y2 }; RECT dstRECT = { dst.x1, dst.y1, dst.x2, dst.y2 }; diff --git a/xbmc/cores/VideoRenderers/VideoShaders/WinVideoFilter.cpp b/xbmc/cores/VideoRenderers/VideoShaders/WinVideoFilter.cpp index d40b617685..55ac58676c 100644 --- a/xbmc/cores/VideoRenderers/VideoShaders/WinVideoFilter.cpp +++ b/xbmc/cores/VideoRenderers/VideoShaders/WinVideoFilter.cpp @@ -311,13 +311,13 @@ bool CYUV2RGBShader::Create(unsigned int sourceWidth, unsigned int sourceHeight, return true; } -void CYUV2RGBShader::Render(CRect sourceRect, CRect destRect, +void CYUV2RGBShader::Render(CRect sourceRect, CPoint dest[], float contrast, float brightness, unsigned int flags, YUVBuffer* YUVbuf) { - PrepareParameters(sourceRect, destRect, + PrepareParameters(sourceRect, dest, contrast, brightness, flags); SetShaderParameters(YUVbuf); Execute(nullptr, 4); @@ -328,45 +328,48 @@ CYUV2RGBShader::~CYUV2RGBShader() } void CYUV2RGBShader::PrepareParameters(CRect sourceRect, - CRect destRect, + CPoint dest[], float contrast, float brightness, unsigned int flags) { - if (m_sourceRect != sourceRect || m_destRect != destRect) + if (m_sourceRect != sourceRect + || m_dest[0] != dest[0] || m_dest[1] != dest[1] + || m_dest[2] != dest[2] || m_dest[3] != dest[3]) { m_sourceRect = sourceRect; - m_destRect = destRect; + for (size_t i = 0; i < 4; ++i) + m_dest[i] = dest[i]; CUSTOMVERTEX* v; CWinShader::LockVertexBuffer((void**)&v); - v[0].x = destRect.x1; - v[0].y = destRect.y1; + v[0].x = m_dest[0].x; + v[0].y = m_dest[0].y; v[0].z = 0.0f; v[0].tu = sourceRect.x1 / m_sourceWidth; v[0].tv = sourceRect.y1 / m_sourceHeight; v[0].tu2 = v[0].tu3 = (sourceRect.x1 / 2.0f) / (m_sourceWidth>>1); v[0].tv2 = v[0].tv3 = (sourceRect.y1 / 2.0f) / (m_sourceHeight>>1); - v[1].x = destRect.x2; - v[1].y = destRect.y1; + v[1].x = m_dest[1].x; + v[1].y = m_dest[1].y; v[1].z = 0.0f; v[1].tu = sourceRect.x2 / m_sourceWidth; v[1].tv = sourceRect.y1 / m_sourceHeight; v[1].tu2 = v[1].tu3 = (sourceRect.x2 / 2.0f) / (m_sourceWidth>>1); v[1].tv2 = v[1].tv3 = (sourceRect.y1 / 2.0f) / (m_sourceHeight>>1); - v[2].x = destRect.x2; - v[2].y = destRect.y2; + v[2].x = m_dest[2].x; + v[2].y = m_dest[2].y; v[2].z = 0.0f; v[2].tu = sourceRect.x2 / m_sourceWidth; v[2].tv = sourceRect.y2 / m_sourceHeight; v[2].tu2 = v[2].tu3 = (sourceRect.x2 / 2.0f) / (m_sourceWidth>>1); v[2].tv2 = v[2].tv3 = (sourceRect.y2 / 2.0f) / (m_sourceHeight>>1); - v[3].x = destRect.x1; - v[3].y = destRect.y2; + v[3].x = m_dest[3].x; + v[3].y = m_dest[3].y; v[3].z = 0.0f; v[3].tu = sourceRect.x1 / m_sourceWidth; v[3].tv = sourceRect.y2 / m_sourceHeight; diff --git a/xbmc/cores/VideoRenderers/VideoShaders/WinVideoFilter.h b/xbmc/cores/VideoRenderers/VideoShaders/WinVideoFilter.h index 294018ba85..41aed5fe60 100644 --- a/xbmc/cores/VideoRenderers/VideoShaders/WinVideoFilter.h +++ b/xbmc/cores/VideoRenderers/VideoShaders/WinVideoFilter.h @@ -78,7 +78,7 @@ class CYUV2RGBShader : public CWinShader public: virtual bool Create(unsigned int sourceWidth, unsigned int sourceHeight, ERenderFormat fmt); virtual void Render(CRect sourceRect, - CRect destRect, + CPoint dest[], float contrast, float brightness, unsigned int flags, @@ -94,7 +94,7 @@ public: protected: virtual void PrepareParameters(CRect sourceRect, - CRect destRect, + CPoint dest[], float contrast, float brightness, unsigned int flags); @@ -103,7 +103,8 @@ protected: private: CYUV2RGBMatrix m_matrix; unsigned int m_sourceWidth, m_sourceHeight; - CRect m_sourceRect , m_destRect; + CRect m_sourceRect; + CPoint m_dest[4]; ERenderFormat m_format; float m_texSteps[2]; diff --git a/xbmc/cores/VideoRenderers/WinRenderer.cpp b/xbmc/cores/VideoRenderers/WinRenderer.cpp index 4821b9b83d..ff85274580 100644 --- a/xbmc/cores/VideoRenderers/WinRenderer.cpp +++ b/xbmc/cores/VideoRenderers/WinRenderer.cpp @@ -34,6 +34,7 @@ #include "utils/log.h" #include "utils/win32/gpu_memcpy_sse4.h" #include "VideoShaders/WinVideoFilter.h" +#include "win32/WIN32Util.h" #include "windowing/WindowingFactory.h" typedef struct { @@ -580,6 +581,8 @@ void CWinRenderer::SelectPSVideoFilter() m_bUseHQScaler = true; } } + if (m_renderOrientation) + m_bUseHQScaler = false; } void CWinRenderer::UpdatePSVideoFilter() @@ -783,7 +786,7 @@ void CWinRenderer::ScaleGUIShader() CRect destRect = CRect(m_rotatedDestCoords[0], m_rotatedDestCoords[2]); // pass contrast and brightness as diffuse color elements (see shader code) - CD3DTexture::DrawQuad(destRect, D3DCOLOR_ARGB(255, contrast, brightness, 255), &m_SWTarget, &tu, + CD3DTexture::DrawQuad(m_rotatedDestCoords, D3DCOLOR_ARGB(255, contrast, brightness, 255), &m_SWTarget, &tu, !cbcontrol ? SHADER_METHOD_RENDER_VIDEO : SHADER_METHOD_RENDER_VIDEO_CONTROL); } @@ -808,64 +811,46 @@ void CWinRenderer::Stage1() CD3D11_VIEWPORT viewPort(0.0f, 0.0f, 0.0f, 0.0f); ID3D11DeviceContext* pContext = g_Windowing.Get3D11Context(); - // store current render target and depth view. ID3D11RenderTargetView *oldRTView = nullptr; ID3D11DepthStencilView* oldDSView = nullptr; - pContext->OMGetRenderTargets(1, &oldRTView, &oldDSView); - // select destination rectangle - CRect destRect; if (m_bUseHQScaler) { - if (m_renderOrientation > 0) - { - // we need to rotate source coordinates for HQ scaller - // so we using ReorderDrawPoints with source coords. - - // save coords - CRect oldDest = m_destRect; - saveRotatedCoords(); - - m_destRect = m_sourceRect; - ReorderDrawPoints(); - // get rotated coords - destRect = CRect(m_rotatedDestCoords[0], m_rotatedDestCoords[2]); - - // restore coords - restoreRotatedCoords(); - m_destRect = oldDest; - } - else - destRect = m_sourceRect; + // store current render target and depth view. + pContext->OMGetRenderTargets(1, &oldRTView, &oldDSView); + // change destination for HQ scallers + ID3D11RenderTargetView* pRTView = m_IntermediateTarget.GetRenderTarget(); + pContext->OMSetRenderTargets(1, &pRTView, nullptr); + // viewport equals intermediate target size + viewPort = CD3D11_VIEWPORT(0.0f, 0.0f, + static_cast<float>(m_IntermediateTarget.GetWidth()), + static_cast<float>(m_IntermediateTarget.GetHeight())); + g_Windowing.ResetScissors(); } else - destRect = g_graphicsContext.StereoCorrection(CRect(m_rotatedDestCoords[0], m_rotatedDestCoords[2])); - // select target view - ID3D11RenderTargetView* pRTView = m_bUseHQScaler ? m_IntermediateTarget.GetRenderTarget() : oldRTView; - // change destination for HQ scallers - if (m_bUseHQScaler) - pContext->OMSetRenderTargets(1, &pRTView, nullptr); - // get rendertarget's dimension - if (pRTView) { - ID3D11Resource* pResource = nullptr; - ID3D11Texture2D* pTexture = nullptr; - - pRTView->GetResource(&pResource); - if (SUCCEEDED(pResource->QueryInterface(__uuidof(ID3D11Texture2D), reinterpret_cast<void**>(&pTexture)))) - { - D3D11_TEXTURE2D_DESC desc; - pTexture->GetDesc(&desc); - viewPort = CD3D11_VIEWPORT(0.0f, 0.0f, static_cast<float>(desc.Width), static_cast<float>(desc.Height)); - } - SAFE_RELEASE(pResource); - SAFE_RELEASE(pTexture); + // viewport equals full backbuffer size + CRect bbSize = g_Windowing.GetBackBufferRect(); + viewPort = CD3D11_VIEWPORT(0.f, 0.f, bbSize.Width(), bbSize.Height()); } - // reset scissors for HQ scaler - if (m_bUseHQScaler) - g_Windowing.ResetScissors(); // reset view port pContext->RSSetViewports(1, &viewPort); + // select destination rectangle + CPoint destPoints[4]; + if (m_renderOrientation) + { + for (size_t i = 0; i < 4; i++) + destPoints[i] = m_rotatedDestCoords[i]; + } + else + { + CRect destRect = m_bUseHQScaler ? m_sourceRect : g_graphicsContext.StereoCorrection(m_destRect); + destPoints[0] = { destRect.x1, destRect.y1 }; + destPoints[1] = { destRect.x2, destRect.y1 }; + destPoints[2] = { destRect.x2, destRect.y2 }; + destPoints[3] = { destRect.x1, destRect.y2 }; + } + // render video frame - m_colorShader->Render(m_sourceRect, destRect, + m_colorShader->Render(m_sourceRect, destPoints, CMediaSettings::GetInstance().GetCurrentVideoSettings().m_Contrast, CMediaSettings::GetInstance().GetCurrentVideoSettings().m_Brightness, m_iFlags, (YUVBuffer*)m_VideoBuffers[m_iYV12RenderBuffer]); @@ -873,9 +858,11 @@ void CWinRenderer::Stage1() g_Windowing.RestoreViewPort(); // Restore the render target and depth view. if (m_bUseHQScaler) + { pContext->OMSetRenderTargets(1, &oldRTView, oldDSView); - SAFE_RELEASE(oldRTView); - SAFE_RELEASE(oldDSView); + SAFE_RELEASE(oldRTView); + SAFE_RELEASE(oldDSView); + } } void CWinRenderer::Stage2() @@ -888,7 +875,6 @@ void CWinRenderer::Stage2() void CWinRenderer::RenderProcessor(DWORD flags) { CSingleLock lock(g_graphicsContext); - CRect destRect = m_bUseHQScaler ? m_sourceRect : g_graphicsContext.StereoCorrection(m_destRect); DXVABuffer *image = (DXVABuffer*)m_VideoBuffers[m_iYV12RenderBuffer]; if (!image->pic) return; @@ -935,7 +921,30 @@ void CWinRenderer::RenderProcessor(DWORD flags) break; } - m_processor->Render(m_sourceRect, destRect, m_IntermediateTarget.Get(), views, flags, image->frameIdx, m_renderOrientation); + CRect destRect; + switch (m_renderOrientation) + { + case 90: + destRect = CRect(m_rotatedDestCoords[3], m_rotatedDestCoords[1]); + break; + case 180: + destRect = m_destRect; + break; + case 270: + destRect = CRect(m_rotatedDestCoords[1], m_rotatedDestCoords[3]); + break; + default: + destRect = m_bUseHQScaler ? m_sourceRect : g_graphicsContext.StereoCorrection(m_destRect); + break; + } + + CRect src = m_sourceRect, dst = destRect; + CRect target = CRect(0.0f, 0.0f, + static_cast<float>(m_IntermediateTarget.GetWidth()), + static_cast<float>(m_IntermediateTarget.GetHeight())); + CWIN32Util::CropSource(src, dst, target, m_renderOrientation); + + m_processor->Render(src, dst, m_IntermediateTarget.Get(), views, flags, image->frameIdx, m_renderOrientation); if (m_bUseHQScaler) { @@ -943,9 +952,25 @@ void CWinRenderer::RenderProcessor(DWORD flags) } else { - // texels - CRect tu = { destRect.x1 / m_destWidth, destRect.y1 / m_destHeight, destRect.x2 / m_destWidth, destRect.y2 / m_destHeight }; - CD3DTexture::DrawQuad(m_destRect, 0xFFFFFFFF, &m_IntermediateTarget, &tu, SHADER_METHOD_RENDER_TEXTURE_BLEND); + CRect oldViewPort; + bool stereoHack = g_graphicsContext.GetStereoMode() == RENDER_STEREO_MODE_SPLIT_HORIZONTAL + || g_graphicsContext.GetStereoMode() == RENDER_STEREO_MODE_SPLIT_VERTICAL; + + if (stereoHack) + { + CRect bbSize = g_Windowing.GetBackBufferRect(); + + g_Windowing.GetViewPort(oldViewPort); + g_Windowing.SetViewPort(bbSize); + g_Windowing.SetCameraPosition(CPoint(bbSize.Width() / 2.f, bbSize.Height() / 2.f), bbSize.Width(), bbSize.Height(), 0.f); + } + + // render frame + CRect tu = { dst.x1 / m_destWidth, dst.y1 / m_destHeight, dst.x2 / m_destWidth, dst.y2 / m_destHeight }; + CD3DTexture::DrawQuad(dst, 0xFFFFFF, &m_IntermediateTarget, &tu, SHADER_METHOD_RENDER_TEXTURE_BLEND); + + if (stereoHack) + g_Windowing.SetViewPort(oldViewPort); } } @@ -1089,7 +1114,7 @@ bool CWinRenderer::Supports(ESCALINGMETHOD method) if (method == VS_SCALINGMETHOD_DXVA_HARDWARE || method == VS_SCALINGMETHOD_AUTO) return true; - else if (!g_advancedSettings.m_DXVAAllowHqScaling) + else if (!g_advancedSettings.m_DXVAAllowHqScaling || m_renderOrientation) return false; } @@ -1097,7 +1122,7 @@ bool CWinRenderer::Supports(ESCALINGMETHOD method) || (method == VS_SCALINGMETHOD_LINEAR && m_renderMethod == RENDER_PS)) return true; - if (g_Windowing.GetFeatureLevel() >= D3D_FEATURE_LEVEL_9_3) + if (g_Windowing.GetFeatureLevel() >= D3D_FEATURE_LEVEL_9_3 && !m_renderOrientation) { if(method == VS_SCALINGMETHOD_CUBIC || method == VS_SCALINGMETHOD_LANCZOS2 diff --git a/xbmc/guilib/D3DResource.cpp b/xbmc/guilib/D3DResource.cpp index e1abe1cb93..8aa8125918 100644 --- a/xbmc/guilib/D3DResource.cpp +++ b/xbmc/guilib/D3DResource.cpp @@ -415,7 +415,7 @@ unsigned int CD3DTexture::GetMemoryUsage(unsigned int pitch) const } // static methods -void CD3DTexture::DrawQuad(const CRect &rect, color_t color, CD3DTexture *texture, const CRect *texCoords, SHADER_METHOD options) +void CD3DTexture::DrawQuad(const CPoint points[4], color_t color, CD3DTexture *texture, const CRect *texCoords, SHADER_METHOD options) { unsigned numViews = 0; ID3D11ShaderResourceView* views = nullptr; @@ -426,20 +426,32 @@ void CD3DTexture::DrawQuad(const CRect &rect, color_t color, CD3DTexture *textur views = texture->GetShaderResource(); } - DrawQuad(rect, color, numViews, &views, texCoords, options); + DrawQuad(points, color, numViews, &views, texCoords, options); } -void CD3DTexture::DrawQuad(const CRect &rect, color_t color, unsigned numViews, ID3D11ShaderResourceView **view, const CRect *texCoords, SHADER_METHOD options) +void CD3DTexture::DrawQuad(const CRect &rect, color_t color, CD3DTexture *texture, const CRect *texCoords, SHADER_METHOD options) +{ + CPoint points[] = + { + { rect.x1, rect.y1 }, + { rect.x2, rect.y1 }, + { rect.x2, rect.y2 }, + { rect.x1, rect.y2 }, + }; + DrawQuad(points, color, texture, texCoords, options); +} + +void CD3DTexture::DrawQuad(const CPoint points[4], color_t color, unsigned numViews, ID3D11ShaderResourceView **view, const CRect *texCoords, SHADER_METHOD options) { XMFLOAT4 xcolor; CD3DHelper::XMStoreColor(&xcolor, color); CRect coords = texCoords ? *texCoords : CRect(0.0f, 0.0f, 1.0f, 1.0f); Vertex verts[4] = { - { XMFLOAT3(rect.x1, rect.y1, 0), xcolor, XMFLOAT2(coords.x1, coords.y1), XMFLOAT2(0.0f, 0.0f) }, - { XMFLOAT3(rect.x2, rect.y1, 0), xcolor, XMFLOAT2(coords.x2, coords.y1), XMFLOAT2(0.0f, 0.0f) }, - { XMFLOAT3(rect.x2, rect.y2, 0), xcolor, XMFLOAT2(coords.x2, coords.y2), XMFLOAT2(0.0f, 0.0f) }, - { XMFLOAT3(rect.x1, rect.y2, 0), xcolor, XMFLOAT2(coords.x1, coords.y2), XMFLOAT2(0.0f, 0.0f) }, + { XMFLOAT3(points[0].x, points[0].y, 0), xcolor, XMFLOAT2(coords.x1, coords.y1), XMFLOAT2(0.0f, 0.0f) }, + { XMFLOAT3(points[1].x, points[1].y, 0), xcolor, XMFLOAT2(coords.x2, coords.y1), XMFLOAT2(0.0f, 0.0f) }, + { XMFLOAT3(points[2].x, points[2].y, 0), xcolor, XMFLOAT2(coords.x2, coords.y2), XMFLOAT2(0.0f, 0.0f) }, + { XMFLOAT3(points[3].x, points[3].y, 0), xcolor, XMFLOAT2(coords.x1, coords.y2), XMFLOAT2(0.0f, 0.0f) }, }; CGUIShaderDX* pGUIShader = g_Windowing.GetGUIShader(); @@ -450,6 +462,17 @@ void CD3DTexture::DrawQuad(const CRect &rect, color_t color, unsigned numViews, pGUIShader->DrawQuad(verts[0], verts[1], verts[2], verts[3]); } +void CD3DTexture::DrawQuad(const CRect &rect, color_t color, unsigned numViews, ID3D11ShaderResourceView **view, const CRect *texCoords, SHADER_METHOD options) +{ + CPoint points[] = + { + { rect.x1, rect.y1 }, + { rect.x2, rect.y1 }, + { rect.x2, rect.y2 }, + { rect.x1, rect.y2 }, + }; + DrawQuad(points, color, numViews, view, texCoords, options); +} CD3DEffect::CD3DEffect() { diff --git a/xbmc/guilib/D3DResource.h b/xbmc/guilib/D3DResource.h index de6ee57a24..ed6cf96d51 100644 --- a/xbmc/guilib/D3DResource.h +++ b/xbmc/guilib/D3DResource.h @@ -124,6 +124,12 @@ public: DXGI_FORMAT GetFormat() const { return m_format; } // static methods + static void DrawQuad(const CPoint points[4], color_t color, CD3DTexture *texture, const CRect *texCoords, + SHADER_METHOD options = SHADER_METHOD_RENDER_TEXTURE_BLEND); + + static void DrawQuad(const CPoint points[4], color_t color, unsigned numViews, ID3D11ShaderResourceView **view, const CRect *texCoords, + SHADER_METHOD options = SHADER_METHOD_RENDER_TEXTURE_BLEND); + static void DrawQuad(const CRect &coords, color_t color, CD3DTexture *texture, const CRect *texCoords, SHADER_METHOD options = SHADER_METHOD_RENDER_TEXTURE_BLEND); diff --git a/xbmc/guilib/Geometry.h b/xbmc/guilib/Geometry.h index 0b92ffdb2c..6dc06f465e 100644 --- a/xbmc/guilib/Geometry.h +++ b/xbmc/guilib/Geometry.h @@ -82,6 +82,13 @@ public: return *this; }; + bool operator !=(const this_type &point) const + { + if (x != point.x) return true; + if (y != point.y) return true; + return false; + }; + T x, y; }; diff --git a/xbmc/rendering/dx/RenderSystemDX.h b/xbmc/rendering/dx/RenderSystemDX.h index 44f4dddb6f..cf58be2302 100644 --- a/xbmc/rendering/dx/RenderSystemDX.h +++ b/xbmc/rendering/dx/RenderSystemDX.h @@ -83,6 +83,7 @@ public: IDXGIOutput* GetCurrentOutput(void) { return m_pOutput; } virtual void Project(float &x, float &y, float &z); + virtual CRect GetBackBufferRect() { return CRect(0.f, 0.f, static_cast<float>(m_nBackBufferWidth), static_cast<float>(m_nBackBufferHeight)); } void FinishCommandList(bool bExecute = true); void FlushGPU(); diff --git a/xbmc/win32/WIN32Util.cpp b/xbmc/win32/WIN32Util.cpp index d166bc2e9a..a0af2fc627 100644 --- a/xbmc/win32/WIN32Util.cpp +++ b/xbmc/win32/WIN32Util.cpp @@ -1469,34 +1469,85 @@ bool CWIN32Util::GetFocussedProcess(std::string &strProcessFile) } // Adjust the src rectangle so that the dst is always contained in the target rectangle. -void CWIN32Util::CropSource(CRect& src, CRect& dst, CRect target) +void CWIN32Util::CropSource(CRect& src, CRect& dst, CRect target, UINT rotation /* = 0 */) { - if(dst.x1 < target.x1) + float s_width = src.Width(), s_height = src.Height(); + float d_width = dst.Width(), d_height = dst.Height(); + + if (dst.x1 < target.x1) { - src.x1 -= (dst.x1 - target.x1) - * (src.x2 - src.x1) - / (dst.x2 - dst.x1); + switch (rotation) + { + case 90: + src.y1 -= (dst.x1 - target.x1) * s_height / d_width; + break; + case 180: + src.x2 += (dst.x1 - target.x1) * s_width / d_width; + break; + case 270: + src.y2 += (dst.x1 - target.x1) * s_height / d_width; + break; + default: + src.x1 -= (dst.x1 - target.x1) * s_width / d_width; + break; + } dst.x1 = target.x1; } if(dst.y1 < target.y1) { - src.y1 -= (dst.y1 - target.y1) - * (src.y2 - src.y1) - / (dst.y2 - dst.y1); + switch (rotation) + { + case 90: + src.x1 -= (dst.y1 - target.y1) * s_width / d_height; + break; + case 180: + src.y2 += (dst.y1 - target.y1) * s_height / d_height; + break; + case 270: + src.x2 += (dst.y1 - target.y1) * s_width / d_height; + break; + default: + src.y1 -= (dst.y1 - target.y1) * s_height / d_height; + break; + } dst.y1 = target.y1; } if(dst.x2 > target.x2) { - src.x2 -= (dst.x2 - target.x2) - * (src.x2 - src.x1) - / (dst.x2 - dst.x1); + switch (rotation) + { + case 90: + src.y2 -= (dst.x2 - target.x2) * s_height / d_width; + break; + case 180: + src.x1 += (dst.x2 - target.x2) * s_width / d_width; + break; + case 270: + src.y1 += (dst.x2 - target.x2) * s_height / d_width; + break; + default: + src.x2 -= (dst.x2 - target.x2) * s_width / d_width; + break; + } dst.x2 = target.x2; } if(dst.y2 > target.y2) { - src.y2 -= (dst.y2 - target.y2) - * (src.y2 - src.y1) - / (dst.y2 - dst.y1); + switch (rotation) + { + case 90: + src.x2 -= (dst.y2 - target.y2) * s_width / d_height; + break; + case 180: + src.y1 += (dst.y2 - target.y2) * s_height / d_height; + break; + case 270: + src.x1 += (dst.y2 - target.y2) * s_width / d_height; + break; + default: + src.y2 -= (dst.y2 - target.y2) * s_height / d_height; + break; + } dst.y2 = target.y2; } // Callers expect integer coordinates. diff --git a/xbmc/win32/WIN32Util.h b/xbmc/win32/WIN32Util.h index 55b1ee8efb..7079e81330 100644 --- a/xbmc/win32/WIN32Util.h +++ b/xbmc/win32/WIN32Util.h @@ -89,7 +89,7 @@ public: static bool UtilRegOpenKeyEx( const HKEY hKeyParent, const char *const pcKey, const REGSAM rsAccessRights, HKEY *hKey, const bool bReadX64= false ); static bool GetFocussedProcess(std::string &strProcessFile); - static void CropSource(CRect& src, CRect& dst, CRect target); + static void CropSource(CRect& src, CRect& dst, CRect target, UINT rotation = 0); static bool IsUsbDevice(const std::wstring &strWdrive); |