Introduce Pipeline trait in wgpu::primitive
Co-authored-by: roguetechh <roguedotllc@gmail.com>
This commit is contained in:
parent
a4829306cb
commit
e937bf2bac
5 changed files with 61 additions and 44 deletions
|
|
@ -128,16 +128,7 @@ impl Primitive {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl shader::Primitive for Primitive {
|
impl shader::Primitive for Primitive {
|
||||||
type Renderer = Pipeline;
|
type Pipeline = Pipeline;
|
||||||
|
|
||||||
fn initialize(
|
|
||||||
&self,
|
|
||||||
device: &wgpu::Device,
|
|
||||||
queue: &wgpu::Queue,
|
|
||||||
format: wgpu::TextureFormat,
|
|
||||||
) -> Pipeline {
|
|
||||||
Pipeline::new(device, queue, format)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn prepare(
|
fn prepare(
|
||||||
&self,
|
&self,
|
||||||
|
|
@ -183,3 +174,13 @@ fn rnd_origin() -> Vec3 {
|
||||||
rand::thread_rng().gen_range(-4.0..2.0),
|
rand::thread_rng().gen_range(-4.0..2.0),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl shader::Pipeline for Pipeline {
|
||||||
|
fn new(
|
||||||
|
device: &wgpu::Device,
|
||||||
|
queue: &wgpu::Queue,
|
||||||
|
format: wgpu::TextureFormat,
|
||||||
|
) -> Pipeline {
|
||||||
|
Self::new(device, queue, format)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -66,4 +66,13 @@ impl Engine {
|
||||||
&self._shell,
|
&self._shell,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn trim(&mut self) {
|
||||||
|
self.text_pipeline.trim();
|
||||||
|
|
||||||
|
self.primitive_storage
|
||||||
|
.write()
|
||||||
|
.expect("primitive storage should be writable")
|
||||||
|
.trim();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -149,8 +149,8 @@ impl Renderer {
|
||||||
self.triangle.trim();
|
self.triangle.trim();
|
||||||
self.text.trim();
|
self.text.trim();
|
||||||
|
|
||||||
// TODO: Move to runtime!
|
// TODO: Provide window id (?)
|
||||||
self.engine.text_pipeline.trim();
|
self.engine.trim();
|
||||||
|
|
||||||
#[cfg(any(feature = "svg", feature = "image"))]
|
#[cfg(any(feature = "svg", feature = "image"))]
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -19,23 +19,12 @@ pub trait Primitive: Debug + MaybeSend + MaybeSync + 'static {
|
||||||
///
|
///
|
||||||
/// All instances of this [`Primitive`] type will share the same
|
/// All instances of this [`Primitive`] type will share the same
|
||||||
/// [`Renderer`].
|
/// [`Renderer`].
|
||||||
type Renderer: MaybeSend + MaybeSync;
|
type Pipeline: Pipeline + MaybeSend + MaybeSync;
|
||||||
|
|
||||||
/// Initializes the [`Renderer`](Self::Renderer) of the [`Primitive`].
|
|
||||||
///
|
|
||||||
/// This will only be called once, when the first [`Primitive`] of this kind
|
|
||||||
/// is encountered.
|
|
||||||
fn initialize(
|
|
||||||
&self,
|
|
||||||
device: &wgpu::Device,
|
|
||||||
queue: &wgpu::Queue,
|
|
||||||
format: wgpu::TextureFormat,
|
|
||||||
) -> Self::Renderer;
|
|
||||||
|
|
||||||
/// Processes the [`Primitive`], allowing for GPU buffer allocation.
|
/// Processes the [`Primitive`], allowing for GPU buffer allocation.
|
||||||
fn prepare(
|
fn prepare(
|
||||||
&self,
|
&self,
|
||||||
renderer: &mut Self::Renderer,
|
pipeline: &mut Self::Pipeline,
|
||||||
device: &wgpu::Device,
|
device: &wgpu::Device,
|
||||||
queue: &wgpu::Queue,
|
queue: &wgpu::Queue,
|
||||||
bounds: &Rectangle,
|
bounds: &Rectangle,
|
||||||
|
|
@ -57,7 +46,7 @@ pub trait Primitive: Debug + MaybeSend + MaybeSync + 'static {
|
||||||
/// By default, it does nothing and returns `false`.
|
/// By default, it does nothing and returns `false`.
|
||||||
fn draw(
|
fn draw(
|
||||||
&self,
|
&self,
|
||||||
_renderer: &Self::Renderer,
|
_pipeline: &Self::Pipeline,
|
||||||
_render_pass: &mut wgpu::RenderPass<'_>,
|
_render_pass: &mut wgpu::RenderPass<'_>,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
false
|
false
|
||||||
|
|
@ -70,7 +59,7 @@ pub trait Primitive: Debug + MaybeSend + MaybeSync + 'static {
|
||||||
/// By default, it does nothing.
|
/// By default, it does nothing.
|
||||||
fn render(
|
fn render(
|
||||||
&self,
|
&self,
|
||||||
_renderer: &Self::Renderer,
|
_pipeline: &Self::Pipeline,
|
||||||
_encoder: &mut wgpu::CommandEncoder,
|
_encoder: &mut wgpu::CommandEncoder,
|
||||||
_target: &wgpu::TextureView,
|
_target: &wgpu::TextureView,
|
||||||
_clip_bounds: &Rectangle<u32>,
|
_clip_bounds: &Rectangle<u32>,
|
||||||
|
|
@ -78,6 +67,26 @@ pub trait Primitive: Debug + MaybeSend + MaybeSync + 'static {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The pipeline of a graphics [`Primitive`].
|
||||||
|
pub trait Pipeline: Any + MaybeSend + MaybeSync {
|
||||||
|
/// Creates the [`Pipeline`] of a [`Primitive`].
|
||||||
|
///
|
||||||
|
/// This will only be called once, when the first [`Primitive`] with this kind
|
||||||
|
/// of [`Pipeline`] is encountered.
|
||||||
|
fn new(
|
||||||
|
device: &wgpu::Device,
|
||||||
|
queue: &wgpu::Queue,
|
||||||
|
format: wgpu::TextureFormat,
|
||||||
|
) -> Self
|
||||||
|
where
|
||||||
|
Self: Sized;
|
||||||
|
|
||||||
|
/// Trims any cached data in the [`Pipeline`].
|
||||||
|
///
|
||||||
|
/// This will normally be called at the end of a frame.
|
||||||
|
fn trim(&mut self) {}
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) trait Stored:
|
pub(crate) trait Stored:
|
||||||
Debug + MaybeSend + MaybeSync + 'static
|
Debug + MaybeSend + MaybeSync + 'static
|
||||||
{
|
{
|
||||||
|
|
@ -122,15 +131,13 @@ impl<P: Primitive> Stored for BlackBox<P> {
|
||||||
viewport: &Viewport,
|
viewport: &Viewport,
|
||||||
) {
|
) {
|
||||||
if !storage.has::<P>() {
|
if !storage.has::<P>() {
|
||||||
storage.store::<P, _>(
|
storage.store::<P, _>(P::Pipeline::new(device, queue, format));
|
||||||
self.primitive.initialize(device, queue, format),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let renderer = storage
|
let renderer = storage
|
||||||
.get_mut::<P>()
|
.get_mut::<P>()
|
||||||
.expect("renderer should be initialized")
|
.expect("renderer should be initialized")
|
||||||
.downcast_mut::<P::Renderer>()
|
.downcast_mut::<P::Pipeline>()
|
||||||
.expect("renderer should have the proper type");
|
.expect("renderer should have the proper type");
|
||||||
|
|
||||||
self.primitive
|
self.primitive
|
||||||
|
|
@ -145,7 +152,7 @@ impl<P: Primitive> Stored for BlackBox<P> {
|
||||||
let renderer = storage
|
let renderer = storage
|
||||||
.get::<P>()
|
.get::<P>()
|
||||||
.expect("renderer should be initialized")
|
.expect("renderer should be initialized")
|
||||||
.downcast_ref::<P::Renderer>()
|
.downcast_ref::<P::Pipeline>()
|
||||||
.expect("renderer should have the proper type");
|
.expect("renderer should have the proper type");
|
||||||
|
|
||||||
self.primitive.draw(renderer, render_pass)
|
self.primitive.draw(renderer, render_pass)
|
||||||
|
|
@ -161,7 +168,7 @@ impl<P: Primitive> Stored for BlackBox<P> {
|
||||||
let renderer = storage
|
let renderer = storage
|
||||||
.get::<P>()
|
.get::<P>()
|
||||||
.expect("renderer should be initialized")
|
.expect("renderer should be initialized")
|
||||||
.downcast_ref::<P::Renderer>()
|
.downcast_ref::<P::Pipeline>()
|
||||||
.expect("renderer should have the proper type");
|
.expect("renderer should have the proper type");
|
||||||
|
|
||||||
self.primitive
|
self.primitive
|
||||||
|
|
@ -198,7 +205,7 @@ pub trait Renderer: core::Renderer {
|
||||||
/// Stores custom, user-provided types.
|
/// Stores custom, user-provided types.
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct Storage {
|
pub struct Storage {
|
||||||
pipelines: FxHashMap<TypeId, Box<dyn AnyConcurrent>>,
|
pipelines: FxHashMap<TypeId, Box<dyn Pipeline>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Storage {
|
impl Storage {
|
||||||
|
|
@ -208,11 +215,8 @@ impl Storage {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Inserts the data `T` in to [`Storage`].
|
/// Inserts the data `T` in to [`Storage`].
|
||||||
pub fn store<T: 'static, D: Any + MaybeSend + MaybeSync>(
|
pub fn store<T: 'static, P: Pipeline>(&mut self, pipeline: P) {
|
||||||
&mut self,
|
let _ = self.pipelines.insert(TypeId::of::<T>(), Box::new(pipeline));
|
||||||
data: D,
|
|
||||||
) {
|
|
||||||
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 data with type `T` if it exists in [`Storage`].
|
||||||
|
|
@ -228,8 +232,11 @@ impl Storage {
|
||||||
.get_mut(&TypeId::of::<T>())
|
.get_mut(&TypeId::of::<T>())
|
||||||
.map(|pipeline| pipeline.as_mut() as &mut dyn Any)
|
.map(|pipeline| pipeline.as_mut() as &mut dyn Any)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Trims the cache of all the pipelines in the [`Storage`].
|
||||||
|
pub fn trim(&mut self) {
|
||||||
|
for pipeline in self.pipelines.values_mut() {
|
||||||
|
pipeline.trim();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
trait AnyConcurrent: Any + MaybeSend + MaybeSync {}
|
|
||||||
|
|
||||||
impl<T> AnyConcurrent for T where T: Any + MaybeSend + MaybeSync {}
|
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ use std::marker::PhantomData;
|
||||||
|
|
||||||
pub use crate::Action;
|
pub use crate::Action;
|
||||||
pub use crate::graphics::Viewport;
|
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.
|
/// A widget which can render custom shaders with Iced's `wgpu` backend.
|
||||||
///
|
///
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue