Bug 1395351: Use the parallel traversal flag more often. r?bholley
MozReview-Commit-ID: JF6i0HDniR2
--- a/layout/style/ServoStyleSet.cpp
+++ b/layout/style/ServoStyleSet.cpp
@@ -869,92 +869,88 @@ ServoStyleSet::HasStateDependentStyle(do
dom::Element* aPseudoElement,
EventStates aStateMask)
{
NS_WARNING("stylo: HasStateDependentStyle always returns zero!");
return nsRestyleHint(0);
}
bool
-ServoStyleSet::StyleDocument(ServoTraversalFlags aBaseFlags)
+ServoStyleSet::StyleDocument(ServoTraversalFlags aFlags)
{
nsIDocument* doc = mPresContext->Document();
if (!doc->GetServoRestyleRoot()) {
return false;
}
- PreTraverse(aBaseFlags);
+ PreTraverse(aFlags);
AutoPrepareTraversal guard(this);
const SnapshotTable& snapshots = Snapshots();
// Restyle the document from the root element and each of the document level
// NAC subtree roots.
bool postTraversalRequired = false;
Element* rootElement = doc->GetRootElement();
MOZ_ASSERT_IF(rootElement, rootElement->HasServoData());
+ if (ShouldTraverseInParallel()) {
+ aFlags |= ServoTraversalFlags::ParallelTraversal;
+ }
+
// Do the first traversal.
DocumentStyleRootIterator iter(doc->GetServoRestyleRoot());
while (Element* root = iter.GetNextStyleRoot()) {
MOZ_ASSERT(MayTraverseFrom(const_cast<Element*>(root)));
// If there were text nodes inserted into the document (but not elements),
// there may be lazy frame construction to do even if no styling is required.
postTraversalRequired |= root->HasFlag(NODE_DESCENDANTS_NEED_FRAMES);
- // Allow the parallel traversal, unless we're traversing traversing one of
- // the native anonymous document style roots, which are tiny and not worth
- // parallelizing over.
- //
- // We only allow the parallel traversal in active (foreground) tabs.
- auto flags = aBaseFlags;
- if (!root->IsInNativeAnonymousSubtree() && mPresContext->PresShell()->IsActive()) {
- flags |= ServoTraversalFlags::ParallelTraversal;
- }
-
- bool required = Servo_TraverseSubtree(root, mRawSet.get(), &snapshots, flags);
+ bool required = Servo_TraverseSubtree(root, mRawSet.get(), &snapshots, aFlags);
postTraversalRequired |= required;
}
// If there are still animation restyles needed, trigger a second traversal to
// update CSS animations or transitions' styles.
//
// Note that we need to check the style root again, because doing another
// PreTraverse on the EffectCompositor might alter the style root. But we
// don't need to worry about NAC, since document-level NAC shouldn't have
// animations.
//
// We don't need to do this for SMIL since SMIL only updates its animation
// values once at the begin of a tick. As a result, even if the previous
// traversal caused, for example, the font-size to change, the SMIL style
// won't be updated until the next tick anyway.
- if (mPresContext->EffectCompositor()->PreTraverse(aBaseFlags)) {
+ if (mPresContext->EffectCompositor()->PreTraverse(aFlags)) {
nsINode* styleRoot = doc->GetServoRestyleRoot();
Element* root = styleRoot->IsElement() ? styleRoot->AsElement() : rootElement;
- auto flags = aBaseFlags | ServoTraversalFlags::ParallelTraversal;
-
- bool required = Servo_TraverseSubtree(root, mRawSet.get(), &snapshots, flags);
+ bool required = Servo_TraverseSubtree(root, mRawSet.get(), &snapshots, aFlags);
postTraversalRequired |= required;
}
return postTraversalRequired;
}
void
ServoStyleSet::StyleNewSubtree(Element* aRoot)
{
MOZ_ASSERT(!aRoot->HasServoData(), "Should have called StyleNewChildren");
PreTraverseSync();
AutoPrepareTraversal guard(this);
// Do the traversal. The snapshots will not be used.
const SnapshotTable& snapshots = Snapshots();
auto flags = ServoTraversalFlags::Empty;
+ if (ShouldTraverseInParallel()) {
+ flags |= ServoTraversalFlags::ParallelTraversal;
+ }
+
DebugOnly<bool> postTraversalRequired =
Servo_TraverseSubtree(aRoot, mRawSet.get(), &snapshots, flags);
MOZ_ASSERT(!postTraversalRequired);
// Annoyingly, the newly-styled content may have animations that need
// starting, which requires traversing them again. Mark the elements
// that need animation processing, then do a forgetful traversal to
// update the styles and clear the animation bits.
@@ -999,23 +995,17 @@ ServoStyleSet::StyleNewChildren(Element*
// traversal, which is buggy.
// Set ourselves up to find the children by marking the parent as having
// dirty descendants.
bool hadDirtyDescendants = aParent->HasDirtyDescendantsForServo();
aParent->SetHasDirtyDescendantsForServo();
auto flags = ServoTraversalFlags::UnstyledOnly;
-
- // If there is an XBL binding on the root element, we do the initial document
- // styling with this API. Not clear how common that is, but we allow parallel
- // traversals in this case to preserve the old behavior (where Servo would
- // use the parallel traversal i.f.f. the traversal root was the document root).
- if (aParent == aParent->OwnerDoc()->GetRootElement() &&
- mPresContext->PresShell()->IsActive()) {
+ if (ShouldTraverseInParallel()) {
flags |= ServoTraversalFlags::ParallelTraversal;
}
// Do the traversal. The snapshots will be ignored.
const SnapshotTable& snapshots = Snapshots();
Servo_TraverseSubtree(aParent, mRawSet.get(), &snapshots, flags);
// Restore the old state of the dirty descendants bit.
@@ -1410,16 +1400,22 @@ ServoStyleSet::MayTraverseFrom(Element*
if (!parent->HasServoData()) {
return false;
}
return !Servo_Element_IsDisplayNone(parent);
}
+bool
+ServoStyleSet::ShouldTraverseInParallel() const
+{
+ return mPresContext->PresShell()->IsActive();
+}
+
void
ServoStyleSet::PrependSheetOfType(SheetType aType,
ServoStyleSheet* aSheet)
{
aSheet->AddStyleSet(this);
mSheets[aType].InsertElementAt(0, aSheet);
}
--- a/layout/style/ServoStyleSet.h
+++ b/layout/style/ServoStyleSet.h
@@ -469,16 +469,18 @@ public:
ServoStyleContext* aNewParentIgnoringFirstLine,
ServoStyleContext* aNewLayoutParent,
Element* aElement);
private:
friend class AutoSetInServoTraversal;
friend class AutoPrepareTraversal;
+ bool ShouldTraverseInParallel() const;
+
/**
* Gets the pending snapshots to handle from the restyle manager.
*/
const SnapshotTable& Snapshots();
bool IsMaster() const { return mKind == Kind::Master; }
bool IsForXBL() const { return mKind == Kind::ForXBL; }