euv_chart/backend/common/impl.rs
1use super::*;
2
3/// Inherent implementation of [`BackendKind`].
4impl BackendKind {
5 /// Returns the name of the backend.
6 ///
7 /// # Returns
8 ///
9 /// - `&'static str` - A `'static str` value.
10 pub fn name(&self) -> &'static str {
11 match self {
12 BackendKind::WebGpu => "webgpu",
13 BackendKind::WebGl2 => "webgl2",
14 BackendKind::Canvas2D => "canvas2d",
15 }
16 }
17
18 /// Returns `true` when the backend runs on the GPU.
19 ///
20 /// # Returns
21 ///
22 /// - `bool` - A boolean.
23 pub fn is_gpu(&self) -> bool {
24 matches!(self, BackendKind::WebGpu | BackendKind::WebGl2)
25 }
26}
27
28/// Inherent implementation of [`BackendFactory`].
29impl BackendFactory {
30 /// Returns a factory.
31 pub fn new() -> Self {
32 Self
33 }
34
35 /// Creates the best backend for the given canvas.
36 ///
37 /// `preferred` is the backend the caller would like; the factory
38 /// falls back to the next one down when the host cannot provide it.
39 /// The fallback chain is always WebGPU, WebGL2, Canvas2D.
40 ///
41 /// # Arguments
42 ///
43 /// - `&HtmlCanvasElement` - The `&HtmlCanvasElement` value.
44 /// - `BackendKind` - The `BackendKind` value.
45 ///
46 /// # Returns
47 ///
48 /// - `Option<Box<dyn ChartBackend>>` - The `Option<Box<dyn ChartBackend>>` value.
49 pub async fn create(
50 canvas: &HtmlCanvasElement,
51 preferred: BackendKind,
52 ) -> Option<Box<dyn ChartBackend>> {
53 let order: &[BackendKind] = match preferred {
54 BackendKind::WebGpu => &[
55 BackendKind::WebGpu,
56 BackendKind::WebGl2,
57 BackendKind::Canvas2D,
58 ],
59 BackendKind::WebGl2 => &[BackendKind::WebGl2, BackendKind::Canvas2D],
60 BackendKind::Canvas2D => &[BackendKind::Canvas2D],
61 };
62
63 for kind in order {
64 match kind {
65 BackendKind::WebGpu => {
66 if let Some(backend) = webgpu::WebGpuChartBackend::create(canvas).await {
67 return Some(Box::new(backend));
68 }
69 }
70 BackendKind::WebGl2 => {
71 if let Some(backend) = webgl::WebGl2ChartBackend::create(canvas) {
72 return Some(Box::new(backend));
73 }
74 }
75 BackendKind::Canvas2D => {
76 if let Some(backend) = canvas2d::Canvas2dChartBackend::create(canvas) {
77 return Some(Box::new(backend));
78 }
79 }
80 }
81 }
82 None
83 }
84
85 /// Returns the backend the host would pick, without creating it.
86 ///
87 /// The check is cheap and synchronous, so a chart can report the
88 /// backend it is about to use before the asynchronous creation
89 /// finishes.
90 ///
91 /// # Arguments
92 ///
93 /// - `BackendKind` - A `BackendKind` parameter.
94 ///
95 /// # Returns
96 ///
97 /// - `BackendKind` - A `BackendKind` value.
98 pub fn detect(preferred: BackendKind) -> BackendKind {
99 if preferred == BackendKind::WebGpu && !webgpu::WebGpuChartBackend::is_supported() {
100 return if webgl::WebGl2ChartBackend::is_supported() {
101 BackendKind::WebGl2
102 } else {
103 BackendKind::Canvas2D
104 };
105 }
106 if preferred == BackendKind::WebGl2 && !webgl::WebGl2ChartBackend::is_supported() {
107 return BackendKind::Canvas2D;
108 }
109 preferred
110 }
111}