Implement preliminary cache grouping for mesh primitives
Due to AA, it's very expensive to render every cached layer independently.
This commit is contained in:
parent
09af6773bd
commit
88b72de282
2 changed files with 107 additions and 53 deletions
|
|
@ -315,9 +315,10 @@ impl Renderer {
|
|||
|
||||
// TODO: Can we avoid collecting here?
|
||||
let layers: Vec<_> = self.layers.iter().collect();
|
||||
let mut i = 0;
|
||||
|
||||
for layer in &layers {
|
||||
match layer {
|
||||
while i < layers.len() {
|
||||
match layers[i] {
|
||||
Layer::Live(live) => {
|
||||
let bounds = live
|
||||
.bounds
|
||||
|
|
@ -393,14 +394,30 @@ impl Renderer {
|
|||
|
||||
image_layer += 1;
|
||||
}
|
||||
|
||||
i += 1;
|
||||
}
|
||||
Layer::Cached(cached) => {
|
||||
Layer::Cached(_) => {
|
||||
let group_len = layers[i..]
|
||||
.iter()
|
||||
.position(|layer| matches!(layer, Layer::Live(_)))
|
||||
.unwrap_or(layers.len());
|
||||
|
||||
let group = layers[i..i + group_len].iter().map(|layer| {
|
||||
let Layer::Cached(cached) = layer else {
|
||||
unreachable!()
|
||||
};
|
||||
|
||||
let bounds = cached
|
||||
.bounds
|
||||
.map(|bounds| bounds * scale_factor)
|
||||
.map(Rectangle::snap)
|
||||
.unwrap_or(Rectangle::with_size(target_size));
|
||||
|
||||
(cached, bounds)
|
||||
});
|
||||
|
||||
for (cached, bounds) in group.clone() {
|
||||
if !cached.quads.is_empty() {
|
||||
engine.quad_pipeline.render_cache(
|
||||
&cached.quads,
|
||||
|
|
@ -408,17 +425,23 @@ impl Renderer {
|
|||
&mut render_pass,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if !cached.meshes.is_empty() {
|
||||
let group_has_meshes = group
|
||||
.clone()
|
||||
.any(|(cached, _)| !cached.meshes.is_empty());
|
||||
|
||||
if group_has_meshes {
|
||||
let _ = ManuallyDrop::into_inner(render_pass);
|
||||
|
||||
engine.triangle_pipeline.render_cache(
|
||||
engine.triangle_pipeline.render_cache_group(
|
||||
device,
|
||||
encoder,
|
||||
frame,
|
||||
target_size,
|
||||
&cached.meshes,
|
||||
bounds,
|
||||
group.clone().map(|(cached, bounds)| {
|
||||
(&cached.meshes, bounds)
|
||||
}),
|
||||
scale_factor,
|
||||
);
|
||||
|
||||
|
|
@ -443,6 +466,7 @@ impl Renderer {
|
|||
));
|
||||
}
|
||||
|
||||
for (cached, bounds) in group {
|
||||
if !cached.text.is_empty() {
|
||||
engine.text_pipeline.render_cache(
|
||||
&cached.text,
|
||||
|
|
@ -462,6 +486,9 @@ impl Renderer {
|
|||
image_layer += 1;
|
||||
}
|
||||
}
|
||||
|
||||
i += group_len;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -136,14 +136,13 @@ impl Pipeline {
|
|||
self.blit.as_mut(),
|
||||
&self.solid,
|
||||
&self.gradient,
|
||||
&self.layers[layer],
|
||||
target_size,
|
||||
meshes,
|
||||
bounds,
|
||||
std::iter::once((&self.layers[layer], meshes, bounds)),
|
||||
scale_factor,
|
||||
);
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn render_cache(
|
||||
&mut self,
|
||||
device: &wgpu::Device,
|
||||
|
|
@ -165,25 +164,51 @@ impl Pipeline {
|
|||
self.blit.as_mut(),
|
||||
&self.solid,
|
||||
&self.gradient,
|
||||
layer,
|
||||
target_size,
|
||||
batch,
|
||||
bounds,
|
||||
std::iter::once((layer, batch, bounds)),
|
||||
scale_factor,
|
||||
);
|
||||
}
|
||||
|
||||
fn render(
|
||||
pub fn render_cache_group<'a>(
|
||||
&mut self,
|
||||
device: &wgpu::Device,
|
||||
encoder: &mut wgpu::CommandEncoder,
|
||||
target: &wgpu::TextureView,
|
||||
target_size: Size<u32>,
|
||||
group: impl Iterator<Item = (&'a Cache, Rectangle<u32>)>,
|
||||
scale_factor: f32,
|
||||
) {
|
||||
let group = group.filter_map(|(cache, bounds)| {
|
||||
if let Cache::Uploaded { batch, layer, .. } = cache {
|
||||
Some((layer, batch, bounds))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
});
|
||||
|
||||
Self::render(
|
||||
device,
|
||||
encoder,
|
||||
target,
|
||||
self.blit.as_mut(),
|
||||
&self.solid,
|
||||
&self.gradient,
|
||||
target_size,
|
||||
group,
|
||||
scale_factor,
|
||||
);
|
||||
}
|
||||
|
||||
fn render<'a>(
|
||||
device: &wgpu::Device,
|
||||
encoder: &mut wgpu::CommandEncoder,
|
||||
target: &wgpu::TextureView,
|
||||
mut blit: Option<&mut msaa::Blit>,
|
||||
solid: &solid::Pipeline,
|
||||
gradient: &gradient::Pipeline,
|
||||
layer: &Layer,
|
||||
target_size: Size<u32>,
|
||||
meshes: &Batch,
|
||||
bounds: Rectangle<u32>,
|
||||
group: impl Iterator<Item = (&'a Layer, &'a Batch, Rectangle<u32>)>,
|
||||
scale_factor: f32,
|
||||
) {
|
||||
{
|
||||
|
|
@ -220,6 +245,7 @@ impl Pipeline {
|
|||
occlusion_query_set: None,
|
||||
});
|
||||
|
||||
for (layer, meshes, bounds) in group {
|
||||
layer.render(
|
||||
solid,
|
||||
gradient,
|
||||
|
|
@ -229,6 +255,7 @@ impl Pipeline {
|
|||
&mut render_pass,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(blit) = blit {
|
||||
blit.draw(encoder, target);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue