aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnton Fedchin <afedchin@ruswizards.com>2016-01-08 22:19:20 +0300
committerAnton Fedchin <anightik@gmail.com>2016-02-08 11:19:33 +0300
commit9ac0c0e2c9ce53ddc094b33307c0bc29955ff4d2 (patch)
treed9871e8171625306ff857e43c6a6d6f314487cef
parent3f1fbbe081c643cc2e80b57cef7a593ab9d39c7c (diff)
[win32] WinRenderer: Fixed rotated videos.
-rw-r--r--xbmc/cores/VideoRenderers/DXVAHD.cpp14
-rw-r--r--xbmc/cores/VideoRenderers/VideoShaders/WinVideoFilter.cpp29
-rw-r--r--xbmc/cores/VideoRenderers/VideoShaders/WinVideoFilter.h7
-rw-r--r--xbmc/cores/VideoRenderers/WinRenderer.cpp141
-rw-r--r--xbmc/guilib/D3DResource.cpp37
-rw-r--r--xbmc/guilib/D3DResource.h6
-rw-r--r--xbmc/guilib/Geometry.h7
-rw-r--r--xbmc/rendering/dx/RenderSystemDX.h1
-rw-r--r--xbmc/win32/WIN32Util.cpp79
-rw-r--r--xbmc/win32/WIN32Util.h2
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);