Skip to content

Commit

Permalink
Merge pull request #1764 from Armada651/safe-exclusive
Browse files Browse the repository at this point in the history
D3D: Only try to apply exclusive mode when the renderer is in focus.
  • Loading branch information
degasus committed Jan 6, 2015
2 parents d8d4c94 + 399b624 commit 25fac02
Show file tree
Hide file tree
Showing 11 changed files with 65 additions and 33 deletions.
1 change: 1 addition & 0 deletions Source/Core/Core/Host.h
Expand Up @@ -25,6 +25,7 @@

bool Host_UIHasFocus();
bool Host_RendererHasFocus();
bool Host_RendererIsFullscreen();
void Host_ConnectWiimote(int wm_idx, bool connect);
void Host_Message(int Id);
void Host_NotifyMapLoaded();
Expand Down
5 changes: 5 additions & 0 deletions Source/Core/DolphinQt/Host.cpp
Expand Up @@ -48,6 +48,11 @@ bool Host_UIHasFocus()
return g_main_window->isActiveWindow();
}

bool Host_RendererIsFullscreen()
{
return false; // TODO
}

void Host_RequestFullscreen(bool enable)
{
// TODO
Expand Down
2 changes: 1 addition & 1 deletion Source/Core/DolphinWX/Frame.h
Expand Up @@ -119,6 +119,7 @@ class CFrame : public CRenderFrame
void OnRenderParentMove(wxMoveEvent& event);
bool RendererHasFocus();
bool UIHasFocus();
bool RendererIsFullscreen();
void DoFullscreen(bool bF);
void ToggleDisplayMode (bool bFullscreen);
void UpdateWiiMenuChoice(wxMenuItem *WiiMenuItem=nullptr);
Expand Down Expand Up @@ -329,7 +330,6 @@ class CFrame : public CRenderFrame

void OnGameListCtrl_ItemActivated(wxListEvent& event);
void OnRenderParentResize(wxSizeEvent& event);
bool RendererIsFullscreen();
void StartGame(const std::string& filename);
void OnChangeColumnsVisible(wxCommandEvent& event);

Expand Down
5 changes: 5 additions & 0 deletions Source/Core/DolphinWX/Main.cpp
Expand Up @@ -572,6 +572,11 @@ bool Host_RendererHasFocus()
return main_frame->RendererHasFocus();
}

bool Host_RendererIsFullscreen()
{
return main_frame->RendererIsFullscreen();
}

void Host_ConnectWiimote(int wm_idx, bool connect)
{
CFrame::ConnectWiimote(wm_idx, connect);
Expand Down
5 changes: 5 additions & 0 deletions Source/Core/DolphinWX/MainAndroid.cpp
Expand Up @@ -94,6 +94,11 @@ bool Host_RendererHasFocus()
return true;
}

bool Host_RendererIsFullscreen()
{
return false;
}

void Host_ConnectWiimote(int wm_idx, bool connect) {}

void Host_SetWiiMoteConnectionState(int _State) {}
Expand Down
9 changes: 8 additions & 1 deletion Source/Core/DolphinWX/MainNoGUI.cpp
Expand Up @@ -26,6 +26,7 @@
#include "VideoCommon/VideoBackendBase.h"

static bool rendererHasFocus = true;
static bool rendererIsFullscreen = false;
static bool running = true;

class Platform
Expand Down Expand Up @@ -89,6 +90,11 @@ bool Host_RendererHasFocus()
return rendererHasFocus;
}

bool Host_RendererIsFullscreen()
{
return rendererIsFullscreen;
}

void Host_ConnectWiimote(int wm_idx, bool connect) {}

void Host_SetWiiMoteConnectionState(int _State) {}
Expand Down Expand Up @@ -158,7 +164,7 @@ class PlatformX11 : public Platform

if (fullscreen)
{
X11Utils::ToggleFullscreen(dpy, win);
rendererIsFullscreen = X11Utils::ToggleFullscreen(dpy, win);
#if defined(HAVE_XRANDR) && HAVE_XRANDR
XRRConfig->ToggleDisplayMode(True);
#endif
Expand Down Expand Up @@ -246,6 +252,7 @@ class PlatformX11 : public Platform
(unsigned int *)&SConfig::GetInstance().m_LocalCoreStartupParameter.iRenderWindowWidth,
(unsigned int *)&SConfig::GetInstance().m_LocalCoreStartupParameter.iRenderWindowHeight,
&borderDummy, &depthDummy);
rendererIsFullscreen = false;
}
usleep(100000);
}
Expand Down
7 changes: 6 additions & 1 deletion Source/Core/DolphinWX/X11Utils.cpp
Expand Up @@ -24,7 +24,7 @@ extern char **environ;
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
XEvent event;
Expand All @@ -38,7 +38,12 @@ void ToggleFullscreen(Display *dpy, Window win)
// Send the event
if (!XSendEvent(dpy, DefaultRootWindow(dpy), False,
SubstructureRedirectMask | SubstructureNotifyMask, &event))
{
ERROR_LOG(VIDEO, "Failed to switch fullscreen/windowed mode.");
return false;
}

return true;
}

void InhibitScreensaver(Display *dpy, Window win, bool suspend)
Expand Down
2 changes: 1 addition & 1 deletion Source/Core/DolphinWX/X11Utils.h
Expand Up @@ -34,7 +34,7 @@
namespace X11Utils
{

void ToggleFullscreen(Display *dpy, Window win);
bool ToggleFullscreen(Display *dpy, Window win);
#if defined(HAVE_WX) && HAVE_WX
Window XWindowFromHandle(void *Handle);
Display *XDisplayFromHandle(void *Handle);
Expand Down
2 changes: 1 addition & 1 deletion Source/Core/VideoBackends/D3D/D3DBase.cpp
Expand Up @@ -265,7 +265,7 @@ HRESULT Create(HWND wnd)
swap_chain_desc.OutputWindow = wnd;
swap_chain_desc.SampleDesc.Count = 1;
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;
memset(&out_desc, 0, sizeof(out_desc));
Expand Down
59 changes: 31 additions & 28 deletions Source/Core/VideoBackends/D3D/Render.cpp
Expand Up @@ -41,13 +41,11 @@ namespace DX11
{

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 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;
ID3D11BlendState* clearblendstates[4] = {nullptr};
ID3D11DepthStencilState* cleardepthstates[3] = {nullptr};
Expand Down Expand Up @@ -230,7 +228,6 @@ Renderer::Renderer(void *&window_handle)

s_last_multisample_mode = g_ActiveConfig.iMultisampleMode;
s_last_efb_scale = g_ActiveConfig.iEFBScale;
s_last_fullscreen_mode = g_ActiveConfig.bFullscreen;
s_last_stereo_mode = g_ActiveConfig.iStereoMode > 0;
s_last_xfb_mode = g_ActiveConfig.bUseRealXFB;
CalculateTargetSize(s_backbuffer_width, s_backbuffer_height);
Expand Down Expand Up @@ -866,20 +863,6 @@ void Renderer::SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight, co
const bool fullscreen = g_ActiveConfig.bFullscreen &&
!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;

if (FramebufferManagerBase::LastXfbWidth() != fbStride || FramebufferManagerBase::LastXfbHeight() != fbHeight)
Expand All @@ -894,6 +877,35 @@ void Renderer::SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight, co
// Flip/present backbuffer to frontbuffer here
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
if (xfbchanged ||
windowResized ||
Expand All @@ -910,17 +922,8 @@ void Renderer::SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight, co
{
// Apply fullscreen state
if (fullscreen_changed)
{
s_last_fullscreen_mode = 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?
D3D::Reset();
SAFE_RELEASE(s_screenshot_texture);
Expand Down
1 change: 1 addition & 0 deletions Source/UnitTests/TestUtils/StubHost.cpp
Expand Up @@ -22,6 +22,7 @@ void Host_RequestFullscreen(bool) {}
void Host_SetStartupDebuggingParameters() {}
bool Host_UIHasFocus() { return false; }
bool Host_RendererHasFocus() { return false; }
bool Host_RendererIsFullscreen() { return false; }
void Host_ConnectWiimote(int, bool) {}
void Host_SetWiiMoteConnectionState(int) {}
void Host_ShowVideoConfig(void*, const std::string&, const std::string&) {}
Expand Down

0 comments on commit 25fac02

Please sign in to comment.