Bug 1284350 - Revert "Bug 1259281 - Mark frames NONVISIBLE if their pres shell is inactive or frozen. r=mstange". a=lizzard
☠☠ backed out by ab6b685c5249 ☠ ☠
authorSeth Fowler <mark.seth.fowler@gmail.com>
Fri, 08 Jul 2016 17:53:41 -0700
changeset 341888 d44a440ae78d1184f942db0298777f5afe09a807
parent 341887 1855158bd62c34b5c931e9092f196b305d392382
child 341889 46963dffa40a98fc1cf17bd85c0397fca80889ec
push id1183
push userraliiev@mozilla.com
push dateMon, 05 Sep 2016 20:01:49 +0000
treeherdermozilla-release@3148731bed45 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmstange, lizzard
bugs1284350, 1259281
milestone49.0a2
Bug 1284350 - Revert "Bug 1259281 - Mark frames NONVISIBLE if their pres shell is inactive or frozen. r=mstange". a=lizzard This reverts commit 245abe06a6300570d94f0003a41b72f195e520c0.
layout/base/nsIPresShell.h
layout/base/nsPresShell.cpp
layout/base/nsPresShell.h
--- a/layout/base/nsIPresShell.h
+++ b/layout/base/nsIPresShell.h
@@ -1228,17 +1228,17 @@ public:
   {
     mObservesMutationsForPrint = aObserve;
   }
   bool ObservesNativeAnonMutationsForPrint()
   {
     return mObservesMutationsForPrint;
   }
 
-  virtual void SetIsActive(bool aIsActive, bool aIsHidden = true) = 0;
+  virtual nsresult SetIsActive(bool aIsActive, bool aIsHidden = true) = 0;
 
   bool IsActive()
   {
     return mIsActive;
   }
 
   // mouse capturing
   static CapturingContentInfo gCaptureInfo;
--- a/layout/base/nsPresShell.cpp
+++ b/layout/base/nsPresShell.cpp
@@ -4649,129 +4649,16 @@ PresShell::NotifyCompositorOfVisibleRegi
                           layersId, presShellId);
 
   SendUpdateVisibleRegion(compositorChild,
                           mVisibleRegions->mInDisplayPort,
                           VisibilityCounter::IN_DISPLAYPORT,
                           layersId, presShellId);
 }
 
-template <typename Func> void
-ForAllTrackedFramesInVisibleSet(const VisibleFrames& aFrames, Func aFunc)
-{
-  for (auto iter = aFrames.ConstIter(); !iter.Done(); iter.Next()) {
-    nsIFrame* frame = iter.Get()->GetKey();
-
-    // Call |aFunc| if we're still tracking the frame's visibility. (We may
-    // not be, if the frame disabled visibility tracking after we added it to
-    // the visible frames list.)
-    if (frame->TrackingVisibility()) {
-      aFunc(frame);
-    }
-  }
-}
-
-void
-PresShell::VisibleFramesContainer::AddFrame(nsIFrame* aFrame,
-                                            VisibilityCounter aCounter)
-{
-  MOZ_ASSERT(aFrame->TrackingVisibility());
-
-  VisibleFrames& frameSet = ForCounter(aCounter);
-
-  uint32_t count = frameSet.Count();
-  frameSet.PutEntry(aFrame);
-
-  if (frameSet.Count() == count) {
-    return;  // The frame was already present.
-  }
-
-  if (mSuppressingVisibility) {
-    return;  // We're not updating visibility counters right now.
-  }
-
-  aFrame->IncVisibilityCount(aCounter);
-}
-
-void
-PresShell::VisibleFramesContainer::RemoveFrame(nsIFrame* aFrame,
-                                               VisibilityCounter aCounter)
-{
-  VisibleFrames& frameSet = ForCounter(aCounter);
-
-  uint32_t count = frameSet.Count();
-  frameSet.RemoveEntry(aFrame);
-
-  if (frameSet.Count() == count) {
-    return;  // The frame wasn't present.
-  }
-
-  if (mSuppressingVisibility) {
-    return;  // We're not updating visibility counters right now.
-  }
-
-  if (!aFrame->TrackingVisibility()) {
-    // We stopped tracking visibility for this frame after it got added to the
-    // set. We don't need to update counters.
-    return;
-  }
-
-  aFrame->DecVisibilityCount(aCounter);
-}
-
-void
-PresShell::VisibleFramesContainer::SuppressVisibility()
-{
-  if (mSuppressingVisibility) {
-    return;  // Nothing to do.
-  }
-
-  mSuppressingVisibility = true;
-
-  // Decrement counters for all the frames we're tracking right now to
-  // maintain the invariant that when visibility is suppressed we don't
-  // increment the counters for any of the frames in our sets. Note that we
-  // decrement the visibility counters from lowest to highest priority to
-  // minimize the number of notifications we have to send - for example, if a
-  // frame is both MAY_BECOME_VISIBLE and IN_DISPLAYPORT, decrementing
-  // IN_DISPLAYPORT first would send it to the MAY_BECOME_VISIBLE state, and
-  // then decrementing MAY_BECOME_VISIBLE would send it to the NONVISIBLE
-  // state, whereas decrementing in the other order transitions the frame
-  // directly from IN_DISPLAYPORT to NONVISIBLE since the frame remains
-  // IN_DISPLAYPORT even if its MAY_BECOME_VISIBLE counter is 0.
-  ForAllTrackedFramesInVisibleSet(mApproximate, [&](nsIFrame* aFrame) {
-    aFrame->DecVisibilityCount(VisibilityCounter::MAY_BECOME_VISIBLE);
-  });
-  ForAllTrackedFramesInVisibleSet(mInDisplayPort, [&](nsIFrame* aFrame) {
-    aFrame->DecVisibilityCount(VisibilityCounter::IN_DISPLAYPORT);
-  });
-}
-
-void
-PresShell::VisibleFramesContainer::UnsuppressVisibility()
-{
-  if (!mSuppressingVisibility) {
-    return;  // Nothing to do.
-  }
-
-  mSuppressingVisibility = false;
-
-  // Increment counters for all the frames we're tracking right now to
-  // maintain the invariant that when visibility is not suppressed we
-  // increment the counters for the frames in our sets - this is the normal
-  // state, in other words. See SuppressVisibility() for why we increment in
-  // this order - the same reasoning applies, but in reverse.
-  ForAllTrackedFramesInVisibleSet(mInDisplayPort, [&](nsIFrame* aFrame) {
-    aFrame->IncVisibilityCount(VisibilityCounter::IN_DISPLAYPORT);
-  });
-  ForAllTrackedFramesInVisibleSet(mApproximate, [&](nsIFrame* aFrame) {
-    aFrame->IncVisibilityCount(VisibilityCounter::MAY_BECOME_VISIBLE);
-  });
-}
-
 nsresult
 PresShell::RenderDocument(const nsRect& aRect, uint32_t aFlags,
                           nscolor aBackgroundColor,
                           gfxContext* aThebesContext)
 {
   NS_ENSURE_TRUE(!(aFlags & RENDER_IS_UNTRUSTED), NS_ERROR_NOT_IMPLEMENTED);
 
   nsRootPresContext* rootPresContext = mPresContext->GetRootPresContext();
@@ -5902,22 +5789,43 @@ PresShell::MarkFramesInListApproximately
     MOZ_ASSERT(frame);
 
     if (!frame->TrackingVisibility()) {
       continue;
     }
 
     // Use the presshell containing the frame.
     auto* presShell = static_cast<PresShell*>(frame->PresContext()->PresShell());
+    uint32_t count = presShell->mApproximatelyVisibleFrames.Count();
     MOZ_ASSERT(!presShell->AssumeAllFramesVisible());
-    presShell->mVisibleFrames.AddFrame(frame, VisibilityCounter::MAY_BECOME_VISIBLE);
+    presShell->mApproximatelyVisibleFrames.PutEntry(frame);
+    if (presShell->mApproximatelyVisibleFrames.Count() > count) {
+      // The frame was added to mApproximatelyVisibleFrames, so increment its visible count.
+      frame->IncVisibilityCount(VisibilityCounter::MAY_BECOME_VISIBLE);
+    }
+
     presShell->AddFrameToVisibleRegions(frame, VisibilityCounter::MAY_BECOME_VISIBLE);
   }
 }
 
+template <typename Func> void
+ForAllTrackedFramesInVisibleSet(const VisibleFrames& aFrames, Func aFunc)
+{
+  for (auto iter = aFrames.ConstIter(); !iter.Done(); iter.Next()) {
+    nsIFrame* frame = iter.Get()->GetKey();
+
+    // Call |aFunc| if we're still tracking the frame's visibility. (We may
+    // not be, if the frame disabled visibility tracking after we added it to
+    // the visible frames list.)
+    if (frame->TrackingVisibility()) {
+      aFunc(frame);
+    }
+  }
+}
+
 /**
  * This RAII class automatically handles updating visible frames sets. It also
  * handles updating visible regions (used for the APZ minimap debugger) when
  * the appropriate prefs are enabled.
  *
  * Because we don't want to cause unnecessary IPC traffic between the content
  * process and the compositor process, avoid nesting multiple
  * AutoUpdateVisibility instances. Instead, pass a list of VisibilityCounters
@@ -5947,40 +5855,30 @@ struct MOZ_STACK_CLASS AutoUpdateVisibil
   AutoUpdateVisibility(PresShell* aPresShell,
                        Notify aNotifyStrategy,
                        std::initializer_list<VisibilityCounter> aCounters,
                        Maybe<OnNonvisible> aNonvisibleAction = Nothing())
     : mNonvisibleAction(aNonvisibleAction)
     , mPresShell(aPresShell)
     , mNotifyStrategy(aNotifyStrategy)
   {
-    // If visibility tracking is suppressed, we're not incrementing or
-    // decrementing visibility counters and we don't want to visualize visible
-    // regions, so we can just clear the visible frame sets and skip the rest.
-    if (mPresShell->mVisibleFrames.IsVisibilitySuppressed()) {
-      mPresShell->mVisibleFrames.mApproximate.Clear();
-      mPresShell->mVisibleFrames.mInDisplayPort.Clear();
-      mPresShell->mVisibleRegions = nullptr;
-      return;
-    }
-
     // Clear the visible frames sets we're updating, but save the old set so
     // we can decrement their counter later. This is how we mark frames
     // nonvisible if they don't end up in the set during the visibility
     // update.
     for (VisibilityCounter counter : aCounters) {
       switch (counter) {
         case VisibilityCounter::MAY_BECOME_VISIBLE:
           mOldApproximatelyVisibleFrames.emplace();
-          mPresShell->mVisibleFrames.mApproximate.SwapElements(*mOldApproximatelyVisibleFrames);
+          mPresShell->mApproximatelyVisibleFrames.SwapElements(*mOldApproximatelyVisibleFrames);
           break;
 
         case VisibilityCounter::IN_DISPLAYPORT:
           mOldInDisplayPortFrames.emplace();
-          mPresShell->mVisibleFrames.mInDisplayPort.SwapElements(*mOldInDisplayPortFrames);
+          mPresShell->mInDisplayPortFrames.SwapElements(*mOldInDisplayPortFrames);
           break;
       }
     }
 
     // If we're not visualizing visible regions, we're done.
     if (!gfxPrefs::APZMinimap() ||
         !gfxPrefs::APZMinimapVisibilityEnabled()) {
       mPresShell->mVisibleRegions = nullptr;
@@ -6103,17 +6001,23 @@ PresShell::MarkFramesInSubtreeApproximat
                                                    bool aRemoveOnly /* = false */)
 {
   MOZ_ASSERT(aFrame->PresContext()->PresShell() == this, "wrong presshell");
 
   if (aFrame->TrackingVisibility() &&
       aFrame->StyleVisibility()->IsVisible() &&
       (!aRemoveOnly || aFrame->IsVisibleOrMayBecomeVisibleSoon())) {
     MOZ_ASSERT(!AssumeAllFramesVisible());
-    mVisibleFrames.AddFrame(aFrame, VisibilityCounter::MAY_BECOME_VISIBLE);
+    uint32_t count = mApproximatelyVisibleFrames.Count();
+    mApproximatelyVisibleFrames.PutEntry(aFrame);
+    if (mApproximatelyVisibleFrames.Count() > count) {
+      // The frame was added to mApproximatelyVisibleFrames, so increment its visible count.
+      aFrame->IncVisibilityCount(VisibilityCounter::MAY_BECOME_VISIBLE);
+    }
+
     AddFrameToVisibleRegions(aFrame, VisibilityCounter::MAY_BECOME_VISIBLE);
   }
 
   nsSubDocumentFrame* subdocFrame = do_QueryFrame(aFrame);
   if (subdocFrame) {
     nsIPresShell* presShell = subdocFrame->GetSubdocumentPresShellForPainting(
       nsSubDocumentFrame::IGNORE_PAINT_SUPPRESSION);
     if (presShell && !presShell->AssumeAllFramesVisible()) {
@@ -6230,20 +6134,20 @@ PresShell::DoUpdateApproximateFrameVisib
     return;
   }
 
   RebuildApproximateFrameVisibility(/* aRect = */ nullptr, aRemoveOnly);
   ClearVisibleFramesForUnvisitedPresShells(rootFrame->GetView(), true);
 
 #ifdef DEBUG_FRAME_VISIBILITY_DISPLAY_LIST
   // This can be used to debug the frame walker by comparing beforeFrameList
-  // and mVisibleFrames.mApproximate in RebuildFrameVisibilityDisplayList to
-  // see if they produce the same results (mVisibleFrames.mApproximate holds
-  // the frames the display list thinks are visible, beforeFrameList holds the
-  // frames the frame walker thinks are visible).
+  // and mApproximatelyVisibleFrames in RebuildFrameVisibilityDisplayList to see if
+  // they produce the same results (mApproximatelyVisibleFrames holds the frames the
+  // display list thinks are visible, beforeFrameList holds the frames the
+  // frame walker thinks are visible).
   nsDisplayListBuilder builder(rootFrame, nsDisplayListBuilderMode::FRAME_VISIBILITY, false);
   nsRect updateRect(nsPoint(0, 0), rootFrame->GetSize());
   nsIFrame* rootScroll = GetRootScrollFrame();
   if (rootScroll) {
     nsIContent* content = rootScroll->GetContent();
     if (content) {
       Unused << nsLayoutUtils::GetDisplayPortForVisibilityTesting(content, &updateRect,
         RelativeTo::ScrollFrame);
@@ -6387,42 +6291,65 @@ PresShell::MarkFrameVisible(nsIFrame* aF
   // Make sure it's in this pres shell.
   nsCOMPtr<nsIContent> content = aFrame->GetContent();
   if (content) {
     PresShell* shell = static_cast<PresShell*>(content->OwnerDoc()->GetShell());
     MOZ_ASSERT(!shell || shell == this, "wrong shell");
   }
 #endif
 
-  mVisibleFrames.AddFrame(aFrame, aCounter);
+  VisibleFrames& frameSet = VisibleFramesForCounter(aCounter);
+
+  if (!frameSet.Contains(aFrame)) {
+    MOZ_ASSERT(!AssumeAllFramesVisible());
+    frameSet.PutEntry(aFrame);
+    aFrame->IncVisibilityCount(aCounter);
+  }
+
   AddFrameToVisibleRegions(aFrame, aCounter);
 }
 
+static void
+RemoveFrameFromVisibleSet(nsIFrame* aFrame,
+                          VisibleFrames& aSet,
+                          VisibilityCounter aCounter)
+{
+  uint32_t count = aSet.Count();
+  aSet.RemoveEntry(aFrame);
+
+  if (aFrame->TrackingVisibility() && aSet.Count() < count) {
+    aFrame->DecVisibilityCount(aCounter);
+  }
+
+}
+
 void
 PresShell::MarkFrameNonvisible(nsIFrame* aFrame)
 {
 #ifdef DEBUG
   // Make sure it's in this pres shell.
   nsCOMPtr<nsIContent> content = aFrame->GetContent();
   if (content) {
     PresShell* shell = static_cast<PresShell*>(content->OwnerDoc()->GetShell());
     MOZ_ASSERT(!shell || shell == this, "wrong shell");
   }
 #endif
 
   if (AssumeAllFramesVisible()) {
-    MOZ_ASSERT(mVisibleFrames.mApproximate.Count() == 0,
+    MOZ_ASSERT(mApproximatelyVisibleFrames.Count() == 0,
                "Shouldn't have any frames in the approximate visibility set");
-    MOZ_ASSERT(mVisibleFrames.mInDisplayPort.Count() == 0,
+    MOZ_ASSERT(mInDisplayPortFrames.Count() == 0,
                "Shouldn't have any frames in the in-displayport visibility set");
     return;
   }
 
-  mVisibleFrames.RemoveFrame(aFrame, VisibilityCounter::MAY_BECOME_VISIBLE);
-  mVisibleFrames.RemoveFrame(aFrame, VisibilityCounter::IN_DISPLAYPORT);
+  RemoveFrameFromVisibleSet(aFrame, mApproximatelyVisibleFrames,
+                            VisibilityCounter::MAY_BECOME_VISIBLE);
+  RemoveFrameFromVisibleSet(aFrame, mInDisplayPortFrames,
+                            VisibilityCounter::IN_DISPLAYPORT);
 }
 
 class nsAutoNotifyDidPaint
 {
 public:
   nsAutoNotifyDidPaint(PresShell* aShell, uint32_t aFlags)
     : mShell(aShell), mFlags(aFlags)
   {
@@ -9266,18 +9193,19 @@ PresShell::Freeze()
 
   nsPresContext* presContext = GetPresContext();
   if (presContext &&
       presContext->RefreshDriver()->PresContext() == presContext) {
     presContext->RefreshDriver()->Freeze();
   }
 
   mFrozen = true;
-
-  UpdateFrameVisibilityOnActiveStateChange();
+  if (mDocument) {
+    UpdateImageLockingState();
+  }
 }
 
 void
 PresShell::FireOrClearDelayedEvents(bool aFireEvents)
 {
   mNoDelayedMouseEvents = false;
   mNoDelayedKeyEvents = false;
   if (!aFireEvents) {
@@ -9333,18 +9261,18 @@ PresShell::Thaw()
     mDocument->EnumerateSubDocuments(ThawSubDocument, nullptr);
 
   // Get the activeness of our presshell, as this might have changed
   // while we were in the bfcache
   QueryIsActive();
 
   // We're now unfrozen
   mFrozen = false;
-
-  UpdateFrameVisibilityOnActiveStateChange();
+  UpdateImageLockingState();
+
   UnsuppressPainting();
 }
 
 //--------------------------------------------------------
 // Start of protected and private methods on the PresShell
 //--------------------------------------------------------
 
 void
@@ -11179,17 +11107,17 @@ SetPluginIsActive(nsISupports* aSupports
 
   nsIFrame *frame = content->GetPrimaryFrame();
   nsIObjectFrame *objectFrame = do_QueryFrame(frame);
   if (objectFrame) {
     objectFrame->SetIsDocumentActive(*static_cast<bool*>(aClosure));
   }
 }
 
-void
+nsresult
 PresShell::SetIsActive(bool aIsActive, bool aIsHidden)
 {
   NS_PRECONDITION(mDocument, "should only be called with a document");
 
   mIsActive = aIsActive;
 
   // Keep track of whether we've called TabChild::MakeHidden() or not.
   // This can still be true even if aIsHidden is false.
@@ -11201,18 +11129,17 @@ PresShell::SetIsActive(bool aIsActive, b
     presContext->RefreshDriver()->SetThrottled(!mIsActive);
   }
 
   // Propagate state-change to my resource documents' PresShells
   mDocument->EnumerateExternalResources(SetExternalResourceIsActive,
                                         &aIsActive);
   mDocument->EnumerateActivityObservers(SetPluginIsActive,
                                         &aIsActive);
-  UpdateFrameVisibilityOnActiveStateChange();
-
+  nsresult rv = UpdateImageLockingState();
 #ifdef ACCESSIBILITY
   if (aIsActive) {
     nsAccessibilityService* accService = AccService();
     if (accService) {
       accService->PresShellActivated(this);
     }
   }
 #endif
@@ -11250,47 +11177,43 @@ PresShell::SetIsActive(bool aIsActive, b
             root->SchedulePaint();
           }
         }
       } else {
         tab->MakeHidden();
       }
     }
   }
-}
-
-void
-PresShell::UpdateFrameVisibilityOnActiveStateChange()
-{
-  // A pres shell is "active" if it's being displayed in a visible tab. We
-  // only consider frames visible if they're in an active pres shell. A pres
-  // shell may also be "frozen", which means that it does not receive events -
-  // this is the case for e.g. documents in the back/forward cache. We don't
-  // want to consider frames visible in frozen pres shells, so we'll only
-  // treat this pres shell as active if it's also not frozen.
-  bool treatAsActive = mIsActive && !mFrozen;
-
-  // Update the document's image locking state.
-  // XXX(seth): Note that in the future the visibility tracking API will allow
-  // frames and content to manage their own image locking state. (And they
-  // mostly already do.) However, we can't get rid of the old approach until
-  // CSS images have visibility tracking - see bug 1218990.
-  mDocument->SetImageLockingState(treatAsActive);
-
-  if (treatAsActive) {
-    // Unsuppress frame visibility, marking the frames in all of our visible
-    // frame sets as visible. This will trigger decoding for visible images,
-    // which will help minimize flashing when a document gets foregrounded.
-    mVisibleFrames.UnsuppressVisibility();
-  } else {
-    // Suppress frame visibility, marking the frames in all of our visible
-    // frame sets nonvisible. This will allow them to stop animations, release
-    // memory, and generally reduce their resource usage.
-    mVisibleFrames.SuppressVisibility();
-  }
+  return rv;
+}
+
+/*
+ * Determines the current image locking state. Called when one of the
+ * dependent factors changes.
+ */
+nsresult
+PresShell::UpdateImageLockingState()
+{
+  // We're locked if we're both thawed and active.
+  bool locked = !mFrozen && mIsActive;
+
+  nsresult rv = mDocument->SetImageLockingState(locked);
+
+  if (locked) {
+    // Request decodes for visible image frames; we want to start decoding as
+    // quickly as possible when we get foregrounded to minimize flashing.
+    for (auto iter = mApproximatelyVisibleFrames.Iter(); !iter.Done(); iter.Next()) {
+      nsImageFrame* imageFrame = do_QueryFrame(iter.Get()->GetKey());
+      if (imageFrame) {
+        imageFrame->MaybeDecodeForPredictedSize();
+      }
+    }
+  }
+
+  return rv;
 }
 
 PresShell*
 PresShell::GetRootPresShell()
 {
   if (mPresContext) {
     nsPresContext* rootPresContext = mPresContext->GetRootPresContext();
     if (rootPresContext) {
@@ -11308,18 +11231,18 @@ PresShell::AddSizeOfIncludingThis(Malloc
                                   size_t *aTextRunsSize,
                                   size_t *aPresContextSize)
 {
   mFrameArena.AddSizeOfExcludingThis(aMallocSizeOf, aArenaObjectsSize);
   *aPresShellSize += aMallocSizeOf(this);
   if (mCaret) {
     *aPresShellSize += mCaret->SizeOfIncludingThis(aMallocSizeOf);
   }
-  *aPresShellSize += mVisibleFrames.mApproximate.ShallowSizeOfExcludingThis(aMallocSizeOf);
-  *aPresShellSize += mVisibleFrames.mInDisplayPort.ShallowSizeOfExcludingThis(aMallocSizeOf);
+  *aPresShellSize += mApproximatelyVisibleFrames.ShallowSizeOfExcludingThis(aMallocSizeOf);
+  *aPresShellSize += mInDisplayPortFrames.ShallowSizeOfExcludingThis(aMallocSizeOf);
   *aPresShellSize += mVisibleRegions
                    ? mVisibleRegions->mApproximate.ShallowSizeOfIncludingThis(aMallocSizeOf) +
                      mVisibleRegions->mInDisplayPort.ShallowSizeOfIncludingThis(aMallocSizeOf)
                    : 0;
   *aPresShellSize += mFramesToDirty.ShallowSizeOfExcludingThis(aMallocSizeOf);
   *aPresShellSize += aArenaObjectsSize->mOther;
 
   if (nsStyleSet* styleSet = StyleSet()->GetAsGecko()) {
--- a/layout/base/nsPresShell.h
+++ b/layout/base/nsPresShell.h
@@ -356,17 +356,17 @@ public:
 
   virtual void AddPrintPreviewBackgroundItem(nsDisplayListBuilder& aBuilder,
                                              nsDisplayList& aList,
                                              nsIFrame* aFrame,
                                              const nsRect& aBounds) override;
 
   virtual nscolor ComputeBackstopColor(nsView* aDisplayRoot) override;
 
-  virtual void SetIsActive(bool aIsActive, bool aIsHidden = true) override;
+  virtual nsresult SetIsActive(bool aIsActive, bool aIsHidden = true) override;
 
   virtual bool GetIsViewportOverridden() override {
     return (mMobileViewportManager != nullptr);
   }
 
   virtual bool IsLayoutFlushObserver() override
   {
     return GetPresContext()->RefreshDriver()->
@@ -673,16 +673,17 @@ protected:
     }
   private:
     PresShell* mPresShell;
     bool mFromScroll;
   };
   void ProcessSynthMouseMoveEvent(bool aFromScroll);
 
   void QueryIsActive();
+  nsresult UpdateImageLockingState();
 
   bool InZombieDocument(nsIContent *aContent);
   already_AddRefed<nsIPresShell> GetParentPresShellForEventHandling();
   nsIContent* GetCurrentEventContent();
   nsIFrame* GetCurrentEventFrame();
   nsresult RetargetEventToParent(mozilla::WidgetGUIEvent* aEvent,
                                  nsEventStatus* aEventStatus);
   void PushCurrentEventInfo(nsIFrame* aFrame, nsIContent* aContent);
@@ -771,68 +772,49 @@ protected:
   void DoUpdateApproximateFrameVisibility(bool aRemoveOnly);
 
   void ClearVisibleFramesSets(Maybe<OnNonvisible> aNonvisibleAction = Nothing());
   static void ClearVisibleFramesForUnvisitedPresShells(nsView* aView, bool aClear);
   static void MarkFramesInListApproximatelyVisible(const nsDisplayList& aList);
   void MarkFramesInSubtreeApproximatelyVisible(nsIFrame* aFrame,
                                                const nsRect& aRect,
                                                bool aRemoveOnly = false);
-  void UpdateFrameVisibilityOnActiveStateChange();
 
   void InitVisibleRegionsIfVisualizationEnabled(VisibilityCounter aForCounter);
   void AddFrameToVisibleRegions(nsIFrame* aFrame, VisibilityCounter aForCounter);
   void NotifyCompositorOfVisibleRegionsChange();
 
   nsRevocableEventPtr<nsRunnableMethod<PresShell>> mUpdateApproximateFrameVisibilityEvent;
   nsRevocableEventPtr<nsRunnableMethod<PresShell>> mNotifyCompositorOfVisibleRegionsChangeEvent;
 
-  struct VisibleFramesContainer
+  VisibleFrames& VisibleFramesForCounter(VisibilityCounter aCounter)
   {
-    VisibleFramesContainer() : mSuppressingVisibility(false) { }
-
-    void AddFrame(nsIFrame* aFrame, VisibilityCounter aCounter);
-    void RemoveFrame(nsIFrame* aFrame, VisibilityCounter aCounter);
-
-    bool IsVisibilitySuppressed() const { return mSuppressingVisibility; }
-    void SuppressVisibility();
-    void UnsuppressVisibility();
-
-    VisibleFrames& ForCounter(VisibilityCounter aCounter)
+    switch (aCounter)
     {
-      switch (aCounter)
-      {
-        case VisibilityCounter::MAY_BECOME_VISIBLE: return mApproximate;
-        case VisibilityCounter::IN_DISPLAYPORT:     return mInDisplayPort;
-      }
-      MOZ_CRASH();
+      case VisibilityCounter::MAY_BECOME_VISIBLE: return mApproximatelyVisibleFrames;
+      case VisibilityCounter::IN_DISPLAYPORT:     return mInDisplayPortFrames;
     }
+  }
 
-    // A set of frames that were visible or could be visible soon at the time
-    // that we last did an approximate frame visibility update.
-    VisibleFrames mApproximate;
+  // A set of frames that were visible or could be visible soon at the time
+  // that we last did an approximate frame visibility update.
+  VisibleFrames mApproximatelyVisibleFrames;
 
-    // A set of frames that were visible in the displayport the last time we painted.
-    VisibleFrames mInDisplayPort;
-
-    bool mSuppressingVisibility;
-  };
-
-  VisibleFramesContainer mVisibleFrames;
+  // A set of frames that were visible in the displayport the last time we painted.
+  VisibleFrames mInDisplayPortFrames;
 
   struct VisibleRegionsContainer
   {
     VisibleRegions& ForCounter(VisibilityCounter aCounter)
     {
       switch (aCounter)
       {
         case VisibilityCounter::MAY_BECOME_VISIBLE: return mApproximate;
         case VisibilityCounter::IN_DISPLAYPORT:     return mInDisplayPort;
       }
-      MOZ_CRASH();
     }
 
     // The approximately visible regions calculated during the last update to
     // approximate frame visibility.
     VisibleRegions mApproximate;
 
     // The in-displayport visible regions calculated during the last paint.
     VisibleRegions mInDisplayPort;