diff --git a/include/aquamarine/backend/DRM.hpp b/include/aquamarine/backend/DRM.hpp index b8a7e5f..eb60891 100644 --- a/include/aquamarine/backend/DRM.hpp +++ b/include/aquamarine/backend/DRM.hpp @@ -86,12 +86,19 @@ namespace Aquamarine { Hyprutils::Memory::CWeakPointer backend; std::array boHandles = {0, 0, 0, 0}; + // true if the original buffer is gone and this has been released. + bool dead = false; + private: CDRMFB(Hyprutils::Memory::CSharedPointer buffer_, Hyprutils::Memory::CWeakPointer backend_); uint32_t submitBuffer(); void import(); bool dropped = false, handlesClosed = false; + + struct { + Hyprutils::Signal::CHyprSignalListener destroyBuffer; + } listeners; }; struct SDRMLayer { diff --git a/src/allocator/GBM.cpp b/src/allocator/GBM.cpp index 312e587..d04adec 100644 --- a/src/allocator/GBM.cpp +++ b/src/allocator/GBM.cpp @@ -53,8 +53,7 @@ static SDRMFormat guessFormatFrom(std::vector formats, bool cursor) } Aquamarine::CGBMBuffer::CGBMBuffer(const SAllocatorBufferParams& params, Hyprutils::Memory::CWeakPointer allocator_, - Hyprutils::Memory::CSharedPointer swapchain) : - allocator(allocator_) { + Hyprutils::Memory::CSharedPointer swapchain) : allocator(allocator_) { if (!allocator) return; diff --git a/src/backend/drm/DRM.cpp b/src/backend/drm/DRM.cpp index 8ec94e8..dc6435d 100644 --- a/src/backend/drm/DRM.cpp +++ b/src/backend/drm/DRM.cpp @@ -1308,6 +1308,11 @@ bool Aquamarine::CDRMOutput::commitState(bool onlyTest) { return false; } + if (drmFB->dead) { + backend->backend->log(AQ_LOG_ERROR, "drm: KMS buffer is dead?!"); + return false; + } + if (!isNew && backend->primary) { // this is not a new buffer, and we are not on a primary GPU, which means // this buffer lives on the primary. We need to re-import it to update @@ -1507,6 +1512,13 @@ void Aquamarine::CDRMFB::import() { // FIXME: why does this implode when it doesnt on wlroots or kwin? // closeHandles(); + + listeners.destroyBuffer = buffer->events.destroy.registerListener([this](std::any d) { + drop(); + dead = true; + id = 0; + boHandles = {0, 0, 0, 0}; + }); } void Aquamarine::CDRMFB::reimport() {