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, ...@@ -116,6 +116,15 @@ Node* FlatTreeTraversal::TraverseSiblings(const Node& node,
Node* FlatTreeTraversal::TraverseSiblingsForV1HostChild( Node* FlatTreeTraversal::TraverseSiblingsForV1HostChild(
const Node& node, const Node& node,
TraversalDirection direction) { 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(); ShadowRoot* shadow_root = node.ParentElementShadowRoot();
DCHECK(shadow_root); DCHECK(shadow_root);
if (!shadow_root->HasSlotAssignment()) { if (!shadow_root->HasSlotAssignment()) {
......
...@@ -273,6 +273,7 @@ void SlotAssignment::RecalcAssignment() { ...@@ -273,6 +273,7 @@ void SlotAssignment::RecalcAssignment() {
if (slot) { if (slot) {
slot->AppendAssignedNode(child); slot->AppendAssignedNode(child);
} else { } else {
if (RuntimeEnabledFeatures::FastFlatTreeTraversalEnabled())
child.ClearFlatTreeNodeData(); child.ClearFlatTreeNodeData();
child.LazyReattachIfAttached(); child.LazyReattachIfAttached();
} }
......
...@@ -185,11 +185,15 @@ void HTMLSlotElement::assign(HeapVector<Member<Node>> nodes) { ...@@ -185,11 +185,15 @@ void HTMLSlotElement::assign(HeapVector<Member<Node>> nodes) {
void HTMLSlotElement::AppendAssignedNode(Node& host_child) { void HTMLSlotElement::AppendAssignedNode(Node& host_child) {
DCHECK(host_child.IsSlotable()); DCHECK(host_child.IsSlotable());
if (!RuntimeEnabledFeatures::FastFlatTreeTraversalEnabled())
assigned_nodes_index_.insert(&host_child, assigned_nodes_.size());
assigned_nodes_.push_back(&host_child); assigned_nodes_.push_back(&host_child);
} }
void HTMLSlotElement::ClearAssignedNodes() { void HTMLSlotElement::ClearAssignedNodes() {
assigned_nodes_.clear(); assigned_nodes_.clear();
if (!RuntimeEnabledFeatures::FastFlatTreeTraversalEnabled())
assigned_nodes_index_.clear();
} }
void HTMLSlotElement::ClearAssignedNodesAndFlatTreeChildren() { void HTMLSlotElement::ClearAssignedNodesAndFlatTreeChildren() {
...@@ -239,6 +243,32 @@ void HTMLSlotElement::DispatchSlotChangeEvent() { ...@@ -239,6 +243,32 @@ void HTMLSlotElement::DispatchSlotChangeEvent() {
DispatchScopedEvent(*event); 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 { AtomicString HTMLSlotElement::GetName() const {
return NormalizeSlotName(FastGetAttribute(kNameAttr)); return NormalizeSlotName(FastGetAttribute(kNameAttr));
} }
...@@ -551,6 +581,7 @@ int HTMLSlotElement::tabIndex() const { ...@@ -551,6 +581,7 @@ int HTMLSlotElement::tabIndex() const {
void HTMLSlotElement::Trace(blink::Visitor* visitor) { void HTMLSlotElement::Trace(blink::Visitor* visitor) {
visitor->Trace(assigned_nodes_); visitor->Trace(assigned_nodes_);
visitor->Trace(assigned_nodes_index_);
visitor->Trace(flat_tree_children_); visitor->Trace(flat_tree_children_);
visitor->Trace(assigned_nodes_candidates_); visitor->Trace(assigned_nodes_candidates_);
HTMLElement::Trace(visitor); HTMLElement::Trace(visitor);
......
...@@ -64,12 +64,17 @@ class CORE_EXPORT HTMLSlotElement final : public HTMLElement { ...@@ -64,12 +64,17 @@ class CORE_EXPORT HTMLSlotElement final : public HTMLElement {
return nodes.IsEmpty() ? nullptr : nodes.back().Get(); return nodes.IsEmpty() ? nullptr : nodes.back().Get();
} }
Node* AssignedNodeNextTo(const Node&) const;
Node* AssignedNodePreviousTo(const Node&) const;
void AppendAssignedNode(Node&); void AppendAssignedNode(Node&);
void ClearAssignedNodes();
const HeapVector<Member<Node>> FlattenedAssignedNodes(); const HeapVector<Member<Node>> FlattenedAssignedNodes();
void WillRecalcAssignedNodes() { ClearAssignedNodes(); } void WillRecalcAssignedNodes() { ClearAssignedNodes(); }
void DidRecalcAssignedNodes() { void DidRecalcAssignedNodes() {
if (RuntimeEnabledFeatures::FastFlatTreeTraversalEnabled())
UpdateFlatTreeNodeDataForAssignedNodes(); UpdateFlatTreeNodeDataForAssignedNodes();
RecalcFlatTreeChildren(); RecalcFlatTreeChildren();
} }
...@@ -137,10 +142,10 @@ class CORE_EXPORT HTMLSlotElement final : public HTMLElement { ...@@ -137,10 +142,10 @@ class CORE_EXPORT HTMLSlotElement final : public HTMLElement {
void RecalcFlatTreeChildren(); void RecalcFlatTreeChildren();
void UpdateFlatTreeNodeDataForAssignedNodes(); void UpdateFlatTreeNodeDataForAssignedNodes();
void ClearAssignedNodes();
void ClearAssignedNodesAndFlatTreeChildren(); void ClearAssignedNodesAndFlatTreeChildren();
HeapVector<Member<Node>> assigned_nodes_; HeapVector<Member<Node>> assigned_nodes_;
HeapHashMap<Member<const Node>, unsigned> assigned_nodes_index_;
HeapVector<Member<Node>> flat_tree_children_; HeapVector<Member<Node>> flat_tree_children_;
bool slotchange_event_enqueued_ = false; bool slotchange_event_enqueued_ = false;
......
...@@ -479,6 +479,9 @@ ...@@ -479,6 +479,9 @@
{ {
name: "ExtraWebGLVideoTextureMetadata", name: "ExtraWebGLVideoTextureMetadata",
}, },
{
name: "FastFlatTreeTraversal",
},
{ {
name: "FastMobileScrolling", 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