aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorVaxry <[email protected]>2024-08-02 17:06:21 +0200
committerVaxry <[email protected]>2024-08-03 18:23:44 +0200
commitd4fd26ab4182bd376c51b265c34054e99f7cd8a6 (patch)
treec484d339cf19e5b05f65102df7b910e293339f5f
parent4a555deae199b4abd965c6a043bd22517c6e10bd (diff)
downloadHyprland-d4fd26ab4182bd376c51b265c34054e99f7cd8a6.tar.gz
Hyprland-d4fd26ab4182bd376c51b265c34054e99f7cd8a6.zip
work
-rw-r--r--src/helpers/sync/SyncReleaser.cpp23
-rw-r--r--src/helpers/sync/SyncReleaser.hpp30
-rw-r--r--src/protocols/core/Compositor.cpp4
-rw-r--r--src/protocols/types/Buffer.hpp5
-rw-r--r--src/render/OpenGL.cpp3
-rw-r--r--src/render/Renderer.cpp32
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();