core/surface/buffer: Buffer lock/release fixes (#7110)

This commit is contained in:
Vaxry 2024-07-31 20:47:26 +01:00 committed by GitHub
parent 5489682799
commit 37e1411e8d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
27 changed files with 304 additions and 129 deletions

View file

@ -1,5 +1,10 @@
#include "Buffer.hpp"
IHLBuffer::~IHLBuffer() {
if (locked() && resource)
sendRelease();
}
void IHLBuffer::sendRelease() {
resource->sendRelease();
}
@ -8,3 +13,54 @@ void IHLBuffer::sendReleaseWithSurface(SP<CWLSurfaceResource> surf) {
if (resource && resource->good())
resource->sendReleaseWithSurface(surf);
}
void IHLBuffer::lock() {
nLocks++;
}
void IHLBuffer::unlock() {
nLocks--;
ASSERT(nLocks >= 0);
if (nLocks == 0)
sendRelease();
}
void IHLBuffer::unlockWithSurface(SP<CWLSurfaceResource> surf) {
nLocks--;
ASSERT(nLocks >= 0);
if (nLocks == 0)
sendReleaseWithSurface(surf);
}
bool IHLBuffer::locked() {
return nLocks > 0;
}
void IHLBuffer::unlockOnBufferRelease(WP<CWLSurfaceResource> surf) {
unlockSurface = surf;
hlEvents.backendRelease = events.backendRelease.registerListener([this](std::any data) {
if (unlockSurface.expired())
unlock();
else
unlockWithSurface(unlockSurface.lock());
hlEvents.backendRelease.reset();
});
}
CHLBufferReference::CHLBufferReference(SP<IHLBuffer> buffer_, SP<CWLSurfaceResource> surface_) : buffer(buffer_), surface(surface_) {
buffer->lock();
}
CHLBufferReference::~CHLBufferReference() {
if (buffer.expired())
return;
if (surface)
buffer->unlockWithSurface(surface.lock());
else
buffer->unlock();
}

View file

@ -8,9 +8,7 @@
class IHLBuffer : public Aquamarine::IBuffer {
public:
virtual ~IHLBuffer() {
;
}
virtual ~IHLBuffer();
virtual Aquamarine::eBufferCapability caps() = 0;
virtual Aquamarine::eBufferType type() = 0;
virtual void update(const CRegion& damage) = 0;
@ -18,6 +16,12 @@ class IHLBuffer : public Aquamarine::IBuffer {
virtual bool good() = 0;
virtual void sendRelease();
virtual void sendReleaseWithSurface(SP<CWLSurfaceResource>);
virtual void lock();
virtual void unlock();
virtual void unlockWithSurface(SP<CWLSurfaceResource> surf);
virtual bool locked();
void unlockOnBufferRelease(WP<CWLSurfaceResource> surf /* optional */);
SP<CTexture> texture;
bool opaque = false;
@ -26,4 +30,22 @@ class IHLBuffer : public Aquamarine::IBuffer {
struct {
CHyprSignalListener backendRelease;
} hlEvents;
private:
int nLocks = 0;
WP<CWLSurfaceResource> unlockSurface;
};
// for ref-counting. Releases in ~dtor
// surface optional
class CHLBufferReference {
public:
CHLBufferReference(SP<IHLBuffer> buffer, SP<CWLSurfaceResource> surface);
~CHLBufferReference();
WP<IHLBuffer> buffer;
private:
WP<CWLSurfaceResource> surface;
};

View file

@ -6,6 +6,7 @@ enum eSurfaceRole {
SURFACE_ROLE_LAYER_SHELL,
SURFACE_ROLE_EASTER_EGG,
SURFACE_ROLE_SUBSURFACE,
SURFACE_ROLE_CURSOR,
};
class ISurfaceRole {

View file

@ -29,7 +29,6 @@ bool CWLBufferResource::good() {
}
void CWLBufferResource::sendRelease() {
released = true;
resource->sendRelease();
}

View file

@ -24,8 +24,6 @@ class CWLBufferResource {
WP<CWLBufferResource> self;
bool released = false;
private:
CWLBufferResource(SP<CWlBuffer> resource_);