Skip to main content

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}