@@ -1243,8 +1243,6 @@ impl<'a> SceneBuilder<'a> {
12431243
12441244 self . clip_tree_builder . push_clip_chain ( Some ( info. space_and_clip . clip_chain_id ) , false ) ;
12451245
1246- let external_scroll_offset = self . current_external_scroll_offset ( spatial_node_index) ;
1247-
12481246 // TODO(gw): This is the only remaining call site that relies on ClipId parenting, remove me!
12491247 self . add_rect_clip_node (
12501248 ClipId :: root ( iframe_pipeline_id) ,
@@ -1258,13 +1256,11 @@ impl<'a> SceneBuilder<'a> {
12581256
12591257 self . id_to_index_mapper_stack . push ( NodeIdToIndexMapper :: default ( ) ) ;
12601258
1261- let mut bounds = self . snap_rect (
1259+ let bounds = self . normalize_scroll_offset_and_snap_rect (
12621260 & info. bounds ,
12631261 spatial_node_index,
12641262 ) ;
12651263
1266- bounds = bounds. translate ( external_scroll_offset) ;
1267-
12681264 let spatial_node_index = self . push_reference_frame (
12691265 SpatialId :: root_reference_frame ( iframe_pipeline_id) ,
12701266 spatial_node_index,
@@ -1341,36 +1337,35 @@ impl<'a> SceneBuilder<'a> {
13411337 let spatial_node_index = self . get_space ( common. spatial_id ) ;
13421338
13431339 // If no bounds rect is given, default to clip rect.
1344- let ( rect, clip_rect) = if common. flags . contains ( PrimitiveFlags :: ANTIALISED ) {
1345- ( bounds. unwrap_or ( common. clip_rect ) , common. clip_rect )
1340+ let mut clip_rect = common. clip_rect ;
1341+ let mut prim_rect = bounds. unwrap_or ( clip_rect) ;
1342+ let unsnapped_rect = self . normalize_rect_scroll_offset ( & prim_rect, spatial_node_index) ;
1343+
1344+ // If antialiased, no need to snap but we still need to remove the
1345+ // external scroll offset (it's applied later during frame building,
1346+ // so that we don't intern to a different hash and invalidate content
1347+ // in picture caches unnecessarily).
1348+ if common. flags . contains ( PrimitiveFlags :: ANTIALISED ) {
1349+ prim_rect = self . normalize_rect_scroll_offset ( & prim_rect, spatial_node_index) ;
1350+ clip_rect = self . normalize_rect_scroll_offset ( & clip_rect, spatial_node_index) ;
13461351 } else {
1347- let clip_rect = self . snap_rect (
1348- & common . clip_rect ,
1352+ clip_rect = self . normalize_scroll_offset_and_snap_rect (
1353+ & clip_rect,
13491354 spatial_node_index,
13501355 ) ;
13511356
1352- let rect = bounds. map_or ( clip_rect, |bounds| {
1353- self . snap_rect (
1354- & bounds,
1355- spatial_node_index,
1356- )
1357- } ) ;
1358-
1359- ( rect, clip_rect)
1360- } ;
1361-
1362- let current_offset = self . current_external_scroll_offset ( spatial_node_index) ;
1363-
1364- let rect = rect. translate ( current_offset) ;
1365- let clip_rect = clip_rect. translate ( current_offset) ;
1366- let unsnapped_rect = bounds. unwrap_or ( common. clip_rect ) . translate ( current_offset) ;
1357+ prim_rect = self . normalize_scroll_offset_and_snap_rect (
1358+ & prim_rect,
1359+ spatial_node_index,
1360+ ) ;
1361+ }
13671362
13681363 let clip_node_id = self . get_clip_node (
13691364 common. clip_chain_id ,
13701365 ) ;
13711366
13721367 let layout = LayoutPrimitiveInfo {
1373- rect,
1368+ rect : prim_rect ,
13741369 clip_rect,
13751370 flags : common. flags ,
13761371 } ;
@@ -1389,11 +1384,29 @@ impl<'a> SceneBuilder<'a> {
13891384 )
13901385 }
13911386
1392- pub fn snap_rect (
1387+ // Remove the effect of the external scroll offset embedded in the display list
1388+ // coordinates by Gecko. This ensures that we don't necessarily invalidate picture
1389+ // cache tiles due to the embedded scroll offsets.
1390+ fn normalize_rect_scroll_offset (
1391+ & mut self ,
1392+ rect : & LayoutRect ,
1393+ spatial_node_index : SpatialNodeIndex ,
1394+ ) -> LayoutRect {
1395+ let current_offset = self . current_external_scroll_offset ( spatial_node_index) ;
1396+
1397+ rect. translate ( current_offset)
1398+ }
1399+
1400+ // Remove external scroll offset and snap a rect. The external scroll offset must
1401+ // be removed first, as it may be fractional (which we don't want to affect the
1402+ // snapping behavior during scene building).
1403+ fn normalize_scroll_offset_and_snap_rect (
13931404 & mut self ,
13941405 rect : & LayoutRect ,
13951406 target_spatial_node : SpatialNodeIndex ,
13961407 ) -> LayoutRect {
1408+ let rect = self . normalize_rect_scroll_offset ( rect, target_spatial_node) ;
1409+
13971410 self . snap_to_device . set_target_spatial_node (
13981411 target_spatial_node,
13991412 self . spatial_tree ,
@@ -1522,15 +1535,12 @@ impl<'a> SceneBuilder<'a> {
15221535 profile_scope ! ( "hit_test" ) ;
15231536
15241537 let spatial_node_index = self . get_space ( info. spatial_id ) ;
1525- let current_offset = self . current_external_scroll_offset ( spatial_node_index) ;
15261538
1527- let mut rect = self . snap_rect (
1539+ let rect = self . normalize_scroll_offset_and_snap_rect (
15281540 & info. rect ,
15291541 spatial_node_index,
15301542 ) ;
15311543
1532- rect = rect. translate ( current_offset) ;
1533-
15341544 let layout = LayoutPrimitiveInfo {
15351545 rect,
15361546 clip_rect : rect,
@@ -2820,13 +2830,11 @@ impl<'a> SceneBuilder<'a> {
28202830 points_range : ItemRange < LayoutPoint > ,
28212831 ) {
28222832 let spatial_node_index = self . get_space ( spatial_id) ;
2823- let external_scroll_offset = self . current_external_scroll_offset ( spatial_node_index) ;
28242833
2825- let mut snapped_mask_rect = self . snap_rect (
2834+ let snapped_mask_rect = self . normalize_scroll_offset_and_snap_rect (
28262835 & image_mask. rect ,
28272836 spatial_node_index,
28282837 ) ;
2829- snapped_mask_rect = snapped_mask_rect. translate ( external_scroll_offset) ;
28302838
28312839 let points: Vec < LayoutPoint > = points_range. iter ( ) . collect ( ) ;
28322840
@@ -2870,15 +2878,12 @@ impl<'a> SceneBuilder<'a> {
28702878 clip_rect : & LayoutRect ,
28712879 ) {
28722880 let spatial_node_index = self . get_space ( spatial_id) ;
2873- let external_scroll_offset = self . current_external_scroll_offset ( spatial_node_index) ;
28742881
2875- let mut snapped_clip_rect = self . snap_rect (
2882+ let snapped_clip_rect = self . normalize_scroll_offset_and_snap_rect (
28762883 clip_rect,
28772884 spatial_node_index,
28782885 ) ;
28792886
2880- snapped_clip_rect = snapped_clip_rect. translate ( external_scroll_offset) ;
2881-
28822887 let item = ClipItemKey {
28832888 kind : ClipItemKeyKind :: rectangle ( snapped_clip_rect, ClipMode :: Clip ) ,
28842889 spatial_node_index,
@@ -2905,15 +2910,12 @@ impl<'a> SceneBuilder<'a> {
29052910 clip : & ComplexClipRegion ,
29062911 ) {
29072912 let spatial_node_index = self . get_space ( spatial_id) ;
2908- let external_scroll_offset = self . current_external_scroll_offset ( spatial_node_index) ;
29092913
2910- let mut snapped_region_rect = self . snap_rect (
2914+ let snapped_region_rect = self . normalize_scroll_offset_and_snap_rect (
29112915 & clip. rect ,
29122916 spatial_node_index,
29132917 ) ;
29142918
2915- snapped_region_rect = snapped_region_rect. translate ( external_scroll_offset) ;
2916-
29172919 let item = ClipItemKey {
29182920 kind : ClipItemKeyKind :: rounded_rect (
29192921 snapped_region_rect,
0 commit comments