Skip to main content

dioxus_native/
dioxus_renderer.rs

1use std::rc::Rc;
2use std::sync::Arc;
3use std::{any::Any, cell::RefCell};
4
5use anyrender::{RenderContext, WindowRenderer};
6
7// Renderer imports
8cfg_if::cfg_if! {
9    if #[cfg(feature = "vello")] {
10        pub use anyrender_vello::{
11            VelloRendererOptions as InnerRendererOptions, VelloWindowRenderer as InnerRenderer,
12            wgpu::{Features, Limits},
13        };
14    } else if #[cfg(feature = "vello-cpu-base")] {
15        use anyrender_vello_cpu::VelloCpuWindowRenderer as InnerRenderer;
16    } else if #[cfg(feature = "skia")] {
17        use anyrender_skia::SkiaWindowRenderer as InnerRenderer;
18        } else if #[cfg(feature = "vello-hybrid")] {
19        pub use anyrender_vello_hybrid::{
20            VelloHybridRendererOptions as InnerRendererOptions, VelloHybridWindowRenderer as InnerRenderer,
21            wgpu::{Features, Limits},
22        };
23    } else {
24        compile_error!("At least one renderer feature must be enabled");
25    }
26}
27
28#[derive(Clone)]
29pub struct DioxusNativeWindowRenderer {
30    inner: Rc<RefCell<InnerRenderer>>,
31}
32
33impl Default for DioxusNativeWindowRenderer {
34    fn default() -> Self {
35        Self::new()
36    }
37}
38
39impl DioxusNativeWindowRenderer {
40    pub fn new() -> Self {
41        let vello_renderer = InnerRenderer::new();
42        Self::with_inner_renderer(vello_renderer)
43    }
44
45    #[cfg(any(feature = "vello-hybrid", feature = "vello"))]
46    pub fn with_features_and_limits(features: Option<Features>, limits: Option<Limits>) -> Self {
47        let vello_renderer = InnerRenderer::with_options(InnerRendererOptions {
48            features,
49            limits,
50            ..Default::default()
51        });
52        Self::with_inner_renderer(vello_renderer)
53    }
54
55    fn with_inner_renderer(vello_renderer: InnerRenderer) -> Self {
56        Self {
57            inner: Rc::new(RefCell::new(vello_renderer)),
58        }
59    }
60}
61
62impl RenderContext for DioxusNativeWindowRenderer {
63    fn try_register_custom_resource(
64        &mut self,
65        resource: Box<dyn Any>,
66    ) -> Result<anyrender::ResourceId, anyrender::RegisterResourceError> {
67        self.inner
68            .borrow_mut()
69            .try_register_custom_resource(resource)
70    }
71
72    fn unregister_resource(&mut self, resource_id: anyrender::ResourceId) {
73        self.inner.borrow_mut().unregister_resource(resource_id)
74    }
75
76    fn renderer_specific_context(&self) -> Option<Box<dyn Any>> {
77        self.inner.borrow_mut().renderer_specific_context()
78    }
79}
80impl WindowRenderer for DioxusNativeWindowRenderer {
81    type ScenePainter<'a>
82        = <InnerRenderer as WindowRenderer>::ScenePainter<'a>
83    where
84        Self: 'a;
85
86    fn resume<F: FnOnce() + 'static>(
87        &mut self,
88        window: Arc<dyn anyrender::WindowHandle>,
89        width: u32,
90        height: u32,
91        on_ready: F,
92    ) {
93        self.inner
94            .borrow_mut()
95            .resume(window, width, height, on_ready)
96    }
97
98    fn complete_resume(&mut self) -> bool {
99        self.inner.borrow_mut().complete_resume()
100    }
101
102    fn suspend(&mut self) {
103        self.inner.borrow_mut().suspend()
104    }
105
106    fn is_active(&self) -> bool {
107        self.inner.borrow().is_active()
108    }
109
110    fn is_pending(&self) -> bool {
111        self.inner.borrow().is_pending()
112    }
113
114    fn set_size(&mut self, width: u32, height: u32) {
115        self.inner.borrow_mut().set_size(width, height)
116    }
117
118    fn render<F: FnOnce(&mut Self::ScenePainter<'_>)>(&mut self, draw_fn: F) {
119        self.inner.borrow_mut().render(draw_fn)
120    }
121}