Use pixels for presentation in iced_tiny_skia when possible

This commit is contained in:
Héctor Ramón Jiménez 2023-04-08 05:58:27 +02:00
parent 3ee367355d
commit 16e6efe020
No known key found for this signature in database
GPG key ID: 140CC052C94F138E
2 changed files with 69 additions and 13 deletions

View file

@ -4,6 +4,8 @@ version = "0.1.0"
edition = "2021" edition = "2021"
[features] [features]
default = ["gpu"]
gpu = ["pixels"]
image = ["iced_graphics/image"] image = ["iced_graphics/image"]
svg = ["resvg"] svg = ["resvg"]
geometry = ["iced_graphics/geometry"] geometry = ["iced_graphics/geometry"]
@ -31,6 +33,10 @@ default-features = false
version = "1.6.1" version = "1.6.1"
features = ["std"] features = ["std"]
[dependencies.pixels]
version = "0.12"
optional = true
[dependencies.resvg] [dependencies.resvg]
version = "0.29" version = "0.29"
optional = true optional = true

View file

@ -11,9 +11,13 @@ pub struct Compositor<Theme> {
_theme: PhantomData<Theme>, _theme: PhantomData<Theme>,
} }
pub struct Surface { pub enum Surface {
window: softbuffer::GraphicsContext, Cpu {
buffer: Vec<u32>, window: softbuffer::GraphicsContext,
buffer: Vec<u32>,
},
#[cfg(feature = "gpu")]
Gpu { pixels: pixels::Pixels },
} }
impl<Theme> crate::graphics::Compositor for Compositor<Theme> { impl<Theme> crate::graphics::Compositor for Compositor<Theme> {
@ -36,11 +40,29 @@ impl<Theme> crate::graphics::Compositor for Compositor<Theme> {
width: u32, width: u32,
height: u32, height: u32,
) -> Surface { ) -> Surface {
#[cfg(feature = "gpu")]
{
let surface_texture =
pixels::SurfaceTexture::new(width, height, window);
if let Ok(pixels) =
pixels::PixelsBuilder::new(width, height, surface_texture)
.texture_format(pixels::wgpu::TextureFormat::Bgra8UnormSrgb)
.build()
{
log::info!("GPU surface created");
return Surface::Gpu { pixels };
}
}
let window = let window =
unsafe { softbuffer::GraphicsContext::new(window, window) } unsafe { softbuffer::GraphicsContext::new(window, window) }
.expect("Create softbuffer for window"); .expect("Create softbuffer for window");
Surface { log::info!("CPU surface created");
Surface::Cpu {
window, window,
buffer: vec![0; width as usize * height as usize], buffer: vec![0; width as usize * height as usize],
} }
@ -52,7 +74,19 @@ impl<Theme> crate::graphics::Compositor for Compositor<Theme> {
width: u32, width: u32,
height: u32, height: u32,
) { ) {
surface.buffer.resize((width * height) as usize, 0); match surface {
Surface::Cpu { buffer, .. } => {
buffer.resize((width * height) as usize, 0);
}
#[cfg(feature = "gpu")]
Surface::Gpu { pixels } => {
pixels
.resize_surface(width, height)
.expect("Resize surface");
pixels.resize_buffer(width, height).expect("Resize buffer");
}
}
} }
fn fetch_information(&self) -> Information { fn fetch_information(&self) -> Information {
@ -106,9 +140,15 @@ pub fn present<Theme, T: AsRef<str>>(
) -> Result<(), compositor::SurfaceError> { ) -> Result<(), compositor::SurfaceError> {
let physical_size = viewport.physical_size(); let physical_size = viewport.physical_size();
let buffer = match surface {
Surface::Cpu { buffer, .. } => bytemuck::cast_slice_mut(buffer),
#[cfg(feature = "gpu")]
Surface::Gpu { pixels } => pixels.frame_mut(),
};
let drawn = backend.draw( let drawn = backend.draw(
&mut tiny_skia::PixmapMut::from_bytes( &mut tiny_skia::PixmapMut::from_bytes(
bytemuck::cast_slice_mut(&mut surface.buffer), buffer,
physical_size.width, physical_size.width,
physical_size.height, physical_size.height,
) )
@ -121,12 +161,22 @@ pub fn present<Theme, T: AsRef<str>>(
); );
if drawn { if drawn {
surface.window.set_buffer( match surface {
&surface.buffer, Surface::Cpu { window, buffer } => {
physical_size.width as u16, window.set_buffer(
physical_size.height as u16, buffer,
); physical_size.width as u16,
} physical_size.height as u16,
);
Ok(()) Ok(())
}
#[cfg(feature = "gpu")]
Surface::Gpu { pixels } => {
pixels.render().map_err(|_| compositor::SurfaceError::Lost)
}
}
} else {
Ok(())
}
} }