@@ -1243,8 +1243,6 @@ impl<'a> SceneBuilder<'a> {
1243
1243
1244
1244
self . clip_tree_builder . push_clip_chain ( Some ( info. space_and_clip . clip_chain_id ) , false ) ;
1245
1245
1246
- let external_scroll_offset = self . current_external_scroll_offset ( spatial_node_index) ;
1247
-
1248
1246
// TODO(gw): This is the only remaining call site that relies on ClipId parenting, remove me!
1249
1247
self . add_rect_clip_node (
1250
1248
ClipId :: root ( iframe_pipeline_id) ,
@@ -1258,13 +1256,11 @@ impl<'a> SceneBuilder<'a> {
1258
1256
1259
1257
self . id_to_index_mapper_stack . push ( NodeIdToIndexMapper :: default ( ) ) ;
1260
1258
1261
- let mut bounds = self . snap_rect (
1259
+ let bounds = self . normalize_scroll_offset_and_snap_rect (
1262
1260
& info. bounds ,
1263
1261
spatial_node_index,
1264
1262
) ;
1265
1263
1266
- bounds = bounds. translate ( external_scroll_offset) ;
1267
-
1268
1264
let spatial_node_index = self . push_reference_frame (
1269
1265
SpatialId :: root_reference_frame ( iframe_pipeline_id) ,
1270
1266
spatial_node_index,
@@ -1341,36 +1337,35 @@ impl<'a> SceneBuilder<'a> {
1341
1337
let spatial_node_index = self . get_space ( common. spatial_id ) ;
1342
1338
1343
1339
// 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) ;
1346
1351
} 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,
1349
1354
spatial_node_index,
1350
1355
) ;
1351
1356
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
+ }
1367
1362
1368
1363
let clip_node_id = self . get_clip_node (
1369
1364
common. clip_chain_id ,
1370
1365
) ;
1371
1366
1372
1367
let layout = LayoutPrimitiveInfo {
1373
- rect,
1368
+ rect : prim_rect ,
1374
1369
clip_rect,
1375
1370
flags : common. flags ,
1376
1371
} ;
@@ -1389,11 +1384,29 @@ impl<'a> SceneBuilder<'a> {
1389
1384
)
1390
1385
}
1391
1386
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 (
1393
1404
& mut self ,
1394
1405
rect : & LayoutRect ,
1395
1406
target_spatial_node : SpatialNodeIndex ,
1396
1407
) -> LayoutRect {
1408
+ let rect = self . normalize_rect_scroll_offset ( rect, target_spatial_node) ;
1409
+
1397
1410
self . snap_to_device . set_target_spatial_node (
1398
1411
target_spatial_node,
1399
1412
self . spatial_tree ,
@@ -1522,15 +1535,12 @@ impl<'a> SceneBuilder<'a> {
1522
1535
profile_scope ! ( "hit_test" ) ;
1523
1536
1524
1537
let spatial_node_index = self . get_space ( info. spatial_id ) ;
1525
- let current_offset = self . current_external_scroll_offset ( spatial_node_index) ;
1526
1538
1527
- let mut rect = self . snap_rect (
1539
+ let rect = self . normalize_scroll_offset_and_snap_rect (
1528
1540
& info. rect ,
1529
1541
spatial_node_index,
1530
1542
) ;
1531
1543
1532
- rect = rect. translate ( current_offset) ;
1533
-
1534
1544
let layout = LayoutPrimitiveInfo {
1535
1545
rect,
1536
1546
clip_rect : rect,
@@ -2820,13 +2830,11 @@ impl<'a> SceneBuilder<'a> {
2820
2830
points_range : ItemRange < LayoutPoint > ,
2821
2831
) {
2822
2832
let spatial_node_index = self . get_space ( spatial_id) ;
2823
- let external_scroll_offset = self . current_external_scroll_offset ( spatial_node_index) ;
2824
2833
2825
- let mut snapped_mask_rect = self . snap_rect (
2834
+ let snapped_mask_rect = self . normalize_scroll_offset_and_snap_rect (
2826
2835
& image_mask. rect ,
2827
2836
spatial_node_index,
2828
2837
) ;
2829
- snapped_mask_rect = snapped_mask_rect. translate ( external_scroll_offset) ;
2830
2838
2831
2839
let points: Vec < LayoutPoint > = points_range. iter ( ) . collect ( ) ;
2832
2840
@@ -2870,15 +2878,12 @@ impl<'a> SceneBuilder<'a> {
2870
2878
clip_rect : & LayoutRect ,
2871
2879
) {
2872
2880
let spatial_node_index = self . get_space ( spatial_id) ;
2873
- let external_scroll_offset = self . current_external_scroll_offset ( spatial_node_index) ;
2874
2881
2875
- let mut snapped_clip_rect = self . snap_rect (
2882
+ let snapped_clip_rect = self . normalize_scroll_offset_and_snap_rect (
2876
2883
clip_rect,
2877
2884
spatial_node_index,
2878
2885
) ;
2879
2886
2880
- snapped_clip_rect = snapped_clip_rect. translate ( external_scroll_offset) ;
2881
-
2882
2887
let item = ClipItemKey {
2883
2888
kind : ClipItemKeyKind :: rectangle ( snapped_clip_rect, ClipMode :: Clip ) ,
2884
2889
spatial_node_index,
@@ -2905,15 +2910,12 @@ impl<'a> SceneBuilder<'a> {
2905
2910
clip : & ComplexClipRegion ,
2906
2911
) {
2907
2912
let spatial_node_index = self . get_space ( spatial_id) ;
2908
- let external_scroll_offset = self . current_external_scroll_offset ( spatial_node_index) ;
2909
2913
2910
- let mut snapped_region_rect = self . snap_rect (
2914
+ let snapped_region_rect = self . normalize_scroll_offset_and_snap_rect (
2911
2915
& clip. rect ,
2912
2916
spatial_node_index,
2913
2917
) ;
2914
2918
2915
- snapped_region_rect = snapped_region_rect. translate ( external_scroll_offset) ;
2916
-
2917
2919
let item = ClipItemKey {
2918
2920
kind : ClipItemKeyKind :: rounded_rect (
2919
2921
snapped_region_rect,
0 commit comments