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