Commit d9cba271 authored by Hayato Ito's avatar Hayato Ito Committed by Commit Bot

Guard fast flat tree traversal (fftt) by runtime flag

While in working on the WIP CL, https://crrev.com/c/1350441, I've found that
there is an edge case where fast flat tree traversal might return dirty
result. So it would be safe to guard the feature of fast flat tree traversal
by the runtime flag, and continue to develop under the flag.

This CL is basically rewriting the following two CLs with runtime flag,

- https://crrev.com/c/1337225
- https://crrev.com/c/1341744

and bring back old code which runs when the flag is disabled.

BUG: 906494

Change-Id: I7a1940643925c1ef583cf55f1a79bfa0190ef40c
Reviewed-on: https://chromium-review.googlesource.com/c/1356167Reviewed-by: default avatarKent Tamura <tkent@chromium.org>
Commit-Queue: Hayato Ito <hayato@chromium.org>
Cr-Commit-Position: refs/heads/master@{#612548}
parent 07714205
......@@ -116,6 +116,15 @@ Node* FlatTreeTraversal::TraverseSiblings(const Node& node,
Node* FlatTreeTraversal::TraverseSiblingsForV1HostChild(
const Node& node,
TraversalDirection direction) {
if (!RuntimeEnabledFeatures::FastFlatTreeTraversalEnabled()) {
HTMLSlotElement* slot = node.AssignedSlot();
if (!slot)
return nullptr;
return direction == kTraversalDirectionForward
? slot->AssignedNodeNextTo(node)
: slot->AssignedNodePreviousTo(node);
}
ShadowRoot* shadow_root = node.ParentElementShadowRoot();
DCHECK(shadow_root);
if (!shadow_root->HasSlotAssignment()) {
......
......@@ -273,7 +273,8 @@ void SlotAssignment::RecalcAssignment() {
if (slot) {
slot->AppendAssignedNode(child);
} else {
child.ClearFlatTreeNodeData();
if (RuntimeEnabledFeatures::FastFlatTreeTraversalEnabled())
child.ClearFlatTreeNodeData();
child.LazyReattachIfAttached();
}
}
......
......@@ -185,11 +185,15 @@ void HTMLSlotElement::assign(HeapVector<Member<Node>> nodes) {
void HTMLSlotElement::AppendAssignedNode(Node& host_child) {
DCHECK(host_child.IsSlotable());
if (!RuntimeEnabledFeatures::FastFlatTreeTraversalEnabled())
assigned_nodes_index_.insert(&host_child, assigned_nodes_.size());
assigned_nodes_.push_back(&host_child);
}
void HTMLSlotElement::ClearAssignedNodes() {
assigned_nodes_.clear();
if (!RuntimeEnabledFeatures::FastFlatTreeTraversalEnabled())
assigned_nodes_index_.clear();
}
void HTMLSlotElement::ClearAssignedNodesAndFlatTreeChildren() {
......@@ -239,6 +243,32 @@ void HTMLSlotElement::DispatchSlotChangeEvent() {
DispatchScopedEvent(*event);
}
Node* HTMLSlotElement::AssignedNodeNextTo(const Node& node) const {
DCHECK(!RuntimeEnabledFeatures::FastFlatTreeTraversalEnabled());
DCHECK(SupportsAssignment());
ContainingShadowRoot()->GetSlotAssignment().RecalcAssignment();
auto it = assigned_nodes_index_.find(&node);
DCHECK(it != assigned_nodes_index_.end());
unsigned index = it->value;
if (index + 1 == assigned_nodes_.size())
return nullptr;
return assigned_nodes_[index + 1].Get();
}
Node* HTMLSlotElement::AssignedNodePreviousTo(const Node& node) const {
DCHECK(!RuntimeEnabledFeatures::FastFlatTreeTraversalEnabled());
DCHECK(SupportsAssignment());
ContainingShadowRoot()->GetSlotAssignment().RecalcAssignment();
auto it = assigned_nodes_index_.find(&node);
DCHECK(it != assigned_nodes_index_.end());
unsigned index = it->value;
if (index == 0)
return nullptr;
return assigned_nodes_[index - 1].Get();
}
AtomicString HTMLSlotElement::GetName() const {
return NormalizeSlotName(FastGetAttribute(kNameAttr));
}
......@@ -551,6 +581,7 @@ int HTMLSlotElement::tabIndex() const {
void HTMLSlotElement::Trace(blink::Visitor* visitor) {
visitor->Trace(assigned_nodes_);
visitor->Trace(assigned_nodes_index_);
visitor->Trace(flat_tree_children_);
visitor->Trace(assigned_nodes_candidates_);
HTMLElement::Trace(visitor);
......
......@@ -64,13 +64,18 @@ class CORE_EXPORT HTMLSlotElement final : public HTMLElement {
return nodes.IsEmpty() ? nullptr : nodes.back().Get();
}
Node* AssignedNodeNextTo(const Node&) const;
Node* AssignedNodePreviousTo(const Node&) const;
void AppendAssignedNode(Node&);
void ClearAssignedNodes();
const HeapVector<Member<Node>> FlattenedAssignedNodes();
void WillRecalcAssignedNodes() { ClearAssignedNodes(); }
void DidRecalcAssignedNodes() {
UpdateFlatTreeNodeDataForAssignedNodes();
if (RuntimeEnabledFeatures::FastFlatTreeTraversalEnabled())
UpdateFlatTreeNodeDataForAssignedNodes();
RecalcFlatTreeChildren();
}
......@@ -137,10 +142,10 @@ class CORE_EXPORT HTMLSlotElement final : public HTMLElement {
void RecalcFlatTreeChildren();
void UpdateFlatTreeNodeDataForAssignedNodes();
void ClearAssignedNodes();
void ClearAssignedNodesAndFlatTreeChildren();
HeapVector<Member<Node>> assigned_nodes_;
HeapHashMap<Member<const Node>, unsigned> assigned_nodes_index_;
HeapVector<Member<Node>> flat_tree_children_;
bool slotchange_event_enqueued_ = false;
......
......@@ -479,6 +479,9 @@
{
name: "ExtraWebGLVideoTextureMetadata",
},
{
name: "FastFlatTreeTraversal",
},
{
name: "FastMobileScrolling",
},
......
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