Avoid generating empty caches in iced_wgpu

This commit is contained in:
Héctor Ramón Jiménez 2024-04-06 03:06:40 +02:00
parent 7eb16452f3
commit 441aac2599
No known key found for this signature in database
GPG key ID: 4C07CEC81AFA161F
4 changed files with 66 additions and 22 deletions

View file

@ -38,8 +38,8 @@ pub enum Geometry {
#[derive(Clone)] #[derive(Clone)]
pub struct Cache { pub struct Cache {
pub meshes: triangle::Cache, pub meshes: Option<triangle::Cache>,
pub text: text::Cache, pub text: Option<text::Cache>,
} }
impl Cached for Geometry { impl Cached for Geometry {
@ -53,8 +53,17 @@ impl Cached for Geometry {
match self { match self {
Self::Live { meshes, text } => { Self::Live { meshes, text } => {
if let Some(mut previous) = previous { if let Some(mut previous) = previous {
previous.meshes.update(meshes); if let Some(cache) = &mut previous.meshes {
previous.text.update(text); cache.update(meshes);
} else {
previous.meshes = triangle::Cache::new(meshes);
}
if let Some(cache) = &mut previous.text {
cache.update(text);
} else {
previous.text = text::Cache::new(text);
}
previous previous
} else { } else {

View file

@ -517,8 +517,13 @@ impl graphics::geometry::Renderer for Renderer {
self.layers.draw_text_group(text); self.layers.draw_text_group(text);
} }
Geometry::Cached(cache) => { Geometry::Cached(cache) => {
self.layers.draw_mesh_cache(cache.meshes); if let Some(meshes) = cache.meshes {
self.layers.draw_text_cache(cache.text); self.layers.draw_mesh_cache(meshes);
}
if let Some(text) = cache.text {
self.layers.draw_text_cache(text);
}
} }
} }
} }

View file

@ -43,14 +43,18 @@ pub struct Cache {
pub struct Id(u64); pub struct Id(u64);
impl Cache { impl Cache {
pub fn new(text: Vec<Text>) -> Self { pub fn new(text: Vec<Text>) -> Option<Self> {
static NEXT_ID: AtomicU64 = AtomicU64::new(0); static NEXT_ID: AtomicU64 = AtomicU64::new(0);
Self { if text.is_empty() {
return None;
}
Some(Self {
id: Id(NEXT_ID.fetch_add(1, atomic::Ordering::Relaxed)), id: Id(NEXT_ID.fetch_add(1, atomic::Ordering::Relaxed)),
text: Rc::from(text), text: Rc::from(text),
version: 0, version: 0,
} })
} }
pub fn update(&mut self, text: Vec<Text>) { pub fn update(&mut self, text: Vec<Text>) {
@ -78,8 +82,12 @@ impl Storage {
Self::default() Self::default()
} }
fn get(&self, id: Id) -> Option<&Upload> { fn get(&self, cache: &Cache) -> Option<&Upload> {
self.uploads.get(&id) if cache.text.is_empty() {
return None;
}
self.uploads.get(&cache.id)
} }
fn prepare( fn prepare(
@ -97,8 +105,9 @@ impl Storage {
hash_map::Entry::Occupied(entry) => { hash_map::Entry::Occupied(entry) => {
let upload = entry.into_mut(); let upload = entry.into_mut();
if upload.version != cache.version if !cache.text.is_empty()
|| upload.transformation != new_transformation && (upload.version != cache.version
|| upload.transformation != new_transformation)
{ {
let _ = prepare( let _ = prepare(
device, device,
@ -154,6 +163,12 @@ impl Storage {
transformation: new_transformation, transformation: new_transformation,
version: 0, version: 0,
}); });
log::info!(
"New text upload: {} (total: {})",
cache.id.0,
self.uploads.len()
);
} }
} }
@ -291,7 +306,7 @@ impl Pipeline {
layer_count += 1; layer_count += 1;
} }
Item::Cached { cache, .. } => { Item::Cached { cache, .. } => {
if let Some(upload) = storage.get(cache.id) { if let Some(upload) = storage.get(cache) {
upload upload
.renderer .renderer
.render(&upload.atlas, render_pass) .render(&upload.atlas, render_pass)

View file

@ -38,14 +38,18 @@ pub struct Cache {
pub struct Id(u64); pub struct Id(u64);
impl Cache { impl Cache {
pub fn new(meshes: Vec<Mesh>) -> Self { pub fn new(meshes: Vec<Mesh>) -> Option<Self> {
static NEXT_ID: AtomicU64 = AtomicU64::new(0); static NEXT_ID: AtomicU64 = AtomicU64::new(0);
Self { if meshes.is_empty() {
return None;
}
Some(Self {
id: Id(NEXT_ID.fetch_add(1, atomic::Ordering::Relaxed)), id: Id(NEXT_ID.fetch_add(1, atomic::Ordering::Relaxed)),
batch: Rc::from(meshes), batch: Rc::from(meshes),
version: 0, version: 0,
} })
} }
pub fn update(&mut self, meshes: Vec<Mesh>) { pub fn update(&mut self, meshes: Vec<Mesh>) {
@ -72,8 +76,12 @@ impl Storage {
Self::default() Self::default()
} }
fn get(&self, id: Id) -> Option<&Upload> { fn get(&self, cache: &Cache) -> Option<&Upload> {
self.uploads.get(&id) if cache.batch.is_empty() {
return None;
}
self.uploads.get(&cache.id)
} }
fn prepare( fn prepare(
@ -90,8 +98,9 @@ impl Storage {
hash_map::Entry::Occupied(entry) => { hash_map::Entry::Occupied(entry) => {
let upload = entry.into_mut(); let upload = entry.into_mut();
if upload.version != cache.version if !cache.batch.is_empty()
|| upload.transformation != new_transformation && (upload.version != cache.version
|| upload.transformation != new_transformation)
{ {
upload.layer.prepare( upload.layer.prepare(
device, device,
@ -125,6 +134,12 @@ impl Storage {
transformation: new_transformation, transformation: new_transformation,
version: 0, version: 0,
}); });
log::info!(
"New mesh upload: {} (total: {})",
cache.id.0,
self.uploads.len()
);
} }
} }
@ -247,7 +262,7 @@ impl Pipeline {
transformation, transformation,
cache, cache,
} => { } => {
let upload = storage.get(cache.id)?; let upload = storage.get(cache)?;
Some(( Some((
&upload.layer, &upload.layer,