summaryrefslogtreecommitdiff
path: root/src/protocols
diff options
context:
space:
mode:
authorIkalco <73481042+ikalco@users.noreply.github.com>2025-03-08 13:24:22 -0600
committerGitHub <noreply@github.com>2025-03-08 20:24:22 +0100
commitd30cc19d253a3db784ad10c3084f58cbb52d325a (patch)
treef103d165ae71579be9211ca4499de370b8be648e /src/protocols
parentf15b49e0fd54d2cecc77f7eedbf7cd8f22215707 (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.cpp14
-rw-r--r--src/protocols/types/Buffer.cpp11
-rw-r--r--src/protocols/types/Buffer.hpp2
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;