Bug 1517722 - Update webrender to commit 8a7212b628ae39e7251201b0a9761c74bab42c5d (WR PR #3465). r=kats
authorWR Updater Bot <graphics-team@mozilla.staktrace.com>
Fri, 04 Jan 2019 13:25:17 +0000
changeset 509645 2b6f049b5daf133771afb38efe807a7fd73a4f19
parent 509633 58c32489a2fb49af3a36dfccdf390e4da969bc86
child 509646 1b01f47f32c02a3335ee107c53ebf85306026875
push id10547
push userffxbld-merge
push dateMon, 21 Jan 2019 13:03:58 +0000
treeherdermozilla-beta@24ec1916bffe [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskats
bugs1517722
milestone66.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 1517722 - Update webrender to commit 8a7212b628ae39e7251201b0a9761c74bab42c5d (WR PR #3465). r=kats https://github.com/servo/webrender/pull/3465 Differential Revision: https://phabricator.services.mozilla.com/D15721
gfx/webrender_bindings/revision.txt
gfx/wr/webrender/src/picture.rs
--- a/gfx/webrender_bindings/revision.txt
+++ b/gfx/webrender_bindings/revision.txt
@@ -1,1 +1,1 @@
-da88c56f2448e66421fe8e2cab386a61e8b956b5
+8a7212b628ae39e7251201b0a9761c74bab42c5d
--- a/gfx/wr/webrender/src/picture.rs
+++ b/gfx/wr/webrender/src/picture.rs
@@ -95,16 +95,20 @@ pub struct GlobalTransformInfo {
 #[derive(Debug)]
 pub struct OpacityBindingInfo {
     /// The current value retrieved from dynamic scene properties.
     value: f32,
     /// True if it was changed (or is new) since the last frame build.
     changed: bool,
 }
 
+/// A stable ID for a given tile, to help debugging.
+#[derive(Debug, Copy, Clone)]
+struct TileId(usize);
+
 /// Information about a cached tile.
 #[derive(Debug)]
 pub struct Tile {
     /// The current world rect of thie tile.
     world_rect: WorldRect,
     /// The current local rect of this tile.
     pub local_rect: LayoutRect,
     /// The valid rect within this tile.
@@ -113,29 +117,34 @@ pub struct Tile {
     /// (reasonably) efficiently hashed and compared.
     descriptor: TileDescriptor,
     /// Handle to the cached texture for this tile.
     pub handle: TextureCacheHandle,
     /// If true, this tile is marked valid, and the existing texture
     /// cache handle can be used. Tiles are invalidated during the
     /// build_dirty_regions method.
     is_valid: bool,
+    /// The tile id is stable between display lists and / or frames,
+    /// if the tile is retained. Useful for debugging tile evictions.
+    id: TileId,
 }
 
 impl Tile {
     /// Construct a new, invalid tile.
     fn new(
+        id: TileId,
     ) -> Self {
         Tile {
             local_rect: LayoutRect::zero(),
             world_rect: WorldRect::zero(),
             valid_rect: WorldRect::zero(),
             handle: TextureCacheHandle::invalid(),
             descriptor: TileDescriptor::new(),
             is_valid: false,
+            id,
         }
     }
 
     /// Clear the dependencies for a tile.
     fn clear(&mut self) {
         self.descriptor.clear();
     }
 }
@@ -285,16 +294,18 @@ pub struct TileCache {
     /// A list of blits from the framebuffer to be applied during this frame.
     pub pending_blits: Vec<TileBlit>,
     /// The current world bounding rect of this tile cache. This is used
     /// to derive a local clip rect, such that we don't obscure in the
     /// z-buffer any items placed earlier in the render order (such as
     /// scroll bars in gecko, when the content overflows under the
     /// scroll bar).
     world_bounding_rect: WorldRect,
+    /// Counter for the next id to assign for a new tile.
+    next_id: usize,
 }
 
 impl TileCache {
     pub fn new(spatial_node_index: SpatialNodeIndex) -> Self {
         TileCache {
             spatial_node_index,
             tiles: Vec::new(),
             map_local_to_world: SpaceMapper::new(
@@ -307,19 +318,26 @@ impl TileCache {
             dirty_region: None,
             needs_update: true,
             world_origin: WorldPoint::zero(),
             world_tile_size: WorldSize::zero(),
             tile_count: TileSize::zero(),
             scroll_offset: None,
             pending_blits: Vec::new(),
             world_bounding_rect: WorldRect::zero(),
+            next_id: 0,
         }
     }
 
+    fn next_id(&mut self) -> TileId {
+        let id = TileId(self.next_id);
+        self.next_id += 1;
+        id
+    }
+
     /// Get the tile coordinates for a given rectangle.
     fn get_tile_coords_for_rect(
         &self,
         rect: &WorldRect,
     ) -> (TileOffset, TileOffset) {
         // Translate the rectangle into the virtual tile space
         let origin = rect.origin - self.world_origin;
 
@@ -516,17 +534,17 @@ impl TileCache {
         for y in 0 .. y_tiles {
             for x in 0 .. x_tiles {
                 let px = p0.x + x as f32 * TILE_SIZE_WIDTH as f32;
                 let py = p0.y + y as f32 * TILE_SIZE_HEIGHT as f32;
                 let key = (px.round() as i32, py.round() as i32);
 
                 let mut tile = match old_tiles.remove(&key) {
                     Some(tile) => tile,
-                    None => Tile::new(),
+                    None => Tile::new(self.next_id()),
                 };
 
                 tile.world_rect = WorldRect::new(
                     WorldPoint::new(
                         px / frame_context.device_pixel_scale.0,
                         py / frame_context.device_pixel_scale.0,
                     ),
                     self.world_tile_size,
@@ -892,35 +910,42 @@ impl TileCache {
         );
 
         let local_clip_rect = map_surface_to_world
             .unmap(&self.world_bounding_rect)
             .expect("bug: unable to map local clip rect");
 
         // Step through each tile and invalidate if the dependencies have changed.
         for (i, tile) in self.tiles.iter_mut().enumerate() {
+            // Invalidate if the backing texture was evicted.
+            if resource_cache.texture_cache.is_allocated(&tile.handle) {
+                // Request the backing texture so it won't get evicted this frame.
+                // We specifically want to mark the tile texture as used, even
+                // if it's detected not visible below and skipped. This is because
+                // we maintain the set of tiles we care about based on visibility
+                // during pre_update. If a tile still exists after that, we are
+                // assuming that it's either visible or we want to retain it for
+                // a while in case it gets scrolled back onto screen soon.
+                // TODO(gw): Consider switching to manual eviction policy?
+                resource_cache.texture_cache.request(&tile.handle, gpu_cache);
+            } else {
+                tile.is_valid = false;
+            }
+
             let visible_rect = match tile
                 .world_rect
                 .intersection(&frame_context.screen_world_rect)
             {
                 Some(rect) => rect,
                 None => continue,
             };
 
             // Check the content of the tile is the same
             tile.is_valid &= tile.descriptor.is_valid();
 
-            // Invalidate if the backing texture was evicted.
-            if !resource_cache.texture_cache.is_allocated(&tile.handle) {
-                tile.is_valid = false;
-            }
-
-            // Request the backing texture so it won't get evicted this frame.
-            resource_cache.texture_cache.request(&tile.handle, gpu_cache);
-
             // Decide how to handle this tile when drawing this frame.
             if tile.is_valid {
                 // If the tile is valid, we will generally want to draw it
                 // on screen. However, if there are no primitives there is
                 // no need to draw it.
                 if !tile.descriptor.prims.is_empty() {
                     self.tiles_to_draw.push(TileIndex(i));
                 }