diff options
author | 2024-04-09 22:25:16 +0200 | |
---|---|---|
committer | 2024-04-09 22:25:16 +0200 | |
commit | 6ad5bb3597f640ac329801adf735d633bf0a512f (patch) | |
tree | f0928edacd09d6537878d22b00ad7ed7829c9ac0 /wgpu | |
parent | 2c6fd9ac14c5d270e05b97b7a7fab811d25834c4 (diff) | |
download | iced-6ad5bb3597f640ac329801adf735d633bf0a512f.tar.gz iced-6ad5bb3597f640ac329801adf735d633bf0a512f.tar.bz2 iced-6ad5bb3597f640ac329801adf735d633bf0a512f.zip |
Port `iced_tiny_skia` to new layering architecture
Diffstat (limited to 'wgpu')
-rw-r--r-- | wgpu/src/geometry.rs | 24 | ||||
-rw-r--r-- | wgpu/src/layer.rs | 301 | ||||
-rw-r--r-- | wgpu/src/lib.rs | 58 | ||||
-rw-r--r-- | wgpu/src/primitive.rs | 6 |
4 files changed, 173 insertions, 216 deletions
diff --git a/wgpu/src/geometry.rs b/wgpu/src/geometry.rs index 985650e2..60967082 100644 --- a/wgpu/src/geometry.rs +++ b/wgpu/src/geometry.rs @@ -19,18 +19,6 @@ use lyon::tessellation; use std::borrow::Cow; -/// A frame for drawing some geometry. -#[allow(missing_debug_implementations)] -pub struct Frame { - clip_bounds: Rectangle, - buffers: BufferStack, - meshes: Vec<Mesh>, - text: Vec<Text>, - transforms: Transforms, - fill_tessellator: tessellation::FillTessellator, - stroke_tessellator: tessellation::StrokeTessellator, -} - #[derive(Debug)] pub enum Geometry { Live { meshes: Vec<Mesh>, text: Vec<Text> }, @@ -79,6 +67,18 @@ impl Cached for Geometry { } } +/// A frame for drawing some geometry. +#[allow(missing_debug_implementations)] +pub struct Frame { + clip_bounds: Rectangle, + buffers: BufferStack, + meshes: Vec<Mesh>, + text: Vec<Text>, + transforms: Transforms, + fill_tessellator: tessellation::FillTessellator, + stroke_tessellator: tessellation::StrokeTessellator, +} + impl Frame { /// Creates a new [`Frame`] with the given [`Size`]. pub fn new(size: Size) -> Frame { diff --git a/wgpu/src/layer.rs b/wgpu/src/layer.rs index 7a18e322..9526c5a8 100644 --- a/wgpu/src/layer.rs +++ b/wgpu/src/layer.rs @@ -1,6 +1,8 @@ use crate::core::renderer; use crate::core::{Background, Color, Point, Rectangle, Transformation}; +use crate::graphics; use crate::graphics::color; +use crate::graphics::layer; use crate::graphics::text::{Editor, Paragraph}; use crate::graphics::Mesh; use crate::image::{self, Image}; @@ -9,6 +11,8 @@ use crate::quad::{self, Quad}; use crate::text::{self, Text}; use crate::triangle; +pub type Stack = layer::Stack<Layer>; + #[derive(Debug)] pub struct Layer { pub bounds: Rectangle, @@ -17,48 +21,18 @@ pub struct Layer { pub primitives: primitive::Batch, pub text: text::Batch, pub images: image::Batch, + pending_meshes: Vec<Mesh>, + pending_text: Vec<Text>, } -impl Default for Layer { - fn default() -> Self { - Self { - bounds: Rectangle::INFINITE, - quads: quad::Batch::default(), - triangles: triangle::Batch::default(), - primitives: primitive::Batch::default(), - text: text::Batch::default(), - images: image::Batch::default(), - } - } -} - -#[derive(Debug)] -pub struct Stack { - layers: Vec<Layer>, - transformations: Vec<Transformation>, - previous: Vec<usize>, - pending_meshes: Vec<Vec<Mesh>>, - pending_text: Vec<Vec<Text>>, - current: usize, - active_count: usize, -} - -impl Stack { - pub fn new() -> Self { - Self { - layers: vec![Layer::default()], - transformations: vec![Transformation::IDENTITY], - previous: vec![], - pending_meshes: vec![Vec::new()], - pending_text: vec![Vec::new()], - current: 0, - active_count: 1, - } - } - - pub fn draw_quad(&mut self, quad: renderer::Quad, background: Background) { - let transformation = self.transformations.last().unwrap(); - let bounds = quad.bounds * *transformation; +impl Layer { + pub fn draw_quad( + &mut self, + quad: renderer::Quad, + background: Background, + transformation: Transformation, + ) { + let bounds = quad.bounds * transformation; let quad = Quad { position: [bounds.x, bounds.y], @@ -71,7 +45,7 @@ impl Stack { shadow_blur_radius: quad.shadow.blur_radius, }; - self.layers[self.current].quads.add(quad, &background); + self.quads.add(quad, &background); } pub fn draw_paragraph( @@ -80,16 +54,17 @@ impl Stack { position: Point, color: Color, clip_bounds: Rectangle, + transformation: Transformation, ) { let paragraph = Text::Paragraph { paragraph: paragraph.downgrade(), position, color, clip_bounds, - transformation: self.transformations.last().copied().unwrap(), + transformation, }; - self.pending_text[self.current].push(paragraph); + self.pending_text.push(paragraph); } pub fn draw_editor( @@ -98,16 +73,17 @@ impl Stack { position: Point, color: Color, clip_bounds: Rectangle, + transformation: Transformation, ) { let editor = Text::Editor { editor: editor.downgrade(), position, color, clip_bounds, - transformation: self.transformation(), + transformation, }; - self.pending_text[self.current].push(editor); + self.pending_text.push(editor); } pub fn draw_text( @@ -116,9 +92,8 @@ impl Stack { position: Point, color: Color, clip_bounds: Rectangle, + transformation: Transformation, ) { - let transformation = self.transformation(); - let text = Text::Cached { content: text.content, bounds: Rectangle::new(position, text.bounds) * transformation, @@ -133,7 +108,7 @@ impl Stack { clip_bounds: clip_bounds * transformation, }; - self.pending_text[self.current].push(text); + self.pending_text.push(text); } pub fn draw_image( @@ -141,14 +116,15 @@ impl Stack { handle: crate::core::image::Handle, filter_method: crate::core::image::FilterMethod, bounds: Rectangle, + transformation: Transformation, ) { let image = Image::Raster { handle, filter_method, - bounds: bounds * self.transformation(), + bounds: bounds * transformation, }; - self.layers[self.current].images.push(image); + self.images.push(image); } pub fn draw_svg( @@ -156,72 +132,87 @@ impl Stack { handle: crate::core::svg::Handle, color: Option<Color>, bounds: Rectangle, + transformation: Transformation, ) { let svg = Image::Vector { handle, color, - bounds: bounds * self.transformation(), + bounds: bounds * transformation, }; - self.layers[self.current].images.push(svg); + self.images.push(svg); } - pub fn draw_mesh(&mut self, mut mesh: Mesh) { + pub fn draw_mesh( + &mut self, + mut mesh: Mesh, + transformation: Transformation, + ) { match &mut mesh { - Mesh::Solid { transformation, .. } - | Mesh::Gradient { transformation, .. } => { - *transformation = *transformation * self.transformation(); + Mesh::Solid { + transformation: local_transformation, + .. + } + | Mesh::Gradient { + transformation: local_transformation, + .. + } => { + *local_transformation = *local_transformation * transformation; } } - self.pending_meshes[self.current].push(mesh); + self.pending_meshes.push(mesh); } - pub fn draw_mesh_group(&mut self, meshes: Vec<Mesh>) { - self.flush_pending(); - - let transformation = self.transformation(); + pub fn draw_mesh_group( + &mut self, + meshes: Vec<Mesh>, + transformation: Transformation, + ) { + self.flush_meshes(); - self.layers[self.current] - .triangles - .push(triangle::Item::Group { - transformation, - meshes, - }); + self.triangles.push(triangle::Item::Group { + meshes, + transformation, + }); } - pub fn draw_mesh_cache(&mut self, cache: triangle::Cache) { - self.flush_pending(); - - let transformation = self.transformation(); + pub fn draw_mesh_cache( + &mut self, + cache: triangle::Cache, + transformation: Transformation, + ) { + self.flush_meshes(); - self.layers[self.current] - .triangles - .push(triangle::Item::Cached { - transformation, - cache, - }); + self.triangles.push(triangle::Item::Cached { + cache, + transformation, + }); } - pub fn draw_text_group(&mut self, text: Vec<Text>) { - self.flush_pending(); - - let transformation = self.transformation(); + pub fn draw_text_group( + &mut self, + text: Vec<Text>, + transformation: Transformation, + ) { + self.flush_text(); - self.layers[self.current].text.push(text::Item::Group { - transformation, + self.text.push(text::Item::Group { text, + transformation, }); } - pub fn draw_text_cache(&mut self, cache: text::Cache) { - self.flush_pending(); - - let transformation = self.transformation(); + pub fn draw_text_cache( + &mut self, + cache: text::Cache, + transformation: Transformation, + ) { + self.flush_text(); - self.layers[self.current].text.push(text::Item::Cached { - transformation, + self.text.push(text::Item::Cached { cache, + transformation, }); } @@ -229,112 +220,74 @@ impl Stack { &mut self, bounds: Rectangle, primitive: Box<dyn Primitive>, + transformation: Transformation, ) { - let bounds = bounds * self.transformation(); + let bounds = bounds * transformation; - self.layers[self.current] - .primitives + self.primitives .push(primitive::Instance { bounds, primitive }); } - pub fn push_clip(&mut self, bounds: Rectangle) { - self.previous.push(self.current); - - self.current = self.active_count; - self.active_count += 1; - - let bounds = bounds * self.transformation(); - - if self.current == self.layers.len() { - self.layers.push(Layer { - bounds, - ..Layer::default() + fn flush_meshes(&mut self) { + if !self.pending_meshes.is_empty() { + self.triangles.push(triangle::Item::Group { + transformation: Transformation::IDENTITY, + meshes: self.pending_meshes.drain(..).collect(), }); - self.pending_meshes.push(Vec::new()); - self.pending_text.push(Vec::new()); - } else { - self.layers[self.current].bounds = bounds; } } - pub fn pop_clip(&mut self) { - self.flush_pending(); - - self.current = self.previous.pop().unwrap(); - } - - pub fn push_transformation(&mut self, transformation: Transformation) { - self.flush_pending(); - - self.transformations - .push(self.transformation() * transformation); - } - - pub fn pop_transformation(&mut self) { - let _ = self.transformations.pop(); - } - - fn transformation(&self) -> Transformation { - self.transformations.last().copied().unwrap() + fn flush_text(&mut self) { + if !self.pending_text.is_empty() { + self.text.push(text::Item::Group { + transformation: Transformation::IDENTITY, + text: self.pending_text.drain(..).collect(), + }); + } } +} - pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut Layer> { - self.flush_pending(); - - self.layers[..self.active_count].iter_mut() +impl graphics::Layer for Layer { + fn with_bounds(bounds: Rectangle) -> Self { + Self { + bounds, + ..Self::default() + } } - pub fn iter(&self) -> impl Iterator<Item = &Layer> { - self.layers[..self.active_count].iter() + fn flush(&mut self) { + self.flush_meshes(); + self.flush_text(); } - pub fn clear(&mut self) { - for (live, pending_meshes) in self.layers[..self.active_count] - .iter_mut() - .zip(self.pending_meshes.iter_mut()) - { - live.bounds = Rectangle::INFINITE; - - live.quads.clear(); - live.triangles.clear(); - live.primitives.clear(); - live.text.clear(); - live.images.clear(); - pending_meshes.clear(); - } - - self.current = 0; - self.active_count = 1; - self.previous.clear(); + fn resize(&mut self, bounds: Rectangle) { + self.bounds = bounds; } - // We want to keep the allocated memory - #[allow(clippy::drain_collect)] - fn flush_pending(&mut self) { - let transformation = self.transformation(); - - let pending_meshes = &mut self.pending_meshes[self.current]; - if !pending_meshes.is_empty() { - self.layers[self.current] - .triangles - .push(triangle::Item::Group { - transformation, - meshes: pending_meshes.drain(..).collect(), - }); - } + fn reset(&mut self) { + self.bounds = Rectangle::INFINITE; - let pending_text = &mut self.pending_text[self.current]; - if !pending_text.is_empty() { - self.layers[self.current].text.push(text::Item::Group { - transformation, - text: pending_text.drain(..).collect(), - }); - } + self.quads.clear(); + self.triangles.clear(); + self.primitives.clear(); + self.text.clear(); + self.images.clear(); + self.pending_meshes.clear(); + self.pending_text.clear(); } } -impl Default for Stack { +impl Default for Layer { fn default() -> Self { - Self::new() + Self { + bounds: Rectangle::INFINITE, + quads: quad::Batch::default(), + triangles: triangle::Batch::default(), + primitives: primitive::Batch::default(), + text: text::Batch::default(), + images: image::Batch::default(), + pending_meshes: Vec::new(), + pending_text: Vec::new(), + } } } diff --git a/wgpu/src/lib.rs b/wgpu/src/lib.rs index b1ae4e89..178522de 100644 --- a/wgpu/src/lib.rs +++ b/wgpu/src/lib.rs @@ -66,8 +66,6 @@ use crate::core::{ use crate::graphics::text::{Editor, Paragraph}; use crate::graphics::Viewport; -use std::borrow::Cow; - /// A [`wgpu`] graphics renderer for [`iced`]. /// /// [`wgpu`]: https://github.com/gfx-rs/wgpu-rs @@ -422,7 +420,7 @@ impl core::Renderer for Renderer { self.layers.push_clip(bounds); } - fn end_layer(&mut self, _bounds: Rectangle) { + fn end_layer(&mut self) { self.layers.pop_clip(); } @@ -430,7 +428,7 @@ impl core::Renderer for Renderer { self.layers.push_transformation(transformation); } - fn end_transformation(&mut self, _transformation: Transformation) { + fn end_transformation(&mut self) { self.layers.pop_transformation(); } @@ -439,7 +437,8 @@ impl core::Renderer for Renderer { quad: core::renderer::Quad, background: impl Into<Background>, ) { - self.layers.draw_quad(quad, background.into()); + let (layer, transformation) = self.layers.current_mut(); + layer.draw_quad(quad, background.into(), transformation); } fn clear(&mut self) { @@ -464,15 +463,6 @@ impl core::text::Renderer for Renderer { self.default_text_size } - fn load_font(&mut self, font: Cow<'static, [u8]>) { - graphics::text::font_system() - .write() - .expect("Write font system") - .load_font(font); - - // TODO: Invalidate buffer cache - } - fn fill_paragraph( &mut self, text: &Self::Paragraph, @@ -480,8 +470,15 @@ impl core::text::Renderer for Renderer { color: Color, clip_bounds: Rectangle, ) { - self.layers - .draw_paragraph(text, position, color, clip_bounds); + let (layer, transformation) = self.layers.current_mut(); + + layer.draw_paragraph( + text, + position, + color, + clip_bounds, + transformation, + ); } fn fill_editor( @@ -491,8 +488,8 @@ impl core::text::Renderer for Renderer { color: Color, clip_bounds: Rectangle, ) { - self.layers - .draw_editor(editor, position, color, clip_bounds); + let (layer, transformation) = self.layers.current_mut(); + layer.draw_editor(editor, position, color, clip_bounds, transformation); } fn fill_text( @@ -502,7 +499,8 @@ impl core::text::Renderer for Renderer { color: Color, clip_bounds: Rectangle, ) { - self.layers.draw_text(text, position, color, clip_bounds); + let (layer, transformation) = self.layers.current_mut(); + layer.draw_text(text, position, color, clip_bounds, transformation); } } @@ -520,7 +518,8 @@ impl core::image::Renderer for Renderer { filter_method: core::image::FilterMethod, bounds: Rectangle, ) { - self.layers.draw_image(handle, filter_method, bounds); + let (layer, transformation) = self.layers.current_mut(); + layer.draw_image(handle, filter_method, bounds, transformation); } } @@ -536,13 +535,15 @@ impl core::svg::Renderer for Renderer { color_filter: Option<Color>, bounds: Rectangle, ) { - self.layers.draw_svg(handle, color_filter, bounds); + let (layer, transformation) = self.layers.current_mut(); + layer.draw_svg(handle, color_filter, bounds, transformation); } } impl graphics::mesh::Renderer for Renderer { fn draw_mesh(&mut self, mesh: graphics::Mesh) { - self.layers.draw_mesh(mesh); + let (layer, transformation) = self.layers.current_mut(); + layer.draw_mesh(mesh, transformation); } } @@ -556,18 +557,20 @@ impl graphics::geometry::Renderer for Renderer { } fn draw_geometry(&mut self, geometry: Self::Geometry) { + let (layer, transformation) = self.layers.current_mut(); + match geometry { Geometry::Live { meshes, text } => { - self.layers.draw_mesh_group(meshes); - self.layers.draw_text_group(text); + layer.draw_mesh_group(meshes, transformation); + layer.draw_text_group(text, transformation); } Geometry::Cached(cache) => { if let Some(meshes) = cache.meshes { - self.layers.draw_mesh_cache(meshes); + layer.draw_mesh_cache(meshes, transformation); } if let Some(text) = cache.text { - self.layers.draw_text_cache(text); + layer.draw_text_cache(text, transformation); } } } @@ -576,7 +579,8 @@ impl graphics::geometry::Renderer for Renderer { impl primitive::Renderer for Renderer { fn draw_primitive(&mut self, bounds: Rectangle, primitive: impl Primitive) { - self.layers.draw_primitive(bounds, Box::new(primitive)); + let (layer, transformation) = self.layers.current_mut(); + layer.draw_primitive(bounds, Box::new(primitive), transformation); } } diff --git a/wgpu/src/primitive.rs b/wgpu/src/primitive.rs index 4ba1ed9a..1313e752 100644 --- a/wgpu/src/primitive.rs +++ b/wgpu/src/primitive.rs @@ -43,7 +43,7 @@ pub struct Instance { } impl Instance { - /// Creates a new [`Pipeline`] with the given [`Primitive`]. + /// Creates a new [`Instance`] with the given [`Primitive`]. pub fn new(bounds: Rectangle, primitive: impl Primitive) -> Self { Instance { bounds, @@ -80,7 +80,7 @@ impl Storage { self.pipelines.get(&TypeId::of::<T>()).map(|pipeline| { pipeline .downcast_ref::<T>() - .expect("Pipeline with this type does not exist in Storage.") + .expect("Value with this type does not exist in Storage.") }) } @@ -89,7 +89,7 @@ impl Storage { self.pipelines.get_mut(&TypeId::of::<T>()).map(|pipeline| { pipeline .downcast_mut::<T>() - .expect("Pipeline with this type does not exist in Storage.") + .expect("Value with this type does not exist in Storage.") }) } } |