ass_renderer/renderer/
probing.rs1use crate::backends::{BackendType, RenderBackend};
4use crate::renderer::RenderContext;
5use crate::utils::RenderError;
6
7#[cfg(feature = "nostd")]
8use alloc::{boxed::Box, vec::Vec};
9#[cfg(not(feature = "nostd"))]
10use std::vec::Vec;
11
12pub struct BackendProber {
14 preferred_order: Vec<BackendType>,
15}
16
17impl BackendProber {
18 #[allow(clippy::vec_init_then_push)] #[allow(unused_mut)] pub fn new() -> Self {
22 let mut preferred_order = Vec::new();
23
24 #[cfg(feature = "software-backend")]
25 preferred_order.push(BackendType::Software);
26
27 #[cfg(feature = "gpu")]
28 preferred_order.push(BackendType::Gpu);
29
30 Self { preferred_order }
31 }
32
33 pub fn with_preference(preferred_order: Vec<BackendType>) -> Self {
35 Self { preferred_order }
36 }
37
38 pub fn probe_best_backend(
40 &self,
41 context: &RenderContext,
42 ) -> Result<Box<dyn RenderBackend>, RenderError> {
43 for backend_type in &self.preferred_order {
44 match self.try_create_backend(*backend_type, context) {
45 Ok(backend) => {
46 return Ok(backend);
47 }
48 Err(_e) => {}
49 }
50 }
51
52 Err(RenderError::NoBackendAvailable)
53 }
54
55 fn try_create_backend(
57 &self,
58 backend_type: BackendType,
59 context: &RenderContext,
60 ) -> Result<Box<dyn RenderBackend>, RenderError> {
61 match backend_type {
62 #[cfg(feature = "software-backend")]
63 BackendType::Software => {
64 use crate::backends::software::SoftwareBackend;
65 Ok(Box::new(SoftwareBackend::new(context)?))
66 }
67
68 #[cfg(feature = "gpu")]
69 BackendType::Gpu => {
70 use crate::backends::gpu::GpuBackend;
71 Ok(Box::new(GpuBackend::new(
72 context.width(),
73 context.height(),
74 )?))
75 }
76
77 _ => Err(RenderError::UnsupportedBackend(backend_type.as_str())),
78 }
79 }
80
81 pub fn is_backend_available(&self, backend_type: BackendType) -> bool {
83 match backend_type {
84 #[cfg(feature = "software-backend")]
85 BackendType::Software => true,
86
87 #[cfg(feature = "gpu")]
88 BackendType::Gpu => true,
89
90 _ => false,
91 }
92 }
93
94 pub fn available_backends(&self) -> Vec<BackendType> {
96 self.preferred_order
97 .iter()
98 .filter(|&&backend| self.is_backend_available(backend))
99 .copied()
100 .collect()
101 }
102}
103
104impl Default for BackendProber {
105 fn default() -> Self {
106 Self::new()
107 }
108}