mirror of
https://github.com/moonlight-stream/moonlight-qt.git
synced 2026-06-18 14:40:56 +00:00
Recreate the decoder when moving to a new display to allow Pacer to get the new refresh rate
This commit is contained in:
@@ -874,6 +874,8 @@ void Session::exec(int displayOriginX, int displayOriginY)
|
|||||||
SDL_GetError());
|
SDL_GetError());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int currentDisplayIndex = SDL_GetWindowDisplayIndex(m_Window);
|
||||||
|
|
||||||
// Hijack this thread to be the SDL main thread. We have to do this
|
// Hijack this thread to be the SDL main thread. We have to do this
|
||||||
// because we want to suspend all Qt processing until the stream is over.
|
// because we want to suspend all Qt processing until the stream is over.
|
||||||
SDL_Event event;
|
SDL_Event event;
|
||||||
@@ -922,8 +924,13 @@ void Session::exec(int displayOriginX, int displayOriginY)
|
|||||||
// We use SDL_WINDOWEVENT_SIZE_CHANGED rather than SDL_WINDOWEVENT_RESIZED because the latter doesn't
|
// We use SDL_WINDOWEVENT_SIZE_CHANGED rather than SDL_WINDOWEVENT_RESIZED because the latter doesn't
|
||||||
// seem to fire when switching from windowed to full-screen on X11.
|
// seem to fire when switching from windowed to full-screen on X11.
|
||||||
if (event.window.event != SDL_WINDOWEVENT_SIZE_CHANGED && event.window.event != SDL_WINDOWEVENT_SHOWN) {
|
if (event.window.event != SDL_WINDOWEVENT_SIZE_CHANGED && event.window.event != SDL_WINDOWEVENT_SHOWN) {
|
||||||
|
// Check that the window display hasn't changed. If it has, we want
|
||||||
|
// to recreate the decoder to allow it to adapt to the new display.
|
||||||
|
// This will allow Pacer to pull the new display refresh rate.
|
||||||
|
if (SDL_GetWindowDisplayIndex(m_Window) == currentDisplayIndex) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Fall through
|
// Fall through
|
||||||
case SDL_RENDER_DEVICE_RESET:
|
case SDL_RENDER_DEVICE_RESET:
|
||||||
@@ -940,6 +947,7 @@ void Session::exec(int displayOriginX, int displayOriginY)
|
|||||||
SDL_FlushEvent(SDL_WINDOWEVENT);
|
SDL_FlushEvent(SDL_WINDOWEVENT);
|
||||||
|
|
||||||
// Update the window display mode based on our current monitor
|
// Update the window display mode based on our current monitor
|
||||||
|
currentDisplayIndex = SDL_GetWindowDisplayIndex(m_Window);
|
||||||
updateOptimalWindowDisplayMode();
|
updateOptimalWindowDisplayMode();
|
||||||
|
|
||||||
// Now that the old decoder is dead, flush any events it may
|
// Now that the old decoder is dead, flush any events it may
|
||||||
|
|||||||
@@ -11,9 +11,7 @@ class DisplayLinkVsyncSource : public IVsyncSource
|
|||||||
public:
|
public:
|
||||||
DisplayLinkVsyncSource(Pacer* pacer)
|
DisplayLinkVsyncSource(Pacer* pacer)
|
||||||
: m_Pacer(pacer),
|
: m_Pacer(pacer),
|
||||||
m_Window(nullptr),
|
m_DisplayLink(nullptr)
|
||||||
m_DisplayLink(nullptr),
|
|
||||||
m_DisplayId(UINT_MAX)
|
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -48,19 +46,6 @@ public:
|
|||||||
|
|
||||||
SDL_assert(displayLink == me->m_DisplayLink);
|
SDL_assert(displayLink == me->m_DisplayLink);
|
||||||
|
|
||||||
NSScreen* screen = [me->m_Window screen];
|
|
||||||
if (screen != nullptr && getDisplayID(screen) != me->m_DisplayId) {
|
|
||||||
// CVDisplayLinkSetCurrentCGDisplay() will deadlock if called
|
|
||||||
// within a CVDisplayLink callback, so we just teardown the
|
|
||||||
// decoder (and pacer) to let it come back up on the new display.
|
|
||||||
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION,
|
|
||||||
"Streaming window display has changed; resetting decoder");
|
|
||||||
SDL_Event event;
|
|
||||||
event.type = SDL_RENDER_TARGETS_RESET;
|
|
||||||
SDL_PushEvent(&event);
|
|
||||||
return kCVReturnSuccess;
|
|
||||||
}
|
|
||||||
|
|
||||||
// In my testing on macOS 10.13, this callback is invoked about 24 ms
|
// In my testing on macOS 10.13, this callback is invoked about 24 ms
|
||||||
// prior to the specified v-sync time (now - vsyncTime). Since this is
|
// prior to the specified v-sync time (now - vsyncTime). Since this is
|
||||||
// greater than the standard v-sync interval (16 ms = 60 FPS), we will
|
// greater than the standard v-sync interval (16 ms = 60 FPS), we will
|
||||||
@@ -89,10 +74,9 @@ public:
|
|||||||
|
|
||||||
SDL_assert(info.subsystem == SDL_SYSWM_COCOA);
|
SDL_assert(info.subsystem == SDL_SYSWM_COCOA);
|
||||||
|
|
||||||
m_Window = info.info.cocoa.window;
|
|
||||||
m_DisplayFps = displayFps;
|
m_DisplayFps = displayFps;
|
||||||
|
|
||||||
NSScreen* screen = [m_Window screen];
|
NSScreen* screen = [info.info.cocoa.window screen];
|
||||||
CVReturn status;
|
CVReturn status;
|
||||||
if (screen == nullptr) {
|
if (screen == nullptr) {
|
||||||
// Window not visible on any display, so use a
|
// Window not visible on any display, so use a
|
||||||
@@ -104,11 +88,12 @@ public:
|
|||||||
status = CVDisplayLinkCreateWithActiveCGDisplays(&m_DisplayLink);
|
status = CVDisplayLinkCreateWithActiveCGDisplays(&m_DisplayLink);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
m_DisplayId = getDisplayID(screen);
|
CGDirectDisplayID displayId;
|
||||||
|
displayId = getDisplayID(screen);
|
||||||
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION,
|
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION,
|
||||||
"NSWindow on display: %x",
|
"NSWindow on display: %x",
|
||||||
m_DisplayId);
|
displayId);
|
||||||
status = CVDisplayLinkCreateWithCGDisplay(m_DisplayId, &m_DisplayLink);
|
status = CVDisplayLinkCreateWithCGDisplay(displayId, &m_DisplayLink);
|
||||||
}
|
}
|
||||||
if (status != kCVReturnSuccess) {
|
if (status != kCVReturnSuccess) {
|
||||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
|
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
|
||||||
@@ -138,10 +123,8 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
Pacer* m_Pacer;
|
Pacer* m_Pacer;
|
||||||
NSWindow* m_Window;
|
|
||||||
CVDisplayLinkRef m_DisplayLink;
|
CVDisplayLinkRef m_DisplayLink;
|
||||||
int m_DisplayFps;
|
int m_DisplayFps;
|
||||||
CGDirectDisplayID m_DisplayId;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
IVsyncSource* DisplayLinkVsyncSourceFactory::createVsyncSource(Pacer* pacer) {
|
IVsyncSource* DisplayLinkVsyncSourceFactory::createVsyncSource(Pacer* pacer) {
|
||||||
|
|||||||
Reference in New Issue
Block a user