summaryrefslogtreecommitdiffstats
path: root/wgpu
diff options
context:
space:
mode:
authorLibravatar Héctor Ramón Jiménez <hector@hecrj.dev>2024-04-24 21:29:30 +0200
committerLibravatar Héctor Ramón Jiménez <hector@hecrj.dev>2024-04-24 21:29:30 +0200
commit493c36ac712ef04523065b94988a88cc4db16b1a (patch)
tree9a19baac6fa56025a2aa29f3e5d77c7c98cec4b7 /wgpu
parentfdcec0319757d2f87c82787eab34c6bef8c5a799 (diff)
downloadiced-493c36ac712ef04523065b94988a88cc4db16b1a.tar.gz
iced-493c36ac712ef04523065b94988a88cc4db16b1a.tar.bz2
iced-493c36ac712ef04523065b94988a88cc4db16b1a.zip
Make image `Cache` eviction strategy less aggressive in `iced_wgpu`
Instead of trimming unconditionally at the end of a frame, we now trim the cache only when there is a cache miss. This way, images that are not visible but still a part of the layout will stay cached. Eviction will only happen when the images are not a part of the UI for two consectuive frames.
Diffstat (limited to 'wgpu')
-rw-r--r--wgpu/src/image/atlas.rs15
-rw-r--r--wgpu/src/image/atlas/allocator.rs4
-rw-r--r--wgpu/src/image/atlas/layer.rs8
-rw-r--r--wgpu/src/image/mod.rs2
-rw-r--r--wgpu/src/image/raster.rs9
-rw-r--r--wgpu/src/image/vector.rs8
6 files changed, 41 insertions, 5 deletions
diff --git a/wgpu/src/image/atlas.rs b/wgpu/src/image/atlas.rs
index ea36e06d..ae43c3b4 100644
--- a/wgpu/src/image/atlas.rs
+++ b/wgpu/src/image/atlas.rs
@@ -94,7 +94,7 @@ impl Atlas {
entry
};
- log::info!("Allocated atlas entry: {entry:?}");
+ log::debug!("Allocated atlas entry: {entry:?}");
// It is a webgpu requirement that:
// BufferCopyView.layout.bytes_per_row % wgpu::COPY_BYTES_PER_ROW_ALIGNMENT == 0
@@ -147,13 +147,20 @@ impl Atlas {
}
}
- log::info!("Current atlas: {self:?}");
+ if log::log_enabled!(log::Level::Debug) {
+ log::debug!(
+ "Atlas layers: {} (busy: {}, allocations: {})",
+ self.layer_count(),
+ self.layers.iter().filter(|layer| !layer.is_empty()).count(),
+ self.layers.iter().map(Layer::allocations).sum::<usize>(),
+ );
+ }
Some(entry)
}
pub fn remove(&mut self, entry: &Entry) {
- log::info!("Removing atlas entry: {entry:?}");
+ log::debug!("Removing atlas entry: {entry:?}");
match entry {
Entry::Contiguous(allocation) => {
@@ -266,7 +273,7 @@ impl Atlas {
}
fn deallocate(&mut self, allocation: &Allocation) {
- log::info!("Deallocating atlas: {allocation:?}");
+ log::debug!("Deallocating atlas: {allocation:?}");
match allocation {
Allocation::Full { layer } => {
diff --git a/wgpu/src/image/atlas/allocator.rs b/wgpu/src/image/atlas/allocator.rs
index 204a5c26..a51ac1f5 100644
--- a/wgpu/src/image/atlas/allocator.rs
+++ b/wgpu/src/image/atlas/allocator.rs
@@ -33,6 +33,10 @@ impl Allocator {
pub fn is_empty(&self) -> bool {
self.allocations == 0
}
+
+ pub fn allocations(&self) -> usize {
+ self.allocations
+ }
}
pub struct Region {
diff --git a/wgpu/src/image/atlas/layer.rs b/wgpu/src/image/atlas/layer.rs
index cf089601..fd6788d9 100644
--- a/wgpu/src/image/atlas/layer.rs
+++ b/wgpu/src/image/atlas/layer.rs
@@ -11,4 +11,12 @@ impl Layer {
pub fn is_empty(&self) -> bool {
matches!(self, Layer::Empty)
}
+
+ pub fn allocations(&self) -> usize {
+ match self {
+ Layer::Empty => 0,
+ Layer::Busy(allocator) => allocator.allocations(),
+ Layer::Full => 1,
+ }
+ }
}
diff --git a/wgpu/src/image/mod.rs b/wgpu/src/image/mod.rs
index 86731cbf..8b831a3c 100644
--- a/wgpu/src/image/mod.rs
+++ b/wgpu/src/image/mod.rs
@@ -277,7 +277,7 @@ impl Pipeline {
let texture_version = cache.layer_count();
if self.texture_version != texture_version {
- log::info!("Atlas has grown. Recreating bind group...");
+ log::debug!("Atlas has grown. Recreating bind group...");
self.texture =
cache.create_bind_group(device, &self.texture_layout);
diff --git a/wgpu/src/image/raster.rs b/wgpu/src/image/raster.rs
index 441b294f..7a837f28 100644
--- a/wgpu/src/image/raster.rs
+++ b/wgpu/src/image/raster.rs
@@ -40,6 +40,7 @@ impl Memory {
pub struct Cache {
map: FxHashMap<u64, Memory>,
hits: FxHashSet<u64>,
+ should_trim: bool,
}
impl Cache {
@@ -55,6 +56,8 @@ impl Cache {
Err(_) => Memory::Invalid,
};
+ self.should_trim = true;
+
self.insert(handle, memory);
self.get(handle).unwrap()
}
@@ -86,6 +89,11 @@ impl Cache {
/// Trim cache misses from cache
pub fn trim(&mut self, atlas: &mut Atlas) {
+ // Only trim if new entries have landed in the `Cache`
+ if !self.should_trim {
+ return;
+ }
+
let hits = &self.hits;
self.map.retain(|k, memory| {
@@ -101,6 +109,7 @@ impl Cache {
});
self.hits.clear();
+ self.should_trim = false;
}
fn get(&mut self, handle: &image::Handle) -> Option<&mut Memory> {
diff --git a/wgpu/src/image/vector.rs b/wgpu/src/image/vector.rs
index d681b2e6..c6d829af 100644
--- a/wgpu/src/image/vector.rs
+++ b/wgpu/src/image/vector.rs
@@ -37,6 +37,7 @@ pub struct Cache {
rasterized: FxHashMap<(u64, u32, u32, ColorFilter), atlas::Entry>,
svg_hits: FxHashSet<u64>,
rasterized_hits: FxHashSet<(u64, u32, u32, ColorFilter)>,
+ should_trim: bool,
}
type ColorFilter = Option<[u8; 4]>;
@@ -76,6 +77,8 @@ impl Cache {
}
}
+ self.should_trim = true;
+
let _ = self.svgs.insert(handle.id(), svg);
self.svgs.get(&handle.id()).unwrap()
}
@@ -176,6 +179,10 @@ impl Cache {
/// Load svg and upload raster data
pub fn trim(&mut self, atlas: &mut Atlas) {
+ if !self.should_trim {
+ return;
+ }
+
let svg_hits = &self.svg_hits;
let rasterized_hits = &self.rasterized_hits;
@@ -191,6 +198,7 @@ impl Cache {
});
self.svg_hits.clear();
self.rasterized_hits.clear();
+ self.should_trim = false;
}
}