aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorVaxry <[email protected]>2024-07-22 19:19:37 +0200
committerVaxry <[email protected]>2024-07-22 19:19:37 +0200
commit4c3b03516209a49244a8f044143c1162752b8a7a (patch)
treec3af74458823cad89ca984ba78df96b4cfa4c128
parentf17f8b219c699ab52f3d784cad90bdef5bb78188 (diff)
downloadHyprland-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.cpp21
-rw-r--r--src/managers/PointerManager.hpp6
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;
};