From 724fe49c733c8b02345c4f427a47f47a1124bd2a Mon Sep 17 00:00:00 2001 From: Brian Reavis Date: Sat, 27 Jul 2024 06:16:27 -0700 Subject: [PATCH] Fix TextureCache memory leak and add is_empty() method (#14480) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit # Objective Fix a memory leak in `TextureCache` caused by the internal HashMap never having unused entries cleared. This isn't a giant memory leak, given the unused entries are simply empty vectors. Though, if someone goes and resizes a window a bunch, it can lead to hundreds/thousands of TextureDescriptor keys adding up in the hashmap – which isn't ideal. ## Solution - Only retain hashmap entries that still have textures. - I also added an `is_empty()` method to `TextureCache`, which is useful for 3rd-party higher-level caches that might have individual caches by view entity or texture type, for example. ## Testing - Verified the examples still work (this is a trivial change) --- crates/bevy_render/src/texture/texture_cache.rs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/crates/bevy_render/src/texture/texture_cache.rs b/crates/bevy_render/src/texture/texture_cache.rs index 3c15f3354a..81e1b1d81f 100644 --- a/crates/bevy_render/src/texture/texture_cache.rs +++ b/crates/bevy_render/src/texture/texture_cache.rs @@ -82,16 +82,22 @@ impl TextureCache { } } + /// Returns `true` if the texture cache contains no textures. + pub fn is_empty(&self) -> bool { + self.textures.is_empty() + } + /// Updates the cache and only retains recently used textures. pub fn update(&mut self) { - for textures in self.textures.values_mut() { + self.textures.retain(|_, textures| { for texture in textures.iter_mut() { texture.frames_since_last_use += 1; texture.taken = false; } textures.retain(|texture| texture.frames_since_last_use < 3); - } + !textures.is_empty() + }); } }