summaryrefslogtreecommitdiff
path: root/src/helpers/sync/SyncReleaser.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/helpers/sync/SyncReleaser.cpp')
-rw-r--r--src/helpers/sync/SyncReleaser.cpp58
1 files changed, 49 insertions, 9 deletions
diff --git a/src/helpers/sync/SyncReleaser.cpp b/src/helpers/sync/SyncReleaser.cpp
index 198495ab..fca7d7c2 100644
--- a/src/helpers/sync/SyncReleaser.cpp
+++ b/src/helpers/sync/SyncReleaser.cpp
@@ -1,25 +1,65 @@
#include "SyncReleaser.hpp"
#include "SyncTimeline.hpp"
#include "../../render/OpenGL.hpp"
+#include <sys/ioctl.h>
-CSyncReleaser::CSyncReleaser(WP<CSyncTimeline> timeline_, uint64_t point_) : timeline(timeline_), point(point_) {
+#if defined(__linux__)
+#include <linux/sync_file.h>
+#else
+struct sync_merge_data {
+ char name[32];
+ __s32 fd2;
+ __s32 fence;
+ __u32 flags;
+ __u32 pad;
+};
+#define SYNC_IOC_MAGIC '>'
+#define SYNC_IOC_MERGE _IOWR(SYNC_IOC_MAGIC, 3, struct sync_merge_data)
+#endif
+
+using namespace Hyprutils::OS;
+
+CSyncReleaser::CSyncReleaser(SP<CSyncTimeline> timeline, uint64_t point) : m_timeline(timeline), m_point(point) {
;
}
CSyncReleaser::~CSyncReleaser() {
- if (timeline.expired())
+ if (!m_timeline) {
+ Debug::log(ERR, "CSyncReleaser destructing without a timeline");
return;
+ }
+
+ if (m_fd.isValid())
+ m_timeline->importFromSyncFileFD(m_point, m_fd);
+ else
+ m_timeline->signal(m_point);
+}
- if (sync)
- timeline->importFromSyncFileFD(point, sync->fd());
+CFileDescriptor CSyncReleaser::mergeSyncFds(const CFileDescriptor& fd1, const CFileDescriptor& fd2) {
+ struct sync_merge_data data{
+ .name = "merged release fence",
+ .fd2 = fd2.get(),
+ .fence = -1,
+ };
+ int err = -1;
+ do {
+ err = ioctl(fd1.get(), SYNC_IOC_MERGE, &data);
+ } while (err == -1 && (errno == EINTR || errno == EAGAIN));
+ if (err < 0)
+ return CFileDescriptor{};
else
- timeline->signal(point);
+ return CFileDescriptor(data.fence);
}
-void CSyncReleaser::addReleaseSync(SP<CEGLSync> sync_) {
- sync = sync_;
+void CSyncReleaser::addReleaseSync(SP<CEGLSync> sync) {
+ if (m_fd.isValid())
+ m_fd = mergeSyncFds(m_fd, sync->takeFD());
+ else
+ m_fd = sync->fd().duplicate();
+
+ m_sync = sync;
}
void CSyncReleaser::drop() {
- timeline.reset();
-} \ No newline at end of file
+ m_timeline.reset();
+}