зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1548131 - WR reset texture allocation r=gw
Introduce a new texture allocation operation "reset", which acts like a "realloc" but without the contents preserved. Use it for the picture texture cache. Differential Revision: https://phabricator.services.mozilla.com/D29539 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
512461990a
Коммит
9512939607
|
@ -146,6 +146,8 @@ pub enum TextureCacheAllocationKind {
|
|||
/// will be deallocated and its contents blitted over. The new size must
|
||||
/// be greater than the old size.
|
||||
Realloc(TextureCacheAllocInfo),
|
||||
/// Reallocates the texture without preserving its contents.
|
||||
Reset(TextureCacheAllocInfo),
|
||||
/// Frees the texture and the corresponding cache ID.
|
||||
Free,
|
||||
}
|
||||
|
@ -242,10 +244,10 @@ impl TextureUpdateList {
|
|||
match cur.kind {
|
||||
TextureCacheAllocationKind::Alloc(ref mut i) => *i = info,
|
||||
TextureCacheAllocationKind::Realloc(ref mut i) => *i = info,
|
||||
TextureCacheAllocationKind::Reset(ref mut i) => *i = info,
|
||||
TextureCacheAllocationKind::Free => panic!("Reallocating freed texture"),
|
||||
}
|
||||
|
||||
return;
|
||||
return
|
||||
}
|
||||
|
||||
self.allocations.push(TextureCacheAllocation {
|
||||
|
@ -254,6 +256,31 @@ impl TextureUpdateList {
|
|||
});
|
||||
}
|
||||
|
||||
/// Pushes a reallocation operation onto the list, potentially coalescing
|
||||
/// with previous operations.
|
||||
pub fn push_reset(&mut self, id: CacheTextureId, info: TextureCacheAllocInfo) {
|
||||
self.debug_assert_coalesced(id);
|
||||
|
||||
// Coallesce this realloc into a previous alloc or realloc, if available.
|
||||
if let Some(cur) = self.allocations.iter_mut().find(|x| x.id == id) {
|
||||
match cur.kind {
|
||||
TextureCacheAllocationKind::Alloc(ref mut i) => *i = info,
|
||||
TextureCacheAllocationKind::Reset(ref mut i) => *i = info,
|
||||
TextureCacheAllocationKind::Free => panic!("Resetting freed texture"),
|
||||
TextureCacheAllocationKind::Realloc(_) => {
|
||||
// Reset takes precedence over realloc
|
||||
cur.kind = TextureCacheAllocationKind::Reset(info);
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
self.allocations.push(TextureCacheAllocation {
|
||||
id,
|
||||
kind: TextureCacheAllocationKind::Reset(info),
|
||||
});
|
||||
}
|
||||
|
||||
/// Pushes a free operation onto the list, potentially coalescing with
|
||||
/// previous operations.
|
||||
pub fn push_free(&mut self, id: CacheTextureId) {
|
||||
|
@ -269,7 +296,9 @@ impl TextureUpdateList {
|
|||
match removed_kind {
|
||||
Some(TextureCacheAllocationKind::Alloc(..)) => { /* no-op! */ },
|
||||
Some(TextureCacheAllocationKind::Free) => panic!("Double free"),
|
||||
Some(TextureCacheAllocationKind::Realloc(..)) | None => {
|
||||
Some(TextureCacheAllocationKind::Realloc(..)) |
|
||||
Some(TextureCacheAllocationKind::Reset(..)) |
|
||||
None => {
|
||||
self.allocations.push(TextureCacheAllocation {
|
||||
id,
|
||||
kind: TextureCacheAllocationKind::Free,
|
||||
|
|
|
@ -3300,10 +3300,10 @@ impl Renderer {
|
|||
upload_time.profile(|| {
|
||||
for update_list in pending_texture_updates.drain(..) {
|
||||
for allocation in update_list.allocations {
|
||||
let is_realloc = matches!(allocation.kind, TextureCacheAllocationKind::Realloc(..));
|
||||
match allocation.kind {
|
||||
TextureCacheAllocationKind::Alloc(info) |
|
||||
TextureCacheAllocationKind::Realloc(info) => {
|
||||
let old = match allocation.kind {
|
||||
TextureCacheAllocationKind::Alloc(ref info) |
|
||||
TextureCacheAllocationKind::Realloc(ref info) |
|
||||
TextureCacheAllocationKind::Reset(ref info) => {
|
||||
// Create a new native texture, as requested by the texture cache.
|
||||
//
|
||||
// Ensure no PBO is bound when creating the texture storage,
|
||||
|
@ -3332,20 +3332,31 @@ impl Renderer {
|
|||
}
|
||||
}
|
||||
|
||||
let old = self.texture_resolver.texture_cache_map.insert(allocation.id, texture);
|
||||
assert_eq!(old.is_some(), is_realloc, "Renderer and RenderBackend disagree");
|
||||
if let Some(old) = old {
|
||||
self.device.blit_renderable_texture(
|
||||
self.texture_resolver.texture_cache_map.get_mut(&allocation.id).unwrap(),
|
||||
&old
|
||||
);
|
||||
self.device.delete_texture(old);
|
||||
}
|
||||
},
|
||||
self.texture_resolver.texture_cache_map.insert(allocation.id, texture)
|
||||
}
|
||||
TextureCacheAllocationKind::Free => {
|
||||
let texture = self.texture_resolver.texture_cache_map.remove(&allocation.id).unwrap();
|
||||
self.device.delete_texture(texture);
|
||||
},
|
||||
self.texture_resolver.texture_cache_map.remove(&allocation.id)
|
||||
}
|
||||
};
|
||||
|
||||
match allocation.kind {
|
||||
TextureCacheAllocationKind::Alloc(_) => {
|
||||
assert!(old.is_none(), "Renderer and backend disagree!");
|
||||
}
|
||||
TextureCacheAllocationKind::Realloc(_) => {
|
||||
self.device.blit_renderable_texture(
|
||||
self.texture_resolver.texture_cache_map.get_mut(&allocation.id).unwrap(),
|
||||
old.as_ref().unwrap(),
|
||||
);
|
||||
}
|
||||
TextureCacheAllocationKind::Reset(_) |
|
||||
TextureCacheAllocationKind::Free => {
|
||||
assert!(old.is_some(), "Renderer and backend disagree!");
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(old) = old {
|
||||
self.device.delete_texture(old);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2183,6 +2183,9 @@ impl ResourceCache {
|
|||
// and fill out the map as the first step.
|
||||
let mut raw_map = FastHashMap::<String, Arc<Vec<u8>>>::default();
|
||||
|
||||
self.clear(ClearCache::all());
|
||||
self.clear_images(|_| true);
|
||||
|
||||
match caches {
|
||||
Some(cached) => {
|
||||
self.current_frame_id = cached.current_frame_id;
|
||||
|
@ -2194,10 +2197,6 @@ impl ResourceCache {
|
|||
}
|
||||
None => {
|
||||
self.current_frame_id = FrameId::INVALID;
|
||||
self.cached_glyphs.clear();
|
||||
self.cached_glyph_dimensions.clear();
|
||||
self.cached_images.clear();
|
||||
self.cached_render_tasks.clear();
|
||||
self.texture_cache = TextureCache::new(
|
||||
self.texture_cache.max_texture_size(),
|
||||
self.texture_cache.max_texture_layers(),
|
||||
|
|
|
@ -639,7 +639,7 @@ impl TextureCache {
|
|||
self.clear_kind(EntryKind::Picture);
|
||||
if let Some(ref mut picture_texture) = self.picture_texture {
|
||||
if let Some(texture_id) = picture_texture.reset(PICTURE_TEXTURE_ADD_SLICES) {
|
||||
self.pending_updates.push_realloc(texture_id, picture_texture.to_info());
|
||||
self.pending_updates.push_reset(texture_id, picture_texture.to_info());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -44,6 +44,7 @@ impl<'a> RawtestHarness<'a> {
|
|||
self.test_blur_cache();
|
||||
self.test_capture();
|
||||
self.test_zero_height_window();
|
||||
self.test_clear_cache();
|
||||
}
|
||||
|
||||
fn render_and_get_pixels(&mut self, window_rect: FramebufferIntRect) -> Vec<u8> {
|
||||
|
@ -463,7 +464,7 @@ impl<'a> RawtestHarness<'a> {
|
|||
}
|
||||
|
||||
fn test_offscreen_blob(&mut self) {
|
||||
println!("\toffscreen blob update.");
|
||||
println!("\toffscreen blob update...");
|
||||
|
||||
assert_eq!(self.wrench.device_pixel_ratio, 1.);
|
||||
|
||||
|
@ -1298,4 +1299,19 @@ impl<'a> RawtestHarness<'a> {
|
|||
test_rounded_rectangle(WorldPoint::new(200., 100.), WorldSize::new(100., 100.), (0, 5));
|
||||
}
|
||||
|
||||
fn test_clear_cache(&mut self) {
|
||||
println!("\tclear cache test...");
|
||||
|
||||
self.wrench.api.send_message(ApiMsg::DebugCommand(DebugCommand::ClearCaches(ClearCache::all())));
|
||||
|
||||
let layout_size = LayoutSize::new(400., 400.);
|
||||
let builder = DisplayListBuilder::new(self.wrench.root_pipeline_id, layout_size);
|
||||
|
||||
let txn = Transaction::new();
|
||||
let mut epoch = Epoch(0);
|
||||
self.submit_dl(&mut epoch, layout_size, builder, &txn.resource_updates);
|
||||
|
||||
self.rx.recv().unwrap();
|
||||
self.wrench.render();
|
||||
}
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче