tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

commit 44663f537543b39324cf06f9ecd6dfb591440b27
parent 7c1d966586aab3632fc595fdd42404c44d3ed9b7
Author: Nicolas Silva <nical@fastmail.com>
Date:   Thu,  8 Jan 2026 09:27:00 +0000

Bug 2006848 - Add an internal unique identifier to spatial nodes and make it part of the quad cache key. r=gw

The internal spatial node is a simple u64 (unlike SpatialNodeUid which is used on the other side of the interner). This avoids bloating the spatial node struct and unnecessary hashing.

Differential Revision: https://phabricator.services.mozilla.com/D276986

Diffstat:
Mgfx/wr/webrender/src/prepare.rs | 5+++--
Mgfx/wr/webrender/src/quad.rs | 9++++++++-
Mgfx/wr/webrender/src/scene_building.rs | 1-
Mgfx/wr/webrender/src/spatial_node.rs | 5++++-
Mgfx/wr/webrender/src/spatial_tree.rs | 15+++++++++++++--
5 files changed, 28 insertions(+), 7 deletions(-)

diff --git a/gfx/wr/webrender/src/prepare.rs b/gfx/wr/webrender/src/prepare.rs @@ -729,10 +729,10 @@ fn prepare_interned_prim_for_render( }, ); } - PrimitiveInstanceKind::LinearGradient { data_handle, ref mut visible_tiles_range, use_legacy_path: cached, .. } => { + PrimitiveInstanceKind::LinearGradient { data_handle, ref mut visible_tiles_range, use_legacy_path, .. } => { profile_scope!("LinearGradient"); let prim_data = &mut data_stores.linear_grad[*data_handle]; - if !*cached { + if !*use_legacy_path { quad::prepare_repeatable_quad( prim_data, &prim_data.common.prim_rect, @@ -925,6 +925,7 @@ fn prepare_interned_prim_for_render( quad::cache_key( data_handle.uid(), prim_spatial_node_index, + frame_context.spatial_tree, &prim_instance.vis.clip_chain, frame_state.clip_store, &data_stores.clip, diff --git a/gfx/wr/webrender/src/quad.rs b/gfx/wr/webrender/src/quad.rs @@ -42,6 +42,7 @@ const MAX_TILES_PER_QUAD: usize = 4; pub struct QuadCacheKey { pub prim: u64, pub clips: [u64; 3], + pub spatial_node: u64, } /// Describes how clipping affects the rendering of a quad primitive. @@ -1020,6 +1021,7 @@ fn get_prim_render_strategy( pub fn cache_key( prim_uid: ItemUid, prim_spatial_node_index: SpatialNodeIndex, + spatial_tree: &SpatialTree, clip_chain: &ClipChainInstance, clip_store: &ClipStore, interned_clips: &DataStore<ClipIntern>, @@ -1041,9 +1043,14 @@ pub fn cache_key( } } + let spatial_uid = spatial_tree + .get_spatial_node(prim_spatial_node_index) + .uid; + Some(QuadCacheKey { prim: prim_uid.get_uid(), - clips: clip_uids + clips: clip_uids, + spatial_node: spatial_uid, }) } diff --git a/gfx/wr/webrender/src/scene_building.rs b/gfx/wr/webrender/src/scene_building.rs @@ -1651,7 +1651,6 @@ impl<'a> SceneBuilder<'a> { let mut start = info.gradient.start_point; let mut end = info.gradient.end_point; let flags = layout.flags; - let optimized = optimize_linear_gradient( &mut layout.rect, &mut tile_size, diff --git a/gfx/wr/webrender/src/spatial_node.rs b/gfx/wr/webrender/src/spatial_node.rs @@ -301,6 +301,10 @@ pub struct SpatialNode { /// This is calculated in update(). This will be used to decide whether /// to override corresponding picture's raster space as an optimisation. pub is_ancestor_or_self_zooming: bool, + + /// An internal unique identifier for use during frame building (as opposed + /// to SpatialNodeUid which is used before interning). + pub uid: u64, } /// Snap an offset to be incorporated into a transform, where the local space @@ -1051,4 +1055,3 @@ fn test_cst_perspective_relative_scroll() { let ref_transform = transform.then_translate(LayoutVector3D::new(0.0, -50.0, 0.0)); assert!(world_transform.approx_eq(&ref_transform)); } - diff --git a/gfx/wr/webrender/src/spatial_tree.rs b/gfx/wr/webrender/src/spatial_tree.rs @@ -10,7 +10,7 @@ use crate::gpu_types::TransformPalette; use crate::internal_types::{FastHashMap, FastHashSet, FrameMemory, PipelineInstanceId}; use crate::print_tree::{PrintableTree, PrintTree, PrintTreePrinter}; use crate::scene::SceneProperties; -use crate::spatial_node::{ReferenceFrameInfo, SpatialNode, SpatialNodeType, StickyFrameInfo, SpatialNodeDescriptor}; +use crate::spatial_node::{ReferenceFrameInfo, SpatialNode, SpatialNodeDescriptor, SpatialNodeType, StickyFrameInfo}; use crate::spatial_node::{SpatialNodeUid, ScrollFrameKind, SceneSpatialNode, SpatialNodeInfo, SpatialNodeUidKind}; use std::{ops, u32}; use crate::util::{FastTransform, LayoutToWorldFastTransform, MatrixHelpers, ScaleOffset, scale_factors}; @@ -667,6 +667,8 @@ pub struct SpatialTree { /// Stack of current state for each parent node while traversing and updating tree update_state_stack: Vec<TransformUpdateState>, + + next_internal_uid: u64, } #[derive(Clone)] @@ -813,6 +815,7 @@ impl SpatialTree { coord_systems: Vec::new(), root_reference_frame_index: SpatialNodeIndex::INVALID, update_state_stack: Vec::new(), + next_internal_uid: 1, } } @@ -878,6 +881,9 @@ impl SpatialTree { self.get_spatial_node_mut(parent).add_child(SpatialNodeIndex(index as u32)); } + let uid = self.next_internal_uid; + self.next_internal_uid += 1; + let node = SpatialNode { viewport_transform: ScaleOffset::identity(), content_transform: ScaleOffset::identity(), @@ -891,6 +897,7 @@ impl SpatialTree { invertible: true, is_async_zooming: false, is_ancestor_or_self_zooming: false, + uid, }; assert!(index <= self.spatial_nodes.len()); @@ -917,11 +924,15 @@ impl SpatialTree { self.spatial_nodes[new_parent.0 as usize].add_child(SpatialNodeIndex(index as u32)); } + let uid = self.next_internal_uid; + self.next_internal_uid += 1; + let node = &mut self.spatial_nodes[index]; node.node_type = descriptor.node_type; node.pipeline_id = descriptor.pipeline_id; node.parent = parent; + node.uid = uid; } SpatialTreeUpdate::Remove { index, .. } => { let node = &mut self.spatial_nodes[index]; @@ -2116,7 +2127,7 @@ fn test_world_transforms() { PipelineId::dummy(), &LayoutRect::from_size(LayoutSize::new(400.0, 400.0)), &LayoutSize::new(400.0, 800.0), - ScrollFrameKind::Explicit, + ScrollFrameKind::Explicit, LayoutVector2D::new(0.0, 200.0), APZScrollGeneration::default(), HasScrollLinkedEffect::No,