From e8fefd230e31e3137115295fd32fa51497aa47b6 Mon Sep 17 00:00:00 2001 From: Glenn Watson Date: Sun, 28 Jun 2020 21:46:37 +0000 Subject: [PATCH] Bug 1623792 - Store tile cache instances separately from picture primitives. r=Bert,nical This is a partial step towards a larger change. The goal of this and the follow up patches is to move the tile cache instances to be stored in the render backend, rather than inside the picture / primitive tree. This will allow better caching of dependency and visibility state across both frame and scene builds for primitives. This has the potential to significantly reduce or eliminate the amount of work we do per-frame to track per-primitive visibility, clip-chain state and tile assignments. A longer term goal is to allow correlating up-to-date tile caches with pipeline display lists that haven't changed. This would allow WR to skip scene building for content display lists that haven't changed, if only the outer pipeline content has changed. Differential Revision: https://phabricator.services.mozilla.com/D81284 --- gfx/wr/webrender/src/batch.rs | 4 +- gfx/wr/webrender/src/frame_builder.rs | 23 +++-- gfx/wr/webrender/src/picture.rs | 127 ++++++++++++++----------- gfx/wr/webrender/src/prepare.rs | 11 ++- gfx/wr/webrender/src/prim_store/mod.rs | 5 +- gfx/wr/webrender/src/render_backend.rs | 5 +- gfx/wr/webrender/src/render_target.rs | 3 +- gfx/wr/webrender/src/scene.rs | 3 + gfx/wr/webrender/src/scene_building.rs | 22 ++--- gfx/wr/webrender/src/visibility.rs | 14 ++- 10 files changed, 128 insertions(+), 89 deletions(-) diff --git a/gfx/wr/webrender/src/batch.rs b/gfx/wr/webrender/src/batch.rs index f7e0ddd6aee2..73cdd89c138e 100644 --- a/gfx/wr/webrender/src/batch.rs +++ b/gfx/wr/webrender/src/batch.rs @@ -1374,11 +1374,11 @@ impl BatchBuilder { let surface_task = surface.render_tasks.map(|s| s.root); match raster_config.composite_mode { - PictureCompositeMode::TileCache { .. } => { + PictureCompositeMode::TileCache { slice_id } => { // Tile cache instances are added to the composite config, rather than // directly added to batches. This allows them to be drawn with various // present modes during render, such as partial present etc. - let tile_cache = picture.tile_cache.as_ref().unwrap(); + let tile_cache = &ctx.tile_caches[&slice_id]; let map_local_to_world = SpaceMapper::new_with_target( ROOT_SPATIAL_NODE_INDEX, tile_cache.spatial_node_index, diff --git a/gfx/wr/webrender/src/frame_builder.rs b/gfx/wr/webrender/src/frame_builder.rs index b8b80d64b747..8e422a5200ce 100644 --- a/gfx/wr/webrender/src/frame_builder.rs +++ b/gfx/wr/webrender/src/frame_builder.rs @@ -15,7 +15,7 @@ use crate::gpu_types::TransformData; use crate::internal_types::{FastHashMap, PlaneSplitter, SavedTargetIndex}; use crate::picture::{DirtyRegion, RecordedDirtyRegion, PictureUpdateState}; use crate::picture::{RetainedTiles, SurfaceRenderTasks, SurfaceInfo, SurfaceIndex, ROOT_SURFACE_INDEX}; -use crate::picture::{BackdropKind, SubpixelMode, TileCacheLogger}; +use crate::picture::{BackdropKind, SubpixelMode, TileCacheLogger, RasterConfig, PictureCompositeMode}; use crate::prepare::prepare_primitives; use crate::prim_store::{SpaceMapper, PictureIndex, PrimitiveDebugId}; use crate::prim_store::{DeferredResolve}; @@ -391,6 +391,7 @@ impl FrameBuilder { &global_screen_world_rect, &visibility_context, &mut visibility_state, + &mut scene.tile_caches, ); // When there are tiles that are left remaining in the `retained_tiles`, @@ -469,7 +470,8 @@ impl FrameBuilder { &mut frame_state, &frame_context, &mut scratch.primitive, - tile_cache_logger + tile_cache_logger, + &mut scene.tile_caches, ) .unwrap(); @@ -488,6 +490,7 @@ impl FrameBuilder { data_stores, &mut scratch.primitive, tile_cache_logger, + &mut scene.tile_caches, ); } @@ -641,6 +644,7 @@ impl FrameBuilder { scratch: &mut scratch.primitive, screen_world_rect, globals: &self.globals, + tile_caches: &scene.tile_caches, }; build_render_pass( @@ -881,15 +885,18 @@ pub fn build_render_pass( for (pic_index, task_ids) in picture_cache_tasks { profile_scope!("picture_cache_task"); let pic = &ctx.prim_store.pictures[pic_index.0]; - let tile_cache = pic.tile_cache.as_ref().expect("bug"); // Extract raster/surface spatial nodes for this surface. - let (root_spatial_node_index, surface_spatial_node_index) = match pic.raster_config { - Some(ref rc) => { - let surface = &ctx.surfaces[rc.surface_index.0]; - (surface.raster_spatial_node_index, surface.surface_spatial_node_index) + let (root_spatial_node_index, surface_spatial_node_index, tile_cache) = match pic.raster_config { + Some(RasterConfig { surface_index, composite_mode: PictureCompositeMode::TileCache { slice_id }, .. }) => { + let surface = &ctx.surfaces[surface_index.0]; + ( + surface.raster_spatial_node_index, + surface.surface_spatial_node_index, + &ctx.tile_caches[&slice_id], + ) } - None => { + _ => { unreachable!(); } }; diff --git a/gfx/wr/webrender/src/picture.rs b/gfx/wr/webrender/src/picture.rs index 4339204fd2f8..6771ce2e1bdb 100644 --- a/gfx/wr/webrender/src/picture.rs +++ b/gfx/wr/webrender/src/picture.rs @@ -2262,6 +2262,19 @@ pub struct ExternalNativeSurface { pub image_dependencies: [ImageDependency; 3], } +/// The key that identifies a tile cache instance. For now, it's simple the index of +/// the slice as it was created during scene building. +#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] +#[cfg_attr(feature = "capture", derive(Serialize))] +#[cfg_attr(feature = "replay", derive(Deserialize))] +pub struct SliceId(usize); + +impl SliceId { + pub fn new(index: usize) -> Self { + SliceId(index) + } +} + /// Represents a cache of tiles that make up a picture primitives. pub struct TileCacheInstance { /// Index of the tile cache / slice for this frame builder. It's determined @@ -3629,7 +3642,7 @@ impl TileCacheInstance { // diff'ing the invalidation states in a visual tool. let mut pt = PrintTree::new("Picture Cache"); - pt.new_level(format!("Slice {}", self.slice)); + pt.new_level(format!("Slice {:?}", self.slice)); pt.add_item(format!("fract_offset: {:?}", self.fract_offset)); pt.add_item(format!("background_color: {:?}", self.background_color)); @@ -4173,6 +4186,7 @@ pub enum PictureCompositeMode { Blit(BlitReason), /// Used to cache a picture as a series of tiles. TileCache { + slice_id: SliceId, }, /// Apply an SVG filter SvgFilter(Vec, Vec), @@ -4568,10 +4582,6 @@ pub struct PicturePrimitive { /// transform animation and/or scrolling. pub segments_are_valid: bool, - /// If Some(..) the tile cache that is associated with this picture. - #[cfg_attr(feature = "capture", serde(skip))] //TODO - pub tile_cache: Option>, - /// The config options for this picture. pub options: PictureOptions, @@ -4663,29 +4673,32 @@ impl PicturePrimitive { pub fn destroy( &mut self, retained_tiles: &mut RetainedTiles, + tile_caches: &mut FastHashMap>, ) { - if let Some(tile_cache) = self.tile_cache.take() { - if !tile_cache.tiles.is_empty() { - retained_tiles.caches.insert( - tile_cache.slice, - PictureCacheState { - tiles: tile_cache.tiles, - spatial_node_comparer: tile_cache.spatial_node_comparer, - opacity_bindings: tile_cache.opacity_bindings, - color_bindings: tile_cache.color_bindings, - root_transform: tile_cache.root_transform, - current_tile_size: tile_cache.current_tile_size, - native_surface: tile_cache.native_surface, - external_native_surface_cache: tile_cache.external_native_surface_cache, - virtual_offset: tile_cache.virtual_offset, - frame_id: tile_cache.frame_id, - allocations: PictureCacheRecycledAllocations { - old_opacity_bindings: tile_cache.old_opacity_bindings, - old_color_bindings: tile_cache.old_color_bindings, - compare_cache: tile_cache.compare_cache, + if let Some(PictureCompositeMode::TileCache { slice_id }) = self.requested_composite_mode { + if let Some(tile_cache) = tile_caches.remove(&slice_id) { + if !tile_cache.tiles.is_empty() { + retained_tiles.caches.insert( + tile_cache.slice, + PictureCacheState { + tiles: tile_cache.tiles, + spatial_node_comparer: tile_cache.spatial_node_comparer, + opacity_bindings: tile_cache.opacity_bindings, + color_bindings: tile_cache.color_bindings, + root_transform: tile_cache.root_transform, + current_tile_size: tile_cache.current_tile_size, + native_surface: tile_cache.native_surface, + external_native_surface_cache: tile_cache.external_native_surface_cache, + virtual_offset: tile_cache.virtual_offset, + frame_id: tile_cache.frame_id, + allocations: PictureCacheRecycledAllocations { + old_opacity_bindings: tile_cache.old_opacity_bindings, + old_color_bindings: tile_cache.old_color_bindings, + compare_cache: tile_cache.compare_cache, + }, }, - }, - ); + ); + } } } } @@ -4703,7 +4716,6 @@ impl PicturePrimitive { requested_raster_space: RasterSpace, prim_list: PrimitiveList, spatial_node_index: SpatialNodeIndex, - tile_cache: Option>, options: PictureOptions, ) -> Self { PicturePrimitive { @@ -4721,7 +4733,6 @@ impl PicturePrimitive { spatial_node_index, estimated_local_rect: LayoutRect::zero(), precise_local_rect: LayoutRect::zero(), - tile_cache, options, segments_are_valid: false, num_render_tasks: 0, @@ -4762,6 +4773,7 @@ impl PicturePrimitive { frame_context: &FrameBuildingContext, scratch: &mut PrimitiveScratchBuffer, tile_cache_logger: &mut TileCacheLogger, + tile_caches: &mut FastHashMap>, ) -> Option<(PictureContext, PictureState, PrimitiveList)> { if !self.is_visible() { return None; @@ -5222,8 +5234,8 @@ impl PicturePrimitive { Some((render_task_id, render_task_id)) } - PictureCompositeMode::TileCache { .. } => { - let tile_cache = self.tile_cache.as_mut().unwrap(); + PictureCompositeMode::TileCache { slice_id } => { + let tile_cache = tile_caches.get_mut(&slice_id).unwrap(); let mut first = true; // Get the overall world space rect of the picture cache. Used to clip @@ -5614,28 +5626,29 @@ impl PicturePrimitive { #[cfg(feature = "capture")] { if frame_context.debug_flags.contains(DebugFlags::TILE_CACHE_LOGGING_DBG) { - if let Some(ref tile_cache) = self.tile_cache - { - // extract just the fields that we're interested in - let mut tile_cache_tiny = TileCacheInstanceSerializer { - slice: tile_cache.slice, - tiles: FastHashMap::default(), - background_color: tile_cache.background_color, - fract_offset: tile_cache.fract_offset - }; - for (key, tile) in &tile_cache.tiles { - tile_cache_tiny.tiles.insert(*key, TileSerializer { - rect: tile.local_tile_rect, - current_descriptor: tile.current_descriptor.clone(), - fract_offset: tile.fract_offset, - id: tile.id, - root: tile.root.clone(), - background_color: tile.background_color, - invalidation_reason: tile.invalidation_reason.clone() - }); + if let Some(PictureCompositeMode::TileCache { slice_id }) = self.requested_composite_mode { + if let Some(ref tile_cache) = tile_caches.get(&slice_id) { + // extract just the fields that we're interested in + let mut tile_cache_tiny = TileCacheInstanceSerializer { + slice: tile_cache.slice, + tiles: FastHashMap::default(), + background_color: tile_cache.background_color, + fract_offset: tile_cache.fract_offset + }; + for (key, tile) in &tile_cache.tiles { + tile_cache_tiny.tiles.insert(*key, TileSerializer { + rect: tile.local_tile_rect, + current_descriptor: tile.current_descriptor.clone(), + fract_offset: tile.fract_offset, + id: tile.id, + root: tile.root.clone(), + background_color: tile.background_color, + invalidation_reason: tile.invalidation_reason.clone() + }); + } + let text = ron::ser::to_string_pretty(&tile_cache_tiny, Default::default()).unwrap(); + tile_cache_logger.add(text, map_pic_to_world.get_transform()); } - let text = ron::ser::to_string_pretty(&tile_cache_tiny, Default::default()).unwrap(); - tile_cache_logger.add(text, map_pic_to_world.get_transform()); } } } @@ -5657,8 +5670,8 @@ impl PicturePrimitive { // If this is a picture cache, push the dirty region to ensure any // child primitives are culled and clipped to the dirty rect(s). - if let Some(RasterConfig { composite_mode: PictureCompositeMode::TileCache { .. }, .. }) = self.raster_config { - let dirty_region = self.tile_cache.as_ref().unwrap().dirty_region.clone(); + if let Some(RasterConfig { composite_mode: PictureCompositeMode::TileCache { slice_id }, .. }) = self.raster_config { + let dirty_region = tile_caches[&slice_id].dirty_region.clone(); frame_state.push_dirty_region(dirty_region); dirty_region_count += 1; } @@ -5674,8 +5687,8 @@ impl PicturePrimitive { let (is_passthrough, subpixel_mode) = match self.raster_config { Some(RasterConfig { ref composite_mode, .. }) => { let subpixel_mode = match composite_mode { - PictureCompositeMode::TileCache { .. } => { - self.tile_cache.as_ref().unwrap().subpixel_mode.clone() + PictureCompositeMode::TileCache { slice_id } => { + tile_caches[&slice_id].subpixel_mode.clone() } PictureCompositeMode::Blit(..) | PictureCompositeMode::ComponentTransferFilter(..) | @@ -5934,11 +5947,11 @@ impl PicturePrimitive { // See if this picture actually needs a surface for compositing. let actual_composite_mode = match self.requested_composite_mode { Some(PictureCompositeMode::Filter(ref filter)) if filter.is_noop() => None, - Some(PictureCompositeMode::TileCache { .. }) => { + Some(PictureCompositeMode::TileCache { slice_id }) => { // Only allow picture caching composite mode if global picture caching setting // is enabled this frame. if state.composite_state.picture_caching_is_enabled { - Some(PictureCompositeMode::TileCache { }) + Some(PictureCompositeMode::TileCache { slice_id }) } else { None } diff --git a/gfx/wr/webrender/src/prepare.rs b/gfx/wr/webrender/src/prepare.rs index c83b5021a4fa..8b7e19477c3d 100644 --- a/gfx/wr/webrender/src/prepare.rs +++ b/gfx/wr/webrender/src/prepare.rs @@ -21,9 +21,9 @@ use crate::clip::{ClipDataStore, ClipNodeFlags, ClipChainInstance, ClipItemKind} use crate::frame_builder::{FrameBuildingContext, FrameBuildingState, PictureContext, PictureState}; use crate::gpu_cache::{GpuCacheHandle, GpuDataRequest}; use crate::gpu_types::{BrushFlags}; -use crate::internal_types::PlaneSplitAnchor; -use crate::picture::{PicturePrimitive, TileCacheLogger}; -use crate::picture::{PrimitiveList, SurfaceIndex}; +use crate::internal_types::{FastHashMap, PlaneSplitAnchor}; +use crate::picture::{PicturePrimitive, SliceId, TileCacheLogger}; +use crate::picture::{PrimitiveList, SurfaceIndex, TileCacheInstance}; use crate::prim_store::gradient::{GRADIENT_FP_STOPS, GradientCacheKey, GradientStopKey}; use crate::prim_store::gradient::LinearGradientPrimitive; use crate::prim_store::line_dec::MAX_LINE_DECORATION_RESOLUTION; @@ -52,6 +52,7 @@ pub fn prepare_primitives( data_stores: &mut DataStores, scratch: &mut PrimitiveScratchBuffer, tile_cache_log: &mut TileCacheLogger, + tile_caches: &mut FastHashMap>, ) { profile_scope!("prepare_primitives"); for (cluster_index, cluster) in prim_list.clusters.iter_mut().enumerate() { @@ -102,6 +103,7 @@ pub fn prepare_primitives( data_stores, scratch, tile_cache_log, + tile_caches, ) { frame_state.profile_counters.visible_primitives.inc(); } @@ -121,6 +123,7 @@ fn prepare_prim_for_render( data_stores: &mut DataStores, scratch: &mut PrimitiveScratchBuffer, tile_cache_log: &mut TileCacheLogger, + tile_caches: &mut FastHashMap>, ) -> bool { profile_scope!("prepare_prim_for_render"); // If we have dependencies, we need to prepare them first, in order @@ -148,6 +151,7 @@ fn prepare_prim_for_render( frame_context, scratch, tile_cache_log, + tile_caches, ) { Some(info) => Some(info), None => { @@ -192,6 +196,7 @@ fn prepare_prim_for_render( data_stores, scratch, tile_cache_log, + tile_caches, ); // Restore the dependencies (borrow check dance) diff --git a/gfx/wr/webrender/src/prim_store/mod.rs b/gfx/wr/webrender/src/prim_store/mod.rs index 10558b287068..6d835b3b5831 100644 --- a/gfx/wr/webrender/src/prim_store/mod.rs +++ b/gfx/wr/webrender/src/prim_store/mod.rs @@ -20,7 +20,8 @@ use crate::glyph_rasterizer::GlyphKey; use crate::gpu_cache::{GpuCache, GpuCacheAddress, GpuCacheHandle, GpuDataRequest, ToGpuBlocks}; use crate::gpu_types::{BrushFlags}; use crate::intern; -use crate::picture::PicturePrimitive; +use crate::internal_types::FastHashMap; +use crate::picture::{PicturePrimitive, TileCacheInstance, SliceId}; use crate::picture::{RecordedDirtyRegion, RetainedTiles}; use crate::prim_store::backdrop::BackdropDataHandle; use crate::prim_store::borders::{ImageBorderDataHandle, NormalBorderDataHandle}; @@ -1613,10 +1614,12 @@ impl PrimitiveStore { pub fn destroy( &mut self, retained_tiles: &mut RetainedTiles, + tile_caches: &mut FastHashMap>, ) { for pic in &mut self.pictures { pic.destroy( retained_tiles, + tile_caches, ); } } diff --git a/gfx/wr/webrender/src/render_backend.rs b/gfx/wr/webrender/src/render_backend.rs index 540022e6d5b1..c2b1218bdf72 100644 --- a/gfx/wr/webrender/src/render_backend.rs +++ b/gfx/wr/webrender/src/render_backend.rs @@ -732,7 +732,10 @@ impl Document { // and then presumably back in the prim store during the next frame // build. let mut retained_tiles = RetainedTiles::new(); - self.scene.prim_store.destroy(&mut retained_tiles); + self.scene.prim_store.destroy( + &mut retained_tiles, + &mut self.scene.tile_caches, + ); let old_scrolling_states = self.scene.spatial_tree.drain(); self.scene = built_scene; diff --git a/gfx/wr/webrender/src/render_target.rs b/gfx/wr/webrender/src/render_target.rs index 038b50505a26..0d311b678904 100644 --- a/gfx/wr/webrender/src/render_target.rs +++ b/gfx/wr/webrender/src/render_target.rs @@ -16,7 +16,7 @@ use crate::gpu_cache::{GpuCache, GpuCacheAddress}; use crate::gpu_types::{BorderInstance, SvgFilterInstance, BlurDirection, BlurInstance, PrimitiveHeaders, ScalingInstance}; use crate::gpu_types::{TransformPalette, ZBufferIdGenerator}; use crate::internal_types::{FastHashMap, TextureSource, LayerIndex, Swizzle, SavedTargetIndex}; -use crate::picture::{SurfaceInfo, ResolvedSurfaceTexture}; +use crate::picture::{SliceId, SurfaceInfo, ResolvedSurfaceTexture, TileCacheInstance}; use crate::prim_store::{PrimitiveStore, DeferredResolve, PrimitiveScratchBuffer}; use crate::prim_store::gradient::GRADIENT_FP_STOPS; use crate::render_backend::DataStores; @@ -70,6 +70,7 @@ pub struct RenderTargetContext<'a, 'rc> { pub scratch: &'a PrimitiveScratchBuffer, pub screen_world_rect: WorldRect, pub globals: &'a FrameGlobalResources, + pub tile_caches: &'a FastHashMap>, } /// Represents a number of rendering operations on a surface. diff --git a/gfx/wr/webrender/src/scene.rs b/gfx/wr/webrender/src/scene.rs index 3caf68ab6035..719c3146feea 100644 --- a/gfx/wr/webrender/src/scene.rs +++ b/gfx/wr/webrender/src/scene.rs @@ -9,6 +9,7 @@ use api::units::*; use malloc_size_of::{MallocSizeOf, MallocSizeOfOps}; use crate::composite::CompositorKind; use crate::clip::{ClipStore, ClipDataStore}; +use crate::picture::{SliceId, TileCacheInstance}; use crate::spatial_tree::{SpatialTree, SpatialNodeIndex}; use crate::frame_builder::{ChasePrimitive, FrameBuilderConfig}; use crate::hit_test::{HitTester, HitTestingScene, HitTestingSceneStats}; @@ -278,6 +279,7 @@ pub struct BuiltScene { pub hit_testing_scene: Arc, pub content_slice_count: usize, pub picture_cache_spatial_nodes: FastHashSet, + pub tile_caches: FastHashMap>, } impl BuiltScene { @@ -294,6 +296,7 @@ impl BuiltScene { hit_testing_scene: Arc::new(HitTestingScene::new(&HitTestingSceneStats::empty())), content_slice_count: 0, picture_cache_spatial_nodes: FastHashSet::default(), + tile_caches: FastHashMap::default(), config: FrameBuilderConfig { default_font_render_mode: FontRenderMode::Mono, dual_source_blending_is_enabled: true, diff --git a/gfx/wr/webrender/src/scene_building.rs b/gfx/wr/webrender/src/scene_building.rs index a03cabe5e798..7d4764857b93 100644 --- a/gfx/wr/webrender/src/scene_building.rs +++ b/gfx/wr/webrender/src/scene_building.rs @@ -22,7 +22,7 @@ use crate::glyph_rasterizer::FontInstance; use crate::hit_test::{HitTestingItem, HitTestingScene}; use crate::intern::Interner; use crate::internal_types::{FastHashMap, FastHashSet, LayoutPrimitiveInfo, Filter}; -use crate::picture::{Picture3DContext, PictureCompositeMode, PicturePrimitive, PictureOptions}; +use crate::picture::{Picture3DContext, PictureCompositeMode, PicturePrimitive, PictureOptions, SliceId}; use crate::picture::{BlitReason, OrderedPictureChild, PrimitiveList, TileCacheInstance, ClusterFlags}; use crate::prim_store::PrimitiveInstance; use crate::prim_store::{PrimitiveInstanceKind, NinePatchDescriptor, PrimitiveStore}; @@ -302,6 +302,9 @@ pub struct SceneBuilder<'a> { /// The current quality / performance settings for this scene. quality_settings: QualitySettings, + + /// Map of tile caches that were created for this scene + tile_caches: FastHashMap>, } impl<'a> SceneBuilder<'a> { @@ -346,6 +349,7 @@ impl<'a> SceneBuilder<'a> { content_slice_count: 0, picture_cache_spatial_nodes: FastHashSet::default(), quality_settings: view.quality_settings, + tile_caches: FastHashMap::default(), }; let device_pixel_scale = view.accumulated_scale_factor_for_snapping(); @@ -414,6 +418,7 @@ impl<'a> SceneBuilder<'a> { config: builder.config, content_slice_count: builder.content_slice_count, picture_cache_spatial_nodes: builder.picture_cache_spatial_nodes, + tile_caches: builder.tile_caches, } } @@ -573,6 +578,7 @@ impl<'a> SceneBuilder<'a> { &mut self.clip_store, &mut self.picture_cache_spatial_nodes, &self.config, + &mut self.tile_caches, ); main_prim_list.add_prim( @@ -1916,7 +1922,6 @@ impl<'a> SceneBuilder<'a> { stacking_context.requested_raster_space, stacking_context.prim_list, stacking_context.spatial_node_index, - None, PictureOptions::default(), )) ); @@ -1971,7 +1976,6 @@ impl<'a> SceneBuilder<'a> { stacking_context.requested_raster_space, prim_list, stacking_context.spatial_node_index, - None, PictureOptions::default(), )) ); @@ -2036,7 +2040,6 @@ impl<'a> SceneBuilder<'a> { stacking_context.requested_raster_space, prim_list, stacking_context.spatial_node_index, - None, PictureOptions::default(), )) ); @@ -2521,7 +2524,6 @@ impl<'a> SceneBuilder<'a> { raster_space, prim_list, pending_shadow.spatial_node_index, - None, options, )) ); @@ -3270,7 +3272,6 @@ impl<'a> SceneBuilder<'a> { requested_raster_space, prim_list, backdrop_spatial_node_index, - None, PictureOptions { inflate_if_required: false, }, @@ -3455,7 +3456,6 @@ impl<'a> SceneBuilder<'a> { requested_raster_space, prim_list, spatial_node_index, - None, PictureOptions { inflate_if_required, }, @@ -3521,7 +3521,6 @@ impl<'a> SceneBuilder<'a> { requested_raster_space, prim_list, spatial_node_index, - None, PictureOptions { inflate_if_required, }, @@ -3838,7 +3837,6 @@ impl FlattenedStackingContext { self.requested_raster_space, mem::replace(&mut self.prim_list, PrimitiveList::empty()), self.spatial_node_index, - None, PictureOptions::default(), )) ); @@ -4021,6 +4019,7 @@ fn create_tile_cache( clip_store: &mut ClipStore, picture_cache_spatial_nodes: &mut FastHashSet, frame_builder_config: &FrameBuilderConfig, + tile_caches: &mut FastHashMap>, ) -> PrimitiveInstance { // Add this spatial node to the list to check for complex transforms // at the start of a frame build. @@ -4066,9 +4065,11 @@ fn create_tile_cache( parent_clip_chain_id, frame_builder_config, )); + let slice_id = SliceId::new(slice); + tile_caches.insert(slice_id, tile_cache); let pic_index = prim_store.pictures.alloc().init(PicturePrimitive::new_image( - Some(PictureCompositeMode::TileCache { }), + Some(PictureCompositeMode::TileCache { slice_id }), Picture3DContext::Out, None, true, @@ -4076,7 +4077,6 @@ fn create_tile_cache( RasterSpace::Screen, prim_list, scroll_root, - Some(tile_cache), PictureOptions::default(), )); diff --git a/gfx/wr/webrender/src/visibility.rs b/gfx/wr/webrender/src/visibility.rs index 2a06f6fe4cd4..79be10ac449f 100644 --- a/gfx/wr/webrender/src/visibility.rs +++ b/gfx/wr/webrender/src/visibility.rs @@ -19,8 +19,9 @@ use crate::clip::{ClipInstance, ClipChainInstance}; use crate::debug_colors; use crate::frame_builder::FrameBuilderConfig; use crate::gpu_cache::GpuCache; +use crate::internal_types::FastHashMap; use crate::picture::{PictureCompositeMode, ClusterFlags, SurfaceInfo, TileCacheInstance}; -use crate::picture::{PrimitiveList, SurfaceIndex, RetainedTiles, RasterConfig}; +use crate::picture::{PrimitiveList, SurfaceIndex, RetainedTiles, RasterConfig, SliceId}; use crate::prim_store::{ClipTaskIndex, PictureIndex, SpaceMapper, PrimitiveInstanceKind}; use crate::prim_store::{SpaceSnapper, PrimitiveStore, PrimitiveInstance}; use crate::prim_store::image::VisibleImageTile; @@ -184,6 +185,7 @@ pub fn update_primitive_visibility( world_culling_rect: &WorldRect, frame_context: &FrameVisibilityContext, frame_state: &mut FrameVisibilityState, + tile_caches: &mut FastHashMap>, ) -> Option { profile_scope!("update_visibility"); let (mut prim_list, surface_index, apply_local_clip_rect, world_culling_rect, is_composite) = { @@ -197,9 +199,10 @@ pub fn update_primitive_visibility( }; match pic.raster_config { - Some(RasterConfig { composite_mode: PictureCompositeMode::TileCache { .. }, .. }) => { - let mut tile_cache = pic.tile_cache.take().unwrap(); - debug_assert!(frame_state.tile_cache.is_none()); + Some(RasterConfig { composite_mode: PictureCompositeMode::TileCache { slice_id }, .. }) => { + let mut tile_cache = tile_caches + .remove(&slice_id) + .expect("bug: non-existent tile cache"); // If we have a tile cache for this picture, see if any of the // relative transforms have changed, which means we need to @@ -303,6 +306,7 @@ pub fn update_primitive_visibility( &world_culling_rect, frame_context, frame_state, + tile_caches, ); frame_state.clip_chain_stack.pop_clip(); @@ -652,7 +656,7 @@ pub fn update_primitive_visibility( frame_state, ); - pic.tile_cache = Some(tile_cache); + tile_caches.insert(SliceId::new(tile_cache.slice), tile_cache); } None