summaryrefslogtreecommitdiff
path: root/src/protocols/core/Compositor.cpp
diff options
context:
space:
mode:
authorVaxry <vaxry@vaxry.net>2024-06-08 17:27:50 +0200
committerVaxry <vaxry@vaxry.net>2024-06-08 17:27:56 +0200
commit9994b73ad0af5c9ba5fc4058234cea77d0a1ddb1 (patch)
treefe5785672dde5259d45ad9bf76f25135355ffdd1 /src/protocols/core/Compositor.cpp
parentd724556b7ece61a5ff4eb764e6f47ec8089439bf (diff)
buffer: track asynchronous buffers and don't release them until unref
synchronous buffers are read instantly and we can release them, but asynchronous ones have to be locked until they are unref'd from .current to avoid reading from a buffer after .release()
Diffstat (limited to 'src/protocols/core/Compositor.cpp')
-rw-r--r--src/protocols/core/Compositor.cpp16
1 files changed, 12 insertions, 4 deletions
diff --git a/src/protocols/core/Compositor.cpp b/src/protocols/core/Compositor.cpp
index e8503ae8..db6e3258 100644
--- a/src/protocols/core/Compositor.cpp
+++ b/src/protocols/core/Compositor.cpp
@@ -107,6 +107,7 @@ CWLSurfaceResource::CWLSurfaceResource(SP<CWlSurface> resource_) : resource(reso
pending.damage.intersect(CBox{{}, pending.size});
+ auto previousBuffer = current.buffer;
CRegion previousBufferDamage = accumulateCurrentBufferDamage();
current = pending;
@@ -119,11 +120,12 @@ CWLSurfaceResource::CWLSurfaceResource(SP<CWlSurface> resource_) : resource(reso
// current.damage.copy().scale(current.scale).transform(current.transform, current.size.x, current.size.y).add(current.bufferDamage).add(previousBufferDamage);
current.buffer->update(CBox{{}, {INT32_MAX, INT32_MAX}}); // FIXME: figure this out to not use this hack. QT apps are wonky without this.
- // release the buffer, glTexImage2D is synchronous (as in, data is consumed after the call returns)
+ // release the buffer if it's synchronous as update() has done everything thats needed
// so we can let the app know we're done.
- // for dma buffers, this doesn't matter.
- current.buffer->sendRelease();
- bufferReleased = true;
+ if (current.buffer->isSynchronous()) {
+ current.buffer->sendRelease();
+ bufferReleased = true;
+ }
}
// TODO: we should _accumulate_ and not replace above if sync
@@ -146,6 +148,12 @@ CWLSurfaceResource::CWLSurfaceResource(SP<CWlSurface> resource_) : resource(reso
},
nullptr);
}
+
+ // for async buffers, we can only release the buffer once we are unrefing it from current.
+ if (previousBuffer && !previousBuffer->isSynchronous() && !bufferReleased) {
+ previousBuffer->sendRelease();
+ bufferReleased = true;
+ }
});
resource->setDamage([this](CWlSurface* r, int32_t x, int32_t y, int32_t w, int32_t h) { pending.damage.add(CBox{x, y, w, h}); });