diff options
author | 2023-02-25 16:05:42 +0100 | |
---|---|---|
committer | 2023-02-25 16:05:42 +0100 | |
commit | 535d7a4d57e131e661587b36e41820dd6ccccc3e (patch) | |
tree | 0127873baeff222a32bd840e0735f82249f912d3 | |
parent | 8c373cd497e370d356b480380482779397bdb510 (diff) | |
download | iced-535d7a4d57e131e661587b36e41820dd6ccccc3e.tar.gz iced-535d7a4d57e131e661587b36e41820dd6ccccc3e.tar.bz2 iced-535d7a4d57e131e661587b36e41820dd6ccccc3e.zip |
Implement basic presentation with `softbuffer` for `iced_tiny_skia`
-rw-r--r-- | graphics/src/window/compositor.rs | 2 | ||||
-rw-r--r-- | renderer/src/window/compositor.rs | 10 | ||||
-rw-r--r-- | tiny_skia/src/backend.rs | 19 | ||||
-rw-r--r-- | tiny_skia/src/window/compositor.rs | 66 | ||||
-rw-r--r-- | wgpu/src/window/compositor.rs | 10 | ||||
-rw-r--r-- | winit/src/application.rs | 13 |
6 files changed, 90 insertions, 30 deletions
diff --git a/graphics/src/window/compositor.rs b/graphics/src/window/compositor.rs index db4ba45d..15f8dab5 100644 --- a/graphics/src/window/compositor.rs +++ b/graphics/src/window/compositor.rs @@ -28,6 +28,8 @@ pub trait Compositor: Sized { fn create_surface<W: HasRawWindowHandle + HasRawDisplayHandle>( &mut self, window: &W, + width: u32, + height: u32, ) -> Self::Surface; /// Configures a new [`Surface`] with the given dimensions. diff --git a/renderer/src/window/compositor.rs b/renderer/src/window/compositor.rs index 42afddc4..a11374ed 100644 --- a/renderer/src/window/compositor.rs +++ b/renderer/src/window/compositor.rs @@ -52,14 +52,16 @@ impl<Theme> iced_graphics::window::Compositor for Compositor<Theme> { fn create_surface<W: HasRawWindowHandle + HasRawDisplayHandle>( &mut self, window: &W, + width: u32, + height: u32, ) -> Surface { match self { Self::Wgpu(compositor) => { - Surface::Wgpu(compositor.create_surface(window)) - } - Self::TinySkia(compositor) => { - Surface::TinySkia(compositor.create_surface(window)) + Surface::Wgpu(compositor.create_surface(window, width, height)) } + Self::TinySkia(compositor) => Surface::TinySkia( + compositor.create_surface(window, width, height), + ), } } diff --git a/tiny_skia/src/backend.rs b/tiny_skia/src/backend.rs index 4282a745..62373ec7 100644 --- a/tiny_skia/src/backend.rs +++ b/tiny_skia/src/backend.rs @@ -1,7 +1,8 @@ -use crate::{Font, Settings, Size}; +use crate::{Color, Font, Settings, Size, Viewport}; use iced_graphics::backend; use iced_graphics::text; +use iced_graphics::Primitive; use std::borrow::Cow; @@ -17,6 +18,22 @@ impl Backend { default_text_size: settings.default_text_size, } } + + pub fn draw<T: AsRef<str>>( + &mut self, + pixels: &mut tiny_skia::Pixmap, + _primitives: &[Primitive], + _viewport: &Viewport, + background_color: Color, + _overlay: &[T], + ) { + pixels.fill(into_color(background_color)); + } +} + +fn into_color(color: Color) -> tiny_skia::Color { + tiny_skia::Color::from_rgba(color.r, color.g, color.b, color.a) + .expect("Convert color from iced to tiny_skia") } impl iced_graphics::Backend for Backend { diff --git a/tiny_skia/src/window/compositor.rs b/tiny_skia/src/window/compositor.rs index 053bb29b..164d99c6 100644 --- a/tiny_skia/src/window/compositor.rs +++ b/tiny_skia/src/window/compositor.rs @@ -10,7 +10,11 @@ pub struct Compositor<Theme> { _theme: PhantomData<Theme>, } -pub struct Surface; +pub struct Surface { + window: softbuffer::GraphicsContext, + pixels: tiny_skia::Pixmap, + buffer: Vec<u32>, +} impl<Theme> iced_graphics::window::Compositor for Compositor<Theme> { type Settings = Settings; @@ -28,19 +32,33 @@ impl<Theme> iced_graphics::window::Compositor for Compositor<Theme> { fn create_surface<W: HasRawWindowHandle + HasRawDisplayHandle>( &mut self, - _window: &W, + window: &W, + width: u32, + height: u32, ) -> Surface { - // TODO - Surface + let window = + unsafe { softbuffer::GraphicsContext::new(window, window) } + .expect("Create softbuffer for window"); + + let pixels = tiny_skia::Pixmap::new(width, height) + .expect("Create pixmap for window"); + + Surface { + window, + pixels, + buffer: vec![0; (width * height) as usize], + } } fn configure_surface( &mut self, - _surface: &mut Surface, - _width: u32, - _height: u32, + surface: &mut Surface, + width: u32, + height: u32, ) { - // TODO + surface.pixels = tiny_skia::Pixmap::new(width, height) + .expect("Create pixmap for window"); + surface.buffer = vec![0; (width * height) as usize]; } fn fetch_information(&self) -> Information { @@ -84,13 +102,33 @@ pub fn new<Theme>(settings: Settings) -> (Compositor<Theme>, Backend) { pub fn present<Theme, T: AsRef<str>>( _compositor: &mut Compositor<Theme>, - _backend: &mut Backend, - _surface: &mut Surface, - _primitives: &[Primitive], - _viewport: &Viewport, - _background_color: Color, - _overlay: &[T], + backend: &mut Backend, + surface: &mut Surface, + primitives: &[Primitive], + viewport: &Viewport, + background_color: Color, + overlay: &[T], ) -> Result<(), compositor::SurfaceError> { + backend.draw( + &mut surface.pixels, + primitives, + viewport, + background_color, + overlay, + ); + + for (i, pixel) in surface.pixels.pixels_mut().iter().enumerate() { + surface.buffer[i] = u32::from(pixel.red()) << 16 + | u32::from(pixel.green()) << 8 + | u32::from(pixel.blue()); + } + + surface.window.set_buffer( + &surface.buffer, + surface.pixels.width() as u16, + surface.pixels.height() as u16, + ); + // TODO Ok(()) } diff --git a/wgpu/src/window/compositor.rs b/wgpu/src/window/compositor.rs index 7406bfb8..3a4a7123 100644 --- a/wgpu/src/window/compositor.rs +++ b/wgpu/src/window/compositor.rs @@ -201,11 +201,15 @@ impl<Theme> iced_graphics::window::Compositor for Compositor<Theme> { fn create_surface<W: HasRawWindowHandle + HasRawDisplayHandle>( &mut self, window: &W, + width: u32, + height: u32, ) -> wgpu::Surface { #[allow(unsafe_code)] - unsafe { - self.instance.create_surface(window) - } + let mut surface = unsafe { self.instance.create_surface(window) }; + + self.configure_surface(&mut surface, width, height); + + surface } fn configure_surface( diff --git a/winit/src/application.rs b/winit/src/application.rs index 1bfce3a1..b52f0197 100644 --- a/winit/src/application.rs +++ b/winit/src/application.rs @@ -285,21 +285,18 @@ async fn run_instance<A, E, C>( use winit::event; use winit::event_loop::ControlFlow; - let mut clipboard = Clipboard::connect(&window); - let mut cache = user_interface::Cache::default(); - let mut surface = compositor.create_surface(&window); - let mut should_exit = false; - let mut state = State::new(&application, &window); let mut viewport_version = state.viewport_version(); - let physical_size = state.physical_size(); - compositor.configure_surface( - &mut surface, + let mut clipboard = Clipboard::connect(&window); + let mut cache = user_interface::Cache::default(); + let mut surface = compositor.create_surface( + &window, physical_size.width, physical_size.height, ); + let mut should_exit = false; if should_be_visible { window.set_visible(true); |