Bug 1289620 - Hook up initial styling. r=heycam
authorBobby Holley <bobbyholley@gmail.com>
Tue, 26 Jul 2016 17:06:25 -0700
changeset 349027 489e458bd9726e264d635aea49a850d0ff0259f6
parent 349026 4d9e30d1dac162a8319e6fd3d63ed47a49709705
child 349028 5a9751329a6df44ba2f4d3814a8fdaa89d67cfd6
push id1230
push userjlund@mozilla.com
push dateMon, 31 Oct 2016 18:13:35 +0000
treeherdermozilla-release@5e06e3766db2 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersheycam
bugs1289620
milestone50.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1289620 - Hook up initial styling. r=heycam Aside from the parser-side hacks, this should subsume all the current scattered logic in the stylo tree to handle initial styling.
dom/xbl/nsXBLBinding.cpp
layout/base/ServoRestyleManager.cpp
layout/base/nsCSSFrameConstructor.cpp
layout/base/nsPresShell.cpp
layout/style/ServoStyleSet.cpp
layout/style/ServoStyleSet.h
--- a/dom/xbl/nsXBLBinding.cpp
+++ b/dom/xbl/nsXBLBinding.cpp
@@ -235,17 +235,17 @@ nsXBLBinding::InstallAnonymousContent(ns
     // an element is added to a XUL document), we need to notify the
     // XUL document using its special API.
     nsCOMPtr<nsIXULDocument> xuldoc(do_QueryInterface(doc));
     if (xuldoc)
       xuldoc->AddSubtreeToDocument(child);
 #endif
 
     if (servoStyleSet) {
-      servoStyleSet->RestyleSubtree(child, /* aForce = */ true);
+      servoStyleSet->RestyleSubtree(child);
     }
   }
 }
 
 void
 nsXBLBinding::UninstallAnonymousContent(nsIDocument* aDocument,
                                         nsIContent* aAnonParent)
 {
--- a/layout/base/ServoRestyleManager.cpp
+++ b/layout/base/ServoRestyleManager.cpp
@@ -174,16 +174,22 @@ ServoRestyleManager::NoteRestyleHint(Ele
 void
 ServoRestyleManager::ProcessPendingRestyles()
 {
   if (!HasPendingRestyles()) {
     return;
   }
   ServoStyleSet* styleSet = StyleSet();
 
+  if (!styleSet->StylingStarted()) {
+    // If something caused us to restyle, and we haven't started styling yet,
+    // do nothing. Everything is dirty, and we'll style it all later.
+    return;
+  }
+
   nsIDocument* doc = PresContext()->Document();
 
   Element* root = doc->GetRootElement();
   if (root) {
     for (auto iter = mModifiedElements.Iter(); !iter.Done(); iter.Next()) {
       ServoElementSnapshot* snapshot = iter.UserData();
       Element* element = iter.Key();
 
@@ -192,17 +198,17 @@ ServoRestyleManager::ProcessPendingResty
       nsRestyleHint hint = styleSet->ComputeRestyleHint(element, snapshot);
       hint |= snapshot->ExplicitRestyleHint();
 
       if (hint) {
         NoteRestyleHint(element, hint);
       }
     }
 
-    styleSet->RestyleSubtree(root, /* aForce = */ false);
+    styleSet->RestyleSubtree(root);
     RecreateStyleContexts(root, nullptr, styleSet);
   }
 
   mModifiedElements.Clear();
 
   // NB: we restyle from the root element, but the document also gets the
   // HAS_DIRTY_DESCENDANTS flag as part of the loop on PostRestyleEvent, and we
   // use that to check we have pending restyles.
--- a/layout/base/nsCSSFrameConstructor.cpp
+++ b/layout/base/nsCSSFrameConstructor.cpp
@@ -4257,17 +4257,17 @@ nsCSSFrameConstructor::GetAnonymousConte
       content->UnbindFromTree();
       return rv;
     }
   }
 
   if (ServoStyleSet* styleSet = mPresShell->StyleSet()->GetAsServo()) {
     // Eagerly compute styles for the anonymous content tree.
     for (auto& info : aContent) {
-      styleSet->RestyleSubtree(info.mContent, /* aForce = */ true);
+      styleSet->RestyleSubtree(info.mContent);
     }
   }
 
   return NS_OK;
 }
 
 static
 bool IsXULDisplayType(const nsStyleDisplay* aDisplay)
--- a/layout/base/nsPresShell.cpp
+++ b/layout/base/nsPresShell.cpp
@@ -1668,16 +1668,20 @@ PresShell::Initialize(nscoord aWidth, ns
   }
 #endif
 
   // XXX Do a full invalidate at the beginning so that invalidates along
   // the way don't have region accumulation issues?
 
   mPresContext->SetVisibleArea(nsRect(0, 0, aWidth, aHeight));
 
+  if (mStyleSet->IsServo()) {
+    mStyleSet->AsServo()->StartStyling(GetPresContext());
+  }
+
   // Get the root frame from the frame manager
   // XXXbz it would be nice to move this somewhere else... like frame manager
   // Init(), say.  But we need to make sure our views are all set up by the
   // time we do this!
   nsIFrame* rootFrame = mFrameConstructor->GetRootFrame();
   NS_ASSERTION(!rootFrame, "How did that happen, exactly?");
   if (!rootFrame) {
     nsAutoScriptBlocker scriptBlocker;
--- a/layout/style/ServoStyleSet.cpp
+++ b/layout/style/ServoStyleSet.cpp
@@ -15,16 +15,17 @@
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
 ServoStyleSet::ServoStyleSet()
   : mPresContext(nullptr)
   , mRawSet(Servo_InitStyleSet())
   , mBatching(0)
+  , mStylingStarted(false)
 {
 }
 
 void
 ServoStyleSet::Init(nsPresContext* aPresContext)
 {
   mPresContext = aPresContext;
 }
@@ -65,16 +66,26 @@ ServoStyleSet::EndUpdate()
   if (--mBatching > 0) {
     return NS_OK;
   }
 
   // ... do something ...
   return NS_OK;
 }
 
+void
+ServoStyleSet::StartStyling(nsPresContext* aPresContext)
+{
+  Element* root = aPresContext->Document()->GetRootElement();
+  if (root) {
+    RestyleSubtree(root);
+  }
+  mStylingStarted = true;
+}
+
 already_AddRefed<nsStyleContext>
 ServoStyleSet::ResolveStyleFor(Element* aElement,
                                nsStyleContext* aParentContext)
 {
   return GetContext(aElement, aParentContext, nullptr,
                     CSSPseudoElementType::NotPseudo);
 }
 
@@ -384,18 +395,13 @@ ServoStyleSet::HasStateDependentStyle(do
 nsRestyleHint
 ServoStyleSet::ComputeRestyleHint(dom::Element* aElement,
                                   ServoElementSnapshot* aSnapshot)
 {
   return Servo_ComputeRestyleHint(aElement, aSnapshot, mRawSet.get());
 }
 
 void
-ServoStyleSet::RestyleSubtree(nsINode* aNode, bool aForce)
+ServoStyleSet::RestyleSubtree(nsINode* aNode)
 {
-  if (aForce) {
-    MOZ_ASSERT(aNode->IsContent());
-    aNode->SetIsDirtyForServo();
-  }
-
   MOZ_ASSERT(aNode->IsDirtyForServo() || aNode->HasDirtyDescendantsForServo());
   Servo_RestyleSubtree(aNode, mRawSet.get());
 }
--- a/layout/style/ServoStyleSet.h
+++ b/layout/style/ServoStyleSet.h
@@ -50,16 +50,18 @@ public:
   void Shutdown();
 
   bool GetAuthorStyleDisabled() const;
   nsresult SetAuthorStyleDisabled(bool aStyleDisabled);
 
   void BeginUpdate();
   nsresult EndUpdate();
 
+  void StartStyling(nsPresContext* aPresContext);
+
   already_AddRefed<nsStyleContext>
   ResolveStyleFor(dom::Element* aElement,
                   nsStyleContext* aParentContext);
 
   already_AddRefed<nsStyleContext>
   ResolveStyleFor(dom::Element* aElement,
                   nsStyleContext* aParentContext,
                   TreeMatchContext& aTreeMatchContext);
@@ -121,21 +123,20 @@ public:
   /**
    * Computes a restyle hint given a element and a previous element snapshot.
    */
   nsRestyleHint ComputeRestyleHint(dom::Element* aElement,
                                    ServoElementSnapshot* aSnapshot);
 
   /**
    * Restyles a whole subtree of nodes.
-   *
-   * The aForce parameter propagates the dirty bits down the subtree, and when
-   * used aNode needs to be nsIContent.
    */
-  void RestyleSubtree(nsINode* aNode, bool aForce);
+  void RestyleSubtree(nsINode* aNode);
+
+  bool StylingStarted() const { return mStylingStarted; }
 
 private:
   already_AddRefed<nsStyleContext> GetContext(already_AddRefed<ServoComputedValues>,
                                               nsStyleContext* aParentContext,
                                               nsIAtom* aPseudoTag,
                                               CSSPseudoElementType aPseudoType);
 
   already_AddRefed<nsStyleContext> GetContext(nsIContent* aContent,
@@ -143,13 +144,14 @@ private:
                                               nsIAtom* aPseudoTag,
                                               CSSPseudoElementType aPseudoType);
 
   nsPresContext* mPresContext;
   UniquePtr<RawServoStyleSet> mRawSet;
   EnumeratedArray<SheetType, SheetType::Count,
                   nsTArray<RefPtr<ServoStyleSheet>>> mSheets;
   int32_t mBatching;
+  bool mStylingStarted;
 };
 
 } // namespace mozilla
 
 #endif // mozilla_ServoStyleSet_h