-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsync.rs
More file actions
143 lines (130 loc) · 4.91 KB
/
Copy pathsync.rs
File metadata and controls
143 lines (130 loc) · 4.91 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
use crate::native_frame::{ImportedTexture, InteropError, NativeFrame};
/// Describes how the producer signals that a frame is ready and how the
/// consumer signals that it has finished reading.
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
#[non_exhaustive]
pub enum SyncMechanism {
None,
/// An explicit Vulkan external semaphore is signalled by the
/// producer. Reserved for the Linux WPE producer path.
ExplicitExternalSemaphore,
/// An explicit shared D3D12 fence is signalled by the producer.
ExplicitFence,
/// An explicit `MTLSharedEvent` is signalled by the producer
/// (CPU-side via `signaledValue`) before each frame is emitted,
/// and the consumer waits on the corresponding value before
/// sampling. Reserved for the macOS WKWebView producer path.
///
/// Currently a no-op on the macOS producer because
/// ScreenCaptureKit doesn't expose its render queue for explicit
/// fencing — implicit IOSurface coherence is the contract today.
/// See [`crate::native_frame::MetalSharedEventSynchronizer`] and
/// `design_docs/2026-05-07_platform_ceilings.md` for context.
ExplicitMetalEvent,
}
/// Hook points called by [`WgpuTextureImporter`](crate::native_frame::WgpuTextureImporter)
/// around each frame import.
///
/// Implement this to add custom fence/semaphore logic. Two built-in
/// implementations are provided: [`NoopSynchronizer`] and
/// [`ImplicitOnlySynchronizer`]. Platform-specific synchronizers
/// (e.g. [`Dx12FenceSynchronizer`](crate::native_frame::Dx12FenceSynchronizer))
/// live alongside their producer paths.
pub trait InteropSynchronizer {
/// Called after the frame is acquired from the producer, before import.
/// Use this to wait on any producer-side signal.
fn producer_complete(
&self,
frame: &NativeFrame,
mechanism: SyncMechanism,
) -> Result<(), InteropError>;
/// Called after the texture has been imported and is ready for the
/// consumer. Use this to signal any consumer-side fence or semaphore.
fn consumer_ready(
&self,
texture: &ImportedTexture,
mechanism: SyncMechanism,
) -> Result<(), InteropError>;
}
/// A synchronizer that does nothing. Suitable when the caller manages all
/// synchronization externally (e.g. via a shared queue or explicit barriers).
#[derive(Default)]
pub struct NoopSynchronizer;
impl InteropSynchronizer for NoopSynchronizer {
fn producer_complete(
&self,
_frame: &NativeFrame,
_mechanism: SyncMechanism,
) -> Result<(), InteropError> {
Ok(())
}
fn consumer_ready(
&self,
_texture: &ImportedTexture,
_mechanism: SyncMechanism,
) -> Result<(), InteropError> {
Ok(())
}
}
/// Default synchronizer: accepts only [`SyncMechanism::None`]. The
/// keyed-mutex Windows path uses producer-side `IDXGIKeyedMutex` +
/// consumer-side transition-barrier flush, both of which are external to
/// this trait, so the synchronizer just sees `None`.
#[derive(Default)]
pub struct ImplicitOnlySynchronizer;
impl InteropSynchronizer for ImplicitOnlySynchronizer {
fn producer_complete(
&self,
_frame: &NativeFrame,
mechanism: SyncMechanism,
) -> Result<(), InteropError> {
Self::validate(mechanism)
}
fn consumer_ready(
&self,
_texture: &ImportedTexture,
mechanism: SyncMechanism,
) -> Result<(), InteropError> {
Self::validate(mechanism)
}
}
impl ImplicitOnlySynchronizer {
pub(crate) fn validate(mechanism: SyncMechanism) -> Result<(), InteropError> {
match mechanism {
SyncMechanism::None => Ok(()),
other => Err(InteropError::UnsupportedSynchronization(other)),
}
}
}
/// Linux WPE placeholder synchronizer: accepts the explicit external
/// semaphore mechanism so DMABUF frames can flow to the Vulkan importer.
///
/// The actual `vkQueueSubmit` wait is part of the Linux Vulkan import work;
/// until that lands, importing a DMABUF frame still returns
/// [`InteropError::Unsupported`](crate::native_frame::InteropError::Unsupported).
#[derive(Default)]
pub struct ExplicitExternalSemaphoreSynchronizer;
impl InteropSynchronizer for ExplicitExternalSemaphoreSynchronizer {
fn producer_complete(
&self,
_frame: &NativeFrame,
mechanism: SyncMechanism,
) -> Result<(), InteropError> {
Self::validate(mechanism)
}
fn consumer_ready(
&self,
_texture: &ImportedTexture,
mechanism: SyncMechanism,
) -> Result<(), InteropError> {
Self::validate(mechanism)
}
}
impl ExplicitExternalSemaphoreSynchronizer {
pub(crate) fn validate(mechanism: SyncMechanism) -> Result<(), InteropError> {
match mechanism {
SyncMechanism::None | SyncMechanism::ExplicitExternalSemaphore => Ok(()),
other => Err(InteropError::UnsupportedSynchronization(other)),
}
}
}