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
//! Generic Send/Sync shim for parallel per-pass command recording, shared by all
//! three backend executors (`{metal,directx,vulkan}/graph_exec.rs`). Each backend
//! fans its non-composite render-graph passes onto worker threads; every worker
//! records into its own command buffer/list and reaches the immutable subset of
//! the backend context it needs through a `ParallelCtxRef`.
//!
//! The backend context types are not Send/Sync in Rust's type system: they hold
//! COM smart pointers, objc2 protocol objects, RefCells, and the like. The
//! graphics APIs nonetheless permit shared, read-only access to device-derived
//! resources from many threads. A backend adopts that claim for its own context
//! type with a single `unsafe impl ParallelEncodeCtx`, where it documents the
//! audit of every interior-mutable field reachable during encode. The Send/Sync
//! impls on `ParallelCtxRef` below are then keyed off that marker, so the unsafe
//! reasoning lives in one auditable place per backend instead of being repeated
//! on three structurally identical wrapper types.
/// Marker for a backend context that may be shared, read-only, across the
/// parallel-encode worker fan-out.
///
/// # Safety
///
/// Implementing this is a claim that concurrent `&Self` access during command
/// recording is sound: the graphics API allows shared read of device-derived
/// resources, and every interior-mutable field reachable during encode is
/// either atomic or hoisted out of the fan-out before it begins. Each backend's
/// impl carries that audit (see the module docs in each
/// `*/parallel_encoder.rs`).
pub unsafe
/// A handle to a `&'a T` borrow that is Send + Sync when `T: ParallelEncodeCtx`.
/// Worker closures use it to reach the immutable subset of the backend context
/// they need while recording commands into their own command buffer/list.
///
/// The borrow is held directly, so its lifetime is enforced by the type. The
/// wrapper is only used inside each backend's parallel-encoder fan-out in
/// `graph_exec.rs`, which joins all workers before the outer borrow returns. The
/// Send/Sync claim rests entirely on the `T: ParallelEncodeCtx` marker.
// SAFETY: `T: ParallelEncodeCtx` is the backend's audited claim that shared,
// read-only `&T` access across the encode fan-out is sound. The wrapper only
// ever hands out `&T` (via `as_ctx`), so Send + Sync follow from that claim.
unsafe
// SAFETY: as for `Send` above -- the wrapper only ever hands out `&T`.
unsafe