Abstract fullscreen details into SDLC functions

This commit is contained in:
Cameron Gutman 2025-01-30 21:57:37 -06:00
parent 13b2b28c2f
commit a37020b974
10 changed files with 65 additions and 25 deletions

View File

@ -207,3 +207,28 @@ SDLC_VideoDriver SDLC_GetVideoDriver(void)
} }
#endif #endif
} }
bool SDLC_IsFullscreen(SDL_Window* window)
{
return !!(SDL_GetWindowFlags(window) & SDL_WINDOW_FULLSCREEN);
}
bool SDLC_IsFullscreenExclusive(SDL_Window* window)
{
return (SDL_GetWindowFlags(window) & SDL_WINDOW_FULLSCREEN_DESKTOP) == SDL_WINDOW_FULLSCREEN;
}
bool SDLC_IsFullscreenDesktop(SDL_Window* window)
{
return (SDL_GetWindowFlags(window) & SDL_WINDOW_FULLSCREEN_DESKTOP) == SDL_WINDOW_FULLSCREEN_DESKTOP;
}
void SDLC_EnterFullscreen(SDL_Window* window, bool exclusive)
{
SDL_SetWindowFullscreen(window, exclusive ? SDL_WINDOW_FULLSCREEN : SDL_WINDOW_FULLSCREEN_DESKTOP);
}
void SDLC_LeaveFullscreen(SDL_Window* window)
{
SDL_SetWindowFullscreen(window, 0);
}

View File

@ -6,6 +6,7 @@
#pragma once #pragma once
#include <SDL.h> #include <SDL.h>
#include <stdbool.h>
// This is a pure C header for compatibility with SDL.h // This is a pure C header for compatibility with SDL.h
#ifdef __cplusplus #ifdef __cplusplus
@ -90,6 +91,12 @@ typedef enum {
} SDLC_VideoDriver; } SDLC_VideoDriver;
SDLC_VideoDriver SDLC_GetVideoDriver(); SDLC_VideoDriver SDLC_GetVideoDriver();
bool SDLC_IsFullscreen(SDL_Window* window);
bool SDLC_IsFullscreenExclusive(SDL_Window* window);
bool SDLC_IsFullscreenDesktop(SDL_Window* window);
void SDLC_EnterFullscreen(SDL_Window* window, bool exclusive);
void SDLC_LeaveFullscreen(SDL_Window* window);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -289,7 +289,7 @@ void SdlInputHandler::notifyFocusLost()
// This lets user to interact with our window's title bar and with the buttons in it. // This lets user to interact with our window's title bar and with the buttons in it.
// Doing this while the window is full-screen breaks the transition out of FS // Doing this while the window is full-screen breaks the transition out of FS
// (desktop and exclusive), so we must check for that before releasing mouse capture. // (desktop and exclusive), so we must check for that before releasing mouse capture.
if (!(SDL_GetWindowFlags(m_Window) & SDL_WINDOW_FULLSCREEN) && !m_AbsoluteMouseMode) { if (!SDLC_IsFullscreen(m_Window) && !m_AbsoluteMouseMode) {
setCaptureActive(false); setCaptureActive(false);
} }
@ -315,9 +315,8 @@ void SdlInputHandler::updateKeyboardGrabState()
} }
bool shouldGrab = isCaptureActive(); bool shouldGrab = isCaptureActive();
Uint32 windowFlags = SDL_GetWindowFlags(m_Window);
if (m_CaptureSystemKeysMode == StreamingPreferences::CSK_FULLSCREEN && if (m_CaptureSystemKeysMode == StreamingPreferences::CSK_FULLSCREEN &&
!(windowFlags & SDL_WINDOW_FULLSCREEN)) { !SDLC_IsFullscreen(m_Window)) {
// Ungrab if it's fullscreen only and we left fullscreen // Ungrab if it's fullscreen only and we left fullscreen
shouldGrab = false; shouldGrab = false;
} }
@ -355,7 +354,7 @@ bool SdlInputHandler::isSystemKeyCaptureActive()
} }
if (m_CaptureSystemKeysMode == StreamingPreferences::CSK_FULLSCREEN && if (m_CaptureSystemKeysMode == StreamingPreferences::CSK_FULLSCREEN &&
!(windowFlags & SDL_WINDOW_FULLSCREEN)) { !SDLC_IsFullscreen(m_Window)) {
return false; return false;
} }

View File

@ -270,7 +270,7 @@ void SdlInputHandler::updatePointerRegionLock()
// have full control over it and we don't touch it anymore. // have full control over it and we don't touch it anymore.
if (!m_PointerRegionLockToggledByUser) { if (!m_PointerRegionLockToggledByUser) {
// Lock the pointer in true full-screen mode and leave it unlocked in other modes // Lock the pointer in true full-screen mode and leave it unlocked in other modes
m_PointerRegionLockActive = (SDL_GetWindowFlags(m_Window) & SDL_WINDOW_FULLSCREEN_DESKTOP) == SDL_WINDOW_FULLSCREEN; m_PointerRegionLockActive = SDLC_IsFullscreenExclusive(m_Window);
} }
// If region lock is enabled, grab the cursor so it can't accidentally leave our window. // If region lock is enabled, grab the cursor so it can't accidentally leave our window.

View File

@ -851,7 +851,7 @@ bool Session::initialize()
case StreamingPreferences::WM_FULLSCREEN_DESKTOP: case StreamingPreferences::WM_FULLSCREEN_DESKTOP:
// Only use full-screen desktop mode if we're running a desktop environment // Only use full-screen desktop mode if we're running a desktop environment
if (WMUtils::isRunningDesktopEnvironment()) { if (WMUtils::isRunningDesktopEnvironment()) {
m_FullScreenFlag = SDL_WINDOW_FULLSCREEN_DESKTOP; m_FullScreenExclusiveMode = false;
break; break;
} }
// Fall-through // Fall-through
@ -859,13 +859,13 @@ bool Session::initialize()
#ifdef Q_OS_DARWIN #ifdef Q_OS_DARWIN
if (qEnvironmentVariableIntValue("I_WANT_BUGGY_FULLSCREEN") == 0) { if (qEnvironmentVariableIntValue("I_WANT_BUGGY_FULLSCREEN") == 0) {
// Don't use "real" fullscreen on macOS by default. See comments above. // Don't use "real" fullscreen on macOS by default. See comments above.
m_FullScreenFlag = SDL_WINDOW_FULLSCREEN_DESKTOP; m_FullScreenExclusiveMode = false;
} }
else { else {
m_FullScreenFlag = SDL_WINDOW_FULLSCREEN; m_FullScreenExclusiveMode = true;
} }
#else #else
m_FullScreenFlag = SDL_WINDOW_FULLSCREEN; m_FullScreenExclusiveMode = true;
#endif #endif
break; break;
} }
@ -877,7 +877,7 @@ bool Session::initialize()
if (qgetenv("DESKTOP_SESSION") == "LXDE-pi") { if (qgetenv("DESKTOP_SESSION") == "LXDE-pi") {
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION,
"Forcing windowed mode on LXDE-Pi"); "Forcing windowed mode on LXDE-Pi");
m_FullScreenFlag = 0; m_FullScreenExclusiveMode = false;
} }
#endif #endif
@ -1350,10 +1350,15 @@ void Session::getWindowDimensions(int& x, int& y,
void Session::updateOptimalWindowDisplayMode() void Session::updateOptimalWindowDisplayMode()
{ {
SDL_DisplayMode desktopMode, bestMode, mode; SDL_DisplayMode desktopMode, bestMode, mode;
int displayIndex = SDL_GetWindowDisplayIndex(m_Window);
// Nothing to do if we're not using full-screen exclusive mode
if (!m_FullScreenExclusiveMode) {
return;
}
// Try the current display mode first. On macOS, this will be the normal // Try the current display mode first. On macOS, this will be the normal
// scaled desktop resolution setting. // scaled desktop resolution setting.
int displayIndex = SDL_GetWindowDisplayIndex(m_Window);
if (SDL_GetDesktopDisplayMode(displayIndex, &desktopMode) == 0) { if (SDL_GetDesktopDisplayMode(displayIndex, &desktopMode) == 0) {
// If this doesn't fit the selected resolution, use the native // If this doesn't fit the selected resolution, use the native
// resolution of the panel (unscaled). // resolution of the panel (unscaled).
@ -1425,7 +1430,7 @@ void Session::updateOptimalWindowDisplayMode()
bestMode = desktopMode; bestMode = desktopMode;
} }
if ((SDL_GetWindowFlags(m_Window) & SDL_WINDOW_FULLSCREEN_DESKTOP) == SDL_WINDOW_FULLSCREEN) { if (SDLC_IsFullscreenExclusive(m_Window)) {
// Only print when the window is actually in full-screen exclusive mode, // Only print when the window is actually in full-screen exclusive mode,
// otherwise we're not actually using the mode we've set here // otherwise we're not actually using the mode we've set here
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION,
@ -1438,7 +1443,7 @@ void Session::updateOptimalWindowDisplayMode()
void Session::toggleFullscreen() void Session::toggleFullscreen()
{ {
bool fullScreen = !(SDL_GetWindowFlags(m_Window) & m_FullScreenFlag); bool enterFullScreen = !SDLC_IsFullscreen(m_Window);
#if defined(Q_OS_WIN32) || defined(Q_OS_DARWIN) #if defined(Q_OS_WIN32) || defined(Q_OS_DARWIN)
// Destroy the video decoder before toggling full-screen because D3D9 can try // Destroy the video decoder before toggling full-screen because D3D9 can try
@ -1456,13 +1461,18 @@ void Session::toggleFullscreen()
#endif #endif
// Actually enter/leave fullscreen // Actually enter/leave fullscreen
SDL_SetWindowFullscreen(m_Window, fullScreen ? m_FullScreenFlag : 0); if (enterFullScreen) {
SDLC_EnterFullscreen(m_Window, m_FullScreenExclusiveMode);
}
else {
SDLC_LeaveFullscreen(m_Window);
}
#ifdef Q_OS_DARWIN #ifdef Q_OS_DARWIN
// SDL on macOS has a bug that causes the window size to be reset to crazy // SDL on macOS has a bug that causes the window size to be reset to crazy
// large dimensions when exiting out of true fullscreen mode. We can work // large dimensions when exiting out of true fullscreen mode. We can work
// around the issue by manually resetting the position and size here. // around the issue by manually resetting the position and size here.
if (!fullScreen && m_FullScreenFlag == SDL_WINDOW_FULLSCREEN) { if (!enterFullScreen && m_FullScreenExclusiveMode) {
int x, y, width, height; int x, y, width, height;
getWindowDimensions(x, y, width, height); getWindowDimensions(x, y, width, height);
SDL_SetWindowSize(m_Window, width, height); SDL_SetWindowSize(m_Window, width, height);
@ -1913,7 +1923,7 @@ void Session::execInternal()
// Enter full screen if requested // Enter full screen if requested
if (m_IsFullScreen) { if (m_IsFullScreen) {
SDL_SetWindowFullscreen(m_Window, m_FullScreenFlag); SDLC_EnterFullscreen(m_Window, m_FullScreenExclusiveMode);
} }
bool needsFirstEnterCapture = false; bool needsFirstEnterCapture = false;

View File

@ -253,7 +253,7 @@ private:
SDL_SpinLock m_DecoderLock; SDL_SpinLock m_DecoderLock;
bool m_AudioDisabled; bool m_AudioDisabled;
bool m_AudioMuted; bool m_AudioMuted;
Uint32 m_FullScreenFlag; bool m_FullScreenExclusiveMode;
QWindow* m_QtWindow; QWindow* m_QtWindow;
bool m_ThreadedExec; bool m_ThreadedExec;
bool m_UnexpectedTermination; bool m_UnexpectedTermination;

View File

@ -122,7 +122,7 @@ int StreamUtils::getDisplayRefreshRate(SDL_Window* window)
} }
SDL_DisplayMode mode; SDL_DisplayMode mode;
if ((SDL_GetWindowFlags(window) & SDL_WINDOW_FULLSCREEN_DESKTOP) == SDL_WINDOW_FULLSCREEN) { if (SDLC_IsFullscreenExclusive(window)) {
// Use the window display mode for full-screen exclusive mode // Use the window display mode for full-screen exclusive mode
if (SDL_GetWindowDisplayMode(window, &mode) != 0) { if (SDL_GetWindowDisplayMode(window, &mode) != 0) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,

View File

@ -427,7 +427,7 @@ bool D3D11VARenderer::initialize(PDECODER_PARAMETERS params)
// DXVA2 may let us take over for FSE V-sync off cases. However, if we don't have DXGI_FEATURE_PRESENT_ALLOW_TEARING // DXVA2 may let us take over for FSE V-sync off cases. However, if we don't have DXGI_FEATURE_PRESENT_ALLOW_TEARING
// then we should not attempt to do this unless there's no other option (HDR, DXVA2 failed in pass 1, etc). // then we should not attempt to do this unless there's no other option (HDR, DXVA2 failed in pass 1, etc).
if (!m_AllowTearing && m_DecoderSelectionPass == 0 && !(params->videoFormat & VIDEO_FORMAT_MASK_10BIT) && if (!m_AllowTearing && m_DecoderSelectionPass == 0 && !(params->videoFormat & VIDEO_FORMAT_MASK_10BIT) &&
(SDL_GetWindowFlags(params->window) & SDL_WINDOW_FULLSCREEN_DESKTOP) == SDL_WINDOW_FULLSCREEN) { SDLC_IsFullscreenExclusive(params->window)) {
SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION, SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION,
"Defaulting to DXVA2 for FSE without DXGI_FEATURE_PRESENT_ALLOW_TEARING support"); "Defaulting to DXVA2 for FSE without DXGI_FEATURE_PRESENT_ALLOW_TEARING support");
return false; return false;
@ -436,8 +436,8 @@ bool D3D11VARenderer::initialize(PDECODER_PARAMETERS params)
HWND window = (HWND)SDLC_Win32_GetHwnd(params->window); HWND window = (HWND)SDLC_Win32_GetHwnd(params->window);
// Always use windowed or borderless windowed mode.. SDL does mode-setting for us in // Always use windowed or borderless windowed mode. SDL does mode-setting for us in
// full-screen exclusive mode (SDL_WINDOW_FULLSCREEN), so this actually works out okay. // full-screen exclusive mode, so this actually works out okay.
ComPtr<IDXGISwapChain1> swapChain; ComPtr<IDXGISwapChain1> swapChain;
hr = m_Factory->CreateSwapChainForHwnd(m_Device.Get(), hr = m_Factory->CreateSwapChainForHwnd(m_Device.Get(),
window, window,
@ -1184,7 +1184,7 @@ int D3D11VARenderer::getRendererAttributes()
// In windowed mode, we will render as fast we can and DWM will grab whatever is latest at the // In windowed mode, we will render as fast we can and DWM will grab whatever is latest at the
// time unless the user opts for pacing. We will use pacing in full-screen mode and normal DWM // time unless the user opts for pacing. We will use pacing in full-screen mode and normal DWM
// sequencing in full-screen desktop mode to behave similarly to the DXVA2 renderer. // sequencing in full-screen desktop mode to behave similarly to the DXVA2 renderer.
if ((SDL_GetWindowFlags(m_DecoderParams.window) & SDL_WINDOW_FULLSCREEN_DESKTOP) == SDL_WINDOW_FULLSCREEN) { if (SDLC_IsFullscreenExclusive(m_DecoderParams.window)) {
attributes |= RENDERER_ATTRIBUTE_FORCE_PACING; attributes |= RENDERER_ATTRIBUTE_FORCE_PACING;
} }

View File

@ -549,7 +549,6 @@ bool DXVA2Renderer::initializeDevice(SDL_Window* window, bool enableVsync)
} }
int adapterIndex = SDL_Direct3D9GetAdapterIndex(SDL_GetWindowDisplayIndex(window)); int adapterIndex = SDL_Direct3D9GetAdapterIndex(SDL_GetWindowDisplayIndex(window));
Uint32 windowFlags = SDL_GetWindowFlags(window);
// Initialize quirks *before* calling CreateDeviceEx() to allow our below // Initialize quirks *before* calling CreateDeviceEx() to allow our below
// logic to avoid a hang with NahimicOSD.dll's broken full-screen handling. // logic to avoid a hang with NahimicOSD.dll's broken full-screen handling.
@ -583,7 +582,7 @@ bool DXVA2Renderer::initializeDevice(SDL_Window* window, bool enableVsync)
} }
} }
if ((windowFlags & SDL_WINDOW_FULLSCREEN_DESKTOP) == SDL_WINDOW_FULLSCREEN) { if (SDLC_IsFullscreenExclusive(window)) {
d3dpp.Windowed = false; d3dpp.Windowed = false;
d3dpp.BackBufferWidth = currentMode.Width; d3dpp.BackBufferWidth = currentMode.Width;
d3dpp.BackBufferHeight = currentMode.Height; d3dpp.BackBufferHeight = currentMode.Height;

View File

@ -144,7 +144,7 @@ bool SdlRenderer::initialize(PDECODER_PARAMETERS params)
switch (SDLC_GetVideoDriver()) { switch (SDLC_GetVideoDriver()) {
case SDLC_VIDEO_WIN32: case SDLC_VIDEO_WIN32:
// DWM is always tear-free except in full-screen exclusive mode // DWM is always tear-free except in full-screen exclusive mode
if ((SDL_GetWindowFlags(params->window) & SDL_WINDOW_FULLSCREEN_DESKTOP) == SDL_WINDOW_FULLSCREEN) { if (SDLC_IsFullscreenExclusive(params->window)) {
if (params->enableVsync) { if (params->enableVsync) {
rendererFlags |= SDL_RENDERER_PRESENTVSYNC; rendererFlags |= SDL_RENDERER_PRESENTVSYNC;
} }