Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion examples/custom_shader/src/scene/pipeline.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use vertex::Vertex;
use crate::wgpu;
use crate::wgpu::util::DeviceExt;

use iced::{Rectangle, Size};
use iced::{Rectangle, Size, widget::shader};

const SKY_TEXTURE_SIZE: u32 = 128;

Expand Down Expand Up @@ -410,6 +410,8 @@ impl Pipeline {
}
}

impl shader::Pipeline for Pipeline {}

struct DepthPipeline {
pipeline: wgpu::RenderPipeline,
bind_group_layout: wgpu::BindGroupLayout,
Expand Down
5 changes: 5 additions & 0 deletions wgpu/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,11 @@ impl Renderer {

// TODO: Move to runtime!
self.engine.text_pipeline.trim();
self.engine
.primitive_storage
.write()
.expect("Write primitive storage")
.end_frame();

#[cfg(any(feature = "svg", feature = "image"))]
{
Expand Down
48 changes: 42 additions & 6 deletions wgpu/src/primitive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,10 @@ pub trait Renderer: core::Renderer {
fn draw_primitive(&mut self, bounds: Rectangle, primitive: impl Primitive);
}

/// Stores custom, user-provided types.
/// Stores custom, user-provided pipelines.
#[derive(Default, Debug)]
pub struct Storage {
pipelines: FxHashMap<TypeId, Box<dyn Any + Send + Sync>>,
pipelines: FxHashMap<TypeId, Box<dyn AnyPipeline>>,
}

impl Storage {
Expand All @@ -70,26 +70,62 @@ impl Storage {
self.pipelines.contains_key(&TypeId::of::<T>())
}

/// Inserts the data `T` in to [`Storage`].
pub fn store<T: 'static + Send + Sync>(&mut self, data: T) {
/// Inserts the pipeline `T` in to [`Storage`].
pub fn store<T: 'static + Pipeline + Send + Sync>(&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`].
/// Returns a reference to the 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
.as_any()
.downcast_ref::<T>()
.expect("Value with this type does not exist in Storage.")
})
}

/// Returns a mutable reference to the data with type `T` if it exists in [`Storage`].
/// Returns a mutable reference to the pipeline 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
.as_any_mut()
.downcast_mut::<T>()
.expect("Value with this type does not exist in Storage.")
})
}

/// Triggers the `end_frame` method on all pipelines that exist within [`Storage`].
pub(crate) fn end_frame(&mut self) {
self.pipelines.values_mut().for_each(|pipeline| {
pipeline.end_frame();
});
}
}

/// A pipeline that manages the resources of a shader.
pub trait Pipeline {
/// Called after each frame. Useful for cleaning up unused resources.
fn end_frame(&mut self) {}
}

trait AnyPipeline: Pipeline + Any + Send + Sync {
fn as_any(&self) -> &dyn Any;
fn as_any_mut(&mut self) -> &mut dyn Any;
}

impl<T: Pipeline + Any + Send + Sync> AnyPipeline for T {
fn as_any(&self) -> &dyn Any {
self
}

fn as_any_mut(&mut self) -> &mut dyn Any {
self
}
}

impl Debug for dyn AnyPipeline {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("AnyPipeline").finish_non_exhaustive()
}
}
2 changes: 1 addition & 1 deletion widget/src/shader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use std::marker::PhantomData;

pub use crate::Action;
pub use crate::graphics::Viewport;
pub use primitive::{Primitive, Storage};
pub use primitive::{Pipeline, Primitive, Storage};

/// A widget which can render custom shaders with Iced's `wgpu` backend.
///
Expand Down