From a8b568c6c451cdce3c8d40ae010247be3f25728b Mon Sep 17 00:00:00 2001 From: UjinT34 <41110182+UjinT34@users.noreply.github.com> Date: Fri, 10 Jan 2025 21:42:26 +0300 Subject: [PATCH] core: Add render:allow_early_buffer_release to make buffer release configurable (#9019) --- src/config/ConfigDescriptions.hpp | 6 ++++++ src/config/ConfigManager.cpp | 1 + src/protocols/core/Compositor.cpp | 15 ++++++++++----- 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/src/config/ConfigDescriptions.hpp b/src/config/ConfigDescriptions.hpp index 686b996a..483f1f1f 100644 --- a/src/config/ConfigDescriptions.hpp +++ b/src/config/ConfigDescriptions.hpp @@ -1313,6 +1313,12 @@ inline static const std::vector CONFIG_OPTIONS = { .type = CONFIG_OPTION_INT, .data = SConfigOptionDescription::SRangeData{2, 0, 2}, }, + SConfigOptionDescription{ + .value = "render:allow_early_buffer_release", + .description = "Allow early buffer release event. Fixes stuttering and missing frames for some apps. May cause graphical glitches and memory leaks in others", + .type = CONFIG_OPTION_BOOL, + .data = SConfigOptionDescription::SBoolData{true}, + }, /* * cursor: diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp index 3f8862ee..299dfbc3 100644 --- a/src/config/ConfigManager.cpp +++ b/src/config/ConfigManager.cpp @@ -619,6 +619,7 @@ CConfigManager::CConfigManager() { m_pConfig->addConfigValue("render:expand_undersized_textures", Hyprlang::INT{1}); m_pConfig->addConfigValue("render:xp_mode", Hyprlang::INT{0}); m_pConfig->addConfigValue("render:ctm_animation", Hyprlang::INT{2}); + m_pConfig->addConfigValue("render:allow_early_buffer_release", Hyprlang::INT{1}); m_pConfig->addConfigValue("ecosystem:no_update_news", Hyprlang::INT{0}); m_pConfig->addConfigValue("ecosystem:no_donation_nag", Hyprlang::INT{0}); diff --git a/src/protocols/core/Compositor.cpp b/src/protocols/core/Compositor.cpp index 6213f987..e1d6ef7d 100644 --- a/src/protocols/core/Compositor.cpp +++ b/src/protocols/core/Compositor.cpp @@ -11,6 +11,7 @@ #include "../PresentationTime.hpp" #include "../DRMSyncobj.hpp" #include "../../render/Renderer.hpp" +#include "config/ConfigValue.hpp" #include class CDefaultSurfaceRole : public ISurfaceRole { @@ -423,12 +424,14 @@ void CWLSurfaceResource::unlockPendingState() { } void CWLSurfaceResource::commitPendingState() { - auto const previousBuffer = current.buffer; - current = pending; + static auto PDROP = CConfigValue("render:allow_early_buffer_release"); + auto const previousBuffer = current.buffer; + current = pending; pending.damage.clear(); pending.bufferDamage.clear(); pending.newBuffer = false; - dropPendingBuffer(); // at this point current.buffer holds the same SP and we don't use pending anymore + if (!*PDROP) + dropPendingBuffer(); // at this point current.buffer holds the same SP and we don't use pending anymore events.roleCommit.emit(); @@ -450,8 +453,10 @@ void CWLSurfaceResource::commitPendingState() { // release the buffer if it's synchronous as update() has done everything thats needed // so we can let the app know we're done. // Some clients aren't ready to receive a release this early. Should be fine to release it on the next commitPendingState. - // if (current.buffer->buffer->isSynchronous()) - // dropCurrentBuffer(); + if (current.buffer->buffer->isSynchronous() && *PDROP) { + dropCurrentBuffer(); + dropPendingBuffer(); // at this point current.buffer holds the same SP and we don't use pending anymore + } } // TODO: we should _accumulate_ and not replace above if sync