Skip to content

Commit 89ab2e3

Browse files
committed
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.
1 parent 586af96 commit 89ab2e3

File tree

7 files changed

+482
-95
lines changed

7 files changed

+482
-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

+38-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,24 @@ 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+
resource_cache: &ResourceCache,
197+
) {
198+
self.prim_store.destroy(
199+
retained_tiles,
200+
resource_cache,
201+
);
202+
}
203+
174204
/// Compute the contribution (bounding rectangles, and resources) of layers and their
175205
/// primitives in screen space.
176206
fn build_layer_screen_rects_and_cull_layers(
@@ -227,6 +257,10 @@ impl FrameBuilder {
227257
surfaces.push(root_surface);
228258

229259
let mut pic_update_state = PictureUpdateState::new(surfaces);
260+
let mut retained_tiles = mem::replace(
261+
&mut self.pending_retained_tiles,
262+
FastHashMap::default(),
263+
);
230264

231265
// The first major pass of building a frame is to walk the picture
232266
// tree. This pass must be quick (it should never touch individual
@@ -240,8 +274,10 @@ impl FrameBuilder {
240274
&mut pic_update_state,
241275
&frame_context,
242276
resource_cache,
277+
gpu_cache,
243278
&resources.prim_data_store,
244279
&self.clip_store,
280+
&mut retained_tiles,
245281
);
246282

247283
let mut frame_state = FrameBuildingState {

0 commit comments

Comments
 (0)