diff --git a/xbmc/guilib/GraphicContext.cpp b/xbmc/guilib/GraphicContext.cpp index bd7dff932ef9e..ed7316a7cc40e 100644 --- a/xbmc/guilib/GraphicContext.cpp +++ b/xbmc/guilib/GraphicContext.cpp @@ -32,6 +32,7 @@ #include "input/InputManager.h" #include "GUIWindowManager.h" #include "video/VideoReferenceClock.h" +#include using namespace std; @@ -499,6 +500,43 @@ RESOLUTION CGraphicContext::GetVideoResolution() const return m_Resolution; } +RESOLUTION CGraphicContext::Get3DVideoResolution(RESOLUTION resolution, RENDER_STEREO_MODE mode) const +{ + RESOLUTION best = resolution; + RESOLUTION_INFO curr = CDisplaySettings::Get().GetResolutionInfo(best); + // Find closest refresh rate + for (size_t i = (int)RES_DESKTOP; i < CDisplaySettings::Get().ResolutionInfoSize(); i++) + { + const RESOLUTION_INFO info = CDisplaySettings::Get().GetResolutionInfo((RESOLUTION)i); + + //discard resolutions that are not the same width and height (and interlaced/3D flags) + //or have a too low refreshrate + if (info.iScreenWidth != curr.iScreenWidth + || info.iScreenHeight != curr.iScreenHeight + || info.iScreen != curr.iScreen + || (info.dwFlags & D3DPRESENTFLAG_INTERLACED) != (curr.dwFlags & D3DPRESENTFLAG_INTERLACED) + || fabs(info.fRefreshRate - curr.fRefreshRate) >= FLT_EPSILON) + continue; + + if (mode == RENDER_STEREO_MODE_SPLIT_VERTICAL && info.dwFlags & D3DPRESENTFLAG_MODE3DSBS) + { + best = (RESOLUTION)i; + break; + } + else if (mode == RENDER_STEREO_MODE_SPLIT_HORIZONTAL && info.dwFlags & D3DPRESENTFLAG_MODE3DTB) + { + best = (RESOLUTION)i; + break; + } + else if ((mode == RENDER_STEREO_MODE_OFF || mode == RENDER_STEREO_MODE_MONO) && !(info.dwFlags & (D3DPRESENTFLAG_MODE3DSBS|D3DPRESENTFLAG_MODE3DTB))) + { + best = (RESOLUTION)i; + break; + } + } + return best; +} + void CGraphicContext::ResetOverscan(RESOLUTION_INFO &res) { res.Overscan.left = 0; @@ -1042,7 +1080,7 @@ void CGraphicContext::Flip(const CDirtyRegionList& dirty) if(m_stereoMode != m_nextStereoMode) { m_stereoMode = m_nextStereoMode; - SetVideoResolution(GetVideoResolution(), true); + SetVideoResolution(Get3DVideoResolution(m_Resolution, m_stereoMode), true); g_windowManager.SendMessage(GUI_MSG_NOTIFY_ALL, 0, 0, GUI_MSG_RENDERER_RESET); } } diff --git a/xbmc/guilib/GraphicContext.h b/xbmc/guilib/GraphicContext.h index a8fd03ede5123..8501e58a38630 100644 --- a/xbmc/guilib/GraphicContext.h +++ b/xbmc/guilib/GraphicContext.h @@ -108,6 +108,7 @@ class CGraphicContext : public CCriticalSection, bool IsValidResolution(RESOLUTION res); void SetVideoResolution(RESOLUTION res, bool forceUpdate = false); RESOLUTION GetVideoResolution() const; + RESOLUTION Get3DVideoResolution(RESOLUTION resolution, RENDER_STEREO_MODE mode) const; void ResetOverscan(RESOLUTION res, OVERSCAN &overscan); void ResetOverscan(RESOLUTION_INFO &resinfo); void ResetScreenParameters(RESOLUTION res);