Bug 1768984 - Reuse plane splitters across scenes. r=gfx-reviewers,gw

Currently splane splitters are stored in the built scene and reallocated with every new scene.
This patch moves the responsibility of storing/recycling the plane splitters to the frame builder so that they can be reused in more cases. The scene builder only needs to track splitter indices, it doesn't use the splitter objects themselves.

Alone this patch does not make a large difference because the current version of the plane_split crate reallocates everything each frame. The next version of plane_split does a much better job of recycling allocations, and applying this patch on top of it makes a large difference.

Differential Revision: https://phabricator.services.mozilla.com/D160363
This commit is contained in:
Nicolas Silva 2022-11-09 11:22:34 +00:00
Родитель 5be0d3b13a
Коммит 10546932e6
3 изменённых файлов: 19 добавлений и 12 удалений

Просмотреть файл

@ -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<PlaneSplitter>,
}
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,

Просмотреть файл

@ -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<PictureIndex>,
pub picture_graph: PictureGraph,
pub plane_splitters: Vec<PlaneSplitter>,
pub num_plane_splitters: usize,
pub prim_instances: Vec<PrimitiveInstance>,
pub surfaces: Vec<SurfaceInfo>,
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(),

Просмотреть файл

@ -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<PlaneSplitter>,
/// 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)
});