diff --git a/gfx/wr/webrender/src/frame_builder.rs b/gfx/wr/webrender/src/frame_builder.rs index e02ca0df9717..079db8c1602b 100644 --- a/gfx/wr/webrender/src/frame_builder.rs +++ b/gfx/wr/webrender/src/frame_builder.rs @@ -4,6 +4,7 @@ use api::{ColorF, DebugFlags, FontRenderMode, PremultipliedColorF}; use api::units::*; +use plane_split::BspSplitter; use crate::batch::{BatchBuilder, AlphaBatchBuilder, AlphaBatchContainer, CommandBufferList}; use crate::clip::{ClipStore, ClipTree}; use crate::spatial_tree::{SpatialTree, SpatialNodeIndex}; @@ -136,6 +137,8 @@ pub struct FrameBuilder { prim_headers_prealloc: Preallocator, #[cfg_attr(feature = "capture", serde(skip))] composite_state_prealloc: CompositeStatePreallocator, + #[cfg_attr(feature = "capture", serde(skip))] + plane_splitters: Vec, } pub struct FrameBuildingContext<'a> { @@ -209,6 +212,7 @@ impl FrameBuilder { globals: FrameGlobalResources::empty(), prim_headers_prealloc: Preallocator::new(0), composite_state_prealloc: CompositeStatePreallocator::default(), + plane_splitters: Vec::new(), } } @@ -242,7 +246,8 @@ impl FrameBuilder { // Reset all plane splitters. These are retained from frame to frame to reduce // per-frame allocations - for splitter in &mut scene.plane_splitters { + self.plane_splitters.resize_with(scene.num_plane_splitters, BspSplitter::new); + for splitter in &mut self.plane_splitters { splitter.reset(); } @@ -377,7 +382,7 @@ impl FrameBuilder { dirty_region_stack: scratch.frame.dirty_region_stack.take(), composite_state, num_visible_primitives: 0, - plane_splitters: &mut scene.plane_splitters, + plane_splitters: &mut self.plane_splitters, surface_builder: SurfaceBuilder::new(), cmd_buffers, clip_tree: &mut scene.clip_tree, diff --git a/gfx/wr/webrender/src/scene.rs b/gfx/wr/webrender/src/scene.rs index 93d6bf97cc29..454a2001a915 100644 --- a/gfx/wr/webrender/src/scene.rs +++ b/gfx/wr/webrender/src/scene.rs @@ -12,7 +12,7 @@ use crate::clip::{ClipStore, ClipTree}; use crate::spatial_tree::SpatialTree; use crate::frame_builder::{FrameBuilderConfig}; use crate::hit_test::{HitTester, HitTestingScene, HitTestingSceneStats}; -use crate::internal_types::{FastHashMap, PlaneSplitter}; +use crate::internal_types::FastHashMap; use crate::picture::SurfaceInfo; use crate::picture_graph::PictureGraph; use crate::prim_store::{PrimitiveStore, PrimitiveStoreStats, PictureIndex, PrimitiveInstance}; @@ -289,7 +289,7 @@ pub struct BuiltScene { pub tile_cache_config: TileCacheConfig, pub tile_cache_pictures: Vec, pub picture_graph: PictureGraph, - pub plane_splitters: Vec, + pub num_plane_splitters: usize, pub prim_instances: Vec, pub surfaces: Vec, pub clip_tree: ClipTree, @@ -308,7 +308,7 @@ impl BuiltScene { tile_cache_config: TileCacheConfig::new(0), tile_cache_pictures: Vec::new(), picture_graph: PictureGraph::new(), - plane_splitters: Vec::new(), + num_plane_splitters: 0, prim_instances: Vec::new(), surfaces: Vec::new(), clip_tree: ClipTree::new(), diff --git a/gfx/wr/webrender/src/scene_building.rs b/gfx/wr/webrender/src/scene_building.rs index ec0ba0dc3458..6bbaa73ba2ce 100644 --- a/gfx/wr/webrender/src/scene_building.rs +++ b/gfx/wr/webrender/src/scene_building.rs @@ -56,7 +56,7 @@ use crate::frame_builder::{FrameBuilderConfig}; use crate::glyph_rasterizer::{FontInstance, SharedFontResources}; use crate::hit_test::HitTestingScene; use crate::intern::Interner; -use crate::internal_types::{FastHashMap, LayoutPrimitiveInfo, Filter, PlaneSplitter, PlaneSplitterIndex, PipelineInstanceId}; +use crate::internal_types::{FastHashMap, LayoutPrimitiveInfo, Filter, PlaneSplitterIndex, PipelineInstanceId}; use crate::picture::{Picture3DContext, PictureCompositeMode, PicturePrimitive}; use crate::picture::{BlitReason, OrderedPictureChild, PrimitiveList, SurfaceInfo, PictureFlags}; use crate::picture_graph::PictureGraph; @@ -502,12 +502,14 @@ pub struct SceneBuilder<'a> { /// dependencies, without relying on recursion for those passes. picture_graph: PictureGraph, - /// A list of all the allocated plane splitters for this scene. A plane + /// Keep track of allocated plane splitters for this scene. A plane /// splitter is allocated whenever we encounter a new 3d rendering context. /// They are stored outside the picture since it makes it easier for them /// to be referenced by both the owning 3d rendering context and the child /// pictures that contribute to the splitter. - plane_splitters: Vec, + /// During scene building "allocating" a splitter is just incrementing an index. + /// Splitter objects themselves are allocated and recycled in the frame builder. + next_plane_splitter_index: usize, /// A list of all primitive instances in the scene. We store them as a single /// array so that multiple different systems (e.g. tile-cache, visibility, property @@ -580,7 +582,7 @@ impl<'a> SceneBuilder<'a> { ), snap_to_device, picture_graph: PictureGraph::new(), - plane_splitters: Vec::new(), + next_plane_splitter_index: 0, prim_instances: Vec::new(), pipeline_instance_ids: FastHashMap::default(), surfaces: Vec::new(), @@ -622,7 +624,7 @@ impl<'a> SceneBuilder<'a> { tile_cache_config, tile_cache_pictures, picture_graph: builder.picture_graph, - plane_splitters: builder.plane_splitters, + num_plane_splitters: builder.next_plane_splitter_index, prim_instances: builder.prim_instances, surfaces: builder.surfaces, clip_tree, @@ -2091,8 +2093,8 @@ impl<'a> SceneBuilder<'a> { .unwrap_or(self.spatial_tree.root_reference_frame_index()); let plane_splitter_index = plane_splitter_index.unwrap_or_else(|| { - let index = self.plane_splitters.len(); - self.plane_splitters.push(PlaneSplitter::new()); + let index = self.next_plane_splitter_index; + self.next_plane_splitter_index += 1; PlaneSplitterIndex(index) });