scripts/CLIPPING_ANALYSIS_REPORT.md
Problem: Content inside a scroll container is not being visually clipped, even though the clip infrastructure appears to be set up correctly.
Key Finding: The debug output shows that:
local_clip_rect is being set properly[WR SCENE] RectClip: id=ClipId(1), spatial_id=SpatialId(1), clip_rect=Box2D((68,68), (836,636))
[WR SCENE] ClipChain: id=ClipChainId(0), parent=None
[WR SCENE] RectClip: id=ClipId(2), spatial_id=SpatialId(2), clip_rect=Box2D((0,0), (768,568))
[WR SCENE] ClipChain: id=ClipChainId(1), parent=Some(ClipChainId(0))
[WR SCENE] Rectangle: bounds=Box2D((20,1640), (780,1800)), clip_chain_id=ClipChainId(1), spatial_id=SpatialId(2)
[WR CLIP] build_clip_chain_instance: local_prim_rect=Box2D((20,1640), (780,1800)), local_clip_rect=Box2D((20,1640), (780,1800))
[WR CLIP] local_bounding_rect (intersection)=Box2D((20,1640), (780,1800))
PROBLEM IDENTIFIED: The local_clip_rect equals the local_prim_rect!
This means the clip is NOT being applied. The clip rect should be (0,0)-(768,568) but it's (20,1640)-(780,1800).
The local_clip_rect comes from clip_leaf.local_clip_rect in set_active_clips():
pub fn set_active_clips(...) {
let clip_leaf = clip_tree.get_leaf(clip_leaf_id);
let mut local_clip_rect = clip_leaf.local_clip_rect; // <-- THIS IS THE PROBLEM
...
}
The clip_leaf.local_clip_rect is initialized with the primitive's own clip_rect from CommonItemProperties, NOT from the parent clip chain!
In scene_building.rs, when processing DisplayItem::Rectangle:
let current_clip_chain_id = self.get_clip_chain(item.clip_chain_id());
...
let prim_info = CommonItemProperties {
clip_rect: info.clip_rect, // <-- This is the primitive's own clip_rect
clip_chain_id: current_clip_chain_id,
...
};
The info.clip_rect is set to the primitive's bounds in our compositor code:
let info = CommonItemProperties {
clip_rect: rect, // <-- We set clip_rect = rect (the full primitive bounds)
clip_chain_id: current_clip_chain_id,
...
};
The issue is that CommonItemProperties.clip_rect should be the INTERSECTION of the primitive bounds with the active clip region, not just the primitive bounds.
For items inside a scroll frame, the clip_rect in CommonItemProperties should be clipped to the scroll frame's viewport:
// Instead of:
let info = CommonItemProperties {
clip_rect: rect, // Full primitive rect
...
};
// Should be:
let clipped_rect = rect.intersection(¤t_clip_bounds).unwrap_or(LayoutRect::zero());
let info = CommonItemProperties {
clip_rect: clipped_rect, // Primitive rect clipped to viewport
...
};
WebRender's clip system should handle this through ClipChainId, but the clip_rect field is used as an early-out optimization. If clip_rect is larger than the actual clip region, WebRender may skip clipping.
scene_building.rs)define_clip_rect()define_clip_chain()clip.rs)set_active_clips() - Walks the clip tree to build active clip listbuild_clip_chain_instance() - Creates optimized clip chain for renderingget_clip_result() - Determines Accept/Reject/Partial for each clipvisibility.rs)build_clip_chain_instance() for each primitiveClipTree
├── ClipNodeId (0) - Root
│ └── ClipNodeId (1)
│ ├── handle: ClipDataHandle -> ClipNode with clip_rect
│ └── parent: ClipNodeId (0)
│
└── ClipLeafId (0)
├── node_id: ClipNodeId (1)
└── local_clip_rect: LayoutRect <-- THE PROBLEM SOURCE
Scene Building (scene_building.rs):
[WR SCENE] RectClip: - When a clip rect is defined[WR SCENE] ClipChain: - When a clip chain is defined[WR SCENE] Rectangle: - When a rectangle primitive is addedClip Store (clip.rs):
[WR SET_ACTIVE_CLIPS] - When clips are activated for a primitive[WR CLIP CHAIN] - When a clip node is added to the chain[WR CLIP] build_clip_chain_instance: - When building the final clip instance[WR CLIP] REJECTED: - When a primitive is fully clippedCompositor (compositor2.rs):
[CLIP DEBUG] Rect: - Raw and adjusted coordinates[CLIP DEBUG] PushScrollFrame: - Scroll frame definitionset_active_clips() to see the clip tree traversalclip_leaf.local_clip_rect - This might be set incorrectlyCommonItemProperties.clip_rect - Ensure it's being intersected with clip bounds/webrender/core/src/clip.rs - ClipStore, set_active_clips, build_clip_chain_instance/webrender/core/src/scene_building.rs - How clips are defined and associated/webrender/core/src/visibility.rs - How primitives are culled/dll/src/desktop/compositor2.rs - How we build the display listThe ClipLeafId assigned to each primitive determines which clip chain applies. The issue is that:
(0,0)-(768,568) in scroll spaceclip_chain_id pointing to this clipClipLeaf.local_clip_rect is set to the primitive's own boundslocal_clip_rect as the primary clip sourceThe fix should ensure that the clip_rect in CommonItemProperties is properly constrained to the scroll frame viewport.