Bug 1602458 - Recycle some hash map allocations after scene swap. r=gw
authorNicolas Silva <nsilva@mozilla.com>
Thu, 12 Dec 2019 09:15:02 +0000
changeset 506638 59cfb8104165cd5d25ab10abe0b634995b6a9552
parent 506637 116c84612571ece9fe439cb89292120f5c05f1af
child 506639 1f03147b38545bffc24dcccd819114922860b30e
push id36910
push usercsabou@mozilla.com
push dateThu, 12 Dec 2019 21:50:40 +0000
treeherdermozilla-central@0f6958f49842 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersgw
bugs1602458
milestone73.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
Bug 1602458 - Recycle some hash map allocations after scene swap. r=gw Differential Revision: https://phabricator.services.mozilla.com/D56409
gfx/wr/webrender/src/picture.rs
--- a/gfx/wr/webrender/src/picture.rs
+++ b/gfx/wr/webrender/src/picture.rs
@@ -183,27 +183,36 @@ impl<Src, Dst> From<CoordinateSpaceMappi
 
 /// Information about a picture that is pushed / popped on the
 /// PictureUpdateState during picture traversal pass.
 struct PictureInfo {
     /// The spatial node for this picture.
     _spatial_node_index: SpatialNodeIndex,
 }
 
+/// Picture-caching state to keep between scenes.
 pub struct PictureCacheState {
     /// The tiles retained by this picture cache.
     pub tiles: FastHashMap<TileOffset, Tile>,
     /// State of the spatial nodes from previous frame
     spatial_nodes: FastHashMap<SpatialNodeIndex, SpatialNodeDependency>,
     /// State of opacity bindings from previous frame
     opacity_bindings: FastHashMap<PropertyBindingId, OpacityBindingInfo>,
     /// The current transform of the picture cache root spatial node
     root_transform: TransformKey,
     /// The current tile size in device pixels
     current_tile_size: DeviceIntSize,
+    /// Various allocations we want to avoid re-doing.
+    allocations: PictureCacheRecycledAllocations,
+}
+
+pub struct PictureCacheRecycledAllocations {
+    old_tiles: FastHashMap<TileOffset, Tile>,
+    old_opacity_bindings: FastHashMap<PropertyBindingId, OpacityBindingInfo>,
+    compare_cache: FastHashMap<PrimitiveComparisonKey, PrimitiveCompareResult>,
 }
 
 /// Stores a list of cached picture tiles that are retained
 /// between new scenes.
 #[cfg_attr(feature = "capture", derive(Serialize))]
 pub struct RetainedTiles {
     /// The tiles retained between display lists.
     #[cfg_attr(feature = "capture", serde(skip))] //TODO
@@ -1664,16 +1673,28 @@ impl TileCacheInstance {
 
         // If there are pending retained state, retrieve it.
         if let Some(prev_state) = frame_state.retained_tiles.caches.remove(&self.slice) {
             self.tiles.extend(prev_state.tiles);
             self.root_transform = prev_state.root_transform;
             self.spatial_nodes = prev_state.spatial_nodes;
             self.opacity_bindings = prev_state.opacity_bindings;
             self.current_tile_size = prev_state.current_tile_size;
+
+            fn recycle_map<K: std::cmp::Eq + std::hash::Hash, V>(
+                dest: &mut FastHashMap<K, V>,
+                src: FastHashMap<K, V>,
+            ) {
+                if dest.capacity() < src.capacity() {
+                    *dest = src;
+                }
+            }
+            recycle_map(&mut self.old_tiles, prev_state.allocations.old_tiles);
+            recycle_map(&mut self.old_opacity_bindings, prev_state.allocations.old_opacity_bindings);
+            recycle_map(&mut self.compare_cache, prev_state.allocations.compare_cache);
         }
 
         // Only evaluate what tile size to use fairly infrequently, so that we don't end
         // up constantly invalidating and reallocating tiles if the picture rect size is
         // changing near a threshold value.
         if self.frames_until_size_eval == 0 {
             const TILE_SIZE_TINY: f32 = 32.0;
 
@@ -3116,16 +3137,21 @@ impl PicturePrimitive {
                 retained_tiles.caches.insert(
                     tile_cache.slice,
                     PictureCacheState {
                         tiles: tile_cache.tiles,
                         spatial_nodes: tile_cache.spatial_nodes,
                         opacity_bindings: tile_cache.opacity_bindings,
                         root_transform: tile_cache.root_transform,
                         current_tile_size: tile_cache.current_tile_size,
+                        allocations: PictureCacheRecycledAllocations {
+                            old_tiles: tile_cache.old_tiles,
+                            old_opacity_bindings: tile_cache.old_opacity_bindings,
+                            compare_cache: tile_cache.compare_cache,
+                        },
                     },
                 );
             }
         }
     }
 
     // TODO(gw): We have the PictureOptions struct available. We
     //           should move some of the parameter list in this