Skip to content

Instantly share code, notes, and snippets.

@gulafaran
Created July 27, 2025 20:47
Show Gist options
  • Save gulafaran/6d770583d21551cc062a5b6debbe0402 to your computer and use it in GitHub Desktop.
Save gulafaran/6d770583d21551cc062a5b6debbe0402 to your computer and use it in GitHub Desktop.
diff --git a/src/protocols/types/Buffer.hpp b/src/protocols/types/Buffer.hpp
index f5c1d848..207cad16 100644
--- a/src/protocols/types/Buffer.hpp
+++ b/src/protocols/types/Buffer.hpp
@@ -9,6 +9,7 @@
class CSyncReleaser;
class CHLBufferReference;
+class CEGLSync;
class IHLBuffer : public Aquamarine::IBuffer {
public:
@@ -30,6 +31,7 @@ class IHLBuffer : public Aquamarine::IBuffer {
bool m_opaque = false;
SP<CWLBufferResource> m_resource;
std::vector<UP<CSyncReleaser>> m_syncReleasers;
+ UP<CEGLSync> m_eglSync;
struct {
CHyprSignalListener backendRelease;
diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp
index 918a6e94..45000ac7 100644
--- a/src/render/Renderer.cpp
+++ b/src/render/Renderer.cpp
@@ -2335,7 +2335,6 @@ void CHyprRenderer::endRender(const std::function<void()>& renderingDoneCallback
else
glFlush(); // mark an implicit sync point
- m_usedAsyncBuffers.clear(); // release all buffer refs and hope implicit sync works
if (renderingDoneCallback)
renderingDoneCallback();
@@ -2344,22 +2343,11 @@ void CHyprRenderer::endRender(const std::function<void()>& renderingDoneCallback
UP<CEGLSync> eglSync = CEGLSync::create();
if (eglSync && eglSync->isValid()) {
- for (auto const& buf : m_usedAsyncBuffers) {
- for (const auto& releaser : buf->m_syncReleasers) {
- releaser->addSyncFileFd(eglSync->fd());
- }
- }
-
- // release buffer refs with release points now, since syncReleaser handles actual buffer release based on EGLSync
- std::erase_if(m_usedAsyncBuffers, [](const auto& buf) { return !buf->m_syncReleasers.empty(); });
-
// release buffer refs without release points when EGLSync sync_file/fence is signalled
- g_pEventLoopManager->doOnReadable(eglSync->fd().duplicate(), [renderingDoneCallback, prevbfs = std::move(m_usedAsyncBuffers)]() mutable {
- prevbfs.clear();
+ g_pEventLoopManager->doOnReadable(eglSync->fd().duplicate(), [renderingDoneCallback]() mutable {
if (renderingDoneCallback)
renderingDoneCallback();
});
- m_usedAsyncBuffers.clear();
if (m_renderMode == RENDER_MODE_NORMAL) {
PMONITOR->m_inFence = eglSync->takeFd();
@@ -2367,8 +2355,6 @@ void CHyprRenderer::endRender(const std::function<void()>& renderingDoneCallback
}
} else {
Debug::log(ERR, "renderer: Explicit sync failed, releasing resources");
-
- m_usedAsyncBuffers.clear(); // release all buffer refs and hope implicit sync works
if (renderingDoneCallback)
renderingDoneCallback();
}
diff --git a/src/render/Renderer.hpp b/src/render/Renderer.hpp
index 7798c0d4..f438626c 100644
--- a/src/render/Renderer.hpp
+++ b/src/render/Renderer.hpp
@@ -104,8 +104,6 @@ class CHyprRenderer {
CTimer m_renderTimer;
- std::vector<CHLBufferReference> m_usedAsyncBuffers;
-
struct {
int hotspotX = 0;
int hotspotY = 0;
diff --git a/src/render/pass/SurfacePassElement.cpp b/src/render/pass/SurfacePassElement.cpp
index 87c7016d..78746648 100644
--- a/src/render/pass/SurfacePassElement.cpp
+++ b/src/render/pass/SurfacePassElement.cpp
@@ -6,6 +6,7 @@
#include "../../protocols/DRMSyncobj.hpp"
#include "../../managers/input/InputManager.hpp"
#include "../Renderer.hpp"
+#include "managers/eventLoop/EventLoopManager.hpp"
#include <hyprutils/math/Box.hpp>
#include <hyprutils/math/Vector2D.hpp>
@@ -129,10 +130,32 @@ void CSurfacePassElement::draw(const CRegion& damage) {
if (!g_pHyprRenderer->m_bBlockSurfaceFeedback)
m_data.surface->presentFeedback(m_data.when, m_data.pMonitor->m_self.lock());
- // add async (dmabuf) buffers to usedBuffers so we can handle release later
// sync (shm) buffers will be released in commitState, so no need to track them here
- if (m_data.surface->m_current.buffer && !m_data.surface->m_current.buffer->isSynchronous())
- g_pHyprRenderer->m_usedAsyncBuffers.emplace_back(m_data.surface->m_current.buffer);
+ if (m_data.surface->m_current.buffer && !m_data.surface->m_current.buffer->isSynchronous()) {
+ UP<CEGLSync> eglSync = CEGLSync::create(); // get a fence from the gl pipeline at this point
+ if(eglSync && eglSync->isValid()) {
+ if(m_data.surface->m_current.buffer->m_syncReleasers.empty()) {
+ g_pEventLoopManager->doOnReadable(std::move(eglSync->fd()), [buf = m_data.surface->m_current.buffer]() {
+ // drop buffer ref, and send release.
+ });
+
+ m_data.surface->m_current.buffer = {};
+ }
+ else {
+ m_data.surface->m_current.buffer->m_eglSync = std::move(eglSync);
+ for(auto &r : m_data.surface->m_current.buffer->m_syncReleasers) {
+ r->addSyncFileFd(m_data.surface->m_current.buffer->m_eglSync->fd());
+ }
+ m_data.surface->m_current.buffer = {};
+ }
+ }
+ else
+ Debug::log(ERR, "SurfacePass: Explicit sync failed, releasing buffer");
+ // glflush?
+
+
+ m_data.surface->m_current.buffer = {};
+ }
g_pHyprOpenGL->blend(true);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment