Bug 253889 - part 3: Move all remaining members of nsIPresShell to mozilla::PresShell r=emilio
authorMasayuki Nakano <masayuki@d-toybox.com>
Wed, 01 May 2019 02:28:25 +0000
changeset 531054 cbf6babb97cddfb252b504ef4e39580003f35029
parent 531053 ad0568bbf0d1f39cef9e798283b48d64c40ec9c0
child 531055 d1f9cf74a077fe71234115dafdee9c0723b58e93
push id11265
push userffxbld-merge
push dateMon, 13 May 2019 10:53:39 +0000
treeherdermozilla-beta@77e0fe8dbdd3 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersemilio
bugs253889
milestone68.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 253889 - part 3: Move all remaining members of nsIPresShell to mozilla::PresShell r=emilio Additionally, this sorts out the order of member variables for minimizing the instance size. And also this changes `enum RenderFlags` to `enum class RenderingStateFlags`. Differential Revision: https://phabricator.services.mozilla.com/D29312
layout/base/PresShell.cpp
layout/base/PresShell.h
layout/base/PresShellForwards.h
layout/base/nsIPresShell.h
servo/components/style/gecko/media_queries.rs
--- a/layout/base/PresShell.cpp
+++ b/layout/base/PresShell.cpp
@@ -761,77 +761,75 @@ bool PresShell::AccessibleCaretEnabled(n
   if (StaticPrefs::layout_accessiblecaret_enabled_on_touch() &&
       dom::TouchEvent::PrefEnabled(aDocShell)) {
     return true;
   }
   // Otherwise, disabled.
   return false;
 }
 
-nsIPresShell::nsIPresShell()
+PresShell::PresShell()
     : mViewManager(nullptr),
       mFrameManager(nullptr),
+      mAutoWeakFrames(nullptr),
+#ifdef ACCESSIBILITY
+      mDocAccessible(nullptr),
+#endif  // #ifdef ACCESSIBILITY
+      mCurrentEventFrame(nullptr),
+      mMouseLocation(NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE),
       mPaintCount(0),
-      mAutoWeakFrames(nullptr),
+      mAPZFocusSequenceNumber(0),
       mCanvasBackgroundColor(NS_RGBA(0, 0, 0, 0)),
-      mSelectionFlags(0),
+      mActiveSuppressDisplayport(0),
+      mPresShellId(sNextPresShellId++),
+      mFontSizeInflationEmPerLine(0),
+      mFontSizeInflationMinTwips(0),
+      mFontSizeInflationLineThreshold(0),
+      mSelectionFlags(nsISelectionDisplay::DISPLAY_TEXT |
+                      nsISelectionDisplay::DISPLAY_IMAGES),
       mChangeNestCount(0),
-      mRenderFlags(0),
+      mRenderingStateFlags(RenderingStateFlags::None),
+      mInFlush(false),
+      mCaretEnabled(false),
+      mNeedLayoutFlush(true),
+      mNeedStyleFlush(true),
+      mNeedThrottledAnimationFlush(true),
+      mVisualViewportSizeSet(false),
       mDidInitialize(false),
       mIsDestroying(false),
       mIsReflowing(false),
       mIsObservingDocument(false),
       mForbiddenToFlush(false),
       mIsDocumentGone(false),
       mHaveShutDown(false),
       mPaintingSuppressed(false),
       mLastRootReflowHadUnconstrainedBSize(false),
       mShouldUnsuppressPainting(false),
       mIgnoreFrameDestruction(false),
-      mIsActive(false),
+      mIsActive(true),
       mFrozen(false),
-      mIsFirstPaint(false),
+      mIsFirstPaint(true),  // FIXME/bug 735029: find a better solution
       mObservesMutationsForPrint(false),
       mWasLastReflowInterrupted(false),
       mObservingStyleFlushes(false),
       mObservingLayoutFlushes(false),
       mResizeEventPending(false),
       mFontSizeInflationForceEnabled(false),
       mFontSizeInflationDisabledInMasterProcess(false),
       mFontSizeInflationEnabled(false),
       mPaintingIsFrozen(false),
       mIsNeverPainting(false),
       mResolutionUpdated(false),
       mResolutionUpdatedByApz(false),
-      mPresShellId(0),
-      mFontSizeInflationEmPerLine(0),
-      mFontSizeInflationMinTwips(0),
-      mFontSizeInflationLineThreshold(0),
-      mInFlush(false),
-      mCurrentEventFrame(nullptr) {
-}
-
-PresShell::PresShell()
-    : mCaretEnabled(false),
-      mMouseLocation(NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE),
-#ifdef ACCESSIBILITY
-      mDocAccessible(nullptr),
-#endif  // #ifdef ACCESSIBILITY
-      mAPZFocusSequenceNumber(0),
-      mActiveSuppressDisplayport(0),
-      mNeedLayoutFlush(true),
-      mNeedStyleFlush(true),
-      mNeedThrottledAnimationFlush(true),
-      mVisualViewportSizeSet(false),
       mDocumentLoading(false),
       mNoDelayedMouseEvents(false),
       mNoDelayedKeyEvents(false),
       mApproximateFrameVisibilityVisited(false),
       mNextPaintCompressed(false),
-      mHasCSSBackgroundColor(false),
+      mHasCSSBackgroundColor(true),
       mIsLastChromeOnlyEscapeKeyConsumed(false),
       mHasReceivedPaintMessage(false),
       mIsLastKeyDownCanceled(false),
       mHasHandledUserInput(false),
       mForceDispatchKeyPressEventsForNonPrintableKeys(false),
       mForceUseLegacyKeyCodeAndCharCodeValues(false),
       mInitializedWithKeyPressEventDispatchingBlacklist(false),
       mForceUseLegacyNonPrimaryDispatch(false),
@@ -840,36 +838,23 @@ PresShell::PresShell()
 
 #ifdef MOZ_REFLOW_PERF
   mReflowCountMgr = MakeUnique<ReflowCountMgr>();
   mReflowCountMgr->SetPresContext(mPresContext);
   mReflowCountMgr->SetPresShell(this);
 #endif
   mLastOSWake = mLoadBegin = TimeStamp::Now();
 
-  mSelectionFlags =
-      nsISelectionDisplay::DISPLAY_TEXT | nsISelectionDisplay::DISPLAY_IMAGES;
-  mIsActive = true;
-  // FIXME/bug 735029: find a better solution to this problem
-  mIsFirstPaint = true;
-  mPresShellId = sNextPresShellId++;
-  mFrozen = false;
-  mRenderFlags = 0;
-
   static bool addedSynthMouseMove = false;
   if (!addedSynthMouseMove) {
     Preferences::AddBoolVarCache(&sSynthMouseMove,
                                  "layout.reflow.synthMouseMove", true);
     addedSynthMouseMove = true;
   }
   PointerEventHandler::Initialize();
-  mPaintingIsFrozen = false;
-  mHasCSSBackgroundColor = true;
-  mIsLastChromeOnlyEscapeKeyConsumed = false;
-  mHasReceivedPaintMessage = false;
 }
 
 NS_INTERFACE_TABLE_HEAD(PresShell)
   NS_INTERFACE_TABLE_BEGIN
     // In most cases, PresShell should be treated as concrete class, but need to
     // QI for weak reference.  Therefore, the case needed by do_QueryReferent()
     // should be tested first.
     NS_INTERFACE_TABLE_ENTRY(PresShell, PresShell)
@@ -4508,22 +4493,20 @@ nsresult PresShell::RenderDocument(const
     }
   }
   if (!(aFlags & RenderDocumentFlags::DrawCaret)) {
     wouldFlushRetainedLayers = true;
     flags |= PaintFrameFlags::HideCaret;
   }
   if (aFlags & RenderDocumentFlags::IgnoreViewportScrolling) {
     wouldFlushRetainedLayers = !IgnoringViewportScrolling();
-    mRenderFlags =
-        ChangeFlag(mRenderFlags, true, STATE_IGNORING_VIEWPORT_SCROLLING);
+    mRenderingStateFlags |= RenderingStateFlags::IgnoringViewportScrolling;
   }
   if (aFlags & RenderDocumentFlags::DrawWindowNotFlushing) {
-    mRenderFlags =
-        ChangeFlag(mRenderFlags, true, STATE_DRAWWINDOW_NOT_FLUSHING);
+    mRenderingStateFlags |= RenderingStateFlags::DrawWindowNotFlushing;
   }
   if (aFlags & RenderDocumentFlags::DocumentRelative) {
     // XXX be smarter about this ... drawWindow might want a rect
     // that's "pretty close" to what our retained layer tree covers.
     // In that case, it wouldn't disturb normal rendering too much,
     // and we should allow it.
     wouldFlushRetainedLayers = true;
     flags |= PaintFrameFlags::DocumentRelative;
@@ -5189,18 +5172,23 @@ bool PresShell::AsyncPanZoomEnabled() {
   return gfxPlatform::AsyncPanZoomEnabled();
 }
 
 void PresShell::SetIgnoreViewportScrolling(bool aIgnore) {
   if (IgnoringViewportScrolling() == aIgnore) {
     return;
   }
   RenderingState state(this);
-  state.mRenderFlags = ChangeFlag(state.mRenderFlags, aIgnore,
-                                  STATE_IGNORING_VIEWPORT_SCROLLING);
+  if (aIgnore) {
+    state.mRenderingStateFlags |=
+        RenderingStateFlags::IgnoringViewportScrolling;
+  } else {
+    state.mRenderingStateFlags &=
+        ~RenderingStateFlags::IgnoringViewportScrolling;
+  }
   SetRenderingState(state);
 }
 
 nsresult PresShell::SetResolutionAndScaleTo(float aResolution,
                                             ResolutionChangeOrigin aOrigin) {
   if (!(aResolution > 0.0)) {
     return NS_ERROR_ILLEGAL_VALUE;
   }
@@ -5257,17 +5245,17 @@ float PresShell::GetCumulativeNonRootSca
 void PresShell::SetRestoreResolution(float aResolution,
                                      LayoutDeviceIntSize aDisplaySize) {
   if (mMobileViewportManager) {
     mMobileViewportManager->SetRestoreResolution(aResolution, aDisplaySize);
   }
 }
 
 void PresShell::SetRenderingState(const RenderingState& aState) {
-  if (mRenderFlags != aState.mRenderFlags) {
+  if (mRenderingStateFlags != aState.mRenderingStateFlags) {
     // Rendering state changed in a way that forces us to flush any
     // retained layers we might already have.
     LayerManager* manager = GetLayerManager();
     if (manager) {
       FrameLayerBuilder::InvalidateAllLayers(manager);
     }
   }
 
@@ -5281,17 +5269,17 @@ void PresShell::SetRenderingState(const 
     if (nsIFrame* frame = GetRootFrame()) {
       frame = nsLayoutUtils::GetCrossDocParentFrame(frame);
       if (frame) {
         frame->InvalidateFrame();
       }
     }
   }
 
-  mRenderFlags = aState.mRenderFlags;
+  mRenderingStateFlags = aState.mRenderingStateFlags;
   mResolution = aState.mResolution;
 }
 
 void PresShell::SynthesizeMouseMove(bool aFromScroll) {
   if (!sSynthMouseMove) return;
 
   if (mPaintingSuppressed || !mIsActive || !mPresContext) {
     return;
--- a/layout/base/PresShell.h
+++ b/layout/base/PresShell.h
@@ -61,18 +61,22 @@ class OverflowChangedTracker;
       0xa5, 0x3a, 0x38, 0x8c, 0xb1, 0x29, 0xb0, 0x52 \
     }                                                \
   }
 
 class PresShell final : public nsIPresShell,
                         public nsISelectionController,
                         public nsIObserver,
                         public nsSupportsWeakReference {
+  typedef dom::Document Document;
+  typedef dom::Element Element;
+  typedef gfx::SourceSurface SourceSurface;
   typedef layers::FocusTarget FocusTarget;
-  typedef dom::Element Element;
+  typedef layers::FrameMetrics FrameMetrics;
+  typedef layers::LayerManager LayerManager;
 
   // A set type for tracking visible frames, for use by the visibility code in
   // PresShell. The set contains nsIFrame* pointers.
   typedef nsTHashtable<nsPtrHashKey<nsIFrame>> VisibleFrames;
 
  public:
   PresShell();
 
@@ -858,17 +862,18 @@ class PresShell final : public nsIPresSh
 
   /**
    * Track whether we're ignoring viewport scrolling for the purposes
    * of painting.  If we are ignoring, then layers aren't clipped to
    * the CSS viewport and scrollbars aren't drawn.
    */
   void SetIgnoreViewportScrolling(bool aIgnore);
   bool IgnoringViewportScrolling() const {
-    return mRenderFlags & STATE_IGNORING_VIEWPORT_SCROLLING;
+    return !!(mRenderingStateFlags &
+              RenderingStateFlags::IgnoringViewportScrolling);
   }
 
   float GetResolution() const { return mResolution.valueOr(1.0); }
   float GetCumulativeResolution();
 
   /**
    * Accessors for a flag that tracks whether the most recent change to
    * the pres shell's resolution was originated by the main thread.
@@ -894,17 +899,18 @@ class PresShell final : public nsIPresSh
   void SetRestoreResolution(float aResolution,
                             LayoutDeviceIntSize aDisplaySize);
 
   /**
    * Returns whether we are in a DrawWindow() call that used the
    * DRAWWINDOW_DO_NOT_FLUSH flag.
    */
   bool InDrawWindowNotFlushing() const {
-    return mRenderFlags & STATE_DRAWWINDOW_NOT_FLUSHING;
+    return !!(mRenderingStateFlags &
+              RenderingStateFlags::DrawWindowNotFlushing);
   }
 
   /**
    * Set the isFirstPaint flag.
    */
   void SetIsFirstPaint(bool aIsFirstPaint) { mIsFirstPaint = aIsFirstPaint; }
 
   /**
@@ -1690,44 +1696,37 @@ class PresShell final : public nsIPresSh
    * Implementation methods for FlushPendingNotifications.
    */
   MOZ_CAN_RUN_SCRIPT void DoFlushPendingNotifications(FlushType aType);
   MOZ_CAN_RUN_SCRIPT void DoFlushPendingNotifications(ChangesToFlush aType);
 
   struct RenderingState {
     explicit RenderingState(PresShell* aPresShell)
         : mResolution(aPresShell->mResolution),
-          mRenderFlags(aPresShell->mRenderFlags) {}
+          mRenderingStateFlags(aPresShell->mRenderingStateFlags) {}
     Maybe<float> mResolution;
-    RenderFlags mRenderFlags;
+    RenderingStateFlags mRenderingStateFlags;
   };
 
   struct AutoSaveRestoreRenderingState {
     explicit AutoSaveRestoreRenderingState(PresShell* aPresShell)
         : mPresShell(aPresShell), mOldState(aPresShell) {}
 
     ~AutoSaveRestoreRenderingState() {
-      mPresShell->mRenderFlags = mOldState.mRenderFlags;
+      mPresShell->mRenderingStateFlags = mOldState.mRenderingStateFlags;
       mPresShell->mResolution = mOldState.mResolution;
     }
 
     PresShell* mPresShell;
     RenderingState mOldState;
   };
-  static RenderFlags ChangeFlag(RenderFlags aFlags, bool aOnOff,
-                                eRenderFlag aFlag) {
-    return aOnOff ? (aFlags | aFlag) : (aFlag & ~aFlag);
-  }
-
   void SetRenderingState(const RenderingState& aState);
 
   friend class ::nsPresShellEventCB;
 
-  bool mCaretEnabled;
-
   // methods for painting a range to an offscreen buffer
 
   // given a display list, clip the items within the list to
   // the range
   nsRect ClipListToRange(nsDisplayListBuilder* aBuilder, nsDisplayList* aList,
                          nsRange* aRange);
 
   // create a RangePaintInfo for the range aRange containing the
@@ -2666,50 +2665,130 @@ class PresShell final : public nsIPresSh
   bool mInVerifyReflow = false;
   // The reflow root under which we're currently reflowing.  Null when
   // not in reflow.
   nsIFrame* mCurrentReflowRoot = nullptr;
 
   nsIFrame* mDrawEventTargetFrame = nullptr;
 #endif  // #ifdef DEBUG
 
-  // This is used for synthetic mouse events that are sent when what is under
-  // the mouse pointer may have changed without the mouse moving (eg scrolling,
-  // change to the document contents).
-  // It is set only on a presshell for a root document, this value represents
-  // the last observed location of the mouse relative to that root document. It
-  // is set to (NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE) if the mouse isn't
-  // over our window or there is no last observed mouse location for some
-  // reason.
-  nsPoint mMouseLocation;
-  // This is an APZ state variable that tracks the target guid for the last
-  // mouse event that was processed (corresponding to mMouseLocation). This is
-  // needed for the synthetic mouse events.
-  layers::ScrollableLayerGuid mMouseEventTargetGuid;
+ private:
+  // IMPORTANT: The ownership implicit in the following member variables
+  // has been explicitly checked.  If you add any members to this class,
+  // please make the ownership explicit (pinkerton, scc).
+
+  // These are the same Document and PresContext owned by the DocViewer.
+  // we must share ownership.
+  RefPtr<Document> mDocument;
+  RefPtr<nsPresContext> mPresContext;
+  // The document's style set owns it but we maintain a ref, may be null.
+  RefPtr<StyleSheet> mPrefStyleSheet;
+  UniquePtr<nsCSSFrameConstructor> mFrameConstructor;
+  nsViewManager* mViewManager;  // [WEAK] docViewer owns it so I don't have to
+  RefPtr<nsFrameSelection> mSelection;
+  RefPtr<nsCaret> mCaret;
+  RefPtr<nsCaret> mOriginalCaret;
+  RefPtr<AccessibleCaretEventHub> mAccessibleCaretEventHub;
+  // Pointer into mFrameConstructor - this is purely so that GetRootFrame() can
+  // be inlined:
+  nsFrameManager* mFrameManager;
+  WeakPtr<nsDocShell> mForwardingContainer;
+
+  // The `performance.now()` value when we last started to process reflows.
+  DOMHighResTimeStamp mLastReflowStart{0.0};
+
+  // At least on Win32 and Mac after interupting a reflow we need to post
+  // the resume reflow event off a timer to avoid event starvation because
+  // posted messages are processed before other messages when the modal
+  // moving/sizing loop is running, see bug 491700 for details.
+  nsCOMPtr<nsITimer> mReflowContinueTimer;
+
+#ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
+  // We track allocated pointers in a debug-only hashtable to assert against
+  // missing/double frees.
+  nsTHashtable<nsPtrHashKey<void>> mAllocatedPointers;
+#endif
+
+  // A list of stack weak frames. This is a pointer to the last item in the
+  // list.
+  AutoWeakFrame* mAutoWeakFrames;
+
+  // A hash table of heap allocated weak frames.
+  nsTHashtable<nsPtrHashKey<WeakFrame>> mWeakFrames;
+
+  class DirtyRootsList {
+   public:
+    // Add a dirty root.
+    void Add(nsIFrame* aFrame);
+    // Remove this frame if present.
+    void Remove(nsIFrame* aFrame);
+    // Remove and return one of the shallowest dirty roots from the list.
+    // (If two roots are at the same depth, order is indeterminate.)
+    nsIFrame* PopShallowestRoot();
+    // Remove all dirty roots.
+    void Clear();
+    // Is this frame one of the dirty roots?
+    bool Contains(nsIFrame* aFrame) const;
+    // Are there no dirty roots?
+    bool IsEmpty() const;
+    // Is the given frame an ancestor of any dirty root?
+    bool FrameIsAncestorOfDirtyRoot(nsIFrame* aFrame) const;
+
+   private:
+    struct FrameAndDepth {
+      nsIFrame* mFrame;
+      const uint32_t mDepth;
+
+      // Easy conversion to nsIFrame*, as it's the most likely need.
+      operator nsIFrame*() const { return mFrame; }
+
+      // Used to sort by reverse depths, i.e., deeper < shallower.
+      class CompareByReverseDepth {
+       public:
+        bool Equals(const FrameAndDepth& aA, const FrameAndDepth& aB) const {
+          return aA.mDepth == aB.mDepth;
+        }
+        bool LessThan(const FrameAndDepth& aA, const FrameAndDepth& aB) const {
+          // Reverse depth! So '>' instead of '<'.
+          return aA.mDepth > aB.mDepth;
+        }
+      };
+    };
+    // List of all known dirty roots, sorted by decreasing depths.
+    nsTArray<FrameAndDepth> mList;
+  };
+
+  // Reflow roots that need to be reflowed.
+  DirtyRootsList mDirtyRoots;
+
+#ifdef MOZ_GECKO_PROFILER
+  // These two fields capture call stacks of any changes that require a restyle
+  // or a reflow. Only the first change per restyle / reflow is recorded (the
+  // one that caused a call to SetNeedStyleFlush() / SetNeedLayoutFlush()).
+  UniqueProfilerBacktrace mStyleCause;
+  UniqueProfilerBacktrace mReflowCause;
+#endif
 
   nsTArray<UniquePtr<DelayedEvent>> mDelayedEvents;
 
- private:
   nsRevocableEventPtr<nsSynthMouseMoveEvent> mSynthMouseMoveEvent;
 
   TouchManager mTouchManager;
 
   RefPtr<ZoomConstraintsClient> mZoomConstraintsClient;
   RefPtr<GeckoMVMContext> mMVMContext;
   RefPtr<MobileViewportManager> mMobileViewportManager;
 
   // This timer controls painting suppression.  Until it fires
   // or all frames are constructed, we won't paint anything but
   // our <body> background and scrollbars.
   nsCOMPtr<nsITimer> mPaintSuppressionTimer;
 
   nsCOMPtr<nsITimer> mDelayedPaintTimer;
 
-  TimeStamp mLoadBegin;  // used to time loads
-
   // Information about live content (which still stay in DOM tree).
   // Used in case we need re-dispatch event after sending pointer event,
   // when target of pointer event was deleted during executing user handlers.
   nsCOMPtr<nsIContent> mPointerEventTarget;
 
   nsCOMPtr<nsIContent> mLastAnchorScrolledTo;
 
   // Information needed to properly handle scrolling content into view if the
@@ -2718,48 +2797,184 @@ class PresShell final : public nsIPresSh
   // all our dirty roots.  mContentToScrollTo has a content property storing the
   // details for the scroll operation, see ScrollIntoViewData above.
   nsCOMPtr<nsIContent> mContentToScrollTo;
 
 #ifdef ACCESSIBILITY
   a11y::DocAccessible* mDocAccessible;
 #endif  // #ifdef ACCESSIBILITY
 
+  nsIFrame* mCurrentEventFrame;
+  nsCOMPtr<nsIContent> mCurrentEventContent;
+  nsTArray<nsIFrame*> mCurrentEventFrameStack;
+  nsCOMArray<nsIContent> mCurrentEventContentStack;
+  // Set of frames that we should mark with NS_FRAME_HAS_DIRTY_CHILDREN after
+  // we finish reflowing mCurrentReflowRoot.
+  nsTHashtable<nsPtrHashKey<nsIFrame>> mFramesToDirty;
+  nsTHashtable<nsPtrHashKey<nsIScrollableFrame>> mPendingScrollAnchorSelection;
+  nsTHashtable<nsPtrHashKey<nsIScrollableFrame>> mPendingScrollAnchorAdjustment;
+
+  nsCallbackEventRequest* mFirstCallbackEventRequest = nullptr;
+  nsCallbackEventRequest* mLastCallbackEventRequest = nullptr;
+
+  // This is used for synthetic mouse events that are sent when what is under
+  // the mouse pointer may have changed without the mouse moving (eg scrolling,
+  // change to the document contents).
+  // It is set only on a presshell for a root document, this value represents
+  // the last observed location of the mouse relative to that root document. It
+  // is set to (NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE) if the mouse isn't
+  // over our window or there is no last observed mouse location for some
+  // reason.
+  nsPoint mMouseLocation;
+  // This is an APZ state variable that tracks the target guid for the last
+  // mouse event that was processed (corresponding to mMouseLocation). This is
+  // needed for the synthetic mouse events.
+  layers::ScrollableLayerGuid mMouseEventTargetGuid;
+
   nsSize mVisualViewportSize;
 
+  // The focus information needed for async keyboard scrolling
+  FocusTarget mAPZFocusTarget;
+
+  nsPresArena<8192> mFrameArena;
+
   Maybe<nsPoint> mVisualViewportOffset;
 
   // A pending visual scroll offset that we will ask APZ to scroll to
   // during the next transaction. Cleared when we send the transaction.
   // Only applicable to the RCD pres shell.
   Maybe<VisualScrollUpdate> mPendingVisualScrollUpdate;
 
+  // Used to force allocation and rendering of proportionally more or
+  // less pixels in both dimensions.
+  Maybe<float> mResolution;
+
+  TimeStamp mLoadBegin;  // used to time loads
+
   TimeStamp mLastOSWake;
 
+  // Count of the number of times this presshell has been painted to a window.
+  uint64_t mPaintCount;
+
   // The focus sequence number of the last processed input event
   uint64_t mAPZFocusSequenceNumber;
-  // The focus information needed for async keyboard scrolling
-  FocusTarget mAPZFocusTarget;
 
   nscoord mLastAnchorScrollPositionY = 0;
 
+  // Most recent canvas background color.
+  nscolor mCanvasBackgroundColor;
+
   int32_t mActiveSuppressDisplayport;
 
+  uint32_t mPresShellId;
+
+  // Cached font inflation values. This is done to prevent changing of font
+  // inflation until a page is reloaded.
+  uint32_t mFontSizeInflationEmPerLine;
+  uint32_t mFontSizeInflationMinTwips;
+  uint32_t mFontSizeInflationLineThreshold;
+
+  int16_t mSelectionFlags;
+
+  // This is used to protect ourselves from triggering reflow while in the
+  // middle of frame construction and the like... it really shouldn't be
+  // needed, one hopes, but it is for now.
+  uint16_t mChangeNestCount;
+
+  // Flags controlling how our document is rendered.  These persist
+  // between paints and so are tied with retained layer pixels.
+  // PresShell flushes retained layers when the rendering state
+  // changes in a way that prevents us from being able to (usefully)
+  // re-use old pixels.
+  RenderingStateFlags mRenderingStateFlags;
+
+  // Whether we're currently under a FlushPendingNotifications.
+  // This is used to handle flush reentry correctly.
+  // NOTE: This can't be a bitfield since AutoRestore has a reference to this
+  // variable.
+  bool mInFlush;
+
+  bool mCaretEnabled : 1;
+
   // True if a layout flush might not be a no-op
   bool mNeedLayoutFlush : 1;
 
   // True if a style flush might not be a no-op
   bool mNeedStyleFlush : 1;
 
   // True if there are throttled animations that would be processed when
   // performing a flush with mFlushAnimations == true.
   bool mNeedThrottledAnimationFlush : 1;
 
   bool mVisualViewportSizeSet : 1;
 
+  bool mDidInitialize : 1;
+  bool mIsDestroying : 1;
+  bool mIsReflowing : 1;
+  bool mIsObservingDocument : 1;
+
+  // Whether we shouldn't ever get to FlushPendingNotifications. This flag is
+  // meant only to sanity-check / assert that FlushPendingNotifications doesn't
+  // happen during certain periods of time. It shouldn't be made public nor used
+  // for other purposes.
+  bool mForbiddenToFlush : 1;
+
+  // We've been disconnected from the document.  We will refuse to paint the
+  // document until either our timer fires or all frames are constructed.
+  bool mIsDocumentGone : 1;
+  bool mHaveShutDown : 1;
+
+  // For all documents we initially lock down painting.
+  bool mPaintingSuppressed : 1;
+
+  bool mLastRootReflowHadUnconstrainedBSize : 1;
+
+  // Indicates that it is safe to unlock painting once all pending reflows
+  // have been processed.
+  bool mShouldUnsuppressPainting : 1;
+
+  bool mIgnoreFrameDestruction : 1;
+
+  bool mIsActive : 1;
+  bool mFrozen : 1;
+  bool mIsFirstPaint : 1;
+  bool mObservesMutationsForPrint : 1;
+
+  // Whether the most recent interruptible reflow was actually interrupted:
+  bool mWasLastReflowInterrupted : 1;
+
+  // True if we're observing the refresh driver for style flushes.
+  bool mObservingStyleFlushes : 1;
+
+  // True if we're observing the refresh driver for layout flushes, that is, if
+  // we have a reflow scheduled.
+  //
+  // Guaranteed to be false if mReflowContinueTimer is non-null.
+  bool mObservingLayoutFlushes : 1;
+
+  bool mResizeEventPending : 1;
+
+  bool mFontSizeInflationForceEnabled : 1;
+  bool mFontSizeInflationDisabledInMasterProcess : 1;
+  bool mFontSizeInflationEnabled : 1;
+
+  bool mPaintingIsFrozen : 1;
+
+  // If a document belongs to an invisible DocShell, this flag must be set
+  // to true, so we can avoid any paint calls for widget related to this
+  // presshell.
+  bool mIsNeverPainting : 1;
+
+  // Whether the most recent change to the pres shell resolution was
+  // originated by the main thread.
+  bool mResolutionUpdated : 1;
+
+  // True if the resolution has been ever changed by APZ.
+  bool mResolutionUpdatedByApz : 1;
+
   bool mDocumentLoading : 1;
   bool mNoDelayedMouseEvents : 1;
   bool mNoDelayedKeyEvents : 1;
 
   bool mApproximateFrameVisibilityVisited : 1;
 
   bool mNextPaintCompressed : 1;
 
--- a/layout/base/PresShellForwards.h
+++ b/layout/base/PresShellForwards.h
@@ -209,16 +209,27 @@ enum class PaintFlags {
   PaintSyncDecodeImages = 1 << 2,
 };
 
 MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(PaintFlags)
 
 // See comment at declaration of ScheduleViewManagerFlush() for the detail.
 enum class PaintType { Default, DelayedCompress };
 
+// This is a private enum class of PresShell, but currently,
+// MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS isn't available in class definition.
+// Therefore, we need to put this here.
+enum class RenderingStateFlags : uint8_t {
+  None = 0,
+  IgnoringViewportScrolling = 1 << 0,
+  DrawWindowNotFlushing = 1 << 1,
+};
+
+MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(RenderingStateFlags)
+
 #ifdef DEBUG
 
 enum class VerifyReflowFlags {
   None = 0,
   On = 1 << 0,
   Noisy = 1 << 1,
   All = 1 << 2,
   DumpCommands = 1 << 3,
--- a/layout/base/nsIPresShell.h
+++ b/layout/base/nsIPresShell.h
@@ -148,238 +148,14 @@ class SourceSurface;
  * presentation context, the style manager, the style set and the root
  * frame.
  */
 
 class nsIPresShell : public nsStubDocumentObserver {
  public:
   NS_DECLARE_STATIC_IID_ACCESSOR(NS_IPRESSHELL_IID)
 
- protected:
-  typedef mozilla::dom::Document Document;
-  typedef mozilla::layers::FrameMetrics FrameMetrics;
-  typedef mozilla::layers::LayerManager LayerManager;
-  typedef mozilla::gfx::SourceSurface SourceSurface;
-
-  enum eRenderFlag {
-    STATE_IGNORING_VIEWPORT_SCROLLING = 0x1,
-    STATE_DRAWWINDOW_NOT_FLUSHING = 0x2
-  };
-  typedef uint8_t RenderFlags;  // for storing the above flags
-
- public:
-  nsIPresShell();
-
- protected:
-  // IMPORTANT: The ownership implicit in the following member variables
-  // has been explicitly checked.  If you add any members to this class,
-  // please make the ownership explicit (pinkerton, scc).
-
-  // These are the same Document and PresContext owned by the DocViewer.
-  // we must share ownership.
-  RefPtr<Document> mDocument;
-  RefPtr<nsPresContext> mPresContext;
-  // The document's style set owns it but we maintain a ref, may be null.
-  RefPtr<mozilla::StyleSheet> mPrefStyleSheet;
-  mozilla::UniquePtr<nsCSSFrameConstructor> mFrameConstructor;
-  nsViewManager* mViewManager;  // [WEAK] docViewer owns it so I don't have to
-  nsPresArena<8192> mFrameArena;
-  RefPtr<nsFrameSelection> mSelection;
-  RefPtr<nsCaret> mCaret;
-  RefPtr<nsCaret> mOriginalCaret;
-  RefPtr<mozilla::AccessibleCaretEventHub> mAccessibleCaretEventHub;
-  // Pointer into mFrameConstructor - this is purely so that GetRootFrame() can
-  // be inlined:
-  nsFrameManager* mFrameManager;
-  mozilla::WeakPtr<nsDocShell> mForwardingContainer;
-
-  // The `performance.now()` value when we last started to process reflows.
-  DOMHighResTimeStamp mLastReflowStart{0.0};
-
-  // At least on Win32 and Mac after interupting a reflow we need to post
-  // the resume reflow event off a timer to avoid event starvation because
-  // posted messages are processed before other messages when the modal
-  // moving/sizing loop is running, see bug 491700 for details.
-  nsCOMPtr<nsITimer> mReflowContinueTimer;
-
-#ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
-  // We track allocated pointers in a debug-only hashtable to assert against
-  // missing/double frees.
-  nsTHashtable<nsPtrHashKey<void>> mAllocatedPointers;
-#endif
-
-  // Count of the number of times this presshell has been painted to a window.
-  uint64_t mPaintCount;
-
-  // A list of stack weak frames. This is a pointer to the last item in the
-  // list.
-  AutoWeakFrame* mAutoWeakFrames;
-
-  // A hash table of heap allocated weak frames.
-  nsTHashtable<nsPtrHashKey<WeakFrame>> mWeakFrames;
-
-  class DirtyRootsList {
-   public:
-    // Add a dirty root.
-    void Add(nsIFrame* aFrame);
-    // Remove this frame if present.
-    void Remove(nsIFrame* aFrame);
-    // Remove and return one of the shallowest dirty roots from the list.
-    // (If two roots are at the same depth, order is indeterminate.)
-    nsIFrame* PopShallowestRoot();
-    // Remove all dirty roots.
-    void Clear();
-    // Is this frame one of the dirty roots?
-    bool Contains(nsIFrame* aFrame) const;
-    // Are there no dirty roots?
-    bool IsEmpty() const;
-    // Is the given frame an ancestor of any dirty root?
-    bool FrameIsAncestorOfDirtyRoot(nsIFrame* aFrame) const;
-
-   private:
-    struct FrameAndDepth {
-      nsIFrame* mFrame;
-      const uint32_t mDepth;
-
-      // Easy conversion to nsIFrame*, as it's the most likely need.
-      operator nsIFrame*() const { return mFrame; }
-
-      // Used to sort by reverse depths, i.e., deeper < shallower.
-      class CompareByReverseDepth {
-       public:
-        bool Equals(const FrameAndDepth& aA, const FrameAndDepth& aB) const {
-          return aA.mDepth == aB.mDepth;
-        }
-        bool LessThan(const FrameAndDepth& aA, const FrameAndDepth& aB) const {
-          // Reverse depth! So '>' instead of '<'.
-          return aA.mDepth > aB.mDepth;
-        }
-      };
-    };
-    // List of all known dirty roots, sorted by decreasing depths.
-    nsTArray<FrameAndDepth> mList;
-  };
-
-  // Reflow roots that need to be reflowed.
-  DirtyRootsList mDirtyRoots;
-
-#ifdef MOZ_GECKO_PROFILER
-  // These two fields capture call stacks of any changes that require a restyle
-  // or a reflow. Only the first change per restyle / reflow is recorded (the
-  // one that caused a call to SetNeedStyleFlush() / SetNeedLayoutFlush()).
-  UniqueProfilerBacktrace mStyleCause;
-  UniqueProfilerBacktrace mReflowCause;
-#endif
-
-  // Most recent canvas background color.
-  nscolor mCanvasBackgroundColor;
-
-  // Used to force allocation and rendering of proportionally more or
-  // less pixels in both dimensions.
-  mozilla::Maybe<float> mResolution;
-
-  int16_t mSelectionFlags;
-
-  // This is used to protect ourselves from triggering reflow while in the
-  // middle of frame construction and the like... it really shouldn't be
-  // needed, one hopes, but it is for now.
-  uint16_t mChangeNestCount;
-
-  // Flags controlling how our document is rendered.  These persist
-  // between paints and so are tied with retained layer pixels.
-  // PresShell flushes retained layers when the rendering state
-  // changes in a way that prevents us from being able to (usefully)
-  // re-use old pixels.
-  RenderFlags mRenderFlags;
-  bool mDidInitialize : 1;
-  bool mIsDestroying : 1;
-  bool mIsReflowing : 1;
-  bool mIsObservingDocument : 1;
-  // Whether we shouldn't ever get to FlushPendingNotifications. This flag is
-  // meant only to sanity-check / assert that FlushPendingNotifications doesn't
-  // happen during certain periods of time. It shouldn't be made public nor used
-  // for other purposes.
-  bool mForbiddenToFlush : 1;
-
-  // We've been disconnected from the document.  We will refuse to paint the
-  // document until either our timer fires or all frames are constructed.
-  bool mIsDocumentGone : 1;
-  bool mHaveShutDown : 1;
-
-  // For all documents we initially lock down painting.
-  bool mPaintingSuppressed : 1;
-
-  bool mLastRootReflowHadUnconstrainedBSize : 1;
-
-  // Indicates that it is safe to unlock painting once all pending reflows
-  // have been processed.
-  bool mShouldUnsuppressPainting : 1;
-
-  bool mIgnoreFrameDestruction : 1;
-
-  bool mIsActive : 1;
-  bool mFrozen : 1;
-  bool mIsFirstPaint : 1;
-  bool mObservesMutationsForPrint : 1;
-
-  // Whether the most recent interruptible reflow was actually interrupted:
-  bool mWasLastReflowInterrupted : 1;
-
-  // True if we're observing the refresh driver for style flushes.
-  bool mObservingStyleFlushes : 1;
-
-  // True if we're observing the refresh driver for layout flushes, that is, if
-  // we have a reflow scheduled.
-  //
-  // Guaranteed to be false if mReflowContinueTimer is non-null.
-  bool mObservingLayoutFlushes : 1;
-
-  bool mResizeEventPending : 1;
-
-  bool mFontSizeInflationForceEnabled : 1;
-  bool mFontSizeInflationDisabledInMasterProcess : 1;
-  bool mFontSizeInflationEnabled : 1;
-
-  bool mPaintingIsFrozen : 1;
-
-  // If a document belongs to an invisible DocShell, this flag must be set
-  // to true, so we can avoid any paint calls for widget related to this
-  // presshell.
-  bool mIsNeverPainting : 1;
-
-  // Whether the most recent change to the pres shell resolution was
-  // originated by the main thread.
-  bool mResolutionUpdated : 1;
-
-  // True if the resolution has been ever changed by APZ.
-  bool mResolutionUpdatedByApz : 1;
-
-  uint32_t mPresShellId;
-
-  // Cached font inflation values. This is done to prevent changing of font
-  // inflation until a page is reloaded.
-  uint32_t mFontSizeInflationEmPerLine;
-  uint32_t mFontSizeInflationMinTwips;
-  uint32_t mFontSizeInflationLineThreshold;
-
-  // Whether we're currently under a FlushPendingNotifications.
-  // This is used to handle flush reentry correctly.
-  // NOTE: This can't be a bitfield since AutoRestore has a reference to this
-  // variable.
-  bool mInFlush;
-
-  nsIFrame* mCurrentEventFrame;
-  nsCOMPtr<nsIContent> mCurrentEventContent;
-  nsTArray<nsIFrame*> mCurrentEventFrameStack;
-  nsCOMArray<nsIContent> mCurrentEventContentStack;
-  // Set of frames that we should mark with NS_FRAME_HAS_DIRTY_CHILDREN after
-  // we finish reflowing mCurrentReflowRoot.
-  nsTHashtable<nsPtrHashKey<nsIFrame>> mFramesToDirty;
-  nsTHashtable<nsPtrHashKey<nsIScrollableFrame>> mPendingScrollAnchorSelection;
-  nsTHashtable<nsPtrHashKey<nsIScrollableFrame>> mPendingScrollAnchorAdjustment;
-
-  nsCallbackEventRequest* mFirstCallbackEventRequest = nullptr;
-  nsCallbackEventRequest* mLastCallbackEventRequest = nullptr;
+  nsIPresShell() = default;
 };
 
 NS_DEFINE_STATIC_IID_ACCESSOR(nsIPresShell, NS_IPRESSHELL_IID)
 
 #endif /* nsIPresShell_h___ */
--- a/servo/components/style/gecko/media_queries.rs
+++ b/servo/components/style/gecko/media_queries.rs
@@ -164,17 +164,16 @@ impl Device {
 
     /// Gets the pres context associated with this document.
     #[inline]
     pub fn pres_context(&self) -> Option<&structs::nsPresContext> {
         unsafe {
             self.document()
                 .mPresShell
                 .as_ref()?
-                ._base
                 .mPresContext
                 .mRawPtr
                 .as_ref()
         }
     }
 
     /// Gets the preference stylesheet prefs for our document.
     #[inline]