aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorvaxerski <[email protected]>2024-07-27 17:03:49 +0200
committervaxerski <[email protected]>2024-07-27 17:04:03 +0200
commitdaed75219fa7b4ec345337ec99f816e94bda338c (patch)
treeb49fed0c39c3e43168bce2ba9a45a8ef91a1d4d8
parentec672b1ab95e341a0dcb6679592ae4e5eea9b1cf (diff)
downloadHyprland-daed75219fa7b4ec345337ec99f816e94bda338c.tar.gz
Hyprland-daed75219fa7b4ec345337ec99f816e94bda338c.zip
wayland/compositor: fixup double buffer releases
fixes #7043
-rw-r--r--src/protocols/core/Compositor.cpp19
-rw-r--r--src/protocols/core/Compositor.hpp3
-rw-r--r--src/protocols/types/WLBuffer.cpp1
-rw-r--r--src/protocols/types/WLBuffer.hpp2
4 files changed, 11 insertions, 14 deletions
diff --git a/src/protocols/core/Compositor.cpp b/src/protocols/core/Compositor.cpp
index a31b1fb4..76907cc2 100644
--- a/src/protocols/core/Compositor.cpp
+++ b/src/protocols/core/Compositor.cpp
@@ -79,6 +79,8 @@ CWLSurfaceResource::CWLSurfaceResource(SP<CWlSurface> resource_) : resource(reso
pending.buffer = res && res->buffer ? res->buffer.lock() : nullptr;
pending.size = res && res->buffer ? res->buffer->size : Vector2D{};
pending.texture = res && res->buffer ? res->buffer->texture : nullptr;
+ if (res)
+ res->released = false;
}
Vector2D oldBufSize = current.buffer ? current.buffer->size : Vector2D{};
@@ -86,8 +88,6 @@ CWLSurfaceResource::CWLSurfaceResource(SP<CWlSurface> resource_) : resource(reso
if (oldBufSize != newBufSize || current.buffer != pending.buffer)
pending.bufferDamage = CBox{{}, {INT32_MAX, INT32_MAX}};
-
- bufferReleased = false;
});
resource->setCommit([this](CWlSurface* r) {
@@ -340,9 +340,9 @@ void CWLSurfaceResource::unmap() {
// release the buffers.
// this is necessary for XWayland to function correctly,
// as it does not unmap via the traditional commit(null buffer) method, but via the X11 protocol.
- if (!bufferReleased && current.buffer)
+ if (current.buffer && !current.buffer->resource->released)
current.buffer->sendRelease();
- if (pending.buffer)
+ if (pending.buffer && !pending.buffer->resource->released)
pending.buffer->sendRelease();
pending.buffer.reset();
@@ -420,15 +420,13 @@ void CWLSurfaceResource::commitPendingState() {
if (current.buffer && current.buffer->texture)
current.buffer->texture->m_eTransform = wlTransformToHyprutils(current.transform);
- if (current.buffer && !bufferReleased) {
+ if (current.buffer && !current.buffer->resource->released) {
current.buffer->update(accumulateCurrentBufferDamage());
// release the buffer if it's synchronous as update() has done everything thats needed
// so we can let the app know we're done.
- if (current.buffer->isSynchronous()) {
+ if (current.buffer->isSynchronous())
current.buffer->sendReleaseWithSurface(self.lock());
- bufferReleased = true;
- }
}
// TODO: we should _accumulate_ and not replace above if sync
@@ -453,7 +451,7 @@ void CWLSurfaceResource::commitPendingState() {
}
// for async buffers, we can only release the buffer once we are unrefing it from current.
- if (previousBuffer && !previousBuffer->isSynchronous() && !bufferReleased) {
+ if (previousBuffer && !previousBuffer->isSynchronous() && !previousBuffer->resource->released) {
if (previousBuffer->lockedByBackend) {
previousBuffer->hlEvents.backendRelease = previousBuffer->events.backendRelease.registerListener([this, previousBuffer](std::any data) {
if (!self.expired()) // could be dead in the dtor
@@ -461,12 +459,11 @@ void CWLSurfaceResource::commitPendingState() {
else
previousBuffer->sendRelease();
previousBuffer->hlEvents.backendRelease.reset();
- bufferReleased = true;
});
} else
previousBuffer->sendReleaseWithSurface(self.lock());
- bufferReleased = true;
+ previousBuffer->resource->released = true; // set it here regardless so we dont set more listeners for backendRelease
}
}
diff --git a/src/protocols/core/Compositor.hpp b/src/protocols/core/Compositor.hpp
index 5e6413c8..85bd0d37 100644
--- a/src/protocols/core/Compositor.hpp
+++ b/src/protocols/core/Compositor.hpp
@@ -134,9 +134,6 @@ class CWLSurfaceResource {
SP<CWlSurface> resource;
wl_client* pClient = nullptr;
- // tracks whether we should release the buffer
- bool bufferReleased = false;
-
int stateLocks = 0;
void destroy();
diff --git a/src/protocols/types/WLBuffer.cpp b/src/protocols/types/WLBuffer.cpp
index d34a867d..e42094b1 100644
--- a/src/protocols/types/WLBuffer.cpp
+++ b/src/protocols/types/WLBuffer.cpp
@@ -29,6 +29,7 @@ bool CWLBufferResource::good() {
}
void CWLBufferResource::sendRelease() {
+ released = true;
resource->sendRelease();
}
diff --git a/src/protocols/types/WLBuffer.hpp b/src/protocols/types/WLBuffer.hpp
index 59512128..f4424abc 100644
--- a/src/protocols/types/WLBuffer.hpp
+++ b/src/protocols/types/WLBuffer.hpp
@@ -24,6 +24,8 @@ class CWLBufferResource {
WP<CWLBufferResource> self;
+ bool released = false;
+
private:
CWLBufferResource(SP<CWlBuffer> resource_);