From 865cd94f97d1a6f0bb3391dc40ce4608e50d7acd Mon Sep 17 00:00:00 2001 From: Vaxry Date: Sat, 31 Aug 2024 13:52:04 +0200 Subject: [PATCH] gbm/drm: conform to different scanout requirements for different planes ref https://github.com/hyprwm/Hyprland/issues/7005 --- include/aquamarine/allocator/Swapchain.hpp | 2 ++ src/allocator/GBM.cpp | 12 +++++++++--- src/backend/drm/DRM.cpp | 4 ++-- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/include/aquamarine/allocator/Swapchain.hpp b/include/aquamarine/allocator/Swapchain.hpp index 0e49025..5f10f81 100644 --- a/include/aquamarine/allocator/Swapchain.hpp +++ b/include/aquamarine/allocator/Swapchain.hpp @@ -5,12 +5,14 @@ namespace Aquamarine { class IBackendImplementation; + class IOutput; struct SSwapchainOptions { size_t length = 0; Hyprutils::Math::Vector2D size; uint32_t format = DRM_FORMAT_INVALID; // if you leave this on invalid, the swapchain will choose an appropriate format (and modifier) for you. bool scanout = false, cursor = false /* requires scanout = true */, multigpu = false /* if true, will force linear */; + Hyprutils::Memory::CWeakPointer scanoutOutput; }; class CSwapchain { diff --git a/src/allocator/GBM.cpp b/src/allocator/GBM.cpp index e108a5d..606c8f2 100644 --- a/src/allocator/GBM.cpp +++ b/src/allocator/GBM.cpp @@ -72,14 +72,20 @@ Aquamarine::CGBMBuffer::CGBMBuffer(const SAllocatorBufferParams& params, Hypruti attrs.format = params.format; size = attrs.size; - const bool CURSOR = params.cursor && params.scanout; - const bool MULTIGPU = params.multigpu && params.scanout; + const bool CURSOR = params.cursor && params.scanout; + const bool MULTIGPU = params.multigpu && params.scanout; + const bool EXPLICIT_SCANOUT = params.scanout && swapchain->currentOptions().scanoutOutput; TRACE(allocator->backend->log(AQ_LOG_TRACE, std::format("GBM: Allocating a buffer: size {}, format {}, cursor: {}, multigpu: {}, scanout: {}", attrs.size, fourccToName(attrs.format), CURSOR, MULTIGPU, params.scanout))); - const auto FORMATS = CURSOR ? swapchain->backendImpl->getCursorFormats() : swapchain->backendImpl->getRenderFormats(); + if (EXPLICIT_SCANOUT) + TRACE(allocator->backend->log( + AQ_LOG_TRACE, std::format("GBM: Explicit scanout output, output has {} explicit formats", swapchain->currentOptions().scanoutOutput->getRenderFormats().size()))); + + const auto FORMATS = CURSOR ? swapchain->backendImpl->getCursorFormats() : + (EXPLICIT_SCANOUT ? swapchain->currentOptions().scanoutOutput->getRenderFormats() : swapchain->backendImpl->getRenderFormats()); const auto RENDERABLE = swapchain->backendImpl->getRenderableFormats(); TRACE(allocator->backend->log(AQ_LOG_TRACE, std::format("GBM: Available formats: {}", FORMATS.size()))); diff --git a/src/backend/drm/DRM.cpp b/src/backend/drm/DRM.cpp index 619cc48..5606ecd 100644 --- a/src/backend/drm/DRM.cpp +++ b/src/backend/drm/DRM.cpp @@ -881,7 +881,7 @@ void Aquamarine::CDRMBackend::onReady() { // swapchain has to be created here because allocator is absent in connect if not ready c->output->swapchain = CSwapchain::create(backend->primaryAllocator, self.lock()); - c->output->swapchain->reconfigure(SSwapchainOptions{.length = 0, .scanout = true, .multigpu = !!primary}); // mark the swapchain for scanout + c->output->swapchain->reconfigure(SSwapchainOptions{.length = 0, .scanout = true, .multigpu = !!primary, .scanoutOutput = c->output}); // mark the swapchain for scanout c->output->needsFrame = true; backend->events.newOutput.emit(SP(c->output)); @@ -1283,7 +1283,7 @@ void Aquamarine::SDRMConnector::connect(drmModeConnector* connector) { return; output->swapchain = CSwapchain::create(backend->backend->primaryAllocator, backend->self.lock()); - output->swapchain->reconfigure(SSwapchainOptions{.length = 0, .scanout = true, .multigpu = !!backend->primary}); // mark the swapchain for scanout + output->swapchain->reconfigure(SSwapchainOptions{.length = 0, .scanout = true, .multigpu = !!backend->primary, .scanoutOutput = output}); // mark the swapchain for scanout output->needsFrame = true; backend->backend->events.newOutput.emit(SP(output)); output->scheduleFrame(IOutput::AQ_SCHEDULE_NEW_CONNECTOR);