Bug 1664719 - Pt 2 - Select ancestor clips as shared clips only. r=nical

Instead of selecting any rectangle clips as potential shared clips
for content in a picture cache slice, only select clips that are
positioned by an ancestor spatial node of the picture cache
scroll root.

This ensures we don't incorrectly select rectangle clips on the
primitive as potential shared clips, which will be important in
the follow up patches for this bug.

Differential Revision: https://phabricator.services.mozilla.com/D90052
This commit is contained in:
Glenn Watson 2020-09-14 07:11:28 +00:00
Родитель ecca275fc4
Коммит e05e5e82b8
3 изменённых файлов: 97 добавлений и 1 удалений

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

@ -604,6 +604,31 @@ impl SpatialTree {
self.pipelines_to_discard.insert(pipeline_id); self.pipelines_to_discard.insert(pipeline_id);
} }
/// Check if a given spatial node is an ancestor of another spatial node.
pub fn is_ancestor(
&self,
maybe_parent: SpatialNodeIndex,
maybe_child: SpatialNodeIndex,
) -> bool {
// Early out if same node
if maybe_parent == maybe_child {
return false;
}
let mut current_node = maybe_child;
while current_node != ROOT_SPATIAL_NODE_INDEX {
let node = &self.spatial_nodes[current_node.0 as usize];
current_node = node.parent.expect("bug: no parent");
if current_node == maybe_parent {
return true;
}
}
false
}
/// Find the spatial node that is the scroll root for a given spatial node. /// Find the spatial node that is the scroll root for a given spatial node.
/// A scroll root is the first spatial node when found travelling up the /// A scroll root is the first spatial node when found travelling up the
/// spatial node tree that is an explicit scroll frame. /// spatial node tree that is an explicit scroll frame.
@ -962,3 +987,63 @@ fn test_cst_translation_rotate() {
test_pt(100.0, 0.0, &cst, child1, root, 0.0, -100.0); test_pt(100.0, 0.0, &cst, child1, root, 0.0, -100.0);
} }
#[test]
fn test_is_ancestor1() {
let mut st = SpatialTree::new();
let root = add_reference_frame(
&mut st,
None,
LayoutTransform::identity(),
LayoutVector2D::zero(),
);
let child1_0 = add_reference_frame(
&mut st,
Some(root),
LayoutTransform::identity(),
LayoutVector2D::zero(),
);
let child1_1 = add_reference_frame(
&mut st,
Some(child1_0),
LayoutTransform::identity(),
LayoutVector2D::zero(),
);
let child2 = add_reference_frame(
&mut st,
Some(root),
LayoutTransform::identity(),
LayoutVector2D::zero(),
);
st.update_tree(
WorldPoint::zero(),
DevicePixelScale::new(1.0),
&SceneProperties::new(),
);
assert!(!st.is_ancestor(root, root));
assert!(!st.is_ancestor(child1_0, child1_0));
assert!(!st.is_ancestor(child1_1, child1_1));
assert!(!st.is_ancestor(child2, child2));
assert!(st.is_ancestor(root, child1_0));
assert!(st.is_ancestor(root, child1_1));
assert!(st.is_ancestor(child1_0, child1_1));
assert!(!st.is_ancestor(child1_0, root));
assert!(!st.is_ancestor(child1_1, root));
assert!(!st.is_ancestor(child1_1, child1_0));
assert!(st.is_ancestor(root, child2));
assert!(!st.is_ancestor(child2, root));
assert!(!st.is_ancestor(child1_0, child2));
assert!(!st.is_ancestor(child1_1, child2));
assert!(!st.is_ancestor(child2, child1_0));
assert!(!st.is_ancestor(child2, child1_1));
}

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

@ -211,10 +211,12 @@ impl TileCacheBuilder {
let mut shared_clips = Vec::new(); let mut shared_clips = Vec::new();
add_clips( add_clips(
scroll_root,
prim_instance.clip_set.clip_chain_id, prim_instance.clip_set.clip_chain_id,
&mut shared_clips, &mut shared_clips,
clip_store, clip_store,
interners, interners,
spatial_tree,
); );
self.last_checked_clip_chain = prim_instance.clip_set.clip_chain_id; self.last_checked_clip_chain = prim_instance.clip_set.clip_chain_id;
@ -247,10 +249,12 @@ impl TileCacheBuilder {
let prim_clips_buffer = &mut self.prim_clips_buffer; let prim_clips_buffer = &mut self.prim_clips_buffer;
prim_clips_buffer.clear(); prim_clips_buffer.clear();
add_clips( add_clips(
pending_tile_cache.params.spatial_node_index,
prim_instance.clip_set.clip_chain_id, prim_instance.clip_set.clip_chain_id,
prim_clips_buffer, prim_clips_buffer,
clip_store, clip_store,
interners, interners,
spatial_tree,
); );
pending_tile_cache.params.shared_clips.retain(|h1: &ClipInstance| { pending_tile_cache.params.shared_clips.retain(|h1: &ClipInstance| {
@ -329,10 +333,12 @@ impl TileCacheBuilder {
// Helper fn to collect clip handles from a given clip chain. // Helper fn to collect clip handles from a given clip chain.
fn add_clips( fn add_clips(
scroll_root: SpatialNodeIndex,
clip_chain_id: ClipChainId, clip_chain_id: ClipChainId,
prim_clips: &mut Vec<ClipInstance>, prim_clips: &mut Vec<ClipInstance>,
clip_store: &ClipStore, clip_store: &ClipStore,
interners: &Interners, interners: &Interners,
spatial_tree: &SpatialTree,
) { ) {
let mut current_clip_chain_id = clip_chain_id; let mut current_clip_chain_id = clip_chain_id;
@ -342,7 +348,12 @@ fn add_clips(
let clip_node_data = &interners.clip[clip_chain_node.handle]; let clip_node_data = &interners.clip[clip_chain_node.handle];
if let ClipNodeKind::Rectangle = clip_node_data.clip_node_kind { if let ClipNodeKind::Rectangle = clip_node_data.clip_node_kind {
prim_clips.push(ClipInstance::new(clip_chain_node.handle, clip_chain_node.spatial_node_index)); if spatial_tree.is_ancestor(
clip_chain_node.spatial_node_index,
scroll_root,
) {
prim_clips.push(ClipInstance::new(clip_chain_node.handle, clip_chain_node.spatial_node_index));
}
} }
current_clip_chain_id = clip_chain_node.parent_clip_chain_id; current_clip_chain_id = clip_chain_node.parent_clip_chain_id;

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 12 KiB

После

Ширина:  |  Высота:  |  Размер: 13 KiB