1pub mod error;
7pub mod traits;
8
9#[cfg(feature = "canvas2d")]
10pub mod canvas2d;
11
12pub mod performance;
13
14#[cfg(all(test, feature = "canvas2d"))]
15mod canvas2d_tests;
16
17#[cfg(test)]
18pub mod tests;
19
20pub use error::{RendererError, Result};
29pub use traits::{Renderer, RendererCapabilities, RendererType};
30
31#[cfg(feature = "canvas2d")]
32pub use canvas2d::Canvas2DRenderer;
33
34pub mod detection {
36 use super::traits::RendererType;
37
38 pub fn detect_available_renderers() -> Vec<RendererType> {
40 let mut available = Vec::new();
41
42 #[cfg(feature = "canvas2d")]
43 if is_canvas2d_available() {
44 available.push(RendererType::Canvas2D);
45 }
46
47 #[cfg(feature = "webgl2")]
48 if is_webgl2_available() {
49 available.push(RendererType::WebGL2);
50 }
51
52 #[cfg(feature = "webgpu")]
53 if is_webgpu_available() {
54 available.push(RendererType::WebGPU);
55 }
56
57 available
58 }
59
60 pub fn select_best_renderer() -> Option<RendererType> {
62 let available = detect_available_renderers();
63
64 #[cfg(feature = "webgpu")]
66 if available.contains(&RendererType::WebGPU) {
67 return Some(RendererType::WebGPU);
68 }
69
70 #[cfg(feature = "webgl2")]
71 if available.contains(&RendererType::WebGL2) {
72 return Some(RendererType::WebGL2);
73 }
74
75 #[cfg(feature = "canvas2d")]
76 if available.contains(&RendererType::Canvas2D) {
77 return Some(RendererType::Canvas2D);
78 }
79
80 None
81 }
82
83 #[cfg(feature = "canvas2d")]
84 fn is_canvas2d_available() -> bool {
85 true
87 }
88
89 #[cfg(feature = "webgl2")]
90 fn is_webgl2_available() -> bool {
91 use wasm_bindgen::JsCast;
92 use web_sys::{window, HtmlCanvasElement};
93
94 if let Some(window) = window() {
95 if let Ok(document) = window.document().ok_or("No document") {
96 if let Ok(canvas) = document
97 .create_element("canvas")
98 .map_err(|_| "Cannot create canvas")
99 .and_then(|canvas| {
100 canvas
101 .dyn_into::<HtmlCanvasElement>()
102 .map_err(|_| "Cannot cast to canvas")
103 })
104 {
105 return canvas.get_context("webgl2").is_ok();
106 }
107 }
108 }
109 false
110 }
111
112 #[cfg(feature = "webgpu")]
113 fn is_webgpu_available() -> bool {
114 #[allow(unused_imports)]
116 use wasm_bindgen::JsCast;
117 use web_sys::window;
118
119 if let Some(window) = window() {
120 if let Ok(navigator) = js_sys::Reflect::get(&window, &"navigator".into()) {
121 return js_sys::Reflect::has(&navigator, &"gpu".into()).unwrap_or(false);
122 }
123 }
124 false
125 }
126}
127
128pub mod prelude {
130 pub use super::detection::{detect_available_renderers, select_best_renderer};
131 pub use super::error::{RendererError, Result};
132 pub use super::traits::{Renderer, RendererCapabilities, RendererType};
133
134 #[cfg(feature = "canvas2d")]
135 pub use super::canvas2d::Canvas2DRenderer;
136}