Bug 1711477 - Add a way to get from atlas alloc ID to texture cache handle. r=gfx-reviewers,gw

This will be used in a followup patch to defragment the texture cache.

Differential Revision: https://phabricator.services.mozilla.com/D128252
This commit is contained in:
Nicolas Silva 2021-10-21 08:54:49 +00:00
parent fea049f963
commit fce170afcb
2 changed files with 52 additions and 24 deletions

View File

@ -49,7 +49,7 @@ pub const TEXTURE_REGION_DIMENSIONS: i32 = 512;
/// Items in the texture cache can either be standalone textures,
/// or a sub-rect inside the shared cache.
#[derive(Debug)]
#[derive(Clone, Debug)]
#[cfg_attr(feature = "capture", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
pub enum EntryDetails {
@ -1349,26 +1349,6 @@ impl TextureCache {
), BudgetType::Standalone)
}
/// Allocates a cache entry appropriate for the given parameters.
///
/// This allocates from the shared cache unless the parameters do not meet
/// the shared cache requirements, in which case a standalone texture is
/// used.
fn allocate_cache_entry(
&mut self,
params: &CacheAllocParams,
) -> (CacheEntry, BudgetType) {
assert!(!params.descriptor.size.is_empty());
// If this image doesn't qualify to go in the shared (batching) cache,
// allocate a standalone entry.
if self.is_allowed_in_shared_cache(params.filter, &params.descriptor) {
self.allocate_from_shared_cache(params)
} else {
self.allocate_standalone_entry(params)
}
}
/// Allocates a cache entry for the given parameters, and updates the
/// provided handle to point to the new entry.
fn allocate(
@ -1378,7 +1358,19 @@ impl TextureCache {
eviction: Eviction,
) {
debug_assert!(self.now.is_valid());
let (new_cache_entry, budget_type) = self.allocate_cache_entry(params);
assert!(!params.descriptor.size.is_empty());
// If this image doesn't qualify to go in the shared (batching) cache,
// allocate a standalone entry.
let use_shared_cache = self.is_allowed_in_shared_cache(params.filter, &params.descriptor);
let (new_cache_entry, budget_type) = if use_shared_cache {
self.allocate_from_shared_cache(params)
} else {
self.allocate_standalone_entry(params)
};
let details = new_cache_entry.details.clone();
let texture_id = new_cache_entry.texture_id;
// If the handle points to a valid cache entry, we want to replace the
// cache entry with our newly updated location. We also need to ensure
@ -1417,6 +1409,16 @@ impl TextureCache {
old_entry.evict();
self.free(&old_entry);
}
if let EntryDetails::Cache { alloc_id, .. } = details {
let allocator_list = self.shared_textures.select(
params.descriptor.format,
params.filter,
params.shader,
).0;
allocator_list.set_handle(texture_id, alloc_id, handle);
}
}
pub fn shared_alpha_expected_format(&self) -> ImageFormat {

View File

@ -3,7 +3,8 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
mod guillotine;
use crate::texture_cache::TextureCacheHandle;
use crate::internal_types::FastHashMap;
pub use guillotine::*;
/* This Source Code Form is subject to the terms of the Mozilla Public
@ -54,6 +55,10 @@ pub trait AtlasAllocatorList<TextureParameters> {
texture_alloc_cb: &mut dyn FnMut(DeviceIntSize, &TextureParameters) -> CacheTextureId,
) -> (CacheTextureId, AllocId, DeviceIntRect);
fn set_handle(&mut self, texture_id: CacheTextureId, alloc_id: AllocId, handle: &TextureCacheHandle);
fn remove_handle(&mut self, texture_id: CacheTextureId, alloc_id: AllocId);
/// Deallocate a rectangle and return its size.
fn deallocate(&mut self, texture_id: CacheTextureId, alloc_id: AllocId);
@ -65,6 +70,7 @@ pub trait AtlasAllocatorList<TextureParameters> {
#[cfg_attr(feature = "replay", derive(Deserialize))]
struct TextureUnit<Allocator> {
allocator: Allocator,
handles: FastHashMap<AllocId, TextureCacheHandle>,
texture_id: CacheTextureId,
}
@ -109,6 +115,7 @@ impl<Allocator: AtlasAllocator, TextureParameters> AllocatorList<Allocator, Text
self.units.push(TextureUnit {
allocator: Allocator::new(self.size, &self.atlas_parameters),
handles: FastHashMap::default(),
texture_id,
});
@ -126,6 +133,7 @@ impl<Allocator: AtlasAllocator, TextureParameters> AllocatorList<Allocator, Text
.find(|unit| unit.texture_id == texture_id)
.expect("Unable to find the associated texture array unit");
unit.handles.remove(&alloc_id);
unit.allocator.deallocate(alloc_id);
}
@ -213,6 +221,22 @@ for AllocatorList<Allocator, TextureParameters> {
self.allocate(requested_size, texture_alloc_cb)
}
fn set_handle(&mut self, texture_id: CacheTextureId, alloc_id: AllocId, handle: &TextureCacheHandle) {
let unit = self.units
.iter_mut()
.find(|unit| unit.texture_id == texture_id)
.expect("Unable to find the associated texture array unit");
unit.handles.insert(alloc_id, handle.clone());
}
fn remove_handle(&mut self, texture_id: CacheTextureId, alloc_id: AllocId) {
let unit = self.units
.iter_mut()
.find(|unit| unit.texture_id == texture_id)
.expect("Unable to find the associated texture array unit");
unit.handles.remove(&alloc_id);
}
fn deallocate(&mut self, texture_id: CacheTextureId, alloc_id: AllocId) {
self.deallocate(texture_id, alloc_id);
}
@ -301,7 +325,9 @@ fn bug_1680769() {
// Make some allocations, forcing the the creation of multiple textures.
for _ in 0..50 {
allocations.push(allocators.allocate(size2(256, 256), alloc_cb));
let alloc = allocators.allocate(size2(256, 256), alloc_cb);
allocators.set_handle(alloc.0, alloc.1, &TextureCacheHandle::Empty);
allocations.push(alloc);
}
// Deallocate everything.