Split local state from Engine in iced_wgpu

This commit is contained in:
Héctor Ramón Jiménez 2025-03-24 01:28:39 +01:00
parent 4b075b9731
commit 576dd22733
No known key found for this signature in database
GPG key ID: 7CC46565708259A7
22 changed files with 768 additions and 641 deletions

View file

@ -153,42 +153,47 @@ impl Storage {
}
}
#[derive(Debug)]
#[derive(Debug, Clone)]
pub struct Pipeline {
blit: Option<msaa::Blit>,
msaa: Option<msaa::Pipeline>,
solid: solid::Pipeline,
gradient: gradient::Pipeline,
layers: Vec<Layer>,
prepare_layer: usize,
}
impl Pipeline {
pub fn new(
device: &wgpu::Device,
format: wgpu::TextureFormat,
antialiasing: Option<Antialiasing>,
) -> Pipeline {
Pipeline {
blit: antialiasing.map(|a| msaa::Blit::new(device, format, a)),
solid: solid::Pipeline::new(device, format, antialiasing),
gradient: gradient::Pipeline::new(device, format, antialiasing),
pub struct State {
msaa: Option<msaa::State>,
layers: Vec<Layer>,
prepare_layer: usize,
storage: Storage,
}
impl State {
pub fn new(device: &wgpu::Device, pipeline: &Pipeline) -> Self {
Self {
msaa: pipeline
.msaa
.as_ref()
.map(|pipeline| msaa::State::new(device, pipeline)),
layers: Vec::new(),
prepare_layer: 0,
storage: Storage::new(),
}
}
pub fn prepare(
&mut self,
pipeline: &Pipeline,
device: &wgpu::Device,
encoder: &mut wgpu::CommandEncoder,
belt: &mut wgpu::util::StagingBelt,
storage: &mut Storage,
encoder: &mut wgpu::CommandEncoder,
items: &[Item],
scale: Transformation,
target_size: Size<u32>,
) {
let projection = if let Some(blit) = &mut self.blit {
blit.prepare(device, encoder, belt, target_size) * scale
let projection = if let Some((state, pipeline)) =
self.msaa.as_mut().zip(pipeline.msaa.as_ref())
{
state.prepare(device, encoder, belt, pipeline, target_size) * scale
} else {
Transformation::orthographic(target_size.width, target_size.height)
* scale
@ -203,8 +208,8 @@ impl Pipeline {
if self.layers.len() <= self.prepare_layer {
self.layers.push(Layer::new(
device,
&self.solid,
&self.gradient,
&pipeline.solid,
&pipeline.gradient,
));
}
@ -213,8 +218,8 @@ impl Pipeline {
device,
encoder,
belt,
&self.solid,
&self.gradient,
&pipeline.solid,
&pipeline.gradient,
meshes,
projection * *transformation,
);
@ -225,12 +230,12 @@ impl Pipeline {
transformation,
cache,
} => {
storage.prepare(
self.storage.prepare(
device,
encoder,
belt,
&self.solid,
&self.gradient,
&pipeline.solid,
&pipeline.gradient,
cache,
projection * *transformation,
);
@ -241,9 +246,9 @@ impl Pipeline {
pub fn render(
&mut self,
pipeline: &Pipeline,
encoder: &mut wgpu::CommandEncoder,
target: &wgpu::TextureView,
storage: &Storage,
start: usize,
batch: &Batch,
bounds: Rectangle,
@ -269,7 +274,7 @@ impl Pipeline {
transformation,
cache,
} => {
let upload = storage.get(cache)?;
let upload = self.storage.get(cache)?;
Some((
&upload.layer,
@ -282,9 +287,9 @@ impl Pipeline {
render(
encoder,
target,
self.blit.as_mut(),
&self.solid,
&self.gradient,
self.msaa.as_ref().zip(pipeline.msaa.as_ref()),
&pipeline.solid,
&pipeline.gradient,
bounds,
items,
);
@ -293,47 +298,54 @@ impl Pipeline {
}
pub fn end_frame(&mut self) {
self.storage.trim();
self.prepare_layer = 0;
}
}
impl Pipeline {
pub fn new(
device: &wgpu::Device,
format: wgpu::TextureFormat,
antialiasing: Option<Antialiasing>,
) -> Pipeline {
Pipeline {
msaa: antialiasing.map(|a| msaa::Pipeline::new(device, format, a)),
solid: solid::Pipeline::new(device, format, antialiasing),
gradient: gradient::Pipeline::new(device, format, antialiasing),
}
}
}
fn render<'a>(
encoder: &mut wgpu::CommandEncoder,
target: &wgpu::TextureView,
mut blit: Option<&mut msaa::Blit>,
mut msaa: Option<(&msaa::State, &msaa::Pipeline)>,
solid: &solid::Pipeline,
gradient: &gradient::Pipeline,
bounds: Rectangle,
group: impl Iterator<Item = (&'a Layer, &'a [Mesh], Transformation)>,
) {
{
let (attachment, resolve_target, load) = if let Some(blit) = &mut blit {
let (attachment, resolve_target) = blit.targets();
(
attachment,
Some(resolve_target),
wgpu::LoadOp::Clear(wgpu::Color::TRANSPARENT),
)
let mut render_pass = if let Some((_state, pipeline)) = &mut msaa {
pipeline.render_pass(encoder)
} else {
(target, None, wgpu::LoadOp::Load)
};
let mut render_pass =
encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
label: Some("iced_wgpu.triangle.render_pass"),
color_attachments: &[Some(wgpu::RenderPassColorAttachment {
view: attachment,
resolve_target,
view: target,
resolve_target: None,
ops: wgpu::Operations {
load,
load: wgpu::LoadOp::Load,
store: wgpu::StoreOp::Store,
},
})],
depth_stencil_attachment: None,
timestamp_writes: None,
occlusion_query_set: None,
});
})
};
for (layer, meshes, transformation) in group {
layer.render(
@ -347,8 +359,8 @@ fn render<'a>(
}
}
if let Some(blit) = blit {
blit.draw(encoder, target);
if let Some((state, pipeline)) = msaa {
state.render(pipeline, encoder, target);
}
}
@ -649,7 +661,7 @@ mod solid {
use crate::graphics::mesh;
use crate::triangle;
#[derive(Debug)]
#[derive(Debug, Clone)]
pub struct Pipeline {
pub pipeline: wgpu::RenderPipeline,
pub constants_layout: wgpu::BindGroupLayout,
@ -801,7 +813,7 @@ mod gradient {
use crate::graphics::mesh;
use crate::triangle;
#[derive(Debug)]
#[derive(Debug, Clone)]
pub struct Pipeline {
pub pipeline: wgpu::RenderPipeline,
pub constants_layout: wgpu::BindGroupLayout,