[windowing] WinSystem: Rework to DirectX11.
authorAnton Fedchin <afedchin@ruswizards.com>
Wed, 22 Apr 2015 15:23:54 +0000 (18:23 +0300)
committerAnton Fedchin <afedchin@ruswizards.com>
Sat, 4 Jul 2015 07:25:19 +0000 (10:25 +0300)
xbmc/windowing/windows/WinEventsWin32.cpp
xbmc/windowing/windows/WinSystemWin32.cpp
xbmc/windowing/windows/WinSystemWin32.h
xbmc/windowing/windows/WinSystemWin32DX.cpp
xbmc/windowing/windows/WinSystemWin32DX.h

index c4bd5fc..e91a88e 100644 (file)
@@ -675,7 +675,7 @@ LRESULT CALLBACK CWinEventsWin32::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, L
 
       CLog::Log(LOGDEBUG, __FUNCTION__": window resize event");
 
-      if (!g_Windowing.IsAlteringWindow() && newEvent.resize.w > 0 && newEvent.resize.h > 0)
+      if (g_application.GetRenderGUI() && !g_Windowing.IsAlteringWindow() && newEvent.resize.w > 0 && newEvent.resize.h > 0)
         m_pEventFunc(newEvent);
 
       return(0);
@@ -686,7 +686,7 @@ LRESULT CALLBACK CWinEventsWin32::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, L
 
       CLog::Log(LOGDEBUG, __FUNCTION__": window move event");
 
-      if (!g_Windowing.IsAlteringWindow())
+      if (g_application.GetRenderGUI() && !g_Windowing.IsAlteringWindow())
         m_pEventFunc(newEvent);
 
       return(0);
index e15311c..4d36abb 100644 (file)
@@ -268,12 +268,19 @@ bool CWinSystemWin32::ResizeWindow(int newWidth, int newHeight, int newLeft, int
 
 void CWinSystemWin32::NotifyAppFocusChange(bool bGaining)
 {
-  if (m_bFullScreen && bGaining) //bump ourselves to top
+  if (m_bFullScreen && bGaining)
+  {
     SetWindowPos(m_hWnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOREDRAW);
+  }
 }
 
 bool CWinSystemWin32::SetFullScreen(bool fullScreen, RESOLUTION_INFO& res, bool blankOtherDisplays)
 {
+  return SetFullScreenEx(fullScreen, res, blankOtherDisplays, false);
+}
+
+bool CWinSystemWin32::SetFullScreenEx(bool fullScreen, RESOLUTION_INFO& res, bool blankOtherDisplays, bool forceResChange)
+{
   m_IsAlteringWindow = true;
 
   CLog::Log(LOGDEBUG, "%s (%s) on screen %d with size %dx%d, refresh %f%s", __FUNCTION__, !fullScreen ? "windowed" : (CSettings::Get().GetBool("videoscreen.fakefullscreen") ? "windowed fullscreen" : "true fullscreen"), res.iScreen, res.iWidth, res.iHeight, res.fRefreshRate, (res.dwFlags & D3DPRESENTFLAG_INTERLACED) ? "i" : "");
@@ -308,7 +315,7 @@ bool CWinSystemWin32::SetFullScreen(bool fullScreen, RESOLUTION_INFO& res, bool
   m_bBlankOtherDisplay = blankOtherDisplays;
 
   if (fullScreen && CSettings::Get().GetBool("videoscreen.fakefullscreen"))
-    ChangeResolution(res);
+    ChangeResolution(res, forceResChange);
 
   ResizeInternal(forceResize);
 
@@ -440,7 +447,7 @@ bool CWinSystemWin32::ResizeInternal(bool forceRefresh)
   return true;
 }
 
-bool CWinSystemWin32::ChangeResolution(RESOLUTION_INFO res)
+bool CWinSystemWin32::ChangeResolution(RESOLUTION_INFO res, bool forceChange /*= false*/)
 {
   const MONITOR_DETAILS &details = GetMonitor(res.iScreen);
 
@@ -453,7 +460,8 @@ bool CWinSystemWin32::ChangeResolution(RESOLUTION_INFO res)
       sDevMode.dmPelsWidth != res.iWidth || sDevMode.dmPelsHeight != res.iHeight ||
       sDevMode.dmDisplayFrequency != (int)res.fRefreshRate ||
       ((sDevMode.dmDisplayFlags & DM_INTERLACED) && !(res.dwFlags & D3DPRESENTFLAG_INTERLACED)) ||
-      (!(sDevMode.dmDisplayFlags & DM_INTERLACED) && (res.dwFlags & D3DPRESENTFLAG_INTERLACED)) )
+      (!(sDevMode.dmDisplayFlags & DM_INTERLACED) && (res.dwFlags & D3DPRESENTFLAG_INTERLACED)) 
+      || forceChange)
   {
     ZeroMemory(&sDevMode, sizeof(sDevMode));
     sDevMode.dmSize = sizeof(sDevMode);
index 7e95b57..023d47b 100644 (file)
@@ -135,6 +135,7 @@ public:
   virtual bool CreateNewWindow(const std::string& name, bool fullScreen, RESOLUTION_INFO& res, PHANDLE_EVENT_FUNC userFunction);
   virtual bool ResizeWindow(int newWidth, int newHeight, int newLeft, int newTop);
   virtual bool SetFullScreen(bool fullScreen, RESOLUTION_INFO& res, bool blankOtherDisplays);
+  virtual bool SetFullScreenEx(bool fullScreen, RESOLUTION_INFO& res, bool blankOtherDisplays, bool forceResChange);
   virtual void UpdateResolutions();
   virtual bool CenterWindow();
   virtual void NotifyAppFocusChange(bool bGaining);
@@ -162,7 +163,7 @@ public:
   pCloseGestureInfoHandle PtrCloseGestureInfoHandle;
 
 protected:
-  bool ChangeResolution(RESOLUTION_INFO res);
+  bool ChangeResolution(RESOLUTION_INFO res, bool forceChange = false);
   virtual bool ResizeInternal(bool forceRefresh = false);
   virtual bool UpdateResolutionsInternal();
   virtual bool CreateBlankWindows();
index f73cd55..67931dc 100644 (file)
@@ -65,7 +65,7 @@ void CWinSystemWin32DX::UpdateMonitor()
 bool CWinSystemWin32DX::ResizeWindow(int newWidth, int newHeight, int newLeft, int newTop)
 {
   CWinSystemWin32::ResizeWindow(newWidth, newHeight, newLeft, newTop);
-  CRenderSystemDX::ResetRenderSystem(newWidth, newHeight, false, 0);
+  CRenderSystemDX::OnResize(newWidth, newHeight);
 
   return true;
 }
@@ -77,22 +77,35 @@ void CWinSystemWin32DX::OnMove(int x, int y)
 
 bool CWinSystemWin32DX::SetFullScreen(bool fullScreen, RESOLUTION_INFO& res, bool blankOtherDisplays)
 {
-  // When going DX fullscreen -> windowed, we must reset the D3D device first to
+  // When going DX fullscreen -> windowed, we must switch DXGI device to windowed mode first to
   // get it out of fullscreen mode because it restores a former resolution.
   // We then change to the mode we want.
-  // In other cases, set the window/mode then reset the D3D device.
-
+  // In other cases, set the window/mode then swith DXGI mode.
   bool FS2Windowed = !m_useWindowedDX && UseWindowedDX(fullScreen);
 
   SetMonitor(GetMonitor(res.iScreen).hMonitor);
   CRenderSystemDX::m_interlaced = ((res.dwFlags & D3DPRESENTFLAG_INTERLACED) != 0);
   CRenderSystemDX::m_useWindowedDX = UseWindowedDX(fullScreen);
 
+  // this needed to prevent resize/move events from DXGI during changing mode
+  CWinSystemWin32::m_IsAlteringWindow = true;
   if (FS2Windowed)
-    CRenderSystemDX::ResetRenderSystem(res.iWidth, res.iHeight, fullScreen, res.fRefreshRate);
+    CRenderSystemDX::SetFullScreenInternal();
+
+  // to disable stereo mode in windowed mode we must recreate swapchain and then change display mode
+  // so this flags delays call SetFullScreen _after_ resetting render system
+  bool delaySetFS = CRenderSystemDX::m_bHWStereoEnabled && UseWindowedDX(fullScreen);
+  if (!delaySetFS)
+    CWinSystemWin32::SetFullScreen(fullScreen, res, blankOtherDisplays);
 
-  CWinSystemWin32::SetFullScreen(fullScreen, res, blankOtherDisplays);
+  // this needed to prevent resize/move events from DXGI during changing mode
+  CWinSystemWin32::m_IsAlteringWindow = true;
   CRenderSystemDX::ResetRenderSystem(res.iWidth, res.iHeight, fullScreen, res.fRefreshRate);
+  CWinSystemWin32::m_IsAlteringWindow = false;
+
+  if (delaySetFS)
+    // now resize window and force changing resolution if stereo mode disabled
+    CWinSystemWin32::SetFullScreenEx(fullScreen, res, blankOtherDisplays, !CRenderSystemDX::m_bHWStereoEnabled);
 
   return true;
 }
@@ -122,4 +135,21 @@ std::string CWinSystemWin32DX::GetClipboardText(void)
   return utf8_text;
 }
 
+void CWinSystemWin32DX::NotifyAppFocusChange(bool bGaining)
+{
+  CWinSystemWin32::NotifyAppFocusChange(bGaining);
+
+  // if true fullscreen we need switch render system to/from ff manually like dx9 does
+  if (!UseWindowedDX(m_bFullScreen) && CRenderSystemDX::m_bRenderCreated)
+  {
+    CRenderSystemDX::m_useWindowedDX = !bGaining;
+    CRenderSystemDX::SetFullScreenInternal();
+    CRenderSystemDX::CreateWindowSizeDependentResources();
+
+    // minimize window on lost focus
+    if (!bGaining)
+      ShowWindow(m_hWnd, SW_SHOWMINIMIZED);
+  }
+}
+
 #endif
index 863dba8..06024eb 100644 (file)
@@ -41,6 +41,7 @@ public:
   virtual void OnMove(int x, int y);
   virtual bool SetFullScreen(bool fullScreen, RESOLUTION_INFO& res, bool blankOtherDisplays);
   virtual bool WindowedMode() { return CRenderSystemDX::m_useWindowedDX; }
+  virtual void NotifyAppFocusChange(bool bGaining);
 
   std::string GetClipboardText(void);