From 3645d34d6a1ba1247238e830e9eefd52d9e5b986 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Thu, 21 Mar 2024 22:27:17 +0100 Subject: Implement composable, type-safe renderer fallback --- wgpu/src/primitive.rs | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'wgpu/src/primitive.rs') diff --git a/wgpu/src/primitive.rs b/wgpu/src/primitive.rs index fff927ea..ee9af93c 100644 --- a/wgpu/src/primitive.rs +++ b/wgpu/src/primitive.rs @@ -28,3 +28,11 @@ impl Damage for Custom { } } } + +impl TryFrom for Custom { + type Error = &'static str; + + fn try_from(mesh: Mesh) -> Result { + Ok(Custom::Mesh(mesh)) + } +} -- cgit From b05e61f5c8ae61c9f3c7cc08cded53901ebbccfd Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Wed, 3 Apr 2024 21:07:54 +0200 Subject: Redesign `iced_wgpu` layering architecture --- wgpu/src/primitive.rs | 20 +------------------- 1 file changed, 1 insertion(+), 19 deletions(-) (limited to 'wgpu/src/primitive.rs') diff --git a/wgpu/src/primitive.rs b/wgpu/src/primitive.rs index ee9af93c..8e311d2b 100644 --- a/wgpu/src/primitive.rs +++ b/wgpu/src/primitive.rs @@ -3,8 +3,7 @@ pub mod pipeline; pub use pipeline::Pipeline; -use crate::core::Rectangle; -use crate::graphics::{Damage, Mesh}; +use crate::graphics::Mesh; use std::fmt::Debug; @@ -19,20 +18,3 @@ pub enum Custom { /// A custom pipeline primitive. Pipeline(Pipeline), } - -impl Damage for Custom { - fn bounds(&self) -> Rectangle { - match self { - Self::Mesh(mesh) => mesh.bounds(), - Self::Pipeline(pipeline) => pipeline.bounds, - } - } -} - -impl TryFrom for Custom { - type Error = &'static str; - - fn try_from(mesh: Mesh) -> Result { - Ok(Custom::Mesh(mesh)) - } -} -- cgit From d922b478156488a7bc03c6e791e05c040d702634 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Mon, 8 Apr 2024 15:04:35 +0200 Subject: Reintroduce support for custom primitives in `iced_wgpu` --- wgpu/src/primitive.rs | 103 +++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 89 insertions(+), 14 deletions(-) (limited to 'wgpu/src/primitive.rs') diff --git a/wgpu/src/primitive.rs b/wgpu/src/primitive.rs index 8e311d2b..4ba1ed9a 100644 --- a/wgpu/src/primitive.rs +++ b/wgpu/src/primitive.rs @@ -1,20 +1,95 @@ -//! Draw using different graphical primitives. -pub mod pipeline; +//! Draw custom primitives. +use crate::core::{self, Rectangle}; +use crate::graphics::Viewport; -pub use pipeline::Pipeline; +use rustc_hash::FxHashMap; +use std::any::{Any, TypeId}; +use std::fmt::Debug; -use crate::graphics::Mesh; +/// A batch of primitives. +pub type Batch = Vec; -use std::fmt::Debug; +/// A set of methods which allows a [`Primitive`] to be rendered. +pub trait Primitive: Debug + Send + Sync + 'static { + /// Processes the [`Primitive`], allowing for GPU buffer allocation. + fn prepare( + &self, + device: &wgpu::Device, + queue: &wgpu::Queue, + format: wgpu::TextureFormat, + storage: &mut Storage, + bounds: &Rectangle, + viewport: &Viewport, + ); + + /// Renders the [`Primitive`]. + fn render( + &self, + encoder: &mut wgpu::CommandEncoder, + storage: &Storage, + target: &wgpu::TextureView, + clip_bounds: &Rectangle, + ); +} + +#[derive(Debug)] +/// An instance of a specific [`Primitive`]. +pub struct Instance { + /// The bounds of the [`Instance`]. + pub bounds: Rectangle, + + /// The [`Primitive`] to render. + pub primitive: Box, +} + +impl Instance { + /// Creates a new [`Pipeline`] with the given [`Primitive`]. + pub fn new(bounds: Rectangle, primitive: impl Primitive) -> Self { + Instance { + bounds, + primitive: Box::new(primitive), + } + } +} + +/// A renderer than can draw custom primitives. +pub trait Renderer: core::Renderer { + /// Draws a custom primitive. + fn draw_primitive(&mut self, bounds: Rectangle, primitive: impl Primitive); +} + +/// Stores custom, user-provided types. +#[derive(Default, Debug)] +pub struct Storage { + pipelines: FxHashMap>, +} + +impl Storage { + /// Returns `true` if `Storage` contains a type `T`. + pub fn has(&self) -> bool { + self.pipelines.get(&TypeId::of::()).is_some() + } + + /// Inserts the data `T` in to [`Storage`]. + pub fn store(&mut self, data: T) { + let _ = self.pipelines.insert(TypeId::of::(), Box::new(data)); + } -/// The graphical primitives supported by `iced_wgpu`. -pub type Primitive = crate::graphics::Primitive; + /// Returns a reference to the data with type `T` if it exists in [`Storage`]. + pub fn get(&self) -> Option<&T> { + self.pipelines.get(&TypeId::of::()).map(|pipeline| { + pipeline + .downcast_ref::() + .expect("Pipeline with this type does not exist in Storage.") + }) + } -/// The custom primitives supported by `iced_wgpu`. -#[derive(Debug, Clone, PartialEq)] -pub enum Custom { - /// A mesh primitive. - Mesh(Mesh), - /// A custom pipeline primitive. - Pipeline(Pipeline), + /// Returns a mutable reference to the data with type `T` if it exists in [`Storage`]. + pub fn get_mut(&mut self) -> Option<&mut T> { + self.pipelines.get_mut(&TypeId::of::()).map(|pipeline| { + pipeline + .downcast_mut::() + .expect("Pipeline with this type does not exist in Storage.") + }) + } } -- cgit From 6ad5bb3597f640ac329801adf735d633bf0a512f Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Tue, 9 Apr 2024 22:25:16 +0200 Subject: Port `iced_tiny_skia` to new layering architecture --- wgpu/src/primitive.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'wgpu/src/primitive.rs') 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::()).map(|pipeline| { pipeline .downcast_ref::() - .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::()).map(|pipeline| { pipeline .downcast_mut::() - .expect("Pipeline with this type does not exist in Storage.") + .expect("Value with this type does not exist in Storage.") }) } } -- cgit From aae8e4f5cfabfc3725ac938023fa29a6737a380c Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Thu, 2 May 2024 17:23:32 +0200 Subject: Fix `clippy` lints for new `1.78` stable toolchain --- wgpu/src/primitive.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'wgpu/src/primitive.rs') diff --git a/wgpu/src/primitive.rs b/wgpu/src/primitive.rs index 1313e752..8641f27a 100644 --- a/wgpu/src/primitive.rs +++ b/wgpu/src/primitive.rs @@ -67,7 +67,7 @@ pub struct Storage { impl Storage { /// Returns `true` if `Storage` contains a type `T`. pub fn has(&self) -> bool { - self.pipelines.get(&TypeId::of::()).is_some() + self.pipelines.contains_key(&TypeId::of::()) } /// Inserts the data `T` in to [`Storage`]. -- cgit