From 0ae1baa37bd7b6607f79b33b8a6d8c5daafde0b2 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Thu, 22 Jun 2023 00:38:36 +0200 Subject: Introduce custom backend-specific primitives --- wgpu/src/backend.rs | 7 ++++++- wgpu/src/geometry.rs | 6 +++--- wgpu/src/layer.rs | 11 +++-------- wgpu/src/lib.rs | 6 ++++-- wgpu/src/primitive.rs | 3 +++ wgpu/src/window/compositor.rs | 4 ++-- 6 files changed, 21 insertions(+), 16 deletions(-) create mode 100644 wgpu/src/primitive.rs (limited to 'wgpu/src') diff --git a/wgpu/src/backend.rs b/wgpu/src/backend.rs index f8829e47..596d43c5 100644 --- a/wgpu/src/backend.rs +++ b/wgpu/src/backend.rs @@ -2,7 +2,8 @@ use crate::core; use crate::core::{Color, Font, Point, Size}; use crate::graphics::backend; use crate::graphics::color; -use crate::graphics::{Primitive, Transformation, Viewport}; +use crate::graphics::{Transformation, Viewport}; +use crate::primitive::{self, Primitive}; use crate::quad; use crate::text; use crate::triangle; @@ -334,6 +335,10 @@ impl Backend { } } +impl crate::graphics::Backend for Backend { + type Primitive = primitive::Custom; +} + impl backend::Text for Backend { const ICON_FONT: Font = Font::with_name("Iced-Icons"); const CHECKMARK_ICON: char = '\u{f00c}'; diff --git a/wgpu/src/geometry.rs b/wgpu/src/geometry.rs index f81b5b2f..d43f1065 100644 --- a/wgpu/src/geometry.rs +++ b/wgpu/src/geometry.rs @@ -5,10 +5,10 @@ use crate::graphics::geometry::fill::{self, Fill}; use crate::graphics::geometry::{ LineCap, LineDash, LineJoin, Path, Stroke, Style, Text, }; -use crate::graphics::primitive::{self, Primitive}; -use crate::graphics::Gradient; +use crate::graphics::gradient::{self, Gradient}; +use crate::graphics::primitive; +use crate::Primitive; -use iced_graphics::gradient; use lyon::geom::euclid; use lyon::tessellation; use std::borrow::Cow; diff --git a/wgpu/src/layer.rs b/wgpu/src/layer.rs index 71570e3d..ef850cd9 100644 --- a/wgpu/src/layer.rs +++ b/wgpu/src/layer.rs @@ -12,8 +12,9 @@ use crate::core; use crate::core::alignment; use crate::core::{Color, Font, Point, Rectangle, Size, Vector}; use crate::graphics::color; -use crate::graphics::{Primitive, Viewport}; +use crate::graphics::Viewport; use crate::quad::{self, Quad}; +use crate::Primitive; /// A group of primitives that should be clipped together. #[derive(Debug)] @@ -262,13 +263,7 @@ impl<'a> Layer<'a> { current_layer, ); } - _ => { - // Not supported! - log::warn!( - "Unsupported primitive in `iced_wgpu`: {:?}", - primitive - ); - } + Primitive::Custom(()) => {} } } } diff --git a/wgpu/src/lib.rs b/wgpu/src/lib.rs index 86a962a5..79dfdd24 100644 --- a/wgpu/src/lib.rs +++ b/wgpu/src/lib.rs @@ -24,8 +24,8 @@ html_logo_url = "https://raw.githubusercontent.com/iced-rs/iced/9ab6923e943f784985e9ef9ca28b10278297225d/docs/logo.svg" )] #![deny( - missing_debug_implementations, - missing_docs, + //missing_debug_implementations, + //missing_docs, unsafe_code, unused_results, clippy::extra_unused_lifetimes, @@ -47,6 +47,7 @@ pub mod geometry; mod backend; mod buffer; mod color; +mod primitive; mod quad; mod text; mod triangle; @@ -60,6 +61,7 @@ pub use wgpu; pub use backend::Backend; pub use layer::Layer; +pub use primitive::Primitive; pub use settings::Settings; #[cfg(any(feature = "image", feature = "svg"))] diff --git a/wgpu/src/primitive.rs b/wgpu/src/primitive.rs new file mode 100644 index 00000000..2e31cd53 --- /dev/null +++ b/wgpu/src/primitive.rs @@ -0,0 +1,3 @@ +pub type Primitive = crate::graphics::Primitive; + +pub type Custom = (); diff --git a/wgpu/src/window/compositor.rs b/wgpu/src/window/compositor.rs index 1cfd7b67..cd5b20cc 100644 --- a/wgpu/src/window/compositor.rs +++ b/wgpu/src/window/compositor.rs @@ -3,8 +3,8 @@ use crate::core::{Color, Size}; use crate::graphics; use crate::graphics::color; use crate::graphics::compositor; -use crate::graphics::{Error, Primitive, Viewport}; -use crate::{Backend, Renderer, Settings}; +use crate::graphics::{Error, Viewport}; +use crate::{Backend, Primitive, Renderer, Settings}; use futures::stream::{self, StreamExt}; -- cgit From fa5650cfd1115e6ccec2ad795cf58fd970d5b43c Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Thu, 29 Jun 2023 07:48:03 +0200 Subject: Decouple `Mesh` primitives from main `Primitive` type --- wgpu/src/geometry.rs | 64 +++++++++++++++++++------------------ wgpu/src/layer.rs | 86 +++++++++++++++++++++++++++++--------------------- wgpu/src/layer/mesh.rs | 6 ++-- wgpu/src/lib.rs | 2 +- wgpu/src/primitive.rs | 16 +++++++++- wgpu/src/triangle.rs | 75 ++++++++++++++++++++++--------------------- 6 files changed, 142 insertions(+), 107 deletions(-) (limited to 'wgpu/src') diff --git a/wgpu/src/geometry.rs b/wgpu/src/geometry.rs index d43f1065..e421e0b0 100644 --- a/wgpu/src/geometry.rs +++ b/wgpu/src/geometry.rs @@ -6,8 +6,8 @@ use crate::graphics::geometry::{ LineCap, LineDash, LineJoin, Path, Stroke, Style, Text, }; use crate::graphics::gradient::{self, Gradient}; -use crate::graphics::primitive; -use crate::Primitive; +use crate::graphics::mesh::{self, Mesh}; +use crate::primitive::{self, Primitive}; use lyon::geom::euclid; use lyon::tessellation; @@ -25,8 +25,8 @@ pub struct Frame { } enum Buffer { - Solid(tessellation::VertexBuffers), - Gradient(tessellation::VertexBuffers), + Solid(tessellation::VertexBuffers), + Gradient(tessellation::VertexBuffers), } struct BufferStack { @@ -464,24 +464,28 @@ impl Frame { match buffer { Buffer::Solid(buffer) => { if !buffer.indices.is_empty() { - self.primitives.push(Primitive::SolidMesh { - buffers: primitive::Mesh2D { - vertices: buffer.vertices, - indices: buffer.indices, - }, - size: self.size, - }) + self.primitives.push(Primitive::Custom( + primitive::Custom::Mesh(Mesh::Solid { + buffers: mesh::Indexed { + vertices: buffer.vertices, + indices: buffer.indices, + }, + size: self.size, + }), + )) } } Buffer::Gradient(buffer) => { if !buffer.indices.is_empty() { - self.primitives.push(Primitive::GradientMesh { - buffers: primitive::Mesh2D { - vertices: buffer.vertices, - indices: buffer.indices, - }, - size: self.size, - }) + self.primitives.push(Primitive::Custom( + primitive::Custom::Mesh(Mesh::Gradient { + buffers: mesh::Indexed { + vertices: buffer.vertices, + indices: buffer.indices, + }, + size: self.size, + }), + )) } } } @@ -495,32 +499,32 @@ struct GradientVertex2DBuilder { gradient: gradient::Packed, } -impl tessellation::FillVertexConstructor +impl tessellation::FillVertexConstructor for GradientVertex2DBuilder { fn new_vertex( &mut self, vertex: tessellation::FillVertex<'_>, - ) -> primitive::GradientVertex2D { + ) -> mesh::GradientVertex2D { let position = vertex.position(); - primitive::GradientVertex2D { + mesh::GradientVertex2D { position: [position.x, position.y], gradient: self.gradient, } } } -impl tessellation::StrokeVertexConstructor +impl tessellation::StrokeVertexConstructor for GradientVertex2DBuilder { fn new_vertex( &mut self, vertex: tessellation::StrokeVertex<'_, '_>, - ) -> primitive::GradientVertex2D { + ) -> mesh::GradientVertex2D { let position = vertex.position(); - primitive::GradientVertex2D { + mesh::GradientVertex2D { position: [position.x, position.y], gradient: self.gradient, } @@ -529,32 +533,32 @@ impl tessellation::StrokeVertexConstructor struct TriangleVertex2DBuilder(color::Packed); -impl tessellation::FillVertexConstructor +impl tessellation::FillVertexConstructor for TriangleVertex2DBuilder { fn new_vertex( &mut self, vertex: tessellation::FillVertex<'_>, - ) -> primitive::ColoredVertex2D { + ) -> mesh::SolidVertex2D { let position = vertex.position(); - primitive::ColoredVertex2D { + mesh::SolidVertex2D { position: [position.x, position.y], color: self.0, } } } -impl tessellation::StrokeVertexConstructor +impl tessellation::StrokeVertexConstructor for TriangleVertex2DBuilder { fn new_vertex( &mut self, vertex: tessellation::StrokeVertex<'_, '_>, - ) -> primitive::ColoredVertex2D { + ) -> mesh::SolidVertex2D { let position = vertex.position(); - primitive::ColoredVertex2D { + mesh::SolidVertex2D { position: [position.x, position.y], color: self.0, } diff --git a/wgpu/src/layer.rs b/wgpu/src/layer.rs index ef850cd9..b8f32db1 100644 --- a/wgpu/src/layer.rs +++ b/wgpu/src/layer.rs @@ -11,10 +11,11 @@ pub use text::Text; use crate::core; use crate::core::alignment; use crate::core::{Color, Font, Point, Rectangle, Size, Vector}; +use crate::graphics; use crate::graphics::color; use crate::graphics::Viewport; +use crate::primitive::{self, Primitive}; use crate::quad::{self, Quad}; -use crate::Primitive; /// A group of primitives that should be clipped together. #[derive(Debug)] @@ -180,40 +181,6 @@ impl<'a> Layer<'a> { bounds: *bounds + translation, }); } - Primitive::SolidMesh { buffers, size } => { - let layer = &mut layers[current_layer]; - - let bounds = Rectangle::new( - Point::new(translation.x, translation.y), - *size, - ); - - // Only draw visible content - if let Some(clip_bounds) = layer.bounds.intersection(&bounds) { - layer.meshes.push(Mesh::Solid { - origin: Point::new(translation.x, translation.y), - buffers, - clip_bounds, - }); - } - } - Primitive::GradientMesh { buffers, size } => { - let layer = &mut layers[current_layer]; - - let bounds = Rectangle::new( - Point::new(translation.x, translation.y), - *size, - ); - - // Only draw visible content - if let Some(clip_bounds) = layer.bounds.intersection(&bounds) { - layer.meshes.push(Mesh::Gradient { - origin: Point::new(translation.x, translation.y), - buffers, - clip_bounds, - }); - } - } Primitive::Group { primitives } => { // TODO: Inspect a bit and regroup (?) for primitive in primitives { @@ -263,7 +230,54 @@ impl<'a> Layer<'a> { current_layer, ); } - Primitive::Custom(()) => {} + Primitive::Custom(custom) => match custom { + primitive::Custom::Mesh(mesh) => match mesh { + graphics::Mesh::Solid { buffers, size } => { + let layer = &mut layers[current_layer]; + + let bounds = Rectangle::new( + Point::new(translation.x, translation.y), + *size, + ); + + // Only draw visible content + if let Some(clip_bounds) = + layer.bounds.intersection(&bounds) + { + layer.meshes.push(Mesh::Solid { + origin: Point::new( + translation.x, + translation.y, + ), + buffers, + clip_bounds, + }); + } + } + graphics::Mesh::Gradient { buffers, size } => { + let layer = &mut layers[current_layer]; + + let bounds = Rectangle::new( + Point::new(translation.x, translation.y), + *size, + ); + + // Only draw visible content + if let Some(clip_bounds) = + layer.bounds.intersection(&bounds) + { + layer.meshes.push(Mesh::Gradient { + origin: Point::new( + translation.x, + translation.y, + ), + buffers, + clip_bounds, + }); + } + } + }, + }, } } } diff --git a/wgpu/src/layer/mesh.rs b/wgpu/src/layer/mesh.rs index b7dd9a0b..7c6206cd 100644 --- a/wgpu/src/layer/mesh.rs +++ b/wgpu/src/layer/mesh.rs @@ -1,6 +1,6 @@ //! A collection of triangle primitives. use crate::core::{Point, Rectangle}; -use crate::graphics::primitive; +use crate::graphics::mesh; /// A mesh of triangles. #[derive(Debug, Clone, Copy)] @@ -11,7 +11,7 @@ pub enum Mesh<'a> { origin: Point, /// The vertex and index buffers of the [`Mesh`]. - buffers: &'a primitive::Mesh2D, + buffers: &'a mesh::Indexed, /// The clipping bounds of the [`Mesh`]. clip_bounds: Rectangle, @@ -22,7 +22,7 @@ pub enum Mesh<'a> { origin: Point, /// The vertex and index buffers of the [`Mesh`]. - buffers: &'a primitive::Mesh2D, + buffers: &'a mesh::Indexed, /// The clipping bounds of the [`Mesh`]. clip_bounds: Rectangle, diff --git a/wgpu/src/lib.rs b/wgpu/src/lib.rs index 79dfdd24..0ffaeeef 100644 --- a/wgpu/src/lib.rs +++ b/wgpu/src/lib.rs @@ -38,6 +38,7 @@ #![allow(clippy::inherent_to_string, clippy::type_complexity)] #![cfg_attr(docsrs, feature(doc_auto_cfg))] pub mod layer; +pub mod primitive; pub mod settings; pub mod window; @@ -47,7 +48,6 @@ pub mod geometry; mod backend; mod buffer; mod color; -mod primitive; mod quad; mod text; mod triangle; diff --git a/wgpu/src/primitive.rs b/wgpu/src/primitive.rs index 2e31cd53..a8f1119c 100644 --- a/wgpu/src/primitive.rs +++ b/wgpu/src/primitive.rs @@ -1,3 +1,17 @@ +use crate::core::Rectangle; +use crate::graphics::{Damage, Mesh}; + pub type Primitive = crate::graphics::Primitive; -pub type Custom = (); +#[derive(Debug, Clone, PartialEq)] +pub enum Custom { + Mesh(Mesh), +} + +impl Damage for Custom { + fn bounds(&self) -> Rectangle { + match self { + Self::Mesh(mesh) => mesh.bounds(), + } + } +} diff --git a/wgpu/src/triangle.rs b/wgpu/src/triangle.rs index 3f3635cf..d8b23dfe 100644 --- a/wgpu/src/triangle.rs +++ b/wgpu/src/triangle.rs @@ -393,7 +393,7 @@ impl Uniforms { } mod solid { - use crate::graphics::primitive; + use crate::graphics::mesh; use crate::graphics::Antialiasing; use crate::triangle; use crate::Buffer; @@ -406,7 +406,7 @@ mod solid { #[derive(Debug)] pub struct Layer { - pub vertices: Buffer, + pub vertices: Buffer, pub uniforms: Buffer, pub constants: wgpu::BindGroup, } @@ -493,38 +493,40 @@ mod solid { ), }); - let pipeline = device.create_render_pipeline( - &wgpu::RenderPipelineDescriptor { - label: Some("iced_wgpu::triangle::solid pipeline"), - layout: Some(&layout), - vertex: wgpu::VertexState { - module: &shader, - entry_point: "solid_vs_main", - buffers: &[wgpu::VertexBufferLayout { - array_stride: std::mem::size_of::< - primitive::ColoredVertex2D, - >() - as u64, - step_mode: wgpu::VertexStepMode::Vertex, - attributes: &wgpu::vertex_attr_array!( - // Position - 0 => Float32x2, - // Color - 1 => Float32x4, - ), - }], + let pipeline = + device.create_render_pipeline( + &wgpu::RenderPipelineDescriptor { + label: Some("iced_wgpu::triangle::solid pipeline"), + layout: Some(&layout), + vertex: wgpu::VertexState { + module: &shader, + entry_point: "solid_vs_main", + buffers: &[wgpu::VertexBufferLayout { + array_stride: std::mem::size_of::< + mesh::SolidVertex2D, + >( + ) + as u64, + step_mode: wgpu::VertexStepMode::Vertex, + attributes: &wgpu::vertex_attr_array!( + // Position + 0 => Float32x2, + // Color + 1 => Float32x4, + ), + }], + }, + fragment: Some(wgpu::FragmentState { + module: &shader, + entry_point: "solid_fs_main", + targets: &[triangle::fragment_target(format)], + }), + primitive: triangle::primitive_state(), + depth_stencil: None, + multisample: triangle::multisample_state(antialiasing), + multiview: None, }, - fragment: Some(wgpu::FragmentState { - module: &shader, - entry_point: "solid_fs_main", - targets: &[triangle::fragment_target(format)], - }), - primitive: triangle::primitive_state(), - depth_stencil: None, - multisample: triangle::multisample_state(antialiasing), - multiview: None, - }, - ); + ); Self { pipeline, @@ -535,7 +537,8 @@ mod solid { } mod gradient { - use crate::graphics::{primitive, Antialiasing}; + use crate::graphics::mesh; + use crate::graphics::Antialiasing; use crate::triangle; use crate::Buffer; @@ -547,7 +550,7 @@ mod gradient { #[derive(Debug)] pub struct Layer { - pub vertices: Buffer, + pub vertices: Buffer, pub uniforms: Buffer, pub constants: wgpu::BindGroup, } @@ -645,7 +648,7 @@ mod gradient { entry_point: "gradient_vs_main", buffers: &[wgpu::VertexBufferLayout { array_stride: std::mem::size_of::< - primitive::GradientVertex2D, + mesh::GradientVertex2D, >() as u64, step_mode: wgpu::VertexStepMode::Vertex, -- cgit From 6921564c9f66e8103e19ec658099c5f5c32e8cc5 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Thu, 29 Jun 2023 07:55:52 +0200 Subject: Write missing docs in `iced_graphics` and `iced_wgpu` --- wgpu/src/lib.rs | 4 ++-- wgpu/src/primitive.rs | 4 ++++ 2 files changed, 6 insertions(+), 2 deletions(-) (limited to 'wgpu/src') diff --git a/wgpu/src/lib.rs b/wgpu/src/lib.rs index 0ffaeeef..deb223ef 100644 --- a/wgpu/src/lib.rs +++ b/wgpu/src/lib.rs @@ -24,8 +24,8 @@ html_logo_url = "https://raw.githubusercontent.com/iced-rs/iced/9ab6923e943f784985e9ef9ca28b10278297225d/docs/logo.svg" )] #![deny( - //missing_debug_implementations, - //missing_docs, + missing_debug_implementations, + missing_docs, unsafe_code, unused_results, clippy::extra_unused_lifetimes, diff --git a/wgpu/src/primitive.rs b/wgpu/src/primitive.rs index a8f1119c..8dbf3008 100644 --- a/wgpu/src/primitive.rs +++ b/wgpu/src/primitive.rs @@ -1,10 +1,14 @@ +//! Draw using different graphical primitives. use crate::core::Rectangle; use crate::graphics::{Damage, Mesh}; +/// The graphical primitives supported by `iced_wgpu`. pub type Primitive = crate::graphics::Primitive; +/// The custom primitives supported by `iced_wgpu`. #[derive(Debug, Clone, PartialEq)] pub enum Custom { + /// A mesh primitive. Mesh(Mesh), } -- cgit