summaryrefslogtreecommitdiffstats
path: root/wgpu
diff options
context:
space:
mode:
authorLibravatar Héctor Ramón Jiménez <hector@hecrj.dev>2024-04-09 22:25:16 +0200
committerLibravatar Héctor Ramón Jiménez <hector@hecrj.dev>2024-04-09 22:25:16 +0200
commit6ad5bb3597f640ac329801adf735d633bf0a512f (patch)
treef0928edacd09d6537878d22b00ad7ed7829c9ac0 /wgpu
parent2c6fd9ac14c5d270e05b97b7a7fab811d25834c4 (diff)
downloadiced-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.rs24
-rw-r--r--wgpu/src/layer.rs301
-rw-r--r--wgpu/src/lib.rs58
-rw-r--r--wgpu/src/primitive.rs6
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.")
})
}
}