Implement basic presentation with softbuffer for iced_tiny_skia

This commit is contained in:
Héctor Ramón Jiménez 2023-02-25 16:05:42 +01:00
parent 8c373cd497
commit 535d7a4d57
No known key found for this signature in database
GPG key ID: 140CC052C94F138E
6 changed files with 90 additions and 30 deletions

View file

@ -28,6 +28,8 @@ pub trait Compositor: Sized {
fn create_surface<W: HasRawWindowHandle + HasRawDisplayHandle>( fn create_surface<W: HasRawWindowHandle + HasRawDisplayHandle>(
&mut self, &mut self,
window: &W, window: &W,
width: u32,
height: u32,
) -> Self::Surface; ) -> Self::Surface;
/// Configures a new [`Surface`] with the given dimensions. /// Configures a new [`Surface`] with the given dimensions.

View file

@ -52,14 +52,16 @@ impl<Theme> iced_graphics::window::Compositor for Compositor<Theme> {
fn create_surface<W: HasRawWindowHandle + HasRawDisplayHandle>( fn create_surface<W: HasRawWindowHandle + HasRawDisplayHandle>(
&mut self, &mut self,
window: &W, window: &W,
width: u32,
height: u32,
) -> Surface { ) -> Surface {
match self { match self {
Self::Wgpu(compositor) => { Self::Wgpu(compositor) => {
Surface::Wgpu(compositor.create_surface(window)) Surface::Wgpu(compositor.create_surface(window, width, height))
}
Self::TinySkia(compositor) => {
Surface::TinySkia(compositor.create_surface(window))
} }
Self::TinySkia(compositor) => Surface::TinySkia(
compositor.create_surface(window, width, height),
),
} }
} }

View file

@ -1,7 +1,8 @@
use crate::{Font, Settings, Size}; use crate::{Color, Font, Settings, Size, Viewport};
use iced_graphics::backend; use iced_graphics::backend;
use iced_graphics::text; use iced_graphics::text;
use iced_graphics::Primitive;
use std::borrow::Cow; use std::borrow::Cow;
@ -17,6 +18,22 @@ impl Backend {
default_text_size: settings.default_text_size, 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 { impl iced_graphics::Backend for Backend {

View file

@ -10,7 +10,11 @@ pub struct Compositor<Theme> {
_theme: PhantomData<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> { impl<Theme> iced_graphics::window::Compositor for Compositor<Theme> {
type Settings = Settings; type Settings = Settings;
@ -28,19 +32,33 @@ impl<Theme> iced_graphics::window::Compositor for Compositor<Theme> {
fn create_surface<W: HasRawWindowHandle + HasRawDisplayHandle>( fn create_surface<W: HasRawWindowHandle + HasRawDisplayHandle>(
&mut self, &mut self,
_window: &W, window: &W,
width: u32,
height: u32,
) -> Surface { ) -> Surface {
// TODO let window =
Surface 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( fn configure_surface(
&mut self, &mut self,
_surface: &mut Surface, surface: &mut Surface,
_width: u32, width: u32,
_height: 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 { 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>>( pub fn present<Theme, T: AsRef<str>>(
_compositor: &mut Compositor<Theme>, _compositor: &mut Compositor<Theme>,
_backend: &mut Backend, backend: &mut Backend,
_surface: &mut Surface, surface: &mut Surface,
_primitives: &[Primitive], primitives: &[Primitive],
_viewport: &Viewport, viewport: &Viewport,
_background_color: Color, background_color: Color,
_overlay: &[T], overlay: &[T],
) -> Result<(), compositor::SurfaceError> { ) -> 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 // TODO
Ok(()) Ok(())
} }

View file

@ -201,11 +201,15 @@ impl<Theme> iced_graphics::window::Compositor for Compositor<Theme> {
fn create_surface<W: HasRawWindowHandle + HasRawDisplayHandle>( fn create_surface<W: HasRawWindowHandle + HasRawDisplayHandle>(
&mut self, &mut self,
window: &W, window: &W,
width: u32,
height: u32,
) -> wgpu::Surface { ) -> wgpu::Surface {
#[allow(unsafe_code)] #[allow(unsafe_code)]
unsafe { let mut surface = unsafe { self.instance.create_surface(window) };
self.instance.create_surface(window)
} self.configure_surface(&mut surface, width, height);
surface
} }
fn configure_surface( fn configure_surface(

View file

@ -285,21 +285,18 @@ async fn run_instance<A, E, C>(
use winit::event; use winit::event;
use winit::event_loop::ControlFlow; 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 state = State::new(&application, &window);
let mut viewport_version = state.viewport_version(); let mut viewport_version = state.viewport_version();
let physical_size = state.physical_size(); let physical_size = state.physical_size();
compositor.configure_surface( let mut clipboard = Clipboard::connect(&window);
&mut surface, let mut cache = user_interface::Cache::default();
let mut surface = compositor.create_surface(
&window,
physical_size.width, physical_size.width,
physical_size.height, physical_size.height,
); );
let mut should_exit = false;
if should_be_visible { if should_be_visible {
window.set_visible(true); window.set_visible(true);