Bug 1711462 - Evict non-manual texture cache items when nothing holds on to them. r=gfx-reviewers,gw

Making room in the texture cache as early as possible reduces the likelihood of allocating extra textures. It will also let us discard unused cached render tasks more aggressively in a folowup patch.

Differential Revision: https://phabricator.services.mozilla.com/D115206
This commit is contained in:
Nicolas Silva 2021-05-18 08:20:28 +00:00
Родитель dbda617083
Коммит b134c6a2df
3 изменённых файлов: 34 добавлений и 18 удалений

Просмотреть файл

@ -188,6 +188,16 @@ impl<T, M> LRUCache<T, M> {
}
}
/// Manually evict a specific item.
pub fn remove(&mut self, handle: &WeakFreeListHandle<M>) -> Option<T> {
if let Some(entry) = self.entries.get_opt_mut(handle) {
let strong_handle = self.lru[entry.partition_index as usize].remove(entry.lru_index);
return Some(self.entries.free(strong_handle).value);
}
None
}
/// This is used by the calling code to signal that the element that this handle
/// references has been used on this frame. Internally, it updates the links in
/// the LRU tracking element to move this item to the end of the LRU list. Returns

Просмотреть файл

@ -228,9 +228,7 @@ struct CachedImageInfo {
impl CachedImageInfo {
fn mark_unused(&mut self, texture_cache: &mut TextureCache) {
if self.manual_eviction {
texture_cache.evict_manual_handle(&self.texture_cache_handle);
}
texture_cache.evict_handle(&self.texture_cache_handle);
self.manual_eviction = false;
}
}

Просмотреть файл

@ -1217,21 +1217,29 @@ impl TextureCache {
/// Evict a texture cache handle that was previously set to be in manual
/// eviction mode.
pub fn evict_manual_handle(&mut self, handle: &TextureCacheHandle) {
if let TextureCacheHandle::Manual(handle) = handle {
// Find the strong handle that matches this weak handle. If this
// ever shows up in profiles, we can make it a hash (but the number
// of manual eviction handles is typically small).
// Alternatively, we could make a more forgiving FreeList variant
// which does not differentiate between strong and weak handles.
let index = self.manual_handles.iter().position(|strong_handle| {
strong_handle.matches(handle)
});
if let Some(index) = index {
let handle = self.manual_handles.swap_remove(index);
let entry = self.manual_entries.free(handle);
self.evict_impl(entry);
pub fn evict_handle(&mut self, handle: &TextureCacheHandle) {
match handle {
TextureCacheHandle::Manual(handle) => {
// Find the strong handle that matches this weak handle. If this
// ever shows up in profiles, we can make it a hash (but the number
// of manual eviction handles is typically small).
// Alternatively, we could make a more forgiving FreeList variant
// which does not differentiate between strong and weak handles.
let index = self.manual_handles.iter().position(|strong_handle| {
strong_handle.matches(handle)
});
if let Some(index) = index {
let handle = self.manual_handles.swap_remove(index);
let entry = self.manual_entries.free(handle);
self.evict_impl(entry);
}
}
TextureCacheHandle::Auto(handle) => {
if let Some(entry) = self.lru_cache.remove(handle) {
self.evict_impl(entry);
}
}
_ => {}
}
}
@ -1912,7 +1920,7 @@ mod test_texture_cache {
assert!(bytes_after_allocating > bytes_at_start);
for handle in handles {
texture_cache.evict_manual_handle(&handle);
texture_cache.evict_handle(&handle);
}
let bytes_at_end = texture_cache.total_allocated_bytes_for_testing();