diff options
| author | 2023-11-14 12:49:49 +0100 | |
|---|---|---|
| committer | 2023-11-14 12:49:49 +0100 | |
| commit | 9489e29e6619b14ed9f41a8887c4b34158266f71 (patch) | |
| tree | 34b574112df5f2e63dff66d3a01e470077ce7c9b /wgpu/src/primitive | |
| parent | 2dda9132cda6d2a2279759f3447bae4e1c277555 (diff) | |
| download | iced-9489e29e6619b14ed9f41a8887c4b34158266f71.tar.gz iced-9489e29e6619b14ed9f41a8887c4b34158266f71.tar.bz2 iced-9489e29e6619b14ed9f41a8887c4b34158266f71.zip | |
Re-organize `custom` module as `pipeline` module
... and move `Shader` widget to `iced_widget` crate
Diffstat (limited to '')
| -rw-r--r-- | wgpu/src/primitive.rs | 43 | ||||
| -rw-r--r-- | wgpu/src/primitive/pipeline.rs | 117 | 
2 files changed, 125 insertions, 35 deletions
| diff --git a/wgpu/src/primitive.rs b/wgpu/src/primitive.rs index 4347dcda..fff927ea 100644 --- a/wgpu/src/primitive.rs +++ b/wgpu/src/primitive.rs @@ -1,10 +1,12 @@  //! Draw using different graphical primitives. +pub mod pipeline; + +pub use pipeline::Pipeline; +  use crate::core::Rectangle; -use crate::custom;  use crate::graphics::{Damage, Mesh}; -use std::any::Any; +  use std::fmt::Debug; -use std::sync::Arc;  /// The graphical primitives supported by `iced_wgpu`.  pub type Primitive = crate::graphics::Primitive<Custom>; @@ -14,44 +16,15 @@ pub type Primitive = crate::graphics::Primitive<Custom>;  pub enum Custom {      /// A mesh primitive.      Mesh(Mesh), -    /// A custom shader primitive -    Shader(Shader), -} - -impl Custom { -    /// Create a custom [`Shader`] primitive. -    pub fn shader<P: custom::Primitive>( -        bounds: Rectangle, -        primitive: P, -    ) -> Self { -        Self::Shader(Shader { -            bounds, -            primitive: Arc::new(primitive), -        }) -    } +    /// A custom pipeline primitive. +    Pipeline(Pipeline),  }  impl Damage for Custom {      fn bounds(&self) -> Rectangle {          match self {              Self::Mesh(mesh) => mesh.bounds(), -            Self::Shader(shader) => shader.bounds, +            Self::Pipeline(pipeline) => pipeline.bounds,          }      }  } - -#[derive(Clone, Debug)] -/// A custom primitive which can be used to render primitives associated with a custom pipeline. -pub struct Shader { -    /// The bounds of the [`Shader`]. -    pub bounds: Rectangle, - -    /// The [`custom::Primitive`] to render. -    pub primitive: Arc<dyn custom::Primitive>, -} - -impl PartialEq for Shader { -    fn eq(&self, other: &Self) -> bool { -        self.primitive.type_id() == other.primitive.type_id() -    } -} diff --git a/wgpu/src/primitive/pipeline.rs b/wgpu/src/primitive/pipeline.rs new file mode 100644 index 00000000..b59aeff1 --- /dev/null +++ b/wgpu/src/primitive/pipeline.rs @@ -0,0 +1,117 @@ +//! Draw primitives using custom pipelines. +use crate::core::{Rectangle, Size}; +use crate::graphics::Transformation; + +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 [`Shader`]. +    pub bounds: Rectangle, + +    /// The [`custom::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, +        target_size: Size<u32>, +        scale_factor: f32, +        transform: Transformation, +        storage: &mut Storage, +    ); + +    /// Renders the [`Primitive`]. +    fn render( +        &self, +        storage: &Storage, +        bounds: Rectangle<u32>, +        target: &wgpu::TextureView, +        target_size: Size<u32>, +        encoder: &mut wgpu::CommandEncoder, +    ); +} + +/// A renderer than can draw custom pipeline primitives. +pub trait Renderer: crate::core::Renderer { +    /// Draws a custom pipeline primitive. +    fn draw_pipeline_primitive( +        &mut self, +        bounds: Rectangle, +        primitive: impl Primitive, +    ); +} + +impl<Theme> Renderer for crate::Renderer<Theme> { +    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>>, +} + +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>(&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.") +        }) +    } +} | 
