mirror of
https://github.com/slint-ui/slint.git
synced 2025-11-02 04:48:27 +00:00
Remove the window parameter from the render() function of all the renderers
This makes for a slimmer API and instead we can create the renderer <-> window association behind the scenes ourselves, in set_component.
This commit is contained in:
parent
507428b03e
commit
7d136b6568
14 changed files with 73 additions and 57 deletions
|
|
@ -351,11 +351,10 @@ public:
|
||||||
///
|
///
|
||||||
/// The stride is the amount of pixels between two lines in the buffer.
|
/// The stride is the amount of pixels between two lines in the buffer.
|
||||||
/// It is must be at least as large as the width of the window.
|
/// It is must be at least as large as the width of the window.
|
||||||
PhysicalRegion render(const Window &window, std::span<slint::Rgb8Pixel> buffer,
|
PhysicalRegion render(std::span<slint::Rgb8Pixel> buffer, std::size_t pixel_stride) const
|
||||||
std::size_t pixel_stride) const
|
|
||||||
{
|
{
|
||||||
auto r = cbindgen_private::slint_software_renderer_render_rgb8(
|
auto r = cbindgen_private::slint_software_renderer_render_rgb8(inner, buffer.data(),
|
||||||
inner, &window.window_handle().inner, buffer.data(), buffer.size(), pixel_stride);
|
buffer.size(), pixel_stride);
|
||||||
return PhysicalRegion { r };
|
return PhysicalRegion { r };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -365,12 +364,10 @@ public:
|
||||||
///
|
///
|
||||||
/// The stride is the amount of pixels between two lines in the buffer.
|
/// The stride is the amount of pixels between two lines in the buffer.
|
||||||
/// It is must be at least as large as the width of the window.
|
/// It is must be at least as large as the width of the window.
|
||||||
PhysicalRegion render(const Window &window, std::span<Rgb565Pixel> buffer,
|
PhysicalRegion render(std::span<Rgb565Pixel> buffer, std::size_t pixel_stride) const
|
||||||
std::size_t pixel_stride) const
|
|
||||||
{
|
{
|
||||||
auto r = cbindgen_private::slint_software_renderer_render_rgb565(
|
auto r = cbindgen_private::slint_software_renderer_render_rgb565(
|
||||||
inner, &window.window_handle().inner, reinterpret_cast<uint16_t *>(buffer.data()),
|
inner, reinterpret_cast<uint16_t *>(buffer.data()), buffer.size(), pixel_stride);
|
||||||
buffer.size(), pixel_stride);
|
|
||||||
return PhysicalRegion { r };
|
return PhysicalRegion { r };
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -483,10 +480,7 @@ public:
|
||||||
inner = cbindgen_private::slint_skia_renderer_new(window_handle.inner, initial_size);
|
inner = cbindgen_private::slint_skia_renderer_new(window_handle.inner, initial_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void render(const Window &window) const
|
void render() const { cbindgen_private::slint_skia_renderer_render(inner); }
|
||||||
{
|
|
||||||
cbindgen_private::slint_skia_renderer_render(inner, &window.window_handle().inner);
|
|
||||||
}
|
|
||||||
|
|
||||||
void resize(PhysicalSize size) const
|
void resize(PhysicalSize size) const
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -281,15 +281,12 @@ pub unsafe extern "C" fn slint_software_renderer_drop(r: SoftwareRendererOpaque)
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn slint_software_renderer_render_rgb8(
|
pub unsafe extern "C" fn slint_software_renderer_render_rgb8(
|
||||||
r: SoftwareRendererOpaque,
|
r: SoftwareRendererOpaque,
|
||||||
window_adapter: *const WindowAdapterRcOpaque,
|
|
||||||
buffer: *mut Rgb8Pixel,
|
buffer: *mut Rgb8Pixel,
|
||||||
buffer_len: usize,
|
buffer_len: usize,
|
||||||
pixel_stride: usize,
|
pixel_stride: usize,
|
||||||
) -> IntRect {
|
) -> IntRect {
|
||||||
let buffer = core::slice::from_raw_parts_mut(buffer, buffer_len);
|
let buffer = core::slice::from_raw_parts_mut(buffer, buffer_len);
|
||||||
let renderer = &*(r as *const SoftwareRenderer);
|
let renderer = &*(r as *const SoftwareRenderer);
|
||||||
let window_adapter = &*(window_adapter as *const Rc<dyn WindowAdapter>);
|
|
||||||
renderer.set_window(window_adapter.window());
|
|
||||||
let r = renderer.render(buffer, pixel_stride);
|
let r = renderer.render(buffer, pixel_stride);
|
||||||
let (orig, size) = (r.bounding_box_origin(), r.bounding_box_size());
|
let (orig, size) = (r.bounding_box_origin(), r.bounding_box_size());
|
||||||
i_slint_core::graphics::euclid::rect(orig.x, orig.y, size.width as i32, size.height as i32)
|
i_slint_core::graphics::euclid::rect(orig.x, orig.y, size.width as i32, size.height as i32)
|
||||||
|
|
@ -298,15 +295,12 @@ pub unsafe extern "C" fn slint_software_renderer_render_rgb8(
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn slint_software_renderer_render_rgb565(
|
pub unsafe extern "C" fn slint_software_renderer_render_rgb565(
|
||||||
r: SoftwareRendererOpaque,
|
r: SoftwareRendererOpaque,
|
||||||
window_adapter: *const WindowAdapterRcOpaque,
|
|
||||||
buffer: *mut u16,
|
buffer: *mut u16,
|
||||||
buffer_len: usize,
|
buffer_len: usize,
|
||||||
pixel_stride: usize,
|
pixel_stride: usize,
|
||||||
) -> IntRect {
|
) -> IntRect {
|
||||||
let buffer = core::slice::from_raw_parts_mut(buffer as *mut Rgb565Pixel, buffer_len);
|
let buffer = core::slice::from_raw_parts_mut(buffer as *mut Rgb565Pixel, buffer_len);
|
||||||
let renderer = &*(r as *const SoftwareRenderer);
|
let renderer = &*(r as *const SoftwareRenderer);
|
||||||
let window_adapter = &*(window_adapter as *const Rc<dyn WindowAdapter>);
|
|
||||||
renderer.set_window(window_adapter.window());
|
|
||||||
let r = renderer.render(buffer, pixel_stride);
|
let r = renderer.render(buffer, pixel_stride);
|
||||||
let (orig, size) = (r.bounding_box_origin(), r.bounding_box_size());
|
let (orig, size) = (r.bounding_box_origin(), r.bounding_box_size());
|
||||||
i_slint_core::graphics::euclid::rect(orig.x, orig.y, size.width as i32, size.height as i32)
|
i_slint_core::graphics::euclid::rect(orig.x, orig.y, size.width as i32, size.height as i32)
|
||||||
|
|
@ -458,13 +452,9 @@ pub mod skia {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn slint_skia_renderer_render(
|
pub unsafe extern "C" fn slint_skia_renderer_render(r: SkiaRendererOpaque) {
|
||||||
r: SkiaRendererOpaque,
|
|
||||||
window: *const WindowAdapterRcOpaque,
|
|
||||||
) {
|
|
||||||
let window_adapter = &*(window as *const Rc<dyn WindowAdapter>);
|
|
||||||
let r = &*(r as *const SkiaRenderer);
|
let r = &*(r as *const SkiaRenderer);
|
||||||
r.render(window_adapter.window()).unwrap();
|
r.render().unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
|
|
|
||||||
|
|
@ -82,7 +82,7 @@ struct MyWindowAdapter : public slint_platform::WindowAdapter
|
||||||
|
|
||||||
void render()
|
void render()
|
||||||
{
|
{
|
||||||
m_renderer->render(window());
|
m_renderer->render();
|
||||||
if (has_active_animations())
|
if (has_active_animations())
|
||||||
request_redraw();
|
request_redraw();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -83,7 +83,7 @@ public:
|
||||||
{
|
{
|
||||||
slint_platform::update_timers_and_animations();
|
slint_platform::update_timers_and_animations();
|
||||||
|
|
||||||
m_renderer->render(window());
|
m_renderer->render();
|
||||||
|
|
||||||
if (has_active_animations()) {
|
if (has_active_animations()) {
|
||||||
requestUpdate();
|
requestUpdate();
|
||||||
|
|
|
||||||
|
|
@ -2016,6 +2016,10 @@ impl i_slint_core::renderer::RendererSealed for QtWindow {
|
||||||
self.cache.component_destroyed(component);
|
self.cache.component_destroyed(component);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn set_window_adapter(&self, _window_adapter: &Rc<dyn WindowAdapter>) {
|
||||||
|
// No-op because QtWindow is also the WindowAdapter
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn accessible_item(item: Option<ItemRc>) -> Option<ItemRc> {
|
fn accessible_item(item: Option<ItemRc>) -> Option<ItemRc> {
|
||||||
|
|
|
||||||
|
|
@ -158,6 +158,10 @@ impl RendererSealed for TestingWindow {
|
||||||
fn default_font_size(&self) -> LogicalLength {
|
fn default_font_size(&self) -> LogicalLength {
|
||||||
LogicalLength::new(10.)
|
LogicalLength::new(10.)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn set_window_adapter(&self, _window_adapter: &Rc<dyn WindowAdapter>) {
|
||||||
|
// No-op since TestingWindow is also the WindowAdapter
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Initialize the testing backend.
|
/// Initialize the testing backend.
|
||||||
|
|
|
||||||
|
|
@ -45,8 +45,8 @@ impl super::WinitCompatibleRenderer for GlutinFemtoVGRenderer {
|
||||||
Ok((Self { renderer }, winit_window))
|
Ok((Self { renderer }, winit_window))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render(&self, window: &i_slint_core::api::Window) -> Result<(), PlatformError> {
|
fn render(&self, _window: &i_slint_core::api::Window) -> Result<(), PlatformError> {
|
||||||
self.renderer.render(window)
|
self.renderer.render()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn as_core_renderer(&self) -> &dyn Renderer {
|
fn as_core_renderer(&self) -> &dyn Renderer {
|
||||||
|
|
|
||||||
|
|
@ -63,7 +63,7 @@ impl super::WinitCompatibleRenderer for SkiaRenderer {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render(&self, window: &i_slint_core::api::Window) -> Result<(), PlatformError> {
|
fn render(&self, window: &i_slint_core::api::Window) -> Result<(), PlatformError> {
|
||||||
self.renderer.render(window)
|
self.renderer.render()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn as_core_renderer(&self) -> &dyn i_slint_core::renderer::Renderer {
|
fn as_core_renderer(&self) -> &dyn i_slint_core::renderer::Renderer {
|
||||||
|
|
|
||||||
|
|
@ -63,8 +63,6 @@ impl super::WinitCompatibleRenderer for WinitSoftwareRenderer {
|
||||||
)
|
)
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
self.renderer.set_window(window);
|
|
||||||
|
|
||||||
let mut surface = self.surface.borrow_mut();
|
let mut surface = self.surface.borrow_mut();
|
||||||
|
|
||||||
surface
|
surface
|
||||||
|
|
|
||||||
|
|
@ -2,10 +2,12 @@
|
||||||
// SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-1.1 OR LicenseRef-Slint-commercial
|
// SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-1.1 OR LicenseRef-Slint-commercial
|
||||||
|
|
||||||
use alloc::boxed::Box;
|
use alloc::boxed::Box;
|
||||||
|
use alloc::rc::Rc;
|
||||||
use core::pin::Pin;
|
use core::pin::Pin;
|
||||||
|
|
||||||
use crate::component::ComponentRef;
|
use crate::component::ComponentRef;
|
||||||
use crate::lengths::{LogicalLength, LogicalPoint, LogicalRect, LogicalSize, ScaleFactor};
|
use crate::lengths::{LogicalLength, LogicalPoint, LogicalRect, LogicalSize, ScaleFactor};
|
||||||
|
use crate::window::WindowAdapter;
|
||||||
|
|
||||||
/// This trait represents a Renderer that can render a slint scene.
|
/// This trait represents a Renderer that can render a slint scene.
|
||||||
///
|
///
|
||||||
|
|
@ -103,4 +105,6 @@ pub trait RendererSealed {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn default_font_size(&self) -> LogicalLength;
|
fn default_font_size(&self) -> LogicalLength;
|
||||||
|
|
||||||
|
fn set_window_adapter(&self, _window_adapter: &Rc<dyn WindowAdapter>);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -121,7 +121,7 @@ pub struct SoftwareRenderer {
|
||||||
/// This is the area which was dirty on the previous frame.
|
/// This is the area which was dirty on the previous frame.
|
||||||
/// Only used if repaint_buffer_type == RepaintBufferType::SwappedBuffers
|
/// Only used if repaint_buffer_type == RepaintBufferType::SwappedBuffers
|
||||||
prev_frame_dirty: Cell<DirtyRegion>,
|
prev_frame_dirty: Cell<DirtyRegion>,
|
||||||
window: RefCell<Option<Weak<dyn crate::window::WindowAdapter>>>,
|
maybe_window_adapter: RefCell<Option<Weak<dyn crate::window::WindowAdapter>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SoftwareRenderer {
|
impl SoftwareRenderer {
|
||||||
|
|
@ -141,7 +141,7 @@ impl SoftwareRenderer {
|
||||||
window: Weak<dyn crate::window::WindowAdapter>,
|
window: Weak<dyn crate::window::WindowAdapter>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
window: RefCell::new(Some(window.clone())),
|
maybe_window_adapter: RefCell::new(Some(window.clone())),
|
||||||
repaint_buffer_type,
|
repaint_buffer_type,
|
||||||
partial_cache: Default::default(),
|
partial_cache: Default::default(),
|
||||||
force_dirty: Default::default(),
|
force_dirty: Default::default(),
|
||||||
|
|
@ -159,7 +159,7 @@ impl SoftwareRenderer {
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
pub fn new_without_window(repaint_buffer_type: RepaintBufferType) -> Self {
|
pub fn new_without_window(repaint_buffer_type: RepaintBufferType) -> Self {
|
||||||
Self {
|
Self {
|
||||||
window: RefCell::new(None),
|
maybe_window_adapter: RefCell::new(None),
|
||||||
repaint_buffer_type,
|
repaint_buffer_type,
|
||||||
partial_cache: Default::default(),
|
partial_cache: Default::default(),
|
||||||
force_dirty: Default::default(),
|
force_dirty: Default::default(),
|
||||||
|
|
@ -168,14 +168,6 @@ impl SoftwareRenderer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sets the window to be use for future rendering operations. Call this before calling
|
|
||||||
/// rendering.
|
|
||||||
#[doc(hidden)]
|
|
||||||
pub fn set_window(&self, window: &crate::api::Window) {
|
|
||||||
*self.window.borrow_mut() =
|
|
||||||
Some(Rc::downgrade(&WindowInner::from_pub(window).window_adapter().clone()));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Internal function to apply a dirty region depending on the dirty_tracking_policy.
|
/// Internal function to apply a dirty region depending on the dirty_tracking_policy.
|
||||||
/// Returns the region to actually draw.
|
/// Returns the region to actually draw.
|
||||||
fn apply_dirty_region(
|
fn apply_dirty_region(
|
||||||
|
|
@ -212,7 +204,7 @@ impl SoftwareRenderer {
|
||||||
/// returns the dirty region for this frame (not including the extra_draw_region)
|
/// returns the dirty region for this frame (not including the extra_draw_region)
|
||||||
pub fn render(&self, buffer: &mut [impl TargetPixel], pixel_stride: usize) -> PhysicalRegion {
|
pub fn render(&self, buffer: &mut [impl TargetPixel], pixel_stride: usize) -> PhysicalRegion {
|
||||||
let window = self
|
let window = self
|
||||||
.window
|
.maybe_window_adapter
|
||||||
.borrow()
|
.borrow()
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.and_then(|w| w.upgrade())
|
.and_then(|w| w.upgrade())
|
||||||
|
|
@ -327,7 +319,7 @@ impl SoftwareRenderer {
|
||||||
/// ```
|
/// ```
|
||||||
pub fn render_by_line(&self, line_buffer: impl LineBufferProvider) -> PhysicalRegion {
|
pub fn render_by_line(&self, line_buffer: impl LineBufferProvider) -> PhysicalRegion {
|
||||||
let window = self
|
let window = self
|
||||||
.window
|
.maybe_window_adapter
|
||||||
.borrow()
|
.borrow()
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.and_then(|w| w.upgrade())
|
.and_then(|w| w.upgrade())
|
||||||
|
|
@ -532,6 +524,10 @@ impl RendererSealed for SoftwareRenderer {
|
||||||
fn default_font_size(&self) -> LogicalLength {
|
fn default_font_size(&self) -> LogicalLength {
|
||||||
self::fonts::DEFAULT_FONT_SIZE
|
self::fonts::DEFAULT_FONT_SIZE
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn set_window_adapter(&self, window_adapter: &Rc<dyn WindowAdapter>) {
|
||||||
|
*self.maybe_window_adapter.borrow_mut() = Some(Rc::downgrade(window_adapter));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render_window_frame_by_line(
|
fn render_window_frame_by_line(
|
||||||
|
|
@ -2051,7 +2047,6 @@ impl MinimalSoftwareWindow {
|
||||||
/// Return true if something was redrawn.
|
/// Return true if something was redrawn.
|
||||||
pub fn draw_if_needed(&self, render_callback: impl FnOnce(&SoftwareRenderer)) -> bool {
|
pub fn draw_if_needed(&self, render_callback: impl FnOnce(&SoftwareRenderer)) -> bool {
|
||||||
if self.needs_redraw.replace(false) {
|
if self.needs_redraw.replace(false) {
|
||||||
self.renderer.set_window(&self.window);
|
|
||||||
render_callback(&self.renderer);
|
render_callback(&self.renderer);
|
||||||
true
|
true
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -371,6 +371,7 @@ impl WindowInner {
|
||||||
self.component.replace(ComponentRc::downgrade(component));
|
self.component.replace(ComponentRc::downgrade(component));
|
||||||
self.pinned_fields.window_properties_tracker.set_dirty(); // component changed, layout constraints for sure must be re-calculated
|
self.pinned_fields.window_properties_tracker.set_dirty(); // component changed, layout constraints for sure must be re-calculated
|
||||||
let window_adapter = self.window_adapter();
|
let window_adapter = self.window_adapter();
|
||||||
|
window_adapter.renderer().set_window_adapter(&window_adapter);
|
||||||
{
|
{
|
||||||
let component = ComponentRc::borrow_pin(component);
|
let component = ComponentRc::borrow_pin(component);
|
||||||
let root_item = component.as_ref().get_item_ref(0);
|
let root_item = component.as_ref().get_item_ref(0);
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
use std::cell::{Cell, RefCell};
|
use std::cell::{Cell, RefCell};
|
||||||
use std::pin::Pin;
|
use std::pin::Pin;
|
||||||
use std::rc::Rc;
|
use std::rc::{Rc, Weak};
|
||||||
|
|
||||||
use i_slint_common::sharedfontdb;
|
use i_slint_common::sharedfontdb;
|
||||||
use i_slint_core::api::{
|
use i_slint_core::api::{
|
||||||
|
|
@ -20,7 +20,7 @@ use i_slint_core::lengths::{
|
||||||
};
|
};
|
||||||
use i_slint_core::platform::PlatformError;
|
use i_slint_core::platform::PlatformError;
|
||||||
use i_slint_core::renderer::RendererSealed;
|
use i_slint_core::renderer::RendererSealed;
|
||||||
use i_slint_core::window::WindowInner;
|
use i_slint_core::window::{WindowAdapter, WindowInner};
|
||||||
use i_slint_core::Brush;
|
use i_slint_core::Brush;
|
||||||
|
|
||||||
type PhysicalLength = euclid::Length<f32, PhysicalPx>;
|
type PhysicalLength = euclid::Length<f32, PhysicalPx>;
|
||||||
|
|
@ -71,6 +71,7 @@ unsafe impl OpenGLContextWrapper for WebGLNeedsNoCurrentContext {
|
||||||
/// Use the FemtoVG renderer when implementing a custom Slint platform where you deliver events to
|
/// Use the FemtoVG renderer when implementing a custom Slint platform where you deliver events to
|
||||||
/// Slint and want the scene to be rendered using OpenGL and the FemtoVG renderer.
|
/// Slint and want the scene to be rendered using OpenGL and the FemtoVG renderer.
|
||||||
pub struct FemtoVGRenderer {
|
pub struct FemtoVGRenderer {
|
||||||
|
maybe_window_adapter: RefCell<Option<Weak<dyn WindowAdapter>>>,
|
||||||
rendering_notifier: RefCell<Option<Box<dyn RenderingNotifier>>>,
|
rendering_notifier: RefCell<Option<Box<dyn RenderingNotifier>>>,
|
||||||
canvas: CanvasRc,
|
canvas: CanvasRc,
|
||||||
graphics_cache: itemrenderer::ItemGraphicsCache,
|
graphics_cache: itemrenderer::ItemGraphicsCache,
|
||||||
|
|
@ -135,6 +136,7 @@ impl FemtoVGRenderer {
|
||||||
let canvas = Rc::new(RefCell::new(femtovg_canvas));
|
let canvas = Rc::new(RefCell::new(femtovg_canvas));
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
|
maybe_window_adapter: Default::default(),
|
||||||
rendering_notifier: Default::default(),
|
rendering_notifier: Default::default(),
|
||||||
canvas,
|
canvas,
|
||||||
graphics_cache: Default::default(),
|
graphics_cache: Default::default(),
|
||||||
|
|
@ -148,10 +150,7 @@ impl FemtoVGRenderer {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Render the scene using OpenGL. This function assumes that the context is current.
|
/// Render the scene using OpenGL. This function assumes that the context is current.
|
||||||
pub fn render(
|
pub fn render(&self) -> Result<(), i_slint_core::platform::PlatformError> {
|
||||||
&self,
|
|
||||||
window: &i_slint_core::api::Window,
|
|
||||||
) -> Result<(), i_slint_core::platform::PlatformError> {
|
|
||||||
self.opengl_context.ensure_current()?;
|
self.opengl_context.ensure_current()?;
|
||||||
|
|
||||||
if self.rendering_first_time.take() {
|
if self.rendering_first_time.take() {
|
||||||
|
|
@ -165,6 +164,8 @@ impl FemtoVGRenderer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let window_adapter = self.window_adapter()?;
|
||||||
|
let window = window_adapter.window();
|
||||||
let size = window.size();
|
let size = window.size();
|
||||||
let width = size.width;
|
let width = size.width;
|
||||||
let height = size.height;
|
let height = size.height;
|
||||||
|
|
@ -297,6 +298,14 @@ impl FemtoVGRenderer {
|
||||||
callback(api);
|
callback(api);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn window_adapter(&self) -> Result<Rc<dyn WindowAdapter>, PlatformError> {
|
||||||
|
self.maybe_window_adapter
|
||||||
|
.borrow()
|
||||||
|
.as_ref()
|
||||||
|
.and_then(|w| w.upgrade())
|
||||||
|
.ok_or_else(|| format!("Renderer must be associated with component before use").into())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RendererSealed for FemtoVGRenderer {
|
impl RendererSealed for FemtoVGRenderer {
|
||||||
|
|
@ -463,6 +472,10 @@ impl RendererSealed for FemtoVGRenderer {
|
||||||
self.graphics_cache.component_destroyed(component);
|
self.graphics_cache.component_destroyed(component);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn set_window_adapter(&self, window_adapter: &Rc<dyn WindowAdapter>) {
|
||||||
|
*self.maybe_window_adapter.borrow_mut() = Some(Rc::downgrade(window_adapter));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Drop for FemtoVGRenderer {
|
impl Drop for FemtoVGRenderer {
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@
|
||||||
#![doc(html_logo_url = "https://slint.dev/logo/slint-logo-square-light.svg")]
|
#![doc(html_logo_url = "https://slint.dev/logo/slint-logo-square-light.svg")]
|
||||||
|
|
||||||
use std::cell::{Cell, RefCell};
|
use std::cell::{Cell, RefCell};
|
||||||
use std::rc::Rc;
|
use std::rc::{Rc, Weak};
|
||||||
|
|
||||||
use i_slint_core::api::{
|
use i_slint_core::api::{
|
||||||
GraphicsAPI, PhysicalSize as PhysicalWindowSize, RenderingNotifier, RenderingState,
|
GraphicsAPI, PhysicalSize as PhysicalWindowSize, RenderingNotifier, RenderingState,
|
||||||
|
|
@ -19,7 +19,7 @@ use i_slint_core::lengths::{
|
||||||
LogicalLength, LogicalPoint, LogicalRect, LogicalSize, PhysicalPx, ScaleFactor,
|
LogicalLength, LogicalPoint, LogicalRect, LogicalSize, PhysicalPx, ScaleFactor,
|
||||||
};
|
};
|
||||||
use i_slint_core::platform::PlatformError;
|
use i_slint_core::platform::PlatformError;
|
||||||
use i_slint_core::window::WindowInner;
|
use i_slint_core::window::{WindowAdapter, WindowInner};
|
||||||
use i_slint_core::Brush;
|
use i_slint_core::Brush;
|
||||||
|
|
||||||
type PhysicalLength = euclid::Length<f32, PhysicalPx>;
|
type PhysicalLength = euclid::Length<f32, PhysicalPx>;
|
||||||
|
|
@ -54,6 +54,7 @@ cfg_if::cfg_if! {
|
||||||
/// Use the SkiaRenderer when implementing a custom Slint platform where you deliver events to
|
/// Use the SkiaRenderer when implementing a custom Slint platform where you deliver events to
|
||||||
/// Slint and want the scene to be rendered using Skia as underlying graphics library.
|
/// Slint and want the scene to be rendered using Skia as underlying graphics library.
|
||||||
pub struct SkiaRenderer {
|
pub struct SkiaRenderer {
|
||||||
|
maybe_window_adapter: RefCell<Option<Weak<dyn WindowAdapter>>>,
|
||||||
rendering_notifier: RefCell<Option<Box<dyn RenderingNotifier>>>,
|
rendering_notifier: RefCell<Option<Box<dyn RenderingNotifier>>>,
|
||||||
image_cache: ItemCache<Option<skia_safe::Image>>,
|
image_cache: ItemCache<Option<skia_safe::Image>>,
|
||||||
path_cache: ItemCache<Option<(Vector2D<f32, PhysicalPx>, skia_safe::Path)>>,
|
path_cache: ItemCache<Option<(Vector2D<f32, PhysicalPx>, skia_safe::Path)>>,
|
||||||
|
|
@ -72,6 +73,7 @@ impl SkiaRenderer {
|
||||||
let surface = DefaultSurface::new(window_handle, display_handle, size)?;
|
let surface = DefaultSurface::new(window_handle, display_handle, size)?;
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
|
maybe_window_adapter: Default::default(),
|
||||||
rendering_notifier: Default::default(),
|
rendering_notifier: Default::default(),
|
||||||
image_cache: Default::default(),
|
image_cache: Default::default(),
|
||||||
path_cache: Default::default(),
|
path_cache: Default::default(),
|
||||||
|
|
@ -82,10 +84,7 @@ impl SkiaRenderer {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Render the scene in the previously associated window. The size parameter must match the size of the window.
|
/// Render the scene in the previously associated window. The size parameter must match the size of the window.
|
||||||
pub fn render(
|
pub fn render(&self) -> Result<(), i_slint_core::platform::PlatformError> {
|
||||||
&self,
|
|
||||||
window: &i_slint_core::api::Window,
|
|
||||||
) -> Result<(), i_slint_core::platform::PlatformError> {
|
|
||||||
if self.rendering_first_time.take() {
|
if self.rendering_first_time.take() {
|
||||||
*self.rendering_metrics_collector.borrow_mut() =
|
*self.rendering_metrics_collector.borrow_mut() =
|
||||||
RenderingMetricsCollector::new(&format!(
|
RenderingMetricsCollector::new(&format!(
|
||||||
|
|
@ -100,6 +99,8 @@ impl SkiaRenderer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let window_adapter = self.window_adapter()?;
|
||||||
|
let window = window_adapter.window();
|
||||||
let size = window.size();
|
let size = window.size();
|
||||||
let window_inner = WindowInner::from_pub(window);
|
let window_inner = WindowInner::from_pub(window);
|
||||||
|
|
||||||
|
|
@ -177,6 +178,14 @@ impl SkiaRenderer {
|
||||||
) -> Result<(), i_slint_core::platform::PlatformError> {
|
) -> Result<(), i_slint_core::platform::PlatformError> {
|
||||||
self.surface.resize_event(size)
|
self.surface.resize_event(size)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn window_adapter(&self) -> Result<Rc<dyn WindowAdapter>, PlatformError> {
|
||||||
|
self.maybe_window_adapter
|
||||||
|
.borrow()
|
||||||
|
.as_ref()
|
||||||
|
.and_then(|w| w.upgrade())
|
||||||
|
.ok_or_else(|| format!("Renderer must be associated with component before use").into())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl i_slint_core::renderer::RendererSealed for SkiaRenderer {
|
impl i_slint_core::renderer::RendererSealed for SkiaRenderer {
|
||||||
|
|
@ -333,6 +342,10 @@ impl i_slint_core::renderer::RendererSealed for SkiaRenderer {
|
||||||
self.path_cache.component_destroyed(component);
|
self.path_cache.component_destroyed(component);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn set_window_adapter(&self, window_adapter: &Rc<dyn WindowAdapter>) {
|
||||||
|
*self.maybe_window_adapter.borrow_mut() = Some(Rc::downgrade(window_adapter));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Drop for SkiaRenderer {
|
impl Drop for SkiaRenderer {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue