Loading...
Searching...
No Matches
CaptureCorrelator.hpp
Go to the documentation of this file.
1#pragma once
2
41
42#include <atomic>
43#include <cstddef>
44#include <cstdint>
45#include <mutex>
46
47namespace score::gfx::interop
48{
49
51{
52public:
53 explicit CaptureCorrelator(std::size_t memberCount) noexcept
54 : m_group{memberCount}
55 {
56 }
57
58 CaptureSyncGroup& group() noexcept { return m_group; }
59 std::size_t memberCount() const noexcept { return m_group.memberCount(); }
60
68 int offer(std::size_t member, int slot, std::uint64_t stampNs) noexcept
69 {
70 if(member >= memberCount() || slot < 0)
71 return -1;
72
73 std::lock_guard lock{m_mutex};
74
75 int displaced = -1;
76 if(m_pending[member].slot >= 0)
77 {
78 displaced = m_pending[member].slot;
79 m_displaced.fetch_add(1, std::memory_order_relaxed);
80 }
81 m_pending[member] = Pending{slot, stampNs};
82
83 for(std::size_t i = 0; i < memberCount(); ++i)
84 if(m_pending[i].slot < 0)
85 return displaced;
86
87 publishLocked();
88 return displaced;
89 }
90
98 void drain(int* out) noexcept
99 {
100 std::lock_guard lock{m_mutex};
101 for(std::size_t i = 0; i < memberCount(); ++i)
102 {
103 out[i] = m_pending[i].slot;
104 m_pending[i] = Pending{};
105 }
106 }
107
108 std::uint64_t setsPublished() const noexcept
109 {
110 return m_sets.load(std::memory_order_relaxed);
111 }
115 std::uint64_t displacedFrames() const noexcept
116 {
117 return m_displaced.load(std::memory_order_relaxed);
118 }
119
120private:
121 struct Pending
122 {
123 int slot{-1};
124 std::uint64_t stampNs{0};
125 };
126
127 void publishLocked() noexcept
128 {
129 int slots[CaptureFrameSet::kMaxMembers];
130 std::uint64_t stamps[CaptureFrameSet::kMaxMembers];
131 for(std::size_t i = 0; i < memberCount(); ++i)
132 {
133 slots[i] = m_pending[i].slot;
134 stamps[i] = m_pending[i].stampNs;
135 m_pending[i] = Pending{};
136 }
137 m_group.publish(slots, stamps);
138 m_sets.fetch_add(1, std::memory_order_relaxed);
139 }
140
141 CaptureSyncGroup m_group;
142
143 std::mutex m_mutex;
144 Pending m_pending[CaptureFrameSet::kMaxMembers]{};
145
146 std::atomic<std::uint64_t> m_sets{0};
147 std::atomic<std::uint64_t> m_displaced{0};
148};
149
150} // namespace score::gfx::interop
Frame-accurate correlation across several capture streams.
Definition CaptureCorrelator.hpp:51
std::uint64_t displacedFrames() const noexcept
Definition CaptureCorrelator.hpp:115
int offer(std::size_t member, int slot, std::uint64_t stampNs) noexcept
Offer this member's freshly captured slot.
Definition CaptureCorrelator.hpp:68
void drain(int *out) noexcept
Give up every offer being held, for teardown or a format change.
Definition CaptureCorrelator.hpp:98
Definition CaptureSyncGroup.hpp:100
void publish(const int *slots, const std::uint64_t *stampNs) noexcept
Definition CaptureSyncGroup.hpp:125