From ee0dea62e26812b7f52d788bc29eb3523b9f9761 Mon Sep 17 00:00:00 2001 From: Vaxry Date: Fri, 12 Jul 2024 09:34:30 +0200 Subject: [PATCH] drm/renderer: also use blitting for cursor planes --- include/aquamarine/backend/DRM.hpp | 8 +++- src/backend/drm/DRM.cpp | 59 ++++++++++++++++++++++++------ 2 files changed, 53 insertions(+), 14 deletions(-) diff --git a/include/aquamarine/backend/DRM.hpp b/include/aquamarine/backend/DRM.hpp index 7ff4ed8..66fa69e 100644 --- a/include/aquamarine/backend/DRM.hpp +++ b/include/aquamarine/backend/DRM.hpp @@ -217,7 +217,12 @@ namespace Aquamarine { Hyprutils::Memory::CSharedPointer connector; Hyprutils::Memory::CSharedPointer> frameIdle; - bool lastCommitNoBuffer = true; + struct { + Hyprutils::Memory::CSharedPointer swapchain; + Hyprutils::Memory::CSharedPointer cursorSwapchain; + } mgpu; + + bool lastCommitNoBuffer = true; friend struct SDRMConnector; friend class CDRMLease; @@ -365,7 +370,6 @@ namespace Aquamarine { // multigpu state, only present if this backend is not primary, aka if this->primary != nullptr struct { Hyprutils::Memory::CSharedPointer allocator; - Hyprutils::Memory::CSharedPointer swapchain; Hyprutils::Memory::CSharedPointer renderer; } mgpu; diff --git a/src/backend/drm/DRM.cpp b/src/backend/drm/DRM.cpp index 076e7fe..4cc05d1 100644 --- a/src/backend/drm/DRM.cpp +++ b/src/backend/drm/DRM.cpp @@ -482,13 +482,6 @@ bool Aquamarine::CDRMBackend::initMgpu() { return false; } - mgpu.swapchain = CSwapchain::create(mgpu.allocator, self.lock()); - - if (!mgpu.swapchain) { - backend->log(AQ_LOG_ERROR, "drm: initMgpu: no swapchain"); - return false; - } - mgpu.renderer = CDRMRenderer::attempt(gpu->fd, backend.lock()); if (!mgpu.renderer) { @@ -1358,14 +1351,19 @@ bool Aquamarine::CDRMOutput::commitState(bool onlyTest) { if (backend->shouldBlit()) { TRACE(backend->backend->log(AQ_LOG_TRACE, "drm: Backend requires blit, blitting")); + if (!mgpu.swapchain) { + TRACE(backend->backend->log(AQ_LOG_TRACE, "drm: No swapchain for blit, creating")); + mgpu.swapchain = CSwapchain::create(backend->mgpu.allocator, backend.lock()); + } + auto OPTIONS = swapchain->currentOptions(); OPTIONS.multigpu = false; // this is not a shared swapchain, and additionally, don't make it linear, nvidia would be mad - if (!backend->mgpu.swapchain->reconfigure(OPTIONS)) { + if (!mgpu.swapchain->reconfigure(OPTIONS)) { backend->backend->log(AQ_LOG_ERROR, "drm: Backend requires blit, but the mgpu swapchain failed reconfiguring"); return false; } - auto NEWAQBUF = backend->mgpu.swapchain->next(nullptr); + auto NEWAQBUF = mgpu.swapchain->next(nullptr); if (!backend->mgpu.renderer->blit(STATE.buffer, NEWAQBUF)) { backend->backend->log(AQ_LOG_ERROR, "drm: Backend requires blit, but blit failed"); return false; @@ -1446,17 +1444,54 @@ SP Aquamarine::CDRMOutput::getBackend() { } bool Aquamarine::CDRMOutput::setCursor(SP buffer, const Vector2D& hotspot) { + if (!buffer->dmabuf().success) { + backend->backend->log(AQ_LOG_ERROR, "drm: Cursor buffer has to be a dmabuf"); + return false; + } + if (!buffer) setCursorVisible(false); else { - cursorHotspot = hotspot; - bool isNew = false; - auto fb = CDRMFB::create(buffer, backend, &isNew); + SP fb; + + if (backend->primary) { + TRACE(backend->backend->log(AQ_LOG_TRACE, "drm: Backend requires cursor blit, blitting")); + + if (!mgpu.cursorSwapchain) { + TRACE(backend->backend->log(AQ_LOG_TRACE, "drm: No cursorSwapchain for blit, creating")); + mgpu.cursorSwapchain = CSwapchain::create(backend->mgpu.allocator, backend.lock()); + } + + auto OPTIONS = mgpu.cursorSwapchain->currentOptions(); + OPTIONS.multigpu = false; + OPTIONS.scanout = true; + OPTIONS.cursor = true; + OPTIONS.format = buffer->dmabuf().format; + OPTIONS.size = buffer->dmabuf().size; + OPTIONS.length = 2; + + if (!mgpu.cursorSwapchain->reconfigure(OPTIONS)) { + backend->backend->log(AQ_LOG_ERROR, "drm: Backend requires blit, but the mgpu cursorSwapchain failed reconfiguring"); + return false; + } + + auto NEWAQBUF = mgpu.cursorSwapchain->next(nullptr); + if (!backend->mgpu.renderer->blit(buffer, NEWAQBUF)) { + backend->backend->log(AQ_LOG_ERROR, "drm: Backend requires blit, but cursor blit failed"); + return false; + } + + fb = CDRMFB::create(NEWAQBUF, backend, nullptr); // will return attachment if present + } else + fb = CDRMFB::create(buffer, backend, nullptr); + if (!fb) { backend->backend->log(AQ_LOG_ERROR, "drm: Cursor buffer failed to import to KMS"); return false; } + cursorHotspot = hotspot; + backend->backend->log(AQ_LOG_DEBUG, std::format("drm: Cursor buffer imported into KMS with id {}", fb->id)); connector->crtc->pendingCursor = fb;