Commit d2849642 authored by Rune Lillesveen's avatar Rune Lillesveen Committed by Commit Bot

Allow traversal of dirty v0 shadow for flat tree recalc.

We need to be able to walk the current flat tree ancestors without
updating the distribution when marking the ancestor chain for style
recalc. For Shadow DOM V1, we introduced a separate method for that
since for V1 we update the slot assignment while traversing. For V0, we
need to explicitly update distribution and DCHECK during traversal that
we made sure it was up to date. Here we skip the DCHECK when
FlatTreeStyleRecalc is enabled.

We could have introduced some scoping mechanism that sets a flag from
outside the traversal saying that we intentionally walk a dirty tree
instead of always skipping the DCHECK for FlatTreeStyleRecalc. Since V0
is going away soon, I gathered we could skip the DCHECK.

Multiple tests in the TEST lines below will trigger the DCHECK without
this change and FlatTreeStyleRecalc enabled.

TEST=fast/dom/shadow/
TEST=shadow-dom/

Bug: 972752
Change-Id: I8a850123b9b647a6575c3a2679e382d61c0ed8c7
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1875258Reviewed-by: default avatarMason Freed <masonfreed@chromium.org>
Commit-Queue: Rune Lillesveen <futhark@chromium.org>
Cr-Commit-Position: refs/heads/master@{#710621}
parent 32de3e40
......@@ -1630,6 +1630,15 @@ class CORE_EXPORT Document : public ContainerNode,
return use_count_fragment_directive_;
}
#if DCHECK_IS_ON()
bool AllowDirtyShadowV0Traversal() const {
return allow_dirty_shadow_v0_traversal_;
}
void SetAllowDirtyShadowV0Traversal(bool allow) {
allow_dirty_shadow_v0_traversal_ = allow;
}
#endif
protected:
void ClearXMLVersion() { xml_version_ = String(); }
......@@ -2097,6 +2106,12 @@ class CORE_EXPORT Document : public ContainerNode,
// opposed to a PluginView.
bool is_for_external_handler_ = false;
#if DCHECK_IS_ON()
// Allow traversal of Shadow DOM V0 traversal with dirty distribution.
// Required for marking ancestors style-child-dirty for FlatTreeStyleRecalc.
bool allow_dirty_shadow_v0_traversal_ = false;
#endif
Member<NavigationInitiatorImpl> navigation_initiator_;
Member<LazyLoadImageObserver> lazy_load_image_observer_;
......
......@@ -1225,7 +1225,34 @@ void Node::MarkAncestorsWithChildNeedsDistributionRecalc() {
GetDocument().ScheduleLayoutTreeUpdateIfNeeded();
}
#if DCHECK_IS_ON()
namespace {
class AllowDirtyShadowV0TraversalScope {
STACK_ALLOCATED();
public:
explicit AllowDirtyShadowV0TraversalScope(Document& document)
: document_(&document),
old_value_(document.AllowDirtyShadowV0Traversal()) {
document.SetAllowDirtyShadowV0Traversal(true);
}
~AllowDirtyShadowV0TraversalScope() {
document_->SetAllowDirtyShadowV0Traversal(old_value_);
}
private:
Member<Document> document_;
bool old_value_;
};
} // namespace
#define ALLOW_DIRTY_SHADOW_V0_TRAVERSAL_SCOPE(document) \
AllowDirtyShadowV0TraversalScope traversal_scope(document)
#else // DCHECK_IS_ON()
#define ALLOW_DIRTY_SHADOW_V0_TRAVERSAL_SCOPE(document)
#endif // DCHECK_IS_ON()
void Node::MarkAncestorsWithChildNeedsStyleRecalc() {
ALLOW_DIRTY_SHADOW_V0_TRAVERSAL_SCOPE(GetDocument());
ContainerNode* ancestor = GetStyleRecalcParent();
bool parent_dirty = ancestor && ancestor->IsDirtyForStyleRecalc();
for (; ancestor && !ancestor->ChildNeedsStyleRecalc();
......@@ -1338,6 +1365,7 @@ void Node::SetNeedsStyleRecalc(StyleChangeType change_type,
if (!InActiveDocument())
return;
if (!GetComputedStyle()) {
ALLOW_DIRTY_SHADOW_V0_TRAVERSAL_SCOPE(GetDocument());
// If we don't have a computed style, and our parent element does not have a
// computed style it's not necessary to mark this node for style recalc.
if (auto* parent = GetStyleRecalcParent()) {
......
......@@ -145,8 +145,14 @@ ShadowRootV0::DescendantInsertionPoints() {
const V0InsertionPoint* ShadowRootV0::FinalDestinationInsertionPointFor(
const Node* key) const {
#if DCHECK_IS_ON()
DCHECK(key);
DCHECK(!key->NeedsDistributionRecalc());
// Allow traversal without V0 distribution up-to-date for marking ancestors
// with ChildNeedsStyleRecalc() when FlatTreeStyleRecalc is enabled.
DCHECK(!key->NeedsDistributionRecalc() ||
RuntimeEnabledFeatures::FlatTreeStyleRecalcEnabled() &&
key->GetDocument().AllowDirtyShadowV0Traversal());
#endif
NodeToDestinationInsertionPoints::const_iterator it =
node_to_insertion_points_.find(key);
return it == node_to_insertion_points_.end() ? nullptr : it->value->back();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment