From 9fbdd794b9ffb1240335f176f3278a83941eddd5 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Thu, 16 Aug 2018 22:25:14 -0700 Subject: [PATCH] Improve support for full-screen exclusive mode --- app/streaming/session.cpp | 121 ++++++++---------- .../video/ffmpeg-renderers/dxva2.cpp | 8 +- 2 files changed, 59 insertions(+), 70 deletions(-) diff --git a/app/streaming/session.cpp b/app/streaming/session.cpp index ec7f0a08..fb73009c 100644 --- a/app/streaming/session.cpp +++ b/app/streaming/session.cpp @@ -471,10 +471,14 @@ void Session::getWindowDimensions(bool fullScreen, { int displayIndex = 0; + if (m_Window != nullptr) { + displayIndex = SDL_GetWindowDisplayIndex(m_Window); + SDL_assert(displayIndex >= 0); + } // If there's a display matching this exact resolution, pick that // one (for native full-screen streaming). Otherwise, assume // display 0 for now. TODO: Default to the screen that the Qt window is on - if (fullScreen) { + else if (fullScreen) { for (int i = 0; i < SDL_GetNumVideoDisplays(); i++) { SDL_DisplayMode mode; if (SDL_GetCurrentDisplayMode(i, &mode) == 0 && @@ -489,79 +493,44 @@ void Session::getWindowDimensions(bool fullScreen, } } - if (m_Window != nullptr) { - displayIndex = SDL_GetWindowDisplayIndex(m_Window); - if (displayIndex < 0) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, - "SDL_GetWindowDisplayIndex() failed: %s", - SDL_GetError()); + SDL_Rect usableBounds; + if (SDL_GetDisplayUsableBounds(displayIndex, &usableBounds) == 0) { + width = usableBounds.w; + height = usableBounds.h; + x = usableBounds.x; + y = usableBounds.y; - // Assume display 0 - displayIndex = 0; - } - } + if (m_Window != nullptr) { + int top, left, bottom, right; - if (fullScreen) { - SDL_DisplayMode currentMode; + if (SDL_GetWindowBordersSize(m_Window, &top, &left, &bottom, &right) < 0) { + SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION, + "Unable to get window border size"); + return; + } - if (SDL_GetCurrentDisplayMode(displayIndex, ¤tMode) == 0) { - SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, - "Using current display mode: %dx%dx%d", - currentMode.w, currentMode.h, currentMode.refresh_rate); - width = currentMode.w; - height = currentMode.h; - } - else { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, - "Unable to get current display mode: %s", - SDL_GetError()); - width = m_StreamConfig.width; - height = m_StreamConfig.height; - } + x += left; + y += top; - // Full-screen modes always start at the origin - x = y = SDL_WINDOWPOS_UNDEFINED_DISPLAY(displayIndex); - } - else { - SDL_Rect usableBounds; - if (SDL_GetDisplayUsableBounds(displayIndex, &usableBounds) == 0) { - width = usableBounds.w; - height = usableBounds.h; - x = usableBounds.x; - y = usableBounds.y; + width -= left + right; + height -= top + bottom; - if (m_Window != nullptr) { - int top, left, bottom, right; - - if (SDL_GetWindowBordersSize(m_Window, &top, &left, &bottom, &right) < 0) { - SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION, - "Unable to get window border size"); - return; - } - - x += left; - y += top; - - width -= left + right; - height -= top + bottom; - - // If the stream window can fit within the usable drawing area with 1:1 - // scaling, do that rather than filling the screen. - if (m_StreamConfig.width < width && m_StreamConfig.height < height) { - width = m_StreamConfig.width; - height = m_StreamConfig.height; - } + // If the stream window can fit within the usable drawing area with 1:1 + // scaling, do that rather than filling the screen. + if (m_StreamConfig.width < width && m_StreamConfig.height < height) { + width = m_StreamConfig.width; + height = m_StreamConfig.height; } } - else { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, - "SDL_GetDisplayUsableBounds() failed: %s", - SDL_GetError()); + } + else { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, + "SDL_GetDisplayUsableBounds() failed: %s", + SDL_GetError()); - width = m_StreamConfig.width; - height = m_StreamConfig.height; - x = y = SDL_WINDOWPOS_UNDEFINED_DISPLAY(displayIndex); - } + width = m_StreamConfig.width; + height = m_StreamConfig.height; + x = y = SDL_WINDOWPOS_UNDEFINED_DISPLAY(displayIndex); } } @@ -694,8 +663,7 @@ void Session::exec() y, width, height, - m_Preferences.fullScreen ? - SDL_OS_FULLSCREEN_FLAG : 0); + 0); if (!m_Window) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "SDL_CreateWindow() failed: %s", @@ -718,6 +686,16 @@ void Session::exec() // creation causes our window to be full screen for some reason SDL_SetWindowResizable(m_Window, SDL_TRUE); } + else { + // Update the window display mode based on our current monitor + SDL_DisplayMode mode; + if (SDL_GetDesktopDisplayMode(SDL_GetWindowDisplayIndex(m_Window), &mode) == 0) { + SDL_SetWindowDisplayMode(m_Window, &mode); + } + + // Enter full screen + SDL_SetWindowFullscreen(m_Window, SDL_OS_FULLSCREEN_FLAG); + } QSvgRenderer svgIconRenderer(QString(":/res/moonlight.svg")); QImage svgImage(ICON_SIZE, ICON_SIZE, QImage::Format_RGBA8888); @@ -816,6 +794,13 @@ void Session::exec() // Fall through case SDL_RENDER_DEVICE_RESET: case SDL_RENDER_TARGETS_RESET: + + // Update the window display mode based on our current monitor + SDL_DisplayMode mode; + if (SDL_GetDesktopDisplayMode(SDL_GetWindowDisplayIndex(m_Window), &mode) == 0) { + SDL_SetWindowDisplayMode(m_Window, &mode); + } + SDL_AtomicLock(&m_DecoderLock); // Destroy the old decoder diff --git a/app/streaming/video/ffmpeg-renderers/dxva2.cpp b/app/streaming/video/ffmpeg-renderers/dxva2.cpp index dba799ba..386fac98 100644 --- a/app/streaming/video/ffmpeg-renderers/dxva2.cpp +++ b/app/streaming/video/ffmpeg-renderers/dxva2.cpp @@ -441,8 +441,6 @@ bool DXVA2Renderer::initialize(SDL_Window* window, int videoFormat, int width, i // D3DCREATE_MULTITHREADED to IDirect3D9::CreateDevice(). SDL_SetHint(SDL_HINT_RENDER_DIRECT3D_THREADSAFE, "1"); - // We require full-screen desktop mode to avoid having to enable V-sync - // to synchronize frame delivery (which has a much higher latency penalty). m_SdlRenderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED); if (!m_SdlRenderer) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, @@ -452,6 +450,12 @@ bool DXVA2Renderer::initialize(SDL_Window* window, int videoFormat, int width, i } m_Device = SDL_RenderGetD3D9Device(m_SdlRenderer); + if (m_Device == nullptr) { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, + "SDL_RenderGetD3D9Device() failed: %s", + SDL_GetError()); + return false; + } // Draw a black frame until the video stream starts rendering SDL_SetRenderDrawColor(m_SdlRenderer, 0, 0, 0, SDL_ALPHA_OPAQUE);