diff options
| author | Ikalco <73481042+ikalco@users.noreply.github.com> | 2025-03-08 13:24:22 -0600 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-03-08 20:24:22 +0100 |
| commit | d30cc19d253a3db784ad10c3084f58cbb52d325a (patch) | |
| tree | f103d165ae71579be9211ca4499de370b8be648e /src/protocols | |
| parent | f15b49e0fd54d2cecc77f7eedbf7cd8f22215707 (diff) | |
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
Diffstat (limited to 'src/protocols')
| -rw-r--r-- | src/protocols/core/Compositor.cpp | 14 | ||||
| -rw-r--r-- | src/protocols/types/Buffer.cpp | 11 | ||||
| -rw-r--r-- | src/protocols/types/Buffer.hpp | 2 |
3 files changed, 11 insertions, 16 deletions
diff --git a/src/protocols/core/Compositor.cpp b/src/protocols/core/Compositor.cpp index 06977338..f7af9504 100644 --- a/src/protocols/core/Compositor.cpp +++ b/src/protocols/core/Compositor.cpp @@ -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>{}; } diff --git a/src/protocols/types/Buffer.cpp b/src/protocols/types/Buffer.cpp index ea12f017..9fb6294f 100644 --- a/src/protocols/types/Buffer.cpp +++ b/src/protocols/types/Buffer.cpp @@ -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(); }); } diff --git a/src/protocols/types/Buffer.hpp b/src/protocols/types/Buffer.hpp index 7d84dce7..bd02e2db 100644 --- a/src/protocols/types/Buffer.hpp +++ b/src/protocols/types/Buffer.hpp @@ -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; |
