diff --git a/include/aquamarine/backend/Backend.hpp b/include/aquamarine/backend/Backend.hpp index 7da8039..f5dcbbf 100644 --- a/include/aquamarine/backend/Backend.hpp +++ b/include/aquamarine/backend/Backend.hpp @@ -1,6 +1,7 @@ #pragma once #include +#include #include #include #include @@ -79,6 +80,7 @@ namespace Aquamarine { virtual Hyprutils::Memory::CSharedPointer preferredAllocator() = 0; virtual std::vector getRenderableFormats(); // empty = use getRenderFormats virtual std::vector> getAllocators() = 0; + virtual Hyprutils::Memory::CWeakPointer getPrimary() = 0; }; class CBackend { diff --git a/include/aquamarine/backend/DRM.hpp b/include/aquamarine/backend/DRM.hpp index ad5f3b5..7a04e43 100644 --- a/include/aquamarine/backend/DRM.hpp +++ b/include/aquamarine/backend/DRM.hpp @@ -369,6 +369,7 @@ namespace Aquamarine { virtual Hyprutils::Memory::CSharedPointer preferredAllocator(); virtual std::vector getRenderableFormats(); virtual std::vector> getAllocators(); + virtual Hyprutils::Memory::CWeakPointer getPrimary(); Hyprutils::Memory::CWeakPointer self; diff --git a/include/aquamarine/backend/Headless.hpp b/include/aquamarine/backend/Headless.hpp index aee26a4..1de6a0d 100644 --- a/include/aquamarine/backend/Headless.hpp +++ b/include/aquamarine/backend/Headless.hpp @@ -49,6 +49,7 @@ namespace Aquamarine { virtual bool createOutput(const std::string& name = ""); virtual Hyprutils::Memory::CSharedPointer preferredAllocator(); virtual std::vector> getAllocators(); + virtual Hyprutils::Memory::CWeakPointer getPrimary(); Hyprutils::Memory::CWeakPointer self; diff --git a/include/aquamarine/backend/Wayland.hpp b/include/aquamarine/backend/Wayland.hpp index 33d6502..94d75da 100644 --- a/include/aquamarine/backend/Wayland.hpp +++ b/include/aquamarine/backend/Wayland.hpp @@ -136,6 +136,7 @@ namespace Aquamarine { virtual bool createOutput(const std::string& name = ""); virtual Hyprutils::Memory::CSharedPointer preferredAllocator(); virtual std::vector> getAllocators(); + virtual Hyprutils::Memory::CWeakPointer getPrimary(); Hyprutils::Memory::CWeakPointer self; diff --git a/src/allocator/GBM.cpp b/src/allocator/GBM.cpp index f4ed015..ac64939 100644 --- a/src/allocator/GBM.cpp +++ b/src/allocator/GBM.cpp @@ -72,7 +72,7 @@ Aquamarine::CGBMBuffer::CGBMBuffer(const SAllocatorBufferParams& params, Hypruti const bool CURSOR = params.cursor && params.scanout; const bool MULTIGPU = params.multigpu && params.scanout; - const bool EXPLICIT_SCANOUT = params.scanout && swapchain->currentOptions().scanoutOutput; + const bool EXPLICIT_SCANOUT = params.scanout && swapchain->currentOptions().scanoutOutput && !params.multigpu; TRACE(allocator->backend->log(AQ_LOG_TRACE, std::format("GBM: Allocating a buffer: size {}, format {}, cursor: {}, multigpu: {}, scanout: {}", attrs.size, fourccToName(attrs.format), CURSOR, @@ -153,7 +153,7 @@ Aquamarine::CGBMBuffer::CGBMBuffer(const SAllocatorBufferParams& params, Hypruti } uint32_t flags = GBM_BO_USE_RENDERING; - if (params.scanout) + if (params.scanout && !MULTIGPU) flags |= GBM_BO_USE_SCANOUT; uint64_t modifier = DRM_FORMAT_MOD_INVALID; @@ -223,7 +223,7 @@ Aquamarine::CGBMBuffer::CGBMBuffer(const SAllocatorBufferParams& params, Hypruti free(modName); - if (params.scanout && swapchain->backendImpl->type() == AQ_BACKEND_DRM) { + if (params.scanout && !MULTIGPU && swapchain->backendImpl->type() == AQ_BACKEND_DRM) { // clear the buffer using the DRM renderer to avoid uninitialized mem auto impl = (CDRMBackend*)swapchain->backendImpl.get(); if (impl->rendererState.renderer) diff --git a/src/backend/Headless.cpp b/src/backend/Headless.cpp index e764b2a..be57871 100644 --- a/src/backend/Headless.cpp +++ b/src/backend/Headless.cpp @@ -211,6 +211,10 @@ std::vector> Aquamarine::CHeadlessBackend::getAllocators() { return {backend->primaryAllocator}; } +Hyprutils::Memory::CWeakPointer Aquamarine::CHeadlessBackend::getPrimary() { + return {}; +} + bool Aquamarine::CHeadlessBackend::CTimer::expired() { return std::chrono::steady_clock::now() > when; } diff --git a/src/backend/Wayland.cpp b/src/backend/Wayland.cpp index 1a812fe..ea89a22 100644 --- a/src/backend/Wayland.cpp +++ b/src/backend/Wayland.cpp @@ -447,6 +447,10 @@ std::vector> Aquamarine::CWaylandBackend::getAllocators() { return {backend->primaryAllocator}; } +Hyprutils::Memory::CWeakPointer Aquamarine::CWaylandBackend::getPrimary() { + return {}; +} + Aquamarine::CWaylandOutput::CWaylandOutput(const std::string& name_, Hyprutils::Memory::CWeakPointer backend_) : backend(backend_) { name = name_; diff --git a/src/backend/drm/DRM.cpp b/src/backend/drm/DRM.cpp index 68d5d77..f6c56d9 100644 --- a/src/backend/drm/DRM.cpp +++ b/src/backend/drm/DRM.cpp @@ -993,7 +993,8 @@ void Aquamarine::CDRMBackend::onReady() { backend->log(AQ_LOG_DEBUG, std::format("drm: onReady: connector {} has output name {}", c->id, c->output->name)); // swapchain has to be created here because allocator is absent in connect if not ready - c->output->swapchain = CSwapchain::create(backend->primaryAllocator, self.lock()); + auto primaryBackend = primary ? primary : self; + c->output->swapchain = CSwapchain::create(backend->primaryAllocator, primaryBackend.lock()); c->output->swapchain->reconfigure(SSwapchainOptions{.length = 0, .scanout = true, .multigpu = !!primary, .scanoutOutput = c->output}); // mark the swapchain for scanout c->output->needsFrame = true; @@ -1073,6 +1074,10 @@ std::vector> Aquamarine::CDRMBackend::getAllocators() { return {backend->primaryAllocator, dumbAllocator}; } +Hyprutils::Memory::CWeakPointer Aquamarine::CDRMBackend::getPrimary() { + return primary; +} + bool Aquamarine::SDRMPlane::init(drmModePlane* plane) { id = plane->plane_id; @@ -1467,7 +1472,8 @@ void Aquamarine::SDRMConnector::connect(drmModeConnector* connector) { if (!backend->backend->ready) return; - output->swapchain = CSwapchain::create(backend->backend->primaryAllocator, backend->self.lock()); + auto primaryBackend = backend->primary ? backend->primary : backend; + output->swapchain = CSwapchain::create(backend->backend->primaryAllocator, primaryBackend.lock()); 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));