diff options
author | Vaxry <[email protected]> | 2024-08-02 17:06:21 +0200 |
---|---|---|
committer | Vaxry <[email protected]> | 2024-08-03 18:23:44 +0200 |
commit | d4fd26ab4182bd376c51b265c34054e99f7cd8a6 (patch) | |
tree | c484d339cf19e5b05f65102df7b910e293339f5f | |
parent | 4a555deae199b4abd965c6a043bd22517c6e10bd (diff) | |
download | Hyprland-d4fd26ab4182bd376c51b265c34054e99f7cd8a6.tar.gz Hyprland-d4fd26ab4182bd376c51b265c34054e99f7cd8a6.zip |
work
-rw-r--r-- | src/helpers/sync/SyncReleaser.cpp | 23 | ||||
-rw-r--r-- | src/helpers/sync/SyncReleaser.hpp | 30 | ||||
-rw-r--r-- | src/protocols/core/Compositor.cpp | 4 | ||||
-rw-r--r-- | src/protocols/types/Buffer.hpp | 5 | ||||
-rw-r--r-- | src/render/OpenGL.cpp | 3 | ||||
-rw-r--r-- | src/render/Renderer.cpp | 32 |
6 files changed, 79 insertions, 18 deletions
diff --git a/src/helpers/sync/SyncReleaser.cpp b/src/helpers/sync/SyncReleaser.cpp new file mode 100644 index 00000000..d06efbce --- /dev/null +++ b/src/helpers/sync/SyncReleaser.cpp @@ -0,0 +1,23 @@ +#include "SyncReleaser.hpp" + +CSyncReleaser::CSyncReleaser(WP<CSyncTimeline> timeline_, uint64_t point_) : timeline(timeline_), point(point_) { + ; +} + +CSyncReleaser::~CSyncReleaser() { + if (timeline.expired()) + return; + + if (fd >= 0) + timeline->importFromSyncFileFD(point, fd); + else + timeline->signal(point); +} + +void CSyncReleaser::addReleaseSyncFD(int syncFD) { + fd = syncFD; +} + +void CSyncReleaser::drop() { + timeline.reset(); +}
\ No newline at end of file diff --git a/src/helpers/sync/SyncReleaser.hpp b/src/helpers/sync/SyncReleaser.hpp new file mode 100644 index 00000000..5f323ef4 --- /dev/null +++ b/src/helpers/sync/SyncReleaser.hpp @@ -0,0 +1,30 @@ +#pragma once + +#include <cstdint> +#include <optional> +#include <vector> +#include <functional> +#include "../memory/Memory.hpp" + +/* + A helper (inspired by KDE's KWin) that will release the timeline point in the dtor +*/ + +class CSyncTimeline; + +class CSyncReleaser { + public: + CSyncReleaser(WP<CSyncTimeline> timeline_, uint64_t point_); + ~CSyncReleaser(); + + // drops the releaser, will never signal anymore + void drop(); + + // wait for this gpu job to finish before releasing + void addReleaseSyncFD(int syncFD); + + private: + WP<CSyncTimeline> timeline; + uint64_t point = 0; + int fd = -1; +}; diff --git a/src/protocols/core/Compositor.cpp b/src/protocols/core/Compositor.cpp index 9f4e13f2..098621f4 100644 --- a/src/protocols/core/Compositor.cpp +++ b/src/protocols/core/Compositor.cpp @@ -7,6 +7,7 @@ #include "Subcompositor.hpp" #include "../Viewporter.hpp" #include "../../helpers/Monitor.hpp" +#include "../../helpers/sync/SyncReleaser.hpp" #include "../PresentationTime.hpp" #include "../DRMSyncobj.hpp" #include "../../render/Renderer.hpp" @@ -429,6 +430,9 @@ void CWLSurfaceResource::commitPendingState() { pending.damage.clear(); pending.bufferDamage.clear(); + if (syncobj && syncobj->releaseTimeline && syncobj->releaseTimeline->timeline && current.buffer && current.buffer->buffer) + current.buffer->releaser = makeShared<CSyncReleaser>(syncobj->releaseTimeline->timeline, syncobj->releasePoint); + if (current.texture) current.texture->m_eTransform = wlTransformToHyprutils(current.transform); diff --git a/src/protocols/types/Buffer.hpp b/src/protocols/types/Buffer.hpp index 2f7711cb..7d84dce7 100644 --- a/src/protocols/types/Buffer.hpp +++ b/src/protocols/types/Buffer.hpp @@ -6,6 +6,8 @@ #include <aquamarine/buffer/Buffer.hpp> +class CSyncReleaser; + class IHLBuffer : public Aquamarine::IBuffer { public: virtual ~IHLBuffer(); @@ -41,7 +43,8 @@ class CHLBufferReference { CHLBufferReference(SP<IHLBuffer> buffer, SP<CWLSurfaceResource> surface); ~CHLBufferReference(); - WP<IHLBuffer> buffer; + WP<IHLBuffer> buffer; + SP<CSyncReleaser> releaser; private: WP<CWLSurfaceResource> surface; diff --git a/src/render/OpenGL.cpp b/src/render/OpenGL.cpp index b925fcc9..8abdc0af 100644 --- a/src/render/OpenGL.cpp +++ b/src/render/OpenGL.cpp @@ -2887,6 +2887,9 @@ SP<CEGLSync> CHyprOpenGLImpl::createEGLSync(int fenceFD) { return nullptr; } + // we need to flush otherwise we might not get a valid fd later + glFlush(); + auto eglsync = SP<CEGLSync>(new CEGLSync); eglsync->sync = sync; return eglsync; diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp index 9db7a95f..e3b8c94c 100644 --- a/src/render/Renderer.cpp +++ b/src/render/Renderer.cpp @@ -1,6 +1,7 @@ #include "Renderer.hpp" #include "../Compositor.hpp" #include "../helpers/math/Math.hpp" +#include "../helpers/sync/SyncReleaser.hpp" #include <algorithm> #include <aquamarine/output/Output.hpp> #include <cstring> @@ -1408,22 +1409,6 @@ bool CHyprRenderer::commitPendingAndDoExplicitSync(CMonitor* pMonitor) { // apply timelines for explicit sync pMonitor->output->state->resetExplicitFences(); - auto signalPresented = [this]() { - if (explicitPresented.empty()) - return; - - Debug::log(TRACE, "Explicit sync presented begin, {} syncobjs to signal", explicitPresented.size()); - - for (auto& e : explicitPresented) { - if (!e->syncobj || !e->syncobj->releaseTimeline || e->syncobj->releasePoint <= 0) - continue; - - Debug::log(TRACE, "Explicit sync presented releasePoint {} for timeline handle {}", e->syncobj->releasePoint, e->syncobj->releaseTimeline->timeline->handle); - - e->syncobj->releaseTimeline->timeline->signal(e->syncobj->releasePoint); - } - }; - bool ok = pMonitor->state.commit(); if (!ok) { Debug::log(TRACE, "Monitor state commit failed"); @@ -1445,7 +1430,20 @@ bool CHyprRenderer::commitPendingAndDoExplicitSync(CMonitor* pMonitor) { } else Debug::log(TRACE, "Aquamarine did not return an explicit out fence"); - signalPresented(); + Debug::log(TRACE, "Explicit: {} presented", explicitPresented.size()); + auto sync = g_pHyprOpenGL->createEGLSync(-1); + + if (!sync) + Debug::log(TRACE, "Explicit: can't add sync, EGLSync failed"); + else { + int fd = sync->dupFenceFD(); + for (auto& e : explicitPresented) { + if (!e->current.buffer || !e->current.buffer->releaser) + continue; + + e->current.buffer->releaser->addReleaseSyncFD(fd); + } + } explicitPresented.clear(); |