1// Copyright © SixtyFPS GmbH <info@slint.dev>
2// SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-2.0 OR LicenseRef-Slint-Software-3.0
3
4use std::cell::Cell;
5use std::rc::Rc;
6
7use i_slint_core::renderer::Renderer;
8use i_slint_core::{graphics::RequestedGraphicsAPI, platform::PlatformError};
9use i_slint_renderer_femtovg::{FemtoVGRenderer, FemtoVGRendererExt};
10
11#[cfg(target_arch = "wasm32")]
12use winit::platform::web::WindowExtWebSys;
13
14use super::WinitCompatibleRenderer;
15
16#[cfg(not(target_arch = "wasm32"))]
17mod glcontext;
18
19pub struct GlutinFemtoVGRenderer {
20 renderer: FemtoVGRenderer,
21 suspended: Cell<bool>,
22}
23
24impl GlutinFemtoVGRenderer {
25 pub fn new_suspended() -> Box<dyn WinitCompatibleRenderer> {
26 Box::new(Self {
27 renderer: FemtoVGRenderer::new_without_context(),
28 suspended: Cell::new(true),
29 })
30 }
31}
32
33impl super::WinitCompatibleRenderer for GlutinFemtoVGRenderer {
34 fn render(&self, _window: &i_slint_core::api::Window) -> Result<(), PlatformError> {
35 self.renderer.render()
36 }
37
38 fn as_core_renderer(&self) -> &dyn Renderer {
39 &self.renderer
40 }
41
42 fn resume(
43 &self,
44 event_loop: &dyn crate::event_loop::EventLoopInterface,
45 window_attributes: winit::window::WindowAttributes,
46 #[cfg_attr(target_arch = "wasm32", allow(unused_variables))] requested_graphics_api: Option<
47 RequestedGraphicsAPI,
48 >,
49 ) -> Result<Rc<winit::window::Window>, PlatformError> {
50 #[cfg(not(target_arch = "wasm32"))]
51 let (winit_window, opengl_context) = glcontext::OpenGLContext::new_context(
52 window_attributes,
53 event_loop.event_loop(),
54 requested_graphics_api.map(TryInto::try_into).transpose()?,
55 )?;
56
57 #[cfg(target_arch = "wasm32")]
58 let winit_window =
59 Rc::new(event_loop.create_window(window_attributes).map_err(|winit_os_error| {
60 PlatformError::from(format!(
61 "FemtoVG Renderer: Could not create winit window wrapper for DOM canvas: {}",
62 winit_os_error
63 ))
64 })?);
65
66 self.renderer.set_opengl_context(
67 #[cfg(not(target_arch = "wasm32"))]
68 opengl_context,
69 #[cfg(target_arch = "wasm32")]
70 winit_window
71 .canvas()
72 .ok_or_else(|| "FemtoVG Renderer: winit didn't return a canvas")?,
73 )?;
74
75 self.suspended.set(false);
76
77 Ok(winit_window)
78 }
79
80 fn suspend(&self) -> Result<(), PlatformError> {
81 self.renderer.clear_opengl_context()
82 }
83
84 fn is_suspended(&self) -> bool {
85 self.suspended.get()
86 }
87}
88