diff --git a/src/helpers/Monitor.cpp b/src/helpers/Monitor.cpp index 635427d1..b0ac1a1b 100644 --- a/src/helpers/Monitor.cpp +++ b/src/helpers/Monitor.cpp @@ -396,6 +396,30 @@ int CMonitor::findAvailableDefaultWS() { return INT32_MAX; // shouldn't be reachable } +SP CMonitor::resizeSwapchain(SP swapchain, Vector2D size, bool isCursor) { + if (!swapchain || size != swapchain->currentOptions().size) { + + if (!swapchain) + swapchain = Aquamarine::CSwapchain::create(output->getBackend()->preferredAllocator(), output->getBackend()); + + auto options = swapchain->currentOptions(); + options.size = size; + options.length = 2; + options.scanout = true; + options.cursor = isCursor; + options.multigpu = output->getBackend()->preferredAllocator()->drmFD() != g_pCompositor->m_iDRMFD; + // We do not set the format. If it's unset (DRM_FORMAT_INVALID) then the swapchain will pick for us, + // but if it's set, we don't wanna change it. + + if (!swapchain->reconfigure(options)) { + Debug::log(TRACE, "Failed to reconfigure {} swapchain", isCursor ? "cursor" : "cursor fallback"); + return nullptr; + } + } + + return swapchain; +} + void CMonitor::setupDefaultWS(const SMonitorRule& monitorRule) { // Workspace std::string newDefaultWorkspaceName = ""; @@ -835,6 +859,22 @@ bool CMonitor::attemptDirectScanout() { return true; } +bool CMonitor::resizeCursorSwapchain(Vector2D size) { + auto swapchain = resizeSwapchain(cursorSwapchain, size, true); + if (!cursorSwapchain) + cursorSwapchain = swapchain; + + return !!swapchain; +} + +bool CMonitor::resizeCursorFallbackSwapchain(Vector2D size) { + auto swapchain = resizeSwapchain(cursorFallbackSwapchain, size, false); + if (!cursorFallbackSwapchain) + cursorFallbackSwapchain = swapchain; + + return !!swapchain; +} + CMonitorState::CMonitorState(CMonitor* owner) { m_pOwner = owner; } diff --git a/src/helpers/Monitor.hpp b/src/helpers/Monitor.hpp index 32fc768a..2898d0a8 100644 --- a/src/helpers/Monitor.hpp +++ b/src/helpers/Monitor.hpp @@ -100,6 +100,7 @@ class CMonitor { std::optional forceSize; SP currentMode; SP cursorSwapchain; + SP cursorFallbackSwapchain; bool dpmsStatus = true; bool vrrActive = false; // this can be TRUE even if VRR is not active in the case that this display does not support it. @@ -178,6 +179,8 @@ class CMonitor { CBox logicalBox(); void scheduleDone(); bool attemptDirectScanout(); + bool resizeCursorSwapchain(Vector2D size); + bool resizeCursorFallbackSwapchain(Vector2D size); bool m_bEnabled = false; bool m_bRenderingInitPassed = false; @@ -189,10 +192,11 @@ class CMonitor { } private: - void setupDefaultWS(const SMonitorRule&); - int findAvailableDefaultWS(); + void setupDefaultWS(const SMonitorRule&); + int findAvailableDefaultWS(); + SP resizeSwapchain(SP swapchain, Vector2D size, bool isCursor); - wl_event_source* doneSource = nullptr; + wl_event_source* doneSource = nullptr; struct { CHyprSignalListener frame; diff --git a/src/managers/PointerManager.cpp b/src/managers/PointerManager.cpp index 3b425688..323a354a 100644 --- a/src/managers/PointerManager.cpp +++ b/src/managers/PointerManager.cpp @@ -374,25 +374,8 @@ SP CPointerManager::renderHWCursorBuffer(SPmonitor->cursorSwapchain || maxSize != state->monitor->cursorSwapchain->currentOptions().size) { - - if (!state->monitor->cursorSwapchain) - state->monitor->cursorSwapchain = Aquamarine::CSwapchain::create(state->monitor->output->getBackend()->preferredAllocator(), state->monitor->output->getBackend()); - - auto options = state->monitor->cursorSwapchain->currentOptions(); - options.size = maxSize; - options.length = 2; - options.scanout = true; - options.cursor = true; - options.multigpu = state->monitor->output->getBackend()->preferredAllocator()->drmFD() != g_pCompositor->m_iDRMFD; - // We do not set the format. If it's unset (DRM_FORMAT_INVALID) then the swapchain will pick for us, - // but if it's set, we don't wanna change it. - - if (!state->monitor->cursorSwapchain->reconfigure(options)) { - Debug::log(TRACE, "Failed to reconfigure cursor swapchain"); - return nullptr; - } - } + if (!state->monitor->resizeCursorSwapchain(maxSize)) + return nullptr; // if we already rendered the cursor, revert the swapchain to avoid rendering the cursor over // the current front buffer