diff --git a/DDrawCompat/DDraw/RealPrimarySurface.cpp b/DDrawCompat/DDraw/RealPrimarySurface.cpp index eb61481..2e9181c 100644 --- a/DDrawCompat/DDraw/RealPrimarySurface.cpp +++ b/DDrawCompat/DDraw/RealPrimarySurface.cpp @@ -55,6 +55,7 @@ namespace Compat::CriticalSection g_presentCs; bool g_isDelayedFlipPending = false; + bool g_isOverlayUpdatePending = false; bool g_isUpdatePending = false; bool g_isUpdateReady = false; DWORD g_lastUpdateThreadId = 0; @@ -304,6 +305,7 @@ namespace } Compat::ScopedCriticalSection lock(g_presentCs); + g_isOverlayUpdatePending = false; g_isUpdatePending = false; g_isUpdateReady = false; g_qpcLastUpdate = Time::queryPerformanceCounter() - Time::msToQpc(DELAYED_FLIP_MODE_TIMEOUT_MS); @@ -357,6 +359,7 @@ namespace { { Compat::ScopedCriticalSection lock(g_presentCs); + g_isOverlayUpdatePending = false; g_isUpdatePending = false; g_isUpdateReady = false; } @@ -533,18 +536,16 @@ namespace DDraw PrimarySurface::waitForIdle(); Compat::ScopedCriticalSection lock(g_presentCs); g_isDelayedFlipPending = true; + g_isOverlayUpdatePending = false; g_isUpdatePending = false; g_isUpdateReady = false; g_lastUpdateThreadId = GetCurrentThreadId(); } else { - auto statsWindow = Gdi::GuiThread::getStatsWindow(); - if (statsWindow && statsWindow->isVisible()) - { - statsWindow->updateStats(); - } - updateNow(PrimarySurface::getPrimary()); + D3dDdi::KernelModeThunks::waitForVsyncCounter(g_presentEndVsyncCount); + g_isUpdateReady = true; + flush(); } g_flipEndVsyncCount = D3dDdi::KernelModeThunks::getVsyncCounter() + flipInterval; @@ -570,10 +571,18 @@ namespace DDraw return -1; } - auto statsWindow = Gdi::GuiThread::getStatsWindow(); - if (statsWindow && statsWindow->isVisible()) + static UINT lastOverlayCheckVsyncCount = 0; + if (vsyncCount != lastOverlayCheckVsyncCount) { - statsWindow->updateStats(); + Gdi::Cursor::update(); + Gdi::Caret::blink(); + auto statsWindow = Gdi::GuiThread::getStatsWindow(); + if (statsWindow && statsWindow->isVisible()) + { + statsWindow->updateStats(); + g_qpcLastUpdate = Time::queryPerformanceCounter(); + } + lastOverlayCheckVsyncCount = vsyncCount; } { @@ -599,6 +608,11 @@ namespace DDraw g_isDelayedFlipPending = false; g_isUpdateReady = true; } + else if (g_isOverlayUpdatePending) + { + g_qpcLastUpdate = Time::queryPerformanceCounter(); + g_isUpdateReady = true; + } } if (!g_isUpdateReady) @@ -727,6 +741,12 @@ namespace DDraw return create(*CompatPtr::from(dd.get())); } + void RealPrimarySurface::scheduleOverlayUpdate() + { + Compat::ScopedCriticalSection lock(g_presentCs); + g_isOverlayUpdatePending = true; + } + void RealPrimarySurface::scheduleUpdate() { Compat::ScopedCriticalSection lock(g_presentCs); diff --git a/DDrawCompat/DDraw/RealPrimarySurface.h b/DDrawCompat/DDraw/RealPrimarySurface.h index 4d0ef4b..312ede9 100644 --- a/DDrawCompat/DDraw/RealPrimarySurface.h +++ b/DDrawCompat/DDraw/RealPrimarySurface.h @@ -27,6 +27,7 @@ namespace DDraw static bool isLost(); static void release(); static HRESULT restore(); + static void scheduleOverlayUpdate(); static void scheduleUpdate(); static HRESULT setGammaRamp(DDGAMMARAMP* rampData); static void setUpdateReady(); diff --git a/DDrawCompat/Gdi/Cursor.cpp b/DDrawCompat/Gdi/Cursor.cpp index 0e45c9a..a4996c4 100644 --- a/DDrawCompat/Gdi/Cursor.cpp +++ b/DDrawCompat/Gdi/Cursor.cpp @@ -235,7 +235,7 @@ namespace Gdi (cursorInfo.hCursor != g_prevCursorInfo.hCursor || cursorInfo.ptScreenPos != g_prevCursorInfo.ptScreenPos)) { g_prevCursorInfo = cursorInfo; - DDraw::RealPrimarySurface::scheduleUpdate(); + DDraw::RealPrimarySurface::scheduleOverlayUpdate(); } } } diff --git a/DDrawCompat/Gdi/GuiThread.cpp b/DDrawCompat/Gdi/GuiThread.cpp index 58922f5..9cfe951 100644 --- a/DDrawCompat/Gdi/GuiThread.cpp +++ b/DDrawCompat/Gdi/GuiThread.cpp @@ -6,8 +6,6 @@ #include #include #include -#include -#include #include #include #include @@ -101,16 +99,6 @@ namespace return 0; } - - unsigned WINAPI updateThreadProc(LPVOID /*lpParameter*/) - { - while (true) - { - Sleep(5); - Gdi::Caret::blink(); - Gdi::Cursor::update(); - } - } } namespace Gdi @@ -194,7 +182,6 @@ namespace Gdi void start() { Dll::createThread(messageWindowThreadProc, &g_threadId, THREAD_PRIORITY_TIME_CRITICAL, 0); - Dll::createThread(updateThreadProc, nullptr, THREAD_PRIORITY_TIME_CRITICAL, 0); } } } diff --git a/DDrawCompat/Gdi/WinProc.cpp b/DDrawCompat/Gdi/WinProc.cpp index d1c881e..7e32d18 100644 --- a/DDrawCompat/Gdi/WinProc.cpp +++ b/DDrawCompat/Gdi/WinProc.cpp @@ -521,7 +521,7 @@ namespace BOOL result = CALL_ORIG_FUNC(SetLayeredWindowAttributes)(hwnd, crKey, bAlpha, dwFlags); if (result && DDraw::RealPrimarySurface::isFullscreen()) { - DDraw::RealPrimarySurface::scheduleUpdate(); + DDraw::RealPrimarySurface::scheduleOverlayUpdate(); } return LOG_RESULT(result); } diff --git a/DDrawCompat/Input/Input.cpp b/DDrawCompat/Input/Input.cpp index 6b4df06..a646887 100644 --- a/DDrawCompat/Input/Input.cpp +++ b/DDrawCompat/Input/Input.cpp @@ -58,7 +58,7 @@ namespace } case WM_WINDOWPOSCHANGED: - DDraw::RealPrimarySurface::scheduleUpdate(); + DDraw::RealPrimarySurface::scheduleOverlayUpdate(); break; } @@ -121,6 +121,7 @@ namespace cp.x = min(max(g_monitorRect.left, cp.x), g_monitorRect.right); cp.y = min(max(g_monitorRect.top, cp.y), g_monitorRect.bottom); g_cursorPos = cp; + DDraw::RealPrimarySurface::scheduleOverlayUpdate(); } auto cp = getRelativeCursorPos(); @@ -140,7 +141,6 @@ namespace break; } - DDraw::RealPrimarySurface::scheduleUpdate(); return 1; } return CallNextHookEx(nullptr, nCode, wParam, lParam); diff --git a/DDrawCompat/Overlay/Control.cpp b/DDrawCompat/Overlay/Control.cpp index abfaa1e..5e6adcb 100644 --- a/DDrawCompat/Overlay/Control.cpp +++ b/DDrawCompat/Overlay/Control.cpp @@ -155,7 +155,6 @@ namespace Overlay if (m_parent && (m_style & WS_TABSTOP)) { m_parent->m_highlightedChild = this; - invalidate(); } } diff --git a/DDrawCompat/Overlay/Window.cpp b/DDrawCompat/Overlay/Window.cpp index 6495a48..f9c17ee 100644 --- a/DDrawCompat/Overlay/Window.cpp +++ b/DDrawCompat/Overlay/Window.cpp @@ -106,7 +106,7 @@ namespace Overlay void Window::invalidate() { m_invalid = true; - DDraw::RealPrimarySurface::scheduleUpdate(); + DDraw::RealPrimarySurface::scheduleOverlayUpdate(); } void Window::setTransparency(int transparency) @@ -136,7 +136,7 @@ namespace Overlay } ShowWindow(m_hwnd, SW_HIDE); } - DDraw::RealPrimarySurface::scheduleUpdate(); + DDraw::RealPrimarySurface::scheduleOverlayUpdate(); } LRESULT CALLBACK Window::staticWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)