render: properly release rendered buffers (#9807)

* cleanup eglSync

* properly release buffers in renderer

* add renderingDoneCallback and use it in screencopy

* use static constructor for CEGLSync
This commit is contained in:
Ikalco 2025-04-30 11:35:25 -05:00 committed by GitHub
parent 5d005f11fa
commit 2ee5118d7a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
14 changed files with 119 additions and 161 deletions

View file

@ -105,10 +105,8 @@ CDRMSyncobjSurfaceResource::CDRMSyncobjSurfaceResource(UP<CWpLinuxDrmSyncobjSurf
surface->pending.acquire = pendingAcquire;
pendingAcquire = {};
surface->pending.buffer.release = pendingRelease;
pendingRelease = {};
surface->pending.buffer->syncReleaser = surface->pending.buffer.release.createSyncRelease();
surface->pending.buffer->addReleasePoint(pendingRelease);
pendingRelease = {};
});
}

View file

@ -221,21 +221,11 @@ void CScreencopyFrame::copyDmabuf(std::function<void(bool)> callback) {
}
g_pHyprOpenGL->m_RenderData.blockScreenShader = true;
g_pHyprRenderer->endRender();
auto explicitOptions = g_pHyprRenderer->getExplicitSyncSettings(pMonitor->output);
if (pMonitor->inTimeline && explicitOptions.explicitEnabled) {
if (pMonitor->inTimeline->addWaiter(
[callback, sync = pMonitor->eglSync]() {
LOGM(TRACE, "Copied frame via dma with explicit sync");
callback(true);
},
pMonitor->inTimelinePoint, 0))
return;
// on explicit sync failure, fallthrough to immediate callback
}
LOGM(TRACE, "Copied frame via dma");
callback(true);
g_pHyprRenderer->endRender([callback]() {
LOGM(TRACE, "Copied frame via dma");
callback(true);
});
}
bool CScreencopyFrame::copyShm() {

View file

@ -7,7 +7,6 @@
#include "Subcompositor.hpp"
#include "../Viewporter.hpp"
#include "../../helpers/Monitor.hpp"
#include "../../helpers/sync/SyncReleaser.hpp"
#include "../PresentationTime.hpp"
#include "../DRMSyncobj.hpp"
#include "../types/DMABuffer.hpp"
@ -518,8 +517,7 @@ void CWLSurfaceResource::commitState(SSurfaceState& state) {
nullptr);
}
// release the buffer if it's synchronous (SHM) as update() has done everything thats needed
// so we can let the app know we're done.
// release the buffer if it's synchronous (SHM) as updateSynchronousTexture() has copied the buffer data to a GPU tex
// if it doesn't have a role, we can't release it yet, in case it gets turned into a cursor.
if (current.buffer && current.buffer->isSynchronous() && role->role() != SURFACE_ROLE_UNASSIGNED)
dropCurrentBuffer();
@ -572,12 +570,6 @@ void CWLSurfaceResource::presentFeedback(const Time::steady_tp& when, PHLMONITOR
else
FEEDBACK->presented();
PROTO::presentation->queueData(FEEDBACK);
if (!pMonitor || !pMonitor->inTimeline || !syncobj)
return;
// attach explicit sync
g_pHyprRenderer->explicitPresented.emplace_back(self.lock());
}
CWLCompositorResource::CWLCompositorResource(SP<CWlCompositor> resource_) : resource(resource_) {

View file

@ -7,6 +7,7 @@ IHLBuffer::~IHLBuffer() {
void IHLBuffer::sendRelease() {
resource->sendRelease();
syncReleasers.clear();
}
void IHLBuffer::lock() {
@ -18,10 +19,8 @@ void IHLBuffer::unlock() {
ASSERT(nLocks >= 0);
if (nLocks == 0) {
if (nLocks == 0)
sendRelease();
syncReleaser.reset();
}
}
bool IHLBuffer::locked() {
@ -40,11 +39,17 @@ void IHLBuffer::onBackendRelease(const std::function<void()>& fn) {
});
}
void IHLBuffer::addReleasePoint(CDRMSyncPointState& point) {
ASSERT(locked());
if (point)
syncReleasers.emplace_back(point.createSyncRelease());
}
CHLBufferReference::CHLBufferReference() : buffer(nullptr) {
;
}
CHLBufferReference::CHLBufferReference(const CHLBufferReference& other) : release(other.release), buffer(other.buffer) {
CHLBufferReference::CHLBufferReference(const CHLBufferReference& other) : buffer(other.buffer) {
if (buffer)
buffer->lock();
}
@ -64,8 +69,7 @@ CHLBufferReference& CHLBufferReference::operator=(const CHLBufferReference& othe
other.buffer->lock();
if (buffer)
buffer->unlock();
buffer = other.buffer;
release = other.release;
buffer = other.buffer;
return *this;
}

View file

@ -24,11 +24,12 @@ class IHLBuffer : public Aquamarine::IBuffer {
virtual bool locked();
void onBackendRelease(const std::function<void()>& fn);
void addReleasePoint(CDRMSyncPointState& point);
SP<CTexture> texture;
bool opaque = false;
SP<CWLBufferResource> resource;
UP<CSyncReleaser> syncReleaser;
std::vector<UP<CSyncReleaser>> syncReleasers;
struct {
CHyprSignalListener backendRelease;
@ -57,8 +58,7 @@ class CHLBufferReference {
operator bool() const;
// unlock and drop the buffer without sending release
void drop();
void drop();
CDRMSyncPointState release;
SP<IHLBuffer> buffer;
SP<IHLBuffer> buffer;
};