| author | Nicolas Silva <nsilva@mozilla.com> |
| Thu, 12 Dec 2019 09:10:11 +0000 | |
| changeset 506637 | 116c84612571ece9fe439cb89292120f5c05f1af |
| parent 506636 | afdbc174451905720fd9d9be93e402fc4793aba3 |
| child 506638 | 59cfb8104165cd5d25ab10abe0b634995b6a9552 |
| push id | 36910 |
| push user | csabou@mozilla.com |
| push date | Thu, 12 Dec 2019 21:50:40 +0000 |
| treeherder | mozilla-central@0f6958f49842 [default view] [failures only] |
| perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
| reviewers | gw |
| bugs | 1602458 |
| milestone | 73.0a1 |
| first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
| last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/gfx/wr/webrender/src/picture.rs +++ b/gfx/wr/webrender/src/picture.rs @@ -362,16 +362,19 @@ struct TilePostUpdateContext<'a> { // Mutable state passed to picture cache tiles during post_update struct TilePostUpdateState<'a> { /// Allow access to the texture cache for requesting tiles resource_cache: &'a mut ResourceCache, /// Current configuration and setup for compositing all the picture cache tiles in renderer. composite_state: &'a mut CompositeState, + + /// A cache of comparison results to avoid re-computation during invalidation. + compare_cache: &'a mut FastHashMap<PrimitiveComparisonKey, PrimitiveCompareResult>, } /// Information about the dependencies of a single primitive instance. struct PrimitiveDependencyInfo { /// If true, we should clip the prim rect to the tile boundaries. clip_by_tile: bool, /// Unique content identifier of the primitive. @@ -636,59 +639,56 @@ impl Tile { self.current_descriptor.print(pt); pt.end_level(); } /// Check if the content of the previous and current tile descriptors match fn update_dirty_rects( &mut self, ctx: &TilePostUpdateContext, - state: &TilePostUpdateState, - compare_cache: &mut FastHashMap<PrimitiveComparisonKey, PrimitiveCompareResult>, + state: &mut TilePostUpdateState, invalidation_reason: &mut Option<InvalidationReason>, ) -> PictureRect { let mut prim_comparer = PrimitiveComparer::new( &self.prev_descriptor, &self.current_descriptor, state.resource_cache, ctx.spatial_nodes, ctx.opacity_bindings, ); let mut dirty_rect = PictureRect::zero(); - self.root.update_dirty_rects( &self.prev_descriptor.prims, &self.current_descriptor.prims, &mut prim_comparer, &mut dirty_rect, - compare_cache, + state.compare_cache, invalidation_reason, ); dirty_rect } /// Invalidate a tile based on change in content. This /// must be called even if the tile is not currently /// visible on screen. We might be able to improve this /// later by changing how ComparableVec is used. fn update_content_validity( &mut self, ctx: &TilePostUpdateContext, - state: &TilePostUpdateState, + state: &mut TilePostUpdateState, ) { // Check if the contents of the primitives, clips, and // other dependencies are the same. - let mut compare_cache = FastHashMap::default(); + state.compare_cache.clear(); let mut invalidation_reason = None; let dirty_rect = self.update_dirty_rects( ctx, state, - &mut compare_cache, &mut invalidation_reason, ); if !dirty_rect.is_empty() { self.invalidate( Some(dirty_rect), invalidation_reason.expect("bug: no invalidation_reason"), ); } @@ -1494,16 +1494,19 @@ pub struct TileCacheInstance { root_transform: TransformKey, /// The number of frames until this cache next evaluates what tile size to use. /// If a picture rect size is regularly changing just around a size threshold, /// we don't want to constantly invalidate and reallocate different tile size /// configuration each frame. frames_until_size_eval: usize, /// The current fractional offset of the cached picture fract_offset: PictureVector2D, + /// keep around the hash map used as compare_cache to avoid reallocating it each + /// frame. + compare_cache: FastHashMap<PrimitiveComparisonKey, PrimitiveCompareResult>, } impl TileCacheInstance { pub fn new( slice: usize, spatial_node_index: SpatialNodeIndex, background_color: Option<ColorF>, shared_clips: Vec<ClipDataHandle>, @@ -1540,16 +1543,17 @@ impl TileCacheInstance { backdrop: BackdropInfo::empty(), subpixel_mode: SubpixelMode::Allow, root_transform: TransformKey::Local, shared_clips, shared_clip_chain, current_tile_size: DeviceIntSize::zero(), frames_until_size_eval: 0, fract_offset: PictureVector2D::zero(), + compare_cache: FastHashMap::default(), } } /// Returns true if this tile cache is considered opaque. pub fn is_opaque(&self) -> bool { // If known opaque due to background clear color and being the first slice. // The background_color will only be Some(..) if this is the first slice. match self.background_color { @@ -2282,24 +2286,22 @@ impl TileCacheInstance { spatial_nodes: &self.spatial_nodes, opacity_bindings: &self.opacity_bindings, current_tile_size: self.current_tile_size, }; let mut state = TilePostUpdateState { resource_cache: frame_state.resource_cache, composite_state: frame_state.composite_state, + compare_cache: &mut self.compare_cache, }; // Step through each tile and invalidate if the dependencies have changed. for (key, tile) in self.tiles.iter_mut() { - if tile.post_update( - &ctx, - &mut state, - ) { + if tile.post_update(&ctx, &mut state) { self.tiles_to_draw.push(*key); } } // When under test, record a copy of the dirty region to support // invalidation testing in wrench. if frame_context.config.testing { frame_state.scratch.recorded_dirty_regions.push(self.dirty_region.record());