euv_engine/raytracing/backend/data/struct.rs
1use super::*;
2
3/// A reusable ray-trace surface driven by one fixed backend.
4///
5/// The renderer owns every resource its backend needs: the packed CPU
6/// buffers, the GPU textures, buffers, program, pipeline, and bind
7/// groups, and the output pixel buffer. They are created once — during
8/// [`RayTraceRenderer::init`](super::RayTraceRenderer::init), a resize,
9/// or a scene update — and reused by every later
10/// [`render`](super::RayTraceRenderer::render). A steady-state frame
11/// allocates nothing and repacks nothing.
12///
13/// The backend is explicit. There is no capability probe and no
14/// fallback: a WebGPU request on a browser without WebGPU returns an
15/// error instead of quietly drawing a Canvas 2D frame.
16///
17/// Every method returns [`JsValue`]. An `Ok` always means the frame was
18/// submitted; a failure never degrades to `JsValue::UNDEFINED`, which
19/// would make a dropped frame indistinguishable from a good one.
20///
21/// Every field is `pub(crate)` but is only ever touched through the
22/// accessors the `Data` derive generates, so no consumer can hold a
23/// second reference to an owned resource or write a size the renderer's
24/// own accounting does not know about.
25#[derive(Data, Debug)]
26pub struct RayTraceRenderer {
27 /// The canvas element every backend draws into.
28 #[get(pub(crate))]
29 #[get_mut(pub(crate))]
30 #[set(pub(crate))]
31 pub(crate) canvas: HtmlCanvasElement,
32 /// The backend this renderer was constructed for, immutable for the
33 /// renderer's whole lifetime.
34 #[get(pub(crate), type(copy))]
35 #[get_mut(skip)]
36 #[set(skip)]
37 pub(crate) backend: RayTraceBackend,
38 /// The active backend adapter, or `None` once released.
39 ///
40 /// There is deliberately no plain getter: the adapter owns every GL
41 /// and GPU object the renderer holds and is not `Clone`, so handing
42 /// out a copy is impossible and a `get_*` accessor on an `Option`
43 /// field would unwrap. Reads borrow through the mutable accessor,
44 /// which yields the only reference to the live adapter.
45 #[get(skip)]
46 #[get_mut(pub(crate))]
47 #[set(pub(crate))]
48 pub(crate) adapter: Option<RayTraceBackendAdapter>,
49 /// The CPU mirror of the scene, so a failed GPU upload keeps the
50 /// previous, still renderable, scene. The packed block itself is not
51 /// mirrored: the GPU copy is the live one and a second copy would be
52 /// allocated on every update and read by nobody.
53 #[get(pub(crate))]
54 #[get_mut(skip)]
55 #[set(pub(crate))]
56 pub(crate) scene: RayTraceScene,
57 /// The packed frame block, refilled every frame through its reused
58 /// capacity.
59 #[get(skip)]
60 #[get_mut(pub(crate))]
61 #[set(pub(crate))]
62 pub(crate) packed_frame: Vec<f32>,
63 /// The reused RGBA output buffer of the Canvas path. It stays empty
64 /// on the GPU paths, which present through the driver instead of
65 /// through a CPU copy of the frame.
66 #[get(skip)]
67 #[get_mut(pub(crate))]
68 #[set(pub(crate))]
69 pub(crate) pixels: Vec<u8>,
70 /// The surface width in pixels.
71 #[get(pub(crate), type(copy))]
72 #[get_mut(skip)]
73 #[set(pub(crate))]
74 pub(crate) width: u32,
75 /// The surface height in pixels.
76 #[get(pub(crate), type(copy))]
77 #[get_mut(skip)]
78 #[set(pub(crate))]
79 pub(crate) height: u32,
80 /// Whether [`dispose`](super::RayTraceRenderer::dispose) already ran.
81 ///
82 /// This is set before any resource is released, which is what makes
83 /// `dispose` idempotent and stops the drop cleanup from destroying
84 /// the same GL or GPU object twice.
85 #[get(pub(crate), type(copy))]
86 #[get_mut(skip)]
87 #[set(pub(crate))]
88 pub(crate) disposed: bool,
89}