diff options
author | Vaxry <[email protected]> | 2024-07-22 19:19:37 +0200 |
---|---|---|
committer | Vaxry <[email protected]> | 2024-07-22 19:19:37 +0200 |
commit | 4c3b03516209a49244a8f044143c1162752b8a7a (patch) | |
tree | c3af74458823cad89ca984ba78df96b4cfa4c128 | |
parent | f17f8b219c699ab52f3d784cad90bdef5bb78188 (diff) | |
download | Hyprland-4c3b03516209a49244a8f044143c1162752b8a7a.tar.gz Hyprland-4c3b03516209a49244a8f044143c1162752b8a7a.zip |
pointer/hw: rollback the swapchain on multiple renders without a commit
fixes the hack
-rw-r--r-- | src/managers/PointerManager.cpp | 21 | ||||
-rw-r--r-- | src/managers/PointerManager.hpp | 6 |
2 files changed, 21 insertions, 6 deletions
diff --git a/src/managers/PointerManager.cpp b/src/managers/PointerManager.cpp index 55bd0509..3b425688 100644 --- a/src/managers/PointerManager.cpp +++ b/src/managers/PointerManager.cpp @@ -24,6 +24,14 @@ CPointerManager::CPointerManager() { }, nullptr); }); + + hooks.monitorPreRender = g_pHookSystem->hookDynamic("preRender", [this](void* self, SCallbackInfo& info, std::any data) { + auto state = stateFor(std::any_cast<CMonitor*>(data)->self.lock()); + if (!state) + return; + + state->cursorRendered = false; + }); } void CPointerManager::lockSoftwareAll() { @@ -373,10 +381,7 @@ SP<Aquamarine::IBuffer> CPointerManager::renderHWCursorBuffer(SP<CPointerManager auto options = state->monitor->cursorSwapchain->currentOptions(); options.size = maxSize; - // TODO: this is a band-aid. If the current cursor image has not yet been committed (no rendering has yet been done) - // we should revert the swapchain and avoid rendering to the front buffer. - // as a band-aid, extend the swapchain to 3 as we sometimes double-render on a cursor shape change. - options.length = 3; + options.length = 2; options.scanout = true; options.cursor = true; options.multigpu = state->monitor->output->getBackend()->preferredAllocator()->drmFD() != g_pCompositor->m_iDRMFD; @@ -389,6 +394,14 @@ SP<Aquamarine::IBuffer> CPointerManager::renderHWCursorBuffer(SP<CPointerManager } } + // if we already rendered the cursor, revert the swapchain to avoid rendering the cursor over + // the current front buffer + // this flag will be reset in the preRender hook, so when we commit this buffer to KMS + if (state->cursorRendered) + state->monitor->cursorSwapchain->rollback(); + + state->cursorRendered = true; + auto buf = state->monitor->cursorSwapchain->next(nullptr); if (!buf) { Debug::log(TRACE, "Failed to acquire a buffer from the cursor swapchain"); diff --git a/src/managers/PointerManager.hpp b/src/managers/PointerManager.hpp index cf4f1a94..4a4c4f61 100644 --- a/src/managers/PointerManager.hpp +++ b/src/managers/PointerManager.hpp @@ -163,8 +163,9 @@ class CPointerManager { int softwareLocks = 0; bool hardwareFailed = false; CBox box; // logical - bool entered = false; - bool hwApplied = false; + bool entered = false; + bool hwApplied = false; + bool cursorRendered = false; SP<Aquamarine::IBuffer> cursorFrontBuffer; }; @@ -177,6 +178,7 @@ class CPointerManager { struct { SP<HOOK_CALLBACK_FN> monitorAdded; + SP<HOOK_CALLBACK_FN> monitorPreRender; } hooks; }; |