Bug 1709507 - Reduce allocations and memmove during scene building. r=gfx-reviewers,jrmuizel

This can make scene building up to 10% faster on some pages (such
as the youtube.com front page) that use a large number of clips.

Differential Revision: https://phabricator.services.mozilla.com/D114312
This commit is contained in:
Glenn Watson 2021-05-05 03:00:28 +00:00
Родитель 8d1d39f733
Коммит b845f71b44
4 изменённых файлов: 40 добавлений и 11 удалений

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

@ -722,6 +722,18 @@ impl ClipNode {
}
}
pub struct ClipStoreStats {
templates_capacity: usize,
}
impl ClipStoreStats {
pub fn empty() -> Self {
ClipStoreStats {
templates_capacity: 0,
}
}
}
/// The main clipping public interface that other modules access.
#[derive(MallocSizeOf)]
#[cfg_attr(feature = "capture", derive(Serialize))]
@ -971,18 +983,32 @@ impl ClipChainStack {
}
impl ClipStore {
pub fn new() -> Self {
pub fn new(stats: &ClipStoreStats) -> Self {
let mut templates = FastHashMap::default();
templates.reserve(stats.templates_capacity);
ClipStore {
clip_chain_nodes: Vec::new(),
clip_node_instances: Vec::new(),
active_clip_node_info: Vec::new(),
active_local_clip_rect: None,
active_pic_clip_rect: PictureRect::max_rect(),
templates: FastHashMap::default(),
templates,
chain_builder_stack: Vec::new(),
}
}
pub fn get_stats(&self) -> ClipStoreStats {
// Selecting the smaller of the current capacity and 2*len ensures we don't
// retain a huge hashmap alloc after navigating away from a page with a large
// number of clip templates.
let templates_capacity = self.templates.capacity().min(self.templates.len() * 2);
ClipStoreStats {
templates_capacity,
}
}
/// Register a new clip template for the clip_id defined in the display list.
pub fn register_clip_template(
&mut self,

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

@ -12,7 +12,7 @@ use crate::spatial_tree::{SpatialNodeIndex, SpatialTree};
use crate::internal_types::{FastHashMap, LayoutPrimitiveInfo};
use std::ops;
use std::sync::{Arc, Mutex};
use crate::util::LayoutToWorldFastTransform;
use crate::util::{LayoutToWorldFastTransform, VecHelper};
pub struct SharedHitTester {
// We don't really need a mutex here. We could do with some sort of
@ -489,12 +489,12 @@ fn add_clips(
let template = &clip_store.templates[&clip_id];
for clip in &template.clips {
let hit_test_clip_node = HitTestClipNode::new(
clip.key.into(),
clip.clip.spatial_node_index,
clip_nodes.alloc().init(
HitTestClipNode::new(
clip.key.into(),
clip.clip.spatial_node_index,
)
);
clip_nodes.push(hit_test_clip_node);
}
// The ClipId parenting is terminated when we reach the root ClipId

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

@ -8,7 +8,7 @@ use api::units::*;
use malloc_size_of::{MallocSizeOf, MallocSizeOfOps};
use crate::render_api::MemoryReport;
use crate::composite::CompositorKind;
use crate::clip::ClipStore;
use crate::clip::{ClipStore, ClipStoreStats};
use crate::spatial_tree::SpatialTree;
use crate::frame_builder::{ChasePrimitive, FrameBuilderConfig};
use crate::hit_test::{HitTester, HitTestingScene, HitTestingSceneStats};
@ -286,7 +286,7 @@ impl BuiltScene {
output_rect: DeviceIntRect::zero(),
background_color: None,
prim_store: PrimitiveStore::new(&PrimitiveStoreStats::empty()),
clip_store: ClipStore::new(),
clip_store: ClipStore::new(&ClipStoreStats::empty()),
spatial_tree: SpatialTree::new(),
hit_testing_scene: Arc::new(HitTestingScene::new(&HitTestingSceneStats::empty())),
tile_cache_config: TileCacheConfig::new(0),
@ -319,6 +319,7 @@ impl BuiltScene {
SceneStats {
prim_store_stats: self.prim_store.get_stats(),
hit_test_stats: self.hit_testing_scene.get_stats(),
clip_store_stats: self.clip_store.get_stats(),
}
}
@ -337,6 +338,7 @@ impl BuiltScene {
pub struct SceneStats {
pub prim_store_stats: PrimitiveStoreStats,
pub hit_test_stats: HitTestingSceneStats,
pub clip_store_stats: ClipStoreStats,
}
impl SceneStats {
@ -344,6 +346,7 @@ impl SceneStats {
SceneStats {
prim_store_stats: PrimitiveStoreStats::empty(),
hit_test_stats: HitTestingSceneStats::empty(),
clip_store_stats: ClipStoreStats::empty(),
}
}
}

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

@ -549,7 +549,7 @@ impl<'a> SceneBuilder<'a> {
containing_block_stack: Vec::new(),
raster_space_stack: vec![RasterSpace::Screen],
prim_store: PrimitiveStore::new(&stats.prim_store_stats),
clip_store: ClipStore::new(),
clip_store: ClipStore::new(&stats.clip_store_stats),
interners,
rf_mapper: ReferenceFrameMapper::new(),
external_scroll_mapper: ScrollOffsetMapper::new(),