mirror of
https://github.com/hyprwm/Hyprland.git
synced 2025-08-17 21:13:48 -07:00
renderer: skip ds commits if buffer didn't change (#9556)
this fixes direct scanout glitches by ensuring that attemptDirectScanout doesn't try to recommit the same buffer to AQ which would cause a pageflip event and the backendRelease to release the same buffer too early
This commit is contained in:
@@ -439,9 +439,8 @@ void CWLSurfaceResource::unlockPendingState() {
|
||||
}
|
||||
|
||||
void CWLSurfaceResource::commitPendingState() {
|
||||
static auto PDROP = CConfigValue<Hyprlang::INT>("render:allow_early_buffer_release");
|
||||
auto const previousBuffer = current.buffer;
|
||||
current = pending;
|
||||
static auto PDROP = CConfigValue<Hyprlang::INT>("render:allow_early_buffer_release");
|
||||
current = pending;
|
||||
pending.damage.clear();
|
||||
pending.bufferDamage.clear();
|
||||
pending.newBuffer = false;
|
||||
@@ -495,15 +494,6 @@ void CWLSurfaceResource::commitPendingState() {
|
||||
nullptr);
|
||||
}
|
||||
|
||||
// for async buffers, we can only release the buffer once we are unrefing it from current.
|
||||
// if the backend took it, ref it with the lambda. Otherwise, the end of this scope will release it.
|
||||
if (previousBuffer && previousBuffer->buffer && !previousBuffer->buffer->isSynchronous()) {
|
||||
if (previousBuffer->buffer->lockedByBackend && !previousBuffer->buffer->hlEvents.backendRelease) {
|
||||
previousBuffer->buffer->lock();
|
||||
previousBuffer->buffer->unlockOnBufferRelease(self);
|
||||
}
|
||||
}
|
||||
|
||||
lastBuffer = current.buffer ? current.buffer->buffer : WP<IHLBuffer>{};
|
||||
}
|
||||
|
||||
|
@@ -26,9 +26,14 @@ bool IHLBuffer::locked() {
|
||||
return nLocks > 0;
|
||||
}
|
||||
|
||||
void IHLBuffer::unlockOnBufferRelease(WP<CWLSurfaceResource> surf) {
|
||||
hlEvents.backendRelease = events.backendRelease.registerListener([this](std::any data) {
|
||||
unlock();
|
||||
void IHLBuffer::onBackendRelease(const std::function<void()>& fn) {
|
||||
if (hlEvents.backendRelease) {
|
||||
hlEvents.backendRelease->emit(nullptr);
|
||||
Debug::log(LOG, "backendRelease emitted early");
|
||||
}
|
||||
|
||||
hlEvents.backendRelease = events.backendRelease.registerListener([this, fn](std::any) {
|
||||
fn();
|
||||
hlEvents.backendRelease.reset();
|
||||
});
|
||||
}
|
||||
|
@@ -21,7 +21,7 @@ class IHLBuffer : public Aquamarine::IBuffer {
|
||||
virtual void unlock();
|
||||
virtual bool locked();
|
||||
|
||||
void unlockOnBufferRelease(WP<CWLSurfaceResource> surf /* optional */);
|
||||
void onBackendRelease(const std::function<void()>& fn);
|
||||
|
||||
SP<CTexture> texture;
|
||||
bool opaque = false;
|
||||
|
Reference in New Issue
Block a user