Skip to content

Commit 3d73e38

Browse files
author
bors-servo
authored
Auto merge of #3359 - gw3583:c8, r=kvark
Allow picture caching to work across scenes (display lists). This patch hooks up the primitive interning work with the tile caching work. Since we have a uid that guarantees uniqueness of the content of primitives and clip nodes, we can use that to construct a (reasonably) efficient hash key for the content of a tile. Along with some additional information (such as the state of the transforms used by the tile), we can construct a hash key for the content of a tile that is stable across new display lists, even if the shape of the clip-scroll tree changes in ways that don't affect the tile. This patch takes advantage of that to retain tiles when a new scene is built, where the content of a tile would result in the same output. <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/webrender/3359) <!-- Reviewable:end -->
2 parents 323b7ea + d1e1976 commit 3d73e38

File tree

7 files changed

+459
-95
lines changed

7 files changed

+459
-95
lines changed

webrender/src/batch.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1001,7 +1001,7 @@ impl AlphaBatchBuilder {
10011001
let tile = &tile_cache.tiles[i as usize];
10021002

10031003
// Check if the tile is visible.
1004-
if !tile.is_visible {
1004+
if !tile.is_visible || !tile.in_use {
10051005
continue;
10061006
}
10071007

webrender/src/frame_builder.rs

+36-2
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use gpu_cache::GpuCache;
1212
use gpu_types::{PrimitiveHeaders, TransformPalette, UvRectKind, ZBufferIdGenerator};
1313
use hit_test::{HitTester, HitTestingRun};
1414
use internal_types::{FastHashMap, PlaneSplitter};
15-
use picture::{PictureSurface, PictureUpdateState, SurfaceInfo, ROOT_SURFACE_INDEX, SurfaceIndex};
15+
use picture::{PictureSurface, PictureUpdateState, SurfaceInfo, ROOT_SURFACE_INDEX, SurfaceIndex, TileDescriptor};
1616
use prim_store::{PrimitiveStore, SpaceMapper, PictureIndex, PrimitiveDebugId, PrimitiveScratchBuffer};
1717
#[cfg(feature = "replay")]
1818
use prim_store::{PrimitiveStoreStats};
@@ -23,8 +23,9 @@ use resource_cache::{ResourceCache};
2323
use scene::{ScenePipeline, SceneProperties};
2424
use segment::SegmentBuilder;
2525
use spatial_node::SpatialNode;
26-
use std::f32;
26+
use std::{f32, mem};
2727
use std::sync::Arc;
28+
use texture_cache::TextureCacheHandle;
2829
use tiling::{Frame, RenderPass, RenderPassKind, RenderTargetContext};
2930
use tiling::{SpecialRenderPasses};
3031

@@ -60,6 +61,9 @@ pub struct FrameBuilder {
6061
background_color: Option<ColorF>,
6162
window_size: DeviceIntSize,
6263
root_pic_index: PictureIndex,
64+
/// Cache of surface tiles from the previous frame builder
65+
/// that can optionally be consumed by this frame builder.
66+
pending_retained_tiles: FastHashMap<TileDescriptor, TextureCacheHandle>,
6367
pub prim_store: PrimitiveStore,
6468
pub clip_store: ClipStore,
6569
pub hit_testing_runs: Vec<HitTestingRun>,
@@ -144,6 +148,7 @@ impl FrameBuilder {
144148
window_size: DeviceIntSize::zero(),
145149
background_color: None,
146150
root_pic_index: PictureIndex(0),
151+
pending_retained_tiles: FastHashMap::default(),
147152
config: FrameBuilderConfig {
148153
default_font_render_mode: FontRenderMode::Mono,
149154
dual_source_blending_is_enabled: true,
@@ -153,6 +158,17 @@ impl FrameBuilder {
153158
}
154159
}
155160

161+
/// Provide any cached surface tiles from the previous frame builder
162+
/// to a new frame builder. These will be consumed or dropped the
163+
/// first time a new frame builder creates a frame.
164+
pub fn set_retained_tiles(
165+
&mut self,
166+
retained_tiles: FastHashMap<TileDescriptor, TextureCacheHandle>,
167+
) {
168+
debug_assert!(self.pending_retained_tiles.is_empty());
169+
self.pending_retained_tiles = retained_tiles;
170+
}
171+
156172
pub fn with_display_list_flattener(
157173
screen_rect: DeviceIntRect,
158174
background_color: Option<ColorF>,
@@ -167,10 +183,22 @@ impl FrameBuilder {
167183
screen_rect,
168184
background_color,
169185
window_size,
186+
pending_retained_tiles: FastHashMap::default(),
170187
config: flattener.config,
171188
}
172189
}
173190

191+
/// Destroy an existing frame builder. This is called just before
192+
/// a frame builder is replaced with a newly built scene.
193+
pub fn destroy(
194+
self,
195+
retained_tiles: &mut FastHashMap<TileDescriptor, TextureCacheHandle>,
196+
) {
197+
self.prim_store.destroy(
198+
retained_tiles,
199+
);
200+
}
201+
174202
/// Compute the contribution (bounding rectangles, and resources) of layers and their
175203
/// primitives in screen space.
176204
fn build_layer_screen_rects_and_cull_layers(
@@ -227,6 +255,10 @@ impl FrameBuilder {
227255
surfaces.push(root_surface);
228256

229257
let mut pic_update_state = PictureUpdateState::new(surfaces);
258+
let mut retained_tiles = mem::replace(
259+
&mut self.pending_retained_tiles,
260+
FastHashMap::default(),
261+
);
230262

231263
// The first major pass of building a frame is to walk the picture
232264
// tree. This pass must be quick (it should never touch individual
@@ -240,8 +272,10 @@ impl FrameBuilder {
240272
&mut pic_update_state,
241273
&frame_context,
242274
resource_cache,
275+
gpu_cache,
243276
&resources.prim_data_store,
244277
&self.clip_store,
278+
&mut retained_tiles,
245279
);
246280

247281
let mut frame_state = FrameBuildingState {

0 commit comments

Comments
 (0)