Bug 1267568 part 4 - Replace InFullscreenChange flag of PresShell with IsResizeSuppressed flag in RefreshDriver. r=smaug
authorXidorn Quan <quanxunzhen@gmail.com>
Tue, 03 May 2016 17:58:57 +1000
changeset 334819 da3006dcfb7b7525ef19208d2d38d52c01f72bb3
parent 334818 ffcdd861062d2400e3991964bb151ad17f270faa
child 334820 522031a5febb97d77c84e967c9ee57262c1ef7bb
push id6249
push userjlund@mozilla.com
push dateMon, 01 Aug 2016 13:59:36 +0000
treeherdermozilla-beta@bad9d4f5bf7e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs1267568
milestone49.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 1267568 part 4 - Replace InFullscreenChange flag of PresShell with IsResizeSuppressed flag in RefreshDriver. r=smaug MozReview-Commit-ID: FB3vGXwKZ9O
dom/base/nsDOMWindowUtils.cpp
dom/base/nsGlobalWindow.cpp
layout/base/nsIPresShell.h
layout/base/nsPresShell.cpp
layout/base/nsRefreshDriver.cpp
layout/base/nsRefreshDriver.h
view/nsViewManager.cpp
--- a/dom/base/nsDOMWindowUtils.cpp
+++ b/dom/base/nsDOMWindowUtils.cpp
@@ -3069,36 +3069,31 @@ nsDOMWindowUtils::RemoteFrameFullscreenR
 class MOZ_STACK_CLASS FullscreenChangePrepare
 {
 public:
   FullscreenChangePrepare(nsIPresShell* aPresShell,
                           const nsSize& aSize, nsSize* aOldSize = nullptr)
     : mPresShell(aPresShell)
   {
     if (mPresShell) {
-      mPresShell->SetIsInFullscreenChange(true);
+      if (nsRefreshDriver* rd = mPresShell->GetRefreshDriver()) {
+        rd->SetIsResizeSuppressed();
+      }
     }
     if (aSize.IsEmpty()) {
       return;
     }
     if (nsViewManager* viewManager = mPresShell->GetViewManager()) {
       if (aOldSize) {
         viewManager->GetWindowDimensions(&aOldSize->width, &aOldSize->height);
       }
       viewManager->SetWindowDimensions(aSize.width, aSize.height);
     }
   }
 
-  ~FullscreenChangePrepare()
-  {
-    if (mPresShell) {
-      mPresShell->SetIsInFullscreenChange(false);
-    }
-  }
-
 private:
   nsCOMPtr<nsIPresShell> mPresShell;
 };
 
 class OldWindowSize : public LinkedListElement<OldWindowSize>
 {
 public:
   static void Set(nsPIDOMWindowOuter* aWindow, const nsSize& aSize)
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -6473,19 +6473,22 @@ nsGlobalWindow::SetWidgetFullscreen(Full
   MOZ_ASSERT(this == GetTopInternal(), "Only topmost window should call this");
   MOZ_ASSERT(!AsOuter()->GetFrameElementInternal(), "Content window should not call this");
   MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
 
   if (!NS_WARN_IF(!IsChromeWindow())) {
     auto chromeWin = static_cast<nsGlobalChromeWindow*>(this);
     if (!NS_WARN_IF(chromeWin->mFullscreenPresShell)) {
       if (nsIPresShell* shell = mDocShell->GetPresShell()) {
-        chromeWin->mFullscreenPresShell = do_GetWeakReference(shell);
-        MOZ_ASSERT(chromeWin->mFullscreenPresShell);
-        shell->SetIsInFullscreenChange(true);
+        if (nsRefreshDriver* rd = shell->GetRefreshDriver()) {
+          chromeWin->mFullscreenPresShell = do_GetWeakReference(shell);
+          MOZ_ASSERT(chromeWin->mFullscreenPresShell);
+          rd->SetIsResizeSuppressed();
+          rd->Freeze();
+        }
       }
     }
   }
   nsresult rv = aReason == FullscreenReason::ForFullscreenMode ?
     // If we enter fullscreen for fullscreen mode, we want
     // the native system behavior.
     aWidget->MakeFullScreenWithNativeTransition(aIsFullscreen, aScreen) :
     aWidget->MakeFullScreen(aIsFullscreen, aScreen);
@@ -6523,17 +6526,19 @@ nsGlobalWindow::FinishFullscreenChange(b
   // dispatch a "fullscreen" DOM event so that XUL apps can
   // respond visually if we are kicked into full screen mode
   DispatchCustomEvent(NS_LITERAL_STRING("fullscreen"));
 
   if (!NS_WARN_IF(!IsChromeWindow())) {
     auto chromeWin = static_cast<nsGlobalChromeWindow*>(this);
     if (nsCOMPtr<nsIPresShell> shell =
         do_QueryReferent(chromeWin->mFullscreenPresShell)) {
-      shell->SetIsInFullscreenChange(false);
+      if (nsRefreshDriver* rd = shell->GetRefreshDriver()) {
+        rd->Thaw();
+      }
       chromeWin->mFullscreenPresShell = nullptr;
     }
   }
 
   if (!mWakeLock && mFullScreen) {
     RefPtr<power::PowerManagerService> pmService =
       power::PowerManagerService::GetInstance();
     if (!pmService) {
--- a/layout/base/nsIPresShell.h
+++ b/layout/base/nsIPresShell.h
@@ -1607,19 +1607,16 @@ public:
    * Returns whether the document's style set's rule processor for the
    * specified level of the cascade is shared by multiple style sets.
    *
    * @param aSheetType One of the nsIStyleSheetService.*_SHEET constants.
    */
   nsresult HasRuleProcessorUsedByMultipleStyleSets(uint32_t aSheetType,
                                                    bool* aRetVal);
 
-  bool IsInFullscreenChange() const { return mIsInFullscreenChange; }
-  void SetIsInFullscreenChange(bool aValue);
-
   /**
    * Refresh observer management.
    */
 protected:
   virtual bool AddRefreshObserverExternal(nsARefreshObserver* aObserver,
                                           mozFlushType aFlushType);
   bool AddRefreshObserverInternal(nsARefreshObserver* aObserver,
                                   mozFlushType aFlushType);
@@ -1774,21 +1771,16 @@ protected:
   // style sheets are recorded in mChangedScopeStyleRoots rather than here
   // in mStylesHaveChanged.
   bool                      mStylesHaveChanged : 1;
   bool                      mDidInitialize : 1;
   bool                      mIsDestroying : 1;
   bool                      mIsZombie : 1;
   bool                      mIsReflowing : 1;
 
-  // Indicates that the whole document is performing fullscreen change,
-  // in which case, we need to defer dispatching resize event and freeze
-  // the refresh driver to avoid unnecessary reflow.
-  bool                      mIsInFullscreenChange : 1;
-
   // For all documents we initially lock down painting.
   bool                      mPaintingSuppressed : 1;
 
   // Whether or not form controls should use nsITheme in this shell.
   bool                      mIsThemeSupportDisabled : 1;
 
   bool                      mIsActive : 1;
   bool                      mFrozen : 1;
--- a/layout/base/nsPresShell.cpp
+++ b/layout/base/nsPresShell.cpp
@@ -11295,26 +11295,8 @@ nsIPresShell::HasRuleProcessorUsedByMult
 
   *aRetVal = false;
   if (nsStyleSet* styleSet = mStyleSet->GetAsGecko()) {
     // ServoStyleSets do not have rule processors.
     *aRetVal = styleSet->HasRuleProcessorUsedByMultipleStyleSets(type);
   }
   return NS_OK;
 }
-
-void
-nsIPresShell::SetIsInFullscreenChange(bool aValue)
-{
-  if (mIsInFullscreenChange == aValue) {
-    NS_WARNING(aValue ? "Pres shell has been in fullscreen change?" :
-               "Pres shell is not in fullscreen change?");
-    return;
-  }
-  mIsInFullscreenChange = aValue;
-  if (nsRefreshDriver* rd = mPresContext->RefreshDriver()) {
-    if (aValue) {
-      rd->Freeze();
-    } else {
-      rd->Thaw();
-    }
-  }
-}
--- a/layout/base/nsRefreshDriver.cpp
+++ b/layout/base/nsRefreshDriver.cpp
@@ -1016,17 +1016,18 @@ nsRefreshDriver::nsRefreshDriver(nsPresC
     mMinRecomputeVisibilityInterval(GetMinRecomputeVisibilityInterval()),
     mThrottled(false),
     mNeedToRecomputeVisibility(false),
     mTestControllingRefreshes(false),
     mViewManagerFlushIsPending(false),
     mRequestedHighPrecision(false),
     mInRefresh(false),
     mWaitingForTransaction(false),
-    mSkippedPaints(false)
+    mSkippedPaints(false),
+    mResizeSuppressed(false)
 {
   mMostRecentRefreshEpochTime = JS_Now();
   mMostRecentRefresh = TimeStamp::Now();
   mMostRecentTick = mMostRecentRefresh;
   mNextThrottledFrameRequestTick = mMostRecentTick;
   mNextRecomputeVisibilityTick = mMostRecentTick;
 }
 
@@ -1665,16 +1666,18 @@ nsRefreshDriver::Tick(int64_t aNowEpoch,
     // often depending on what other things are going on and in that
     // situation we don't want to thrash our timer.  So instead we
     // wait until we get a Notify() call when we have no observers
     // before stopping the timer.
     StopTimer();
     return;
   }
 
+  mResizeSuppressed = false;
+
   AutoRestore<bool> restoreInRefresh(mInRefresh);
   mInRefresh = true;
 
   AutoRestore<TimeStamp> restoreTickStart(mTickStart);
   mTickStart = TimeStamp::Now();
 
   gfxPlatform::GetPlatform()->SchedulePaintIfDeviceReset();
 
--- a/layout/base/nsRefreshDriver.h
+++ b/layout/base/nsRefreshDriver.h
@@ -299,16 +299,19 @@ public:
 
   /**
    * Default interval the refresh driver uses, in ms.
    */
   static int32_t DefaultInterval();
 
   bool IsInRefresh() { return mInRefresh; }
 
+  void SetIsResizeSuppressed() { mResizeSuppressed = true; }
+  bool IsResizeSuppressed() const { return mResizeSuppressed; }
+
   /**
    * The latest value of process-wide jank levels.
    *
    * For each i, sJankLevels[i] counts the number of times delivery of
    * vsync to the main thread has been delayed by at least 2^i
    * ms. This data structure has been designed to make it easy to
    * determine how much jank has taken place between two instants in
    * time.
@@ -415,16 +418,21 @@ private:
   // True if the refresh driver is suspended waiting for transaction
   // id's to be returned and shouldn't do any work during Tick().
   bool mWaitingForTransaction;
   // True if Tick() was skipped because of mWaitingForTransaction and
   // we should schedule a new Tick immediately when resumed instead
   // of waiting until the next interval.
   bool mSkippedPaints;
 
+  // True if view managers should delay any resize request until the
+  // next tick by the refresh driver. This flag will be reset at the
+  // start of every tick.
+  bool mResizeSuppressed;
+
   int64_t mMostRecentRefreshEpochTime;
   mozilla::TimeStamp mMostRecentRefresh;
   mozilla::TimeStamp mMostRecentTick;
   mozilla::TimeStamp mTickStart;
   mozilla::TimeStamp mNextThrottledFrameRequestTick;
   mozilla::TimeStamp mNextRecomputeVisibilityTick;
 
   // separate arrays for each flush type we support
--- a/view/nsViewManager.cpp
+++ b/view/nsViewManager.cpp
@@ -193,20 +193,24 @@ void nsViewManager::DoSetWindowDimension
   }
 }
 
 bool
 nsViewManager::ShouldDelayResize() const
 {
   MOZ_ASSERT(mRootView);
   if (!mRootView->IsEffectivelyVisible() ||
-      !mPresShell || !mPresShell->IsVisible() ||
-      mPresShell->IsInFullscreenChange()) {
+      !mPresShell || !mPresShell->IsVisible()) {
     return true;
   }
+  if (nsRefreshDriver* rd = mPresShell->GetRefreshDriver()) {
+    if (rd->IsResizeSuppressed()) {
+      return true;
+    }
+  }
   return false;
 }
 
 void
 nsViewManager::SetWindowDimensions(nscoord aWidth, nscoord aHeight)
 {
   if (mRootView) {
     if (!ShouldDelayResize()) {