From 5f60fc7d00eb08ee39cac1f5eceeb97ffbea0e7f Mon Sep 17 00:00:00 2001 From: Ikalco <73481042+ikalco@users.noreply.github.com> Date: Mon, 17 Mar 2025 16:06:41 -0500 Subject: [PATCH] renderer: only commit hw cursor stuff if needed (#9654) --- src/helpers/Monitor.cpp | 29 ++++++++++++++++++++++++----- src/helpers/Monitor.hpp | 1 + src/managers/PointerManager.cpp | 4 ++++ 3 files changed, 29 insertions(+), 5 deletions(-) diff --git a/src/helpers/Monitor.cpp b/src/helpers/Monitor.cpp index d3c0549cd..2af548d20 100644 --- a/src/helpers/Monitor.cpp +++ b/src/helpers/Monitor.cpp @@ -1355,8 +1355,26 @@ bool CMonitor::attemptDirectScanout() { Debug::log(TRACE, "attemptDirectScanout: surface {:x} passed, will attempt, buffer {}", (uintptr_t)PSURFACE.get(), (uintptr_t)PSURFACE->current.buffer->buffer.get()); - auto PBUFFER = PSURFACE->current.buffer->buffer.lock(); - bool SAMEBUFFER = PBUFFER == output->state->state().buffer; + auto PBUFFER = PSURFACE->current.buffer->buffer.lock(); + + if (PBUFFER == output->state->state().buffer) { + if (scanoutNeedsCursorUpdate) { + if (!state.test()) { + Debug::log(TRACE, "attemptDirectScanout: failed basic test"); + return false; + } + + if (!output->commit()) { + Debug::log(TRACE, "attemptDirectScanout: failed to commit cursor update"); + lastScanout.reset(); + return false; + } + + scanoutNeedsCursorUpdate = false; + } + + return true; + } // FIXME: make sure the buffer actually follows the available scanout dmabuf formats // and comes from the appropriate device. This may implode on multi-gpu!! @@ -1370,8 +1388,7 @@ bool CMonitor::attemptDirectScanout() { drmFormat = params.format; } - if (!SAMEBUFFER) - output->state->setBuffer(PBUFFER); + output->state->setBuffer(PBUFFER); output->state->setPresentationMode(tearingState.activelyTearing ? Aquamarine::eOutputPresentationMode::AQ_OUTPUT_PRESENTATION_IMMEDIATE : Aquamarine::eOutputPresentationMode::AQ_OUTPUT_PRESENTATION_VSYNC); @@ -1426,7 +1443,9 @@ bool CMonitor::attemptDirectScanout() { Debug::log(LOG, "Entered a direct scanout to {:x}: \"{}\"", (uintptr_t)PCANDIDATE.get(), PCANDIDATE->m_szTitle); } - if (!PBUFFER->lockedByBackend || PBUFFER->hlEvents.backendRelease || SAMEBUFFER) + scanoutNeedsCursorUpdate = false; + + if (!PBUFFER->lockedByBackend || PBUFFER->hlEvents.backendRelease) return true; // lock buffer while DRM/KMS is using it, then release it when page flip happens since DRM/KMS should be done by then diff --git a/src/helpers/Monitor.hpp b/src/helpers/Monitor.hpp index 36959aa28..a5ccdbb9b 100644 --- a/src/helpers/Monitor.hpp +++ b/src/helpers/Monitor.hpp @@ -158,6 +158,7 @@ class CMonitor { // for direct scanout PHLWINDOWREF lastScanout; + bool scanoutNeedsCursorUpdate = false; struct { bool canTear = false; diff --git a/src/managers/PointerManager.cpp b/src/managers/PointerManager.cpp index 4f909714e..e4f242303 100644 --- a/src/managers/PointerManager.cpp +++ b/src/managers/PointerManager.cpp @@ -323,6 +323,8 @@ void CPointerManager::onCursorMoved() { const auto CURSORPOS = getCursorPosForMonitor(m); m->output->moveCursor(CURSORPOS, m->shouldSkipScheduleFrameOnMouseEvent()); + + state->monitor->scanoutNeedsCursorUpdate = true; } if (recalc) @@ -382,6 +384,8 @@ bool CPointerManager::setHWCursorBuffer(SP state, SPmonitor->shouldSkipScheduleFrameOnMouseEvent()) g_pCompositor->scheduleFrameForMonitor(state->monitor.lock(), Aquamarine::IOutput::AQ_SCHEDULE_CURSOR_SHAPE); + state->monitor->scanoutNeedsCursorUpdate = true; + return true; }