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?
|
// TODO: Can we avoid collecting here?
|
||||||
let layers: Vec<_> = self.layers.iter().collect();
|
let layers: Vec<_> = self.layers.iter().collect();
|
||||||
|
let mut i = 0;
|
||||||
|
|
||||||
for layer in &layers {
|
while i < layers.len() {
|
||||||
match layer {
|
match layers[i] {
|
||||||
Layer::Live(live) => {
|
Layer::Live(live) => {
|
||||||
let bounds = live
|
let bounds = live
|
||||||
.bounds
|
.bounds
|
||||||
|
|
@ -393,32 +394,54 @@ impl Renderer {
|
||||||
|
|
||||||
image_layer += 1;
|
image_layer += 1;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
Layer::Cached(cached) => {
|
|
||||||
let bounds = cached
|
|
||||||
.bounds
|
|
||||||
.map(|bounds| bounds * scale_factor)
|
|
||||||
.map(Rectangle::snap)
|
|
||||||
.unwrap_or(Rectangle::with_size(target_size));
|
|
||||||
|
|
||||||
if !cached.quads.is_empty() {
|
i += 1;
|
||||||
engine.quad_pipeline.render_cache(
|
}
|
||||||
&cached.quads,
|
Layer::Cached(_) => {
|
||||||
bounds,
|
let group_len = layers[i..]
|
||||||
&mut render_pass,
|
.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,
|
||||||
|
bounds,
|
||||||
|
&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);
|
let _ = ManuallyDrop::into_inner(render_pass);
|
||||||
|
|
||||||
engine.triangle_pipeline.render_cache(
|
engine.triangle_pipeline.render_cache_group(
|
||||||
device,
|
device,
|
||||||
encoder,
|
encoder,
|
||||||
frame,
|
frame,
|
||||||
target_size,
|
target_size,
|
||||||
&cached.meshes,
|
group.clone().map(|(cached, bounds)| {
|
||||||
bounds,
|
(&cached.meshes, bounds)
|
||||||
|
}),
|
||||||
scale_factor,
|
scale_factor,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -443,24 +466,28 @@ impl Renderer {
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
if !cached.text.is_empty() {
|
for (cached, bounds) in group {
|
||||||
engine.text_pipeline.render_cache(
|
if !cached.text.is_empty() {
|
||||||
&cached.text,
|
engine.text_pipeline.render_cache(
|
||||||
bounds,
|
&cached.text,
|
||||||
&mut render_pass,
|
bounds,
|
||||||
);
|
&mut render_pass,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(any(feature = "svg", feature = "image"))]
|
||||||
|
if !cached.images.is_empty() {
|
||||||
|
engine.image_pipeline.render(
|
||||||
|
image_layer,
|
||||||
|
bounds,
|
||||||
|
&mut render_pass,
|
||||||
|
);
|
||||||
|
|
||||||
|
image_layer += 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(any(feature = "svg", feature = "image"))]
|
i += group_len;
|
||||||
if !cached.images.is_empty() {
|
|
||||||
engine.image_pipeline.render(
|
|
||||||
image_layer,
|
|
||||||
bounds,
|
|
||||||
&mut render_pass,
|
|
||||||
);
|
|
||||||
|
|
||||||
image_layer += 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -136,14 +136,13 @@ impl Pipeline {
|
||||||
self.blit.as_mut(),
|
self.blit.as_mut(),
|
||||||
&self.solid,
|
&self.solid,
|
||||||
&self.gradient,
|
&self.gradient,
|
||||||
&self.layers[layer],
|
|
||||||
target_size,
|
target_size,
|
||||||
meshes,
|
std::iter::once((&self.layers[layer], meshes, bounds)),
|
||||||
bounds,
|
|
||||||
scale_factor,
|
scale_factor,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
pub fn render_cache(
|
pub fn render_cache(
|
||||||
&mut self,
|
&mut self,
|
||||||
device: &wgpu::Device,
|
device: &wgpu::Device,
|
||||||
|
|
@ -165,25 +164,51 @@ impl Pipeline {
|
||||||
self.blit.as_mut(),
|
self.blit.as_mut(),
|
||||||
&self.solid,
|
&self.solid,
|
||||||
&self.gradient,
|
&self.gradient,
|
||||||
layer,
|
|
||||||
target_size,
|
target_size,
|
||||||
batch,
|
std::iter::once((layer, batch, bounds)),
|
||||||
bounds,
|
|
||||||
scale_factor,
|
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,
|
device: &wgpu::Device,
|
||||||
encoder: &mut wgpu::CommandEncoder,
|
encoder: &mut wgpu::CommandEncoder,
|
||||||
target: &wgpu::TextureView,
|
target: &wgpu::TextureView,
|
||||||
mut blit: Option<&mut msaa::Blit>,
|
mut blit: Option<&mut msaa::Blit>,
|
||||||
solid: &solid::Pipeline,
|
solid: &solid::Pipeline,
|
||||||
gradient: &gradient::Pipeline,
|
gradient: &gradient::Pipeline,
|
||||||
layer: &Layer,
|
|
||||||
target_size: Size<u32>,
|
target_size: Size<u32>,
|
||||||
meshes: &Batch,
|
group: impl Iterator<Item = (&'a Layer, &'a Batch, Rectangle<u32>)>,
|
||||||
bounds: Rectangle<u32>,
|
|
||||||
scale_factor: f32,
|
scale_factor: f32,
|
||||||
) {
|
) {
|
||||||
{
|
{
|
||||||
|
|
@ -220,14 +245,16 @@ impl Pipeline {
|
||||||
occlusion_query_set: None,
|
occlusion_query_set: None,
|
||||||
});
|
});
|
||||||
|
|
||||||
layer.render(
|
for (layer, meshes, bounds) in group {
|
||||||
solid,
|
layer.render(
|
||||||
gradient,
|
solid,
|
||||||
meshes,
|
gradient,
|
||||||
bounds,
|
meshes,
|
||||||
scale_factor,
|
bounds,
|
||||||
&mut render_pass,
|
scale_factor,
|
||||||
);
|
&mut render_pass,
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(blit) = blit {
|
if let Some(blit) = blit {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue