Merge pull request #1764 from Armada651/safe-exclusive

D3D: Only try to apply exclusive mode when the renderer is in focus.
This commit is contained in:
Markus Wick 2015-01-06 11:00:47 +01:00
commit 25fac0282c
11 changed files with 65 additions and 33 deletions

View File

@ -25,6 +25,7 @@
bool Host_UIHasFocus(); bool Host_UIHasFocus();
bool Host_RendererHasFocus(); bool Host_RendererHasFocus();
bool Host_RendererIsFullscreen();
void Host_ConnectWiimote(int wm_idx, bool connect); void Host_ConnectWiimote(int wm_idx, bool connect);
void Host_Message(int Id); void Host_Message(int Id);
void Host_NotifyMapLoaded(); void Host_NotifyMapLoaded();

View File

@ -48,6 +48,11 @@ bool Host_UIHasFocus()
return g_main_window->isActiveWindow(); return g_main_window->isActiveWindow();
} }
bool Host_RendererIsFullscreen()
{
return false; // TODO
}
void Host_RequestFullscreen(bool enable) void Host_RequestFullscreen(bool enable)
{ {
// TODO // TODO

View File

@ -119,6 +119,7 @@ public:
void OnRenderParentMove(wxMoveEvent& event); void OnRenderParentMove(wxMoveEvent& event);
bool RendererHasFocus(); bool RendererHasFocus();
bool UIHasFocus(); bool UIHasFocus();
bool RendererIsFullscreen();
void DoFullscreen(bool bF); void DoFullscreen(bool bF);
void ToggleDisplayMode (bool bFullscreen); void ToggleDisplayMode (bool bFullscreen);
void UpdateWiiMenuChoice(wxMenuItem *WiiMenuItem=nullptr); void UpdateWiiMenuChoice(wxMenuItem *WiiMenuItem=nullptr);
@ -329,7 +330,6 @@ private:
void OnGameListCtrl_ItemActivated(wxListEvent& event); void OnGameListCtrl_ItemActivated(wxListEvent& event);
void OnRenderParentResize(wxSizeEvent& event); void OnRenderParentResize(wxSizeEvent& event);
bool RendererIsFullscreen();
void StartGame(const std::string& filename); void StartGame(const std::string& filename);
void OnChangeColumnsVisible(wxCommandEvent& event); void OnChangeColumnsVisible(wxCommandEvent& event);

View File

@ -572,6 +572,11 @@ bool Host_RendererHasFocus()
return main_frame->RendererHasFocus(); return main_frame->RendererHasFocus();
} }
bool Host_RendererIsFullscreen()
{
return main_frame->RendererIsFullscreen();
}
void Host_ConnectWiimote(int wm_idx, bool connect) void Host_ConnectWiimote(int wm_idx, bool connect)
{ {
CFrame::ConnectWiimote(wm_idx, connect); CFrame::ConnectWiimote(wm_idx, connect);

View File

@ -94,6 +94,11 @@ bool Host_RendererHasFocus()
return true; return true;
} }
bool Host_RendererIsFullscreen()
{
return false;
}
void Host_ConnectWiimote(int wm_idx, bool connect) {} void Host_ConnectWiimote(int wm_idx, bool connect) {}
void Host_SetWiiMoteConnectionState(int _State) {} void Host_SetWiiMoteConnectionState(int _State) {}

View File

@ -26,6 +26,7 @@
#include "VideoCommon/VideoBackendBase.h" #include "VideoCommon/VideoBackendBase.h"
static bool rendererHasFocus = true; static bool rendererHasFocus = true;
static bool rendererIsFullscreen = false;
static bool running = true; static bool running = true;
class Platform class Platform
@ -89,6 +90,11 @@ bool Host_RendererHasFocus()
return rendererHasFocus; return rendererHasFocus;
} }
bool Host_RendererIsFullscreen()
{
return rendererIsFullscreen;
}
void Host_ConnectWiimote(int wm_idx, bool connect) {} void Host_ConnectWiimote(int wm_idx, bool connect) {}
void Host_SetWiiMoteConnectionState(int _State) {} void Host_SetWiiMoteConnectionState(int _State) {}
@ -158,7 +164,7 @@ class PlatformX11 : public Platform
if (fullscreen) if (fullscreen)
{ {
X11Utils::ToggleFullscreen(dpy, win); rendererIsFullscreen = X11Utils::ToggleFullscreen(dpy, win);
#if defined(HAVE_XRANDR) && HAVE_XRANDR #if defined(HAVE_XRANDR) && HAVE_XRANDR
XRRConfig->ToggleDisplayMode(True); XRRConfig->ToggleDisplayMode(True);
#endif #endif
@ -246,6 +252,7 @@ class PlatformX11 : public Platform
(unsigned int *)&SConfig::GetInstance().m_LocalCoreStartupParameter.iRenderWindowWidth, (unsigned int *)&SConfig::GetInstance().m_LocalCoreStartupParameter.iRenderWindowWidth,
(unsigned int *)&SConfig::GetInstance().m_LocalCoreStartupParameter.iRenderWindowHeight, (unsigned int *)&SConfig::GetInstance().m_LocalCoreStartupParameter.iRenderWindowHeight,
&borderDummy, &depthDummy); &borderDummy, &depthDummy);
rendererIsFullscreen = false;
} }
usleep(100000); usleep(100000);
} }

View File

@ -24,7 +24,7 @@ extern char **environ;
namespace X11Utils namespace X11Utils
{ {
void ToggleFullscreen(Display *dpy, Window win) bool ToggleFullscreen(Display *dpy, Window win)
{ {
// Init X event structure for _NET_WM_STATE_FULLSCREEN client message // Init X event structure for _NET_WM_STATE_FULLSCREEN client message
XEvent event; XEvent event;
@ -38,7 +38,12 @@ void ToggleFullscreen(Display *dpy, Window win)
// Send the event // Send the event
if (!XSendEvent(dpy, DefaultRootWindow(dpy), False, if (!XSendEvent(dpy, DefaultRootWindow(dpy), False,
SubstructureRedirectMask | SubstructureNotifyMask, &event)) SubstructureRedirectMask | SubstructureNotifyMask, &event))
{
ERROR_LOG(VIDEO, "Failed to switch fullscreen/windowed mode."); ERROR_LOG(VIDEO, "Failed to switch fullscreen/windowed mode.");
return false;
}
return true;
} }
void InhibitScreensaver(Display *dpy, Window win, bool suspend) void InhibitScreensaver(Display *dpy, Window win, bool suspend)

View File

@ -34,7 +34,7 @@
namespace X11Utils namespace X11Utils
{ {
void ToggleFullscreen(Display *dpy, Window win); bool ToggleFullscreen(Display *dpy, Window win);
#if defined(HAVE_WX) && HAVE_WX #if defined(HAVE_WX) && HAVE_WX
Window XWindowFromHandle(void *Handle); Window XWindowFromHandle(void *Handle);
Display *XDisplayFromHandle(void *Handle); Display *XDisplayFromHandle(void *Handle);

View File

@ -265,7 +265,7 @@ HRESULT Create(HWND wnd)
swap_chain_desc.OutputWindow = wnd; swap_chain_desc.OutputWindow = wnd;
swap_chain_desc.SampleDesc.Count = 1; swap_chain_desc.SampleDesc.Count = 1;
swap_chain_desc.SampleDesc.Quality = 0; swap_chain_desc.SampleDesc.Quality = 0;
swap_chain_desc.Windowed = !g_ActiveConfig.bFullscreen; swap_chain_desc.Windowed = !g_Config.bFullscreen;
DXGI_OUTPUT_DESC out_desc; DXGI_OUTPUT_DESC out_desc;
memset(&out_desc, 0, sizeof(out_desc)); memset(&out_desc, 0, sizeof(out_desc));

View File

@ -41,13 +41,11 @@ namespace DX11
{ {
static u32 s_last_multisample_mode = 0; static u32 s_last_multisample_mode = 0;
static bool s_last_stereo_mode = false;
static bool s_last_xfb_mode = false;
static Television s_television; static Television s_television;
static bool s_last_fullscreen_mode = false;
static bool s_last_stereo_mode = 0;
static bool s_last_xfb_mode = false;
ID3D11Buffer* access_efb_cbuf = nullptr; ID3D11Buffer* access_efb_cbuf = nullptr;
ID3D11BlendState* clearblendstates[4] = {nullptr}; ID3D11BlendState* clearblendstates[4] = {nullptr};
ID3D11DepthStencilState* cleardepthstates[3] = {nullptr}; ID3D11DepthStencilState* cleardepthstates[3] = {nullptr};
@ -230,7 +228,6 @@ Renderer::Renderer(void *&window_handle)
s_last_multisample_mode = g_ActiveConfig.iMultisampleMode; s_last_multisample_mode = g_ActiveConfig.iMultisampleMode;
s_last_efb_scale = g_ActiveConfig.iEFBScale; s_last_efb_scale = g_ActiveConfig.iEFBScale;
s_last_fullscreen_mode = g_ActiveConfig.bFullscreen;
s_last_stereo_mode = g_ActiveConfig.iStereoMode > 0; s_last_stereo_mode = g_ActiveConfig.iStereoMode > 0;
s_last_xfb_mode = g_ActiveConfig.bUseRealXFB; s_last_xfb_mode = g_ActiveConfig.bUseRealXFB;
CalculateTargetSize(s_backbuffer_width, s_backbuffer_height); CalculateTargetSize(s_backbuffer_width, s_backbuffer_height);
@ -866,20 +863,6 @@ void Renderer::SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight, co
const bool fullscreen = g_ActiveConfig.bFullscreen && const bool fullscreen = g_ActiveConfig.bFullscreen &&
!SConfig::GetInstance().m_LocalCoreStartupParameter.bRenderToMain; !SConfig::GetInstance().m_LocalCoreStartupParameter.bRenderToMain;
bool fullscreen_changed = s_last_fullscreen_mode != fullscreen;
bool fullscreen_state;
if (SUCCEEDED(D3D::GetFullscreenState(&fullscreen_state)))
{
if (fullscreen_state != fullscreen && Host_RendererHasFocus())
{
// The current fullscreen state does not match the configuration,
// this may happen when the renderer frame loses focus. When the
// render frame is in focus again we can re-apply the configuration.
fullscreen_changed = true;
}
}
bool xfbchanged = s_last_xfb_mode != g_ActiveConfig.bUseRealXFB; bool xfbchanged = s_last_xfb_mode != g_ActiveConfig.bUseRealXFB;
if (FramebufferManagerBase::LastXfbWidth() != fbStride || FramebufferManagerBase::LastXfbHeight() != fbHeight) if (FramebufferManagerBase::LastXfbWidth() != fbStride || FramebufferManagerBase::LastXfbHeight() != fbHeight)
@ -894,6 +877,35 @@ void Renderer::SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight, co
// Flip/present backbuffer to frontbuffer here // Flip/present backbuffer to frontbuffer here
D3D::Present(); D3D::Present();
// Check exclusive fullscreen state
bool exclusive_mode, fullscreen_changed = false;
if (SUCCEEDED(D3D::GetFullscreenState(&exclusive_mode)))
{
if (fullscreen && !exclusive_mode)
{
// Exclusive fullscreen is enabled in the configuration, but we're
// not in exclusive mode. Either exclusive fullscreen was turned on
// or the render frame lost focus. When the render frame is in focus
// we can apply exclusive mode.
fullscreen_changed = Host_RendererHasFocus();
}
else if (!fullscreen)
{
if (exclusive_mode)
{
// Exclusive fullscreen is disabled, but we're still in exclusive mode.
fullscreen_changed = true;
}
else if (!g_ActiveConfig.bBorderlessFullscreen && Host_RendererIsFullscreen())
{
// Exclusive fullscreen is disabled and we are no longer in exclusive
// mode. Thus we can now safely notify the UI to exit fullscreen. But
// we should only do so if borderless fullscreen mode is disabled.
Host_RequestFullscreen(false);
}
}
}
// Resize the back buffers NOW to avoid flickering // Resize the back buffers NOW to avoid flickering
if (xfbchanged || if (xfbchanged ||
windowResized || windowResized ||
@ -910,17 +922,8 @@ void Renderer::SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight, co
{ {
// Apply fullscreen state // Apply fullscreen state
if (fullscreen_changed) if (fullscreen_changed)
{
s_last_fullscreen_mode = fullscreen;
D3D::SetFullscreenState(fullscreen); D3D::SetFullscreenState(fullscreen);
// Notify the host that it is safe to exit fullscreen
if (!fullscreen)
{
Host_RequestFullscreen(false);
}
}
// TODO: Aren't we still holding a reference to the back buffer right now? // TODO: Aren't we still holding a reference to the back buffer right now?
D3D::Reset(); D3D::Reset();
SAFE_RELEASE(s_screenshot_texture); SAFE_RELEASE(s_screenshot_texture);

View File

@ -22,6 +22,7 @@ void Host_RequestFullscreen(bool) {}
void Host_SetStartupDebuggingParameters() {} void Host_SetStartupDebuggingParameters() {}
bool Host_UIHasFocus() { return false; } bool Host_UIHasFocus() { return false; }
bool Host_RendererHasFocus() { return false; } bool Host_RendererHasFocus() { return false; }
bool Host_RendererIsFullscreen() { return false; }
void Host_ConnectWiimote(int, bool) {} void Host_ConnectWiimote(int, bool) {}
void Host_SetWiiMoteConnectionState(int) {} void Host_SetWiiMoteConnectionState(int) {}
void Host_ShowVideoConfig(void*, const std::string&, const std::string&) {} void Host_ShowVideoConfig(void*, const std::string&, const std::string&) {}