dioxus_native/
dioxus_renderer.rs

1use std::cell::RefCell;
2use std::rc::Rc;
3use std::sync::Arc;
4
5use anyrender::WindowRenderer;
6
7pub use anyrender_vello::{
8    wgpu::{Features, Limits},
9    CustomPaintSource, VelloRendererOptions,
10};
11
12#[cfg(not(all(target_os = "ios", target_abi = "sim")))]
13pub use anyrender_vello::VelloWindowRenderer as InnerRenderer;
14
15#[cfg(all(target_os = "ios", target_abi = "sim"))]
16pub use anyrender_vello_cpu::VelloCpuWindowRenderer as InnerRenderer;
17
18#[cfg(not(all(target_os = "ios", target_abi = "sim")))]
19pub fn use_wgpu<T: CustomPaintSource>(create_source: impl FnOnce() -> T) -> u64 {
20    use dioxus_core::{consume_context, use_hook_with_cleanup};
21
22    let (_renderer, id) = use_hook_with_cleanup(
23        || {
24            let renderer = consume_context::<DioxusNativeWindowRenderer>();
25            let source = Box::new(create_source());
26            let id = renderer.register_custom_paint_source(source);
27            (renderer, id)
28        },
29        |(renderer, id)| {
30            renderer.unregister_custom_paint_source(id);
31        },
32    );
33
34    id
35}
36
37#[derive(Clone)]
38pub struct DioxusNativeWindowRenderer {
39    inner: Rc<RefCell<InnerRenderer>>,
40}
41
42impl Default for DioxusNativeWindowRenderer {
43    fn default() -> Self {
44        Self::new()
45    }
46}
47
48impl DioxusNativeWindowRenderer {
49    pub fn new() -> Self {
50        let vello_renderer = InnerRenderer::new();
51        Self::with_inner_renderer(vello_renderer)
52    }
53
54    #[cfg(not(all(target_os = "ios", target_abi = "sim")))]
55    pub fn with_features_and_limits(features: Option<Features>, limits: Option<Limits>) -> Self {
56        let vello_renderer = InnerRenderer::with_options(VelloRendererOptions {
57            features,
58            limits,
59            ..Default::default()
60        });
61        Self::with_inner_renderer(vello_renderer)
62    }
63
64    fn with_inner_renderer(vello_renderer: InnerRenderer) -> Self {
65        Self {
66            inner: Rc::new(RefCell::new(vello_renderer)),
67        }
68    }
69}
70
71#[cfg(not(all(target_os = "ios", target_abi = "sim")))]
72impl DioxusNativeWindowRenderer {
73    pub fn register_custom_paint_source(&self, source: Box<dyn CustomPaintSource>) -> u64 {
74        self.inner.borrow_mut().register_custom_paint_source(source)
75    }
76
77    pub fn unregister_custom_paint_source(&self, id: u64) {
78        self.inner.borrow_mut().unregister_custom_paint_source(id)
79    }
80}
81
82impl WindowRenderer for DioxusNativeWindowRenderer {
83    type ScenePainter<'a>
84        = <InnerRenderer as WindowRenderer>::ScenePainter<'a>
85    where
86        Self: 'a;
87
88    fn resume(&mut self, window: Arc<dyn anyrender::WindowHandle>, width: u32, height: u32) {
89        self.inner.borrow_mut().resume(window, width, height)
90    }
91
92    fn suspend(&mut self) {
93        self.inner.borrow_mut().suspend()
94    }
95
96    fn is_active(&self) -> bool {
97        self.inner.borrow().is_active()
98    }
99
100    fn set_size(&mut self, width: u32, height: u32) {
101        self.inner.borrow_mut().set_size(width, height)
102    }
103
104    fn render<F: FnOnce(&mut Self::ScenePainter<'_>)>(&mut self, draw_fn: F) {
105        self.inner.borrow_mut().render(draw_fn)
106    }
107}