mirror of
https://github.com/hyprwm/Hyprland.git
synced 2024-09-11 13:25:42 +03:00
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()
This commit is contained in:
parent
d724556b7e
commit
9994b73ad0
@ -107,6 +107,7 @@ CWLSurfaceResource::CWLSurfaceResource(SP<CWlSurface> resource_) : resource(reso
|
|||||||
|
|
||||||
pending.damage.intersect(CBox{{}, pending.size});
|
pending.damage.intersect(CBox{{}, pending.size});
|
||||||
|
|
||||||
|
auto previousBuffer = current.buffer;
|
||||||
CRegion previousBufferDamage = accumulateCurrentBufferDamage();
|
CRegion previousBufferDamage = accumulateCurrentBufferDamage();
|
||||||
|
|
||||||
current = pending;
|
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.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.
|
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.
|
// so we can let the app know we're done.
|
||||||
// for dma buffers, this doesn't matter.
|
if (current.buffer->isSynchronous()) {
|
||||||
current.buffer->sendRelease();
|
current.buffer->sendRelease();
|
||||||
bufferReleased = true;
|
bufferReleased = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: we should _accumulate_ and not replace above if sync
|
// TODO: we should _accumulate_ and not replace above if sync
|
||||||
@ -146,6 +148,12 @@ CWLSurfaceResource::CWLSurfaceResource(SP<CWlSurface> resource_) : resource(reso
|
|||||||
},
|
},
|
||||||
nullptr);
|
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}); });
|
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}); });
|
||||||
|
@ -49,6 +49,10 @@ eBufferType CWLSHMBuffer::type() {
|
|||||||
return BUFFER_TYPE_SHM;
|
return BUFFER_TYPE_SHM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CWLSHMBuffer::isSynchronous() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
SSHMAttrs CWLSHMBuffer::shm() {
|
SSHMAttrs CWLSHMBuffer::shm() {
|
||||||
SSHMAttrs attrs;
|
SSHMAttrs attrs;
|
||||||
attrs.success = true;
|
attrs.success = true;
|
||||||
|
@ -37,6 +37,7 @@ class CWLSHMBuffer : public IWLBuffer {
|
|||||||
virtual eBufferCapability caps();
|
virtual eBufferCapability caps();
|
||||||
virtual eBufferType type();
|
virtual eBufferType type();
|
||||||
virtual void update(const CRegion& damage);
|
virtual void update(const CRegion& damage);
|
||||||
|
virtual bool isSynchronous();
|
||||||
virtual SSHMAttrs shm();
|
virtual SSHMAttrs shm();
|
||||||
virtual std::tuple<uint8_t*, uint32_t, size_t> beginDataPtr(uint32_t flags);
|
virtual std::tuple<uint8_t*, uint32_t, size_t> beginDataPtr(uint32_t flags);
|
||||||
virtual void endDataPtr();
|
virtual void endDataPtr();
|
||||||
|
@ -49,6 +49,7 @@ class IWLBuffer {
|
|||||||
virtual eBufferCapability caps() = 0;
|
virtual eBufferCapability caps() = 0;
|
||||||
virtual eBufferType type() = 0;
|
virtual eBufferType type() = 0;
|
||||||
virtual void update(const CRegion& damage) = 0;
|
virtual void update(const CRegion& damage) = 0;
|
||||||
|
virtual bool isSynchronous() = 0; // whether the updates to this buffer are synchronous, aka happen over cpu
|
||||||
virtual SDMABUFAttrs dmabuf();
|
virtual SDMABUFAttrs dmabuf();
|
||||||
virtual SSHMAttrs shm();
|
virtual SSHMAttrs shm();
|
||||||
virtual std::tuple<uint8_t*, uint32_t, size_t> beginDataPtr(uint32_t flags);
|
virtual std::tuple<uint8_t*, uint32_t, size_t> beginDataPtr(uint32_t flags);
|
||||||
|
@ -43,6 +43,10 @@ void CDMABuffer::update(const CRegion& damage) {
|
|||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CDMABuffer::isSynchronous() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
SDMABUFAttrs CDMABuffer::dmabuf() {
|
SDMABUFAttrs CDMABuffer::dmabuf() {
|
||||||
return attrs;
|
return attrs;
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,7 @@ class CDMABuffer : public IWLBuffer {
|
|||||||
|
|
||||||
virtual eBufferCapability caps();
|
virtual eBufferCapability caps();
|
||||||
virtual eBufferType type();
|
virtual eBufferType type();
|
||||||
|
virtual bool isSynchronous();
|
||||||
virtual void update(const CRegion& damage);
|
virtual void update(const CRegion& damage);
|
||||||
virtual SDMABUFAttrs dmabuf();
|
virtual SDMABUFAttrs dmabuf();
|
||||||
virtual std::tuple<uint8_t*, uint32_t, size_t> beginDataPtr(uint32_t flags);
|
virtual std::tuple<uint8_t*, uint32_t, size_t> beginDataPtr(uint32_t flags);
|
||||||
|
Loading…
Reference in New Issue
Block a user