mirror of
https://github.com/slint-ui/slint.git
synced 2025-08-04 10:50:00 +00:00
Simplify FemtoVG and Skia renderer API (#3153)
Fold show() into the first time render() is invoked, and hide() into the Drop implementation.
This commit is contained in:
parent
2a56e25788
commit
507428b03e
11 changed files with 59 additions and 116 deletions
|
@ -492,10 +492,6 @@ public:
|
|||
{
|
||||
cbindgen_private::slint_skia_renderer_resize(inner, size);
|
||||
}
|
||||
|
||||
void hide() const { cbindgen_private::slint_skia_renderer_hide(inner); }
|
||||
|
||||
void show() const { cbindgen_private::slint_skia_renderer_show(inner); }
|
||||
};
|
||||
|
||||
/// Call this function at each iteration of the event loop to call the timer handler and advance
|
||||
|
|
|
@ -451,18 +451,6 @@ pub mod skia {
|
|||
drop(Box::from_raw(r as *mut SkiaRenderer))
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn slint_skia_renderer_show(r: SkiaRendererOpaque) {
|
||||
let r = &*(r as *const SkiaRenderer);
|
||||
r.show().unwrap()
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn slint_skia_renderer_hide(r: SkiaRendererOpaque) {
|
||||
let r = &*(r as *const SkiaRenderer);
|
||||
r.hide().unwrap()
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn slint_skia_renderer_resize(r: SkiaRendererOpaque, size: IntSize) {
|
||||
let r = &*(r as *const SkiaRenderer);
|
||||
|
|
|
@ -71,16 +71,11 @@ struct MyWindowAdapter : public slint_platform::WindowAdapter
|
|||
return slint::PhysicalSize({ uint32_t(r.right - r.left), uint32_t(r.bottom - r.top) });
|
||||
}
|
||||
|
||||
void show() const override
|
||||
{
|
||||
ShowWindow(hwnd, SW_SHOWNORMAL);
|
||||
m_renderer->show();
|
||||
}
|
||||
void show() const override { ShowWindow(hwnd, SW_SHOWNORMAL); }
|
||||
|
||||
void hide() const override
|
||||
{
|
||||
// TODO: destroy window
|
||||
m_renderer->hide();
|
||||
}
|
||||
|
||||
void request_redraw() const override { InvalidateRect(hwnd, nullptr, false); }
|
||||
|
|
|
@ -106,13 +106,8 @@ public:
|
|||
->dispatch_scale_factor_change_event(devicePixelRatio());
|
||||
auto window = const_cast<QWindow *>(static_cast<const QWindow *>(this));
|
||||
window->QWindow::show();
|
||||
m_renderer->show();
|
||||
}
|
||||
void hide() const override
|
||||
{
|
||||
m_renderer->hide();
|
||||
const_cast<MyWindow *>(this)->QWindow::hide();
|
||||
}
|
||||
void hide() const override { const_cast<MyWindow *>(this)->QWindow::hide(); }
|
||||
slint::PhysicalSize physical_size() const override
|
||||
{
|
||||
auto windowSize = slint::LogicalSize({ float(width()), float(height()) });
|
||||
|
|
|
@ -34,9 +34,6 @@ mod renderer {
|
|||
where
|
||||
Self: Sized;
|
||||
|
||||
fn show(&self) -> Result<(), PlatformError>;
|
||||
fn hide(&self) -> Result<(), PlatformError>;
|
||||
|
||||
fn render(&self, window: &i_slint_core::api::Window) -> Result<(), PlatformError>;
|
||||
|
||||
fn as_core_renderer(&self) -> &dyn i_slint_core::renderer::Renderer;
|
||||
|
|
|
@ -45,14 +45,6 @@ impl super::WinitCompatibleRenderer for GlutinFemtoVGRenderer {
|
|||
Ok((Self { renderer }, winit_window))
|
||||
}
|
||||
|
||||
fn show(&self) -> Result<(), PlatformError> {
|
||||
self.renderer.show()
|
||||
}
|
||||
|
||||
fn hide(&self) -> Result<(), PlatformError> {
|
||||
self.renderer.hide()
|
||||
}
|
||||
|
||||
fn render(&self, window: &i_slint_core::api::Window) -> Result<(), PlatformError> {
|
||||
self.renderer.render(window)
|
||||
}
|
||||
|
|
|
@ -62,14 +62,6 @@ impl super::WinitCompatibleRenderer for SkiaRenderer {
|
|||
Ok((Self { renderer }, winit_window))
|
||||
}
|
||||
|
||||
fn show(&self) -> Result<(), PlatformError> {
|
||||
self.renderer.show()
|
||||
}
|
||||
|
||||
fn hide(&self) -> Result<(), PlatformError> {
|
||||
self.renderer.hide()
|
||||
}
|
||||
|
||||
fn render(&self, window: &i_slint_core::api::Window) -> Result<(), PlatformError> {
|
||||
self.renderer.render(window)
|
||||
}
|
||||
|
|
|
@ -47,14 +47,6 @@ impl super::WinitCompatibleRenderer for WinitSoftwareRenderer {
|
|||
))
|
||||
}
|
||||
|
||||
fn show(&self) -> Result<(), PlatformError> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn hide(&self) -> Result<(), PlatformError> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn render(&self, window: &i_slint_core::api::Window) -> Result<(), PlatformError> {
|
||||
let size = window.size();
|
||||
|
||||
|
|
|
@ -118,7 +118,6 @@ pub struct WinitWindowAdapter {
|
|||
constraints: Cell<(corelib::layout::LayoutInfo, corelib::layout::LayoutInfo)>,
|
||||
shown: Cell<bool>,
|
||||
|
||||
winit_window: Rc<winit::window::Window>,
|
||||
renderer: Box<dyn WinitCompatibleRenderer>,
|
||||
// We cache the size because winit_window.inner_size() can return different value between calls (eg, on X11)
|
||||
// And we wan see the newer value before the Resized event was received, leading to inconsistencies
|
||||
|
@ -129,6 +128,8 @@ pub struct WinitWindowAdapter {
|
|||
|
||||
#[cfg(enable_accesskit)]
|
||||
pub accesskit_adapter: crate::accesskit::AccessKitAdapter,
|
||||
|
||||
winit_window: Rc<winit::window::Window>, // Last field so that any previously provided window handles are still valid in the drop impl of the renderers, etc.
|
||||
}
|
||||
|
||||
impl WinitWindowAdapter {
|
||||
|
@ -534,7 +535,6 @@ impl WindowAdapterInternal for WinitWindowAdapter {
|
|||
self.size.set(physical_size_to_slint(&size));
|
||||
};
|
||||
|
||||
self.renderer().show()?;
|
||||
winit_window.set_visible(true);
|
||||
|
||||
// Make sure the dark color scheme property is up-to-date, as it may have been queried earlier when
|
||||
|
@ -559,8 +559,6 @@ impl WindowAdapterInternal for WinitWindowAdapter {
|
|||
fn hide(&self) -> Result<(), PlatformError> {
|
||||
self.shown.set(false);
|
||||
|
||||
self.renderer().hide()?;
|
||||
|
||||
self.winit_window().set_visible(false);
|
||||
|
||||
/* FIXME:
|
||||
|
@ -690,7 +688,6 @@ impl WindowAdapterInternal for WinitWindowAdapter {
|
|||
|
||||
impl Drop for WinitWindowAdapter {
|
||||
fn drop(&mut self) {
|
||||
self.renderer.hide().ok(); // ignore errors here, we're going away anyway
|
||||
crate::event_loop::unregister_window(self.winit_window().id());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
#![doc = include_str!("README.md")]
|
||||
#![doc(html_logo_url = "https://slint.dev/logo/slint-logo-square-light.svg")]
|
||||
|
||||
use std::cell::RefCell;
|
||||
use std::cell::{Cell, RefCell};
|
||||
use std::pin::Pin;
|
||||
use std::rc::Rc;
|
||||
|
||||
|
@ -76,6 +76,7 @@ pub struct FemtoVGRenderer {
|
|||
graphics_cache: itemrenderer::ItemGraphicsCache,
|
||||
texture_cache: RefCell<images::TextureCache>,
|
||||
rendering_metrics_collector: RefCell<Option<Rc<RenderingMetricsCollector>>>,
|
||||
rendering_first_time: Cell<bool>,
|
||||
// Last field, so that it's dropped last and context exists and is current when destroying the FemtoVG canvas
|
||||
opengl_context: Box<dyn OpenGLContextWrapper>,
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
|
@ -139,37 +140,13 @@ impl FemtoVGRenderer {
|
|||
graphics_cache: Default::default(),
|
||||
texture_cache: Default::default(),
|
||||
rendering_metrics_collector: Default::default(),
|
||||
rendering_first_time: Cell::new(true),
|
||||
opengl_context,
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
canvas_id: html_canvas.id(),
|
||||
})
|
||||
}
|
||||
|
||||
/// Notifiers the renderer that the underlying window is becoming visible.
|
||||
pub fn show(&self) -> Result<(), PlatformError> {
|
||||
self.opengl_context.ensure_current()?;
|
||||
*self.rendering_metrics_collector.borrow_mut() =
|
||||
RenderingMetricsCollector::new("FemtoVG renderer");
|
||||
|
||||
if let Some(callback) = self.rendering_notifier.borrow_mut().as_mut() {
|
||||
self.with_graphics_api(|api| callback.notify(RenderingState::RenderingSetup, &api))?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Notifiers the renderer that the underlying window will be hidden soon.
|
||||
pub fn hide(&self) -> Result<(), PlatformError> {
|
||||
self.opengl_context.ensure_current()?;
|
||||
self.rendering_metrics_collector.borrow_mut().take();
|
||||
|
||||
if let Some(callback) = self.rendering_notifier.borrow_mut().as_mut() {
|
||||
self.with_graphics_api(|api| callback.notify(RenderingState::RenderingTeardown, &api))?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Render the scene using OpenGL. This function assumes that the context is current.
|
||||
pub fn render(
|
||||
&self,
|
||||
|
@ -177,6 +154,17 @@ impl FemtoVGRenderer {
|
|||
) -> Result<(), i_slint_core::platform::PlatformError> {
|
||||
self.opengl_context.ensure_current()?;
|
||||
|
||||
if self.rendering_first_time.take() {
|
||||
*self.rendering_metrics_collector.borrow_mut() =
|
||||
RenderingMetricsCollector::new("FemtoVG renderer");
|
||||
|
||||
if let Some(callback) = self.rendering_notifier.borrow_mut().as_mut() {
|
||||
self.with_graphics_api(|api| {
|
||||
callback.notify(RenderingState::RenderingSetup, &api)
|
||||
})?;
|
||||
}
|
||||
}
|
||||
|
||||
let size = window.size();
|
||||
let width = size.width;
|
||||
let height = size.height;
|
||||
|
@ -480,7 +468,16 @@ impl RendererSealed for FemtoVGRenderer {
|
|||
impl Drop for FemtoVGRenderer {
|
||||
fn drop(&mut self) {
|
||||
// Ensure the context is current before the renderer is destroyed
|
||||
self.opengl_context.ensure_current().ok();
|
||||
if self.opengl_context.ensure_current().is_ok() {
|
||||
drop(self.rendering_metrics_collector.borrow_mut().take());
|
||||
|
||||
if let Some(callback) = self.rendering_notifier.borrow_mut().as_mut() {
|
||||
self.with_graphics_api(|api| {
|
||||
callback.notify(RenderingState::RenderingTeardown, &api)
|
||||
})
|
||||
.ok();
|
||||
}
|
||||
}
|
||||
|
||||
// Clear these manually to drop any Rc<Canvas>.
|
||||
self.graphics_cache.clear_all();
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
#![doc = include_str!("README.md")]
|
||||
#![doc(html_logo_url = "https://slint.dev/logo/slint-logo-square-light.svg")]
|
||||
|
||||
use std::cell::RefCell;
|
||||
use std::cell::{Cell, RefCell};
|
||||
use std::rc::Rc;
|
||||
|
||||
use i_slint_core::api::{
|
||||
|
@ -58,6 +58,7 @@ pub struct SkiaRenderer {
|
|||
image_cache: ItemCache<Option<skia_safe::Image>>,
|
||||
path_cache: ItemCache<Option<(Vector2D<f32, PhysicalPx>, skia_safe::Path)>>,
|
||||
rendering_metrics_collector: RefCell<Option<Rc<RenderingMetricsCollector>>>,
|
||||
rendering_first_time: Cell<bool>,
|
||||
surface: DefaultSurface,
|
||||
}
|
||||
|
||||
|
@ -75,43 +76,30 @@ impl SkiaRenderer {
|
|||
image_cache: Default::default(),
|
||||
path_cache: Default::default(),
|
||||
rendering_metrics_collector: Default::default(),
|
||||
rendering_first_time: Cell::new(true),
|
||||
surface,
|
||||
})
|
||||
}
|
||||
|
||||
/// Notifiers the renderer that the underlying window is becoming visible.
|
||||
pub fn show(&self) -> Result<(), PlatformError> {
|
||||
*self.rendering_metrics_collector.borrow_mut() = RenderingMetricsCollector::new(&format!(
|
||||
"Skia renderer (skia backend {}; surface: {} bpp)",
|
||||
self.surface.name(),
|
||||
self.surface.bits_per_pixel()?
|
||||
));
|
||||
|
||||
if let Some(callback) = self.rendering_notifier.borrow_mut().as_mut() {
|
||||
self.surface
|
||||
.with_graphics_api(|api| callback.notify(RenderingState::RenderingSetup, &api))
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Notifiers the renderer that the underlying window will be hidden soon.
|
||||
pub fn hide(&self) -> Result<(), i_slint_core::platform::PlatformError> {
|
||||
if let Some(callback) = self.rendering_notifier.borrow_mut().as_mut() {
|
||||
self.surface.with_active_surface(|| {
|
||||
self.surface.with_graphics_api(|api| {
|
||||
callback.notify(RenderingState::RenderingTeardown, &api)
|
||||
})
|
||||
})?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Render the scene in the previously associated window. The size parameter must match the size of the window.
|
||||
pub fn render(
|
||||
&self,
|
||||
window: &i_slint_core::api::Window,
|
||||
) -> Result<(), i_slint_core::platform::PlatformError> {
|
||||
if self.rendering_first_time.take() {
|
||||
*self.rendering_metrics_collector.borrow_mut() =
|
||||
RenderingMetricsCollector::new(&format!(
|
||||
"Skia renderer (skia backend {}; surface: {} bpp)",
|
||||
self.surface.name(),
|
||||
self.surface.bits_per_pixel()?
|
||||
));
|
||||
|
||||
if let Some(callback) = self.rendering_notifier.borrow_mut().as_mut() {
|
||||
self.surface
|
||||
.with_graphics_api(|api| callback.notify(RenderingState::RenderingSetup, &api))
|
||||
}
|
||||
}
|
||||
|
||||
let size = window.size();
|
||||
let window_inner = WindowInner::from_pub(window);
|
||||
|
||||
|
@ -347,6 +335,20 @@ impl i_slint_core::renderer::RendererSealed for SkiaRenderer {
|
|||
}
|
||||
}
|
||||
|
||||
impl Drop for SkiaRenderer {
|
||||
fn drop(&mut self) {
|
||||
if let Some(callback) = self.rendering_notifier.borrow_mut().as_mut() {
|
||||
self.surface
|
||||
.with_active_surface(|| {
|
||||
self.surface.with_graphics_api(|api| {
|
||||
callback.notify(RenderingState::RenderingTeardown, &api)
|
||||
})
|
||||
})
|
||||
.ok();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
trait Surface {
|
||||
const SUPPORTS_GRAPHICS_API: bool;
|
||||
fn new(
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue