diff options
Diffstat (limited to '')
-rw-r--r-- | wgpu/src/primitive.rs | 105 | ||||
-rw-r--r-- | wgpu/src/primitive/pipeline.rs | 116 |
2 files changed, 81 insertions, 140 deletions
diff --git a/wgpu/src/primitive.rs b/wgpu/src/primitive.rs index ee9af93c..1313e752 100644 --- a/wgpu/src/primitive.rs +++ b/wgpu/src/primitive.rs @@ -1,38 +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::core::Rectangle; -use crate::graphics::{Damage, Mesh}; +/// A batch of primitives. +pub type Batch = Vec<Instance>; -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<u32>, + ); +} -/// The graphical primitives supported by `iced_wgpu`. -pub type Primitive = crate::graphics::Primitive<Custom>; +#[derive(Debug)] +/// An instance of a specific [`Primitive`]. +pub struct Instance { + /// The bounds of the [`Instance`]. + pub bounds: Rectangle, -/// 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), + /// The [`Primitive`] to render. + pub primitive: Box<dyn Primitive>, } -impl Damage for Custom { - fn bounds(&self) -> Rectangle { - match self { - Self::Mesh(mesh) => mesh.bounds(), - Self::Pipeline(pipeline) => pipeline.bounds, +impl Instance { + /// Creates a new [`Instance`] with the given [`Primitive`]. + pub fn new(bounds: Rectangle, primitive: impl Primitive) -> Self { + Instance { + bounds, + primitive: Box::new(primitive), } } } -impl TryFrom<Mesh> for Custom { - type Error = &'static str; +/// 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<TypeId, Box<dyn Any + Send>>, +} + +impl Storage { + /// Returns `true` if `Storage` contains a type `T`. + pub fn has<T: 'static>(&self) -> bool { + self.pipelines.get(&TypeId::of::<T>()).is_some() + } + + /// Inserts the data `T` in to [`Storage`]. + pub fn store<T: 'static + Send>(&mut self, data: T) { + let _ = self.pipelines.insert(TypeId::of::<T>(), Box::new(data)); + } + + /// Returns a reference to the data with type `T` if it exists in [`Storage`]. + pub fn get<T: 'static>(&self) -> Option<&T> { + self.pipelines.get(&TypeId::of::<T>()).map(|pipeline| { + pipeline + .downcast_ref::<T>() + .expect("Value with this type does not exist in Storage.") + }) + } - fn try_from(mesh: Mesh) -> Result<Self, Self::Error> { - Ok(Custom::Mesh(mesh)) + /// Returns a mutable reference to the data with type `T` if it exists in [`Storage`]. + pub fn get_mut<T: 'static>(&mut self) -> Option<&mut T> { + self.pipelines.get_mut(&TypeId::of::<T>()).map(|pipeline| { + pipeline + .downcast_mut::<T>() + .expect("Value with this type does not exist in Storage.") + }) } } diff --git a/wgpu/src/primitive/pipeline.rs b/wgpu/src/primitive/pipeline.rs deleted file mode 100644 index 814440ba..00000000 --- a/wgpu/src/primitive/pipeline.rs +++ /dev/null @@ -1,116 +0,0 @@ -//! Draw primitives using custom pipelines. -use crate::core::{self, Rectangle, Size}; - -use std::any::{Any, TypeId}; -use std::collections::HashMap; -use std::fmt::Debug; -use std::sync::Arc; - -#[derive(Clone, Debug)] -/// A custom primitive which can be used to render primitives associated with a custom pipeline. -pub struct Pipeline { - /// The bounds of the [`Pipeline`]. - pub bounds: Rectangle, - - /// The [`Primitive`] to render. - pub primitive: Arc<dyn Primitive>, -} - -impl Pipeline { - /// Creates a new [`Pipeline`] with the given [`Primitive`]. - pub fn new(bounds: Rectangle, primitive: impl Primitive) -> Self { - Pipeline { - bounds, - primitive: Arc::new(primitive), - } - } -} - -impl PartialEq for Pipeline { - fn eq(&self, other: &Self) -> bool { - self.primitive.type_id() == other.primitive.type_id() - } -} - -/// 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, - format: wgpu::TextureFormat, - device: &wgpu::Device, - queue: &wgpu::Queue, - bounds: Rectangle, - target_size: Size<u32>, - scale_factor: f32, - storage: &mut Storage, - ); - - /// Renders the [`Primitive`]. - fn render( - &self, - storage: &Storage, - target: &wgpu::TextureView, - target_size: Size<u32>, - viewport: Rectangle<u32>, - encoder: &mut wgpu::CommandEncoder, - ); -} - -/// A renderer than can draw custom pipeline primitives. -pub trait Renderer: core::Renderer { - /// Draws a custom pipeline primitive. - fn draw_pipeline_primitive( - &mut self, - bounds: Rectangle, - primitive: impl Primitive, - ); -} - -impl Renderer for crate::Renderer { - fn draw_pipeline_primitive( - &mut self, - bounds: Rectangle, - primitive: impl Primitive, - ) { - self.draw_primitive(super::Primitive::Custom(super::Custom::Pipeline( - Pipeline::new(bounds, primitive), - ))); - } -} - -/// Stores custom, user-provided pipelines. -#[derive(Default, Debug)] -pub struct Storage { - pipelines: HashMap<TypeId, Box<dyn Any + Send>>, -} - -impl Storage { - /// Returns `true` if `Storage` contains a pipeline with type `T`. - pub fn has<T: 'static>(&self) -> bool { - self.pipelines.get(&TypeId::of::<T>()).is_some() - } - - /// Inserts the pipeline `T` in to [`Storage`]. - pub fn store<T: 'static + Send>(&mut self, pipeline: T) { - let _ = self.pipelines.insert(TypeId::of::<T>(), Box::new(pipeline)); - } - - /// Returns a reference to pipeline with type `T` if it exists in [`Storage`]. - pub fn get<T: 'static>(&self) -> Option<&T> { - self.pipelines.get(&TypeId::of::<T>()).map(|pipeline| { - pipeline - .downcast_ref::<T>() - .expect("Pipeline with this type does not exist in Storage.") - }) - } - - /// Returns a mutable reference to pipeline `T` if it exists in [`Storage`]. - pub fn get_mut<T: 'static>(&mut self) -> Option<&mut T> { - self.pipelines.get_mut(&TypeId::of::<T>()).map(|pipeline| { - pipeline - .downcast_mut::<T>() - .expect("Pipeline with this type does not exist in Storage.") - }) - } -} |