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, VelloWindowRenderer as InnerRenderer,
10};
11
12pub fn use_wgpu<T: CustomPaintSource>(create_source: impl FnOnce() -> T) -> u64 {
13    use dioxus_core::prelude::{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_features_and_limits(features, limits);
49        Self::with_inner_renderer(vello_renderer)
50    }
51
52    fn with_inner_renderer(vello_renderer: InnerRenderer) -> Self {
53        Self {
54            inner: Rc::new(RefCell::new(vello_renderer)),
55        }
56    }
57}
58
59impl DioxusNativeWindowRenderer {
60    pub fn register_custom_paint_source(&self, source: Box<dyn CustomPaintSource>) -> u64 {
61        self.inner.borrow_mut().register_custom_paint_source(source)
62    }
63
64    pub fn unregister_custom_paint_source(&self, id: u64) {
65        self.inner.borrow_mut().unregister_custom_paint_source(id)
66    }
67}
68
69impl WindowRenderer for DioxusNativeWindowRenderer {
70    type ScenePainter<'a>
71        = <InnerRenderer as WindowRenderer>::ScenePainter<'a>
72    where
73        Self: 'a;
74
75    fn resume(&mut self, window: Arc<dyn anyrender::WindowHandle>, width: u32, height: u32) {
76        self.inner.borrow_mut().resume(window, width, height)
77    }
78
79    fn suspend(&mut self) {
80        self.inner.borrow_mut().suspend()
81    }
82
83    fn is_active(&self) -> bool {
84        self.inner.borrow().is_active()
85    }
86
87    fn set_size(&mut self, width: u32, height: u32) {
88        self.inner.borrow_mut().set_size(width, height)
89    }
90
91    fn render<F: FnOnce(&mut Self::ScenePainter<'_>)>(&mut self, draw_fn: F) {
92        self.inner.borrow_mut().render(draw_fn)
93    }
94}