author | Seth Fowler <mark.seth.fowler@gmail.com> |
Wed, 11 May 2016 19:27:29 -0700 | |
changeset 297083 | 719d6d5d9d2114dec8bff62d646435ab42cf5491 |
parent 297082 | d0aa5cf74699aa4bacbde93e45965a58bb7f8081 |
child 297084 | 7043159e6b741f094e2f81b6b5354a1bc70b3e01 |
push id | 30251 |
push user | cbook@mozilla.com |
push date | Thu, 12 May 2016 09:54:48 +0000 |
treeherder | mozilla-central@c3f5e6079284 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | mstange |
bugs | 1259281 |
milestone | 49.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
|
--- a/layout/base/nsIPresShell.h +++ b/layout/base/nsIPresShell.h @@ -1238,17 +1238,17 @@ public: { mObservesMutationsForPrint = aObserve; } bool ObservesNativeAnonMutationsForPrint() { return mObservesMutationsForPrint; } - virtual nsresult SetIsActive(bool aIsActive, bool aIsHidden = true) = 0; + virtual void 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 @@ -4635,16 +4635,129 @@ 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(); @@ -5731,43 +5844,22 @@ 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->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->mVisibleFrames.AddFrame(frame, 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 @@ -5797,30 +5889,40 @@ 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->mApproximatelyVisibleFrames.SwapElements(*mOldApproximatelyVisibleFrames); + mPresShell->mVisibleFrames.mApproximate.SwapElements(*mOldApproximatelyVisibleFrames); break; case VisibilityCounter::IN_DISPLAYPORT: mOldInDisplayPortFrames.emplace(); - mPresShell->mInDisplayPortFrames.SwapElements(*mOldInDisplayPortFrames); + mPresShell->mVisibleFrames.mInDisplayPort.SwapElements(*mOldInDisplayPortFrames); break; } } // If we're not visualizing visible regions, we're done. if (!gfxPrefs::APZMinimap() || !gfxPrefs::APZMinimapVisibilityEnabled()) { mPresShell->mVisibleRegions = nullptr; @@ -5943,23 +6045,17 @@ 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()); - 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); - } - + mVisibleFrames.AddFrame(aFrame, 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()) { @@ -6076,20 +6172,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 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). + // 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). 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); @@ -6233,65 +6329,42 @@ 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 - VisibleFrames& frameSet = VisibleFramesForCounter(aCounter); - - if (!frameSet.Contains(aFrame)) { - MOZ_ASSERT(!AssumeAllFramesVisible()); - frameSet.PutEntry(aFrame); - aFrame->IncVisibilityCount(aCounter); - } - + mVisibleFrames.AddFrame(aFrame, 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(mApproximatelyVisibleFrames.Count() == 0, + MOZ_ASSERT(mVisibleFrames.mApproximate.Count() == 0, "Shouldn't have any frames in the approximate visibility set"); - MOZ_ASSERT(mInDisplayPortFrames.Count() == 0, + MOZ_ASSERT(mVisibleFrames.mInDisplayPort.Count() == 0, "Shouldn't have any frames in the in-displayport visibility set"); return; } - RemoveFrameFromVisibleSet(aFrame, mApproximatelyVisibleFrames, - VisibilityCounter::MAY_BECOME_VISIBLE); - RemoveFrameFromVisibleSet(aFrame, mInDisplayPortFrames, - VisibilityCounter::IN_DISPLAYPORT); + mVisibleFrames.RemoveFrame(aFrame, VisibilityCounter::MAY_BECOME_VISIBLE); + mVisibleFrames.RemoveFrame(aFrame, VisibilityCounter::IN_DISPLAYPORT); } class nsAutoNotifyDidPaint { public: nsAutoNotifyDidPaint(PresShell* aShell, uint32_t aFlags) : mShell(aShell), mFlags(aFlags) { @@ -9135,19 +9208,18 @@ PresShell::Freeze() nsPresContext* presContext = GetPresContext(); if (presContext && presContext->RefreshDriver()->PresContext() == presContext) { presContext->RefreshDriver()->Freeze(); } mFrozen = true; - if (mDocument) { - UpdateImageLockingState(); - } + + UpdateFrameVisibilityOnActiveStateChange(); } void PresShell::FireOrClearDelayedEvents(bool aFireEvents) { mNoDelayedMouseEvents = false; mNoDelayedKeyEvents = false; if (!aFireEvents) { @@ -9203,18 +9275,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; - UpdateImageLockingState(); - + + UpdateFrameVisibilityOnActiveStateChange(); UnsuppressPainting(); } //-------------------------------------------------------- // Start of protected and private methods on the PresShell //-------------------------------------------------------- void @@ -11049,17 +11121,17 @@ SetPluginIsActive(nsISupports* aSupports nsIFrame *frame = content->GetPrimaryFrame(); nsIObjectFrame *objectFrame = do_QueryFrame(frame); if (objectFrame) { objectFrame->SetIsDocumentActive(*static_cast<bool*>(aClosure)); } } -nsresult +void 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. @@ -11071,17 +11143,18 @@ 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); - nsresult rv = UpdateImageLockingState(); + UpdateFrameVisibilityOnActiveStateChange(); + #ifdef ACCESSIBILITY if (aIsActive) { nsAccessibilityService* accService = AccService(); if (accService) { accService->PresShellActivated(this); } } #endif @@ -11119,43 +11192,47 @@ PresShell::SetIsActive(bool aIsActive, b root->SchedulePaint(); } } } else { tab->MakeHidden(); } } } - 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; +} + +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(); + } } PresShell* PresShell::GetRootPresShell() { if (mPresContext) { nsPresContext* rootPresContext = mPresContext->GetRootPresContext(); if (rootPresContext) { @@ -11173,18 +11250,18 @@ PresShell::AddSizeOfIncludingThis(Malloc size_t *aTextRunsSize, size_t *aPresContextSize) { mFrameArena.AddSizeOfExcludingThis(aMallocSizeOf, aArenaObjectsSize); *aPresShellSize += aMallocSizeOf(this); if (mCaret) { *aPresShellSize += mCaret->SizeOfIncludingThis(aMallocSizeOf); } - *aPresShellSize += mApproximatelyVisibleFrames.ShallowSizeOfExcludingThis(aMallocSizeOf); - *aPresShellSize += mInDisplayPortFrames.ShallowSizeOfExcludingThis(aMallocSizeOf); + *aPresShellSize += mVisibleFrames.mApproximate.ShallowSizeOfExcludingThis(aMallocSizeOf); + *aPresShellSize += mVisibleFrames.mInDisplayPort.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 @@ -355,17 +355,17 @@ public: virtual void AddPrintPreviewBackgroundItem(nsDisplayListBuilder& aBuilder, nsDisplayList& aList, nsIFrame* aFrame, const nsRect& aBounds) override; virtual nscolor ComputeBackstopColor(nsView* aDisplayRoot) override; - virtual nsresult SetIsActive(bool aIsActive, bool aIsHidden = true) override; + virtual void SetIsActive(bool aIsActive, bool aIsHidden = true) override; virtual bool GetIsViewportOverridden() override { return (mMobileViewportManager != nullptr); } virtual bool IsLayoutFlushObserver() override { return GetPresContext()->RefreshDriver()-> @@ -672,17 +672,16 @@ 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,49 +770,68 @@ 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; - VisibleFrames& VisibleFramesForCounter(VisibilityCounter aCounter) + struct VisibleFramesContainer { - switch (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) { - case VisibilityCounter::MAY_BECOME_VISIBLE: return mApproximatelyVisibleFrames; - case VisibilityCounter::IN_DISPLAYPORT: return mInDisplayPortFrames; + switch (aCounter) + { + case VisibilityCounter::MAY_BECOME_VISIBLE: return mApproximate; + case VisibilityCounter::IN_DISPLAYPORT: return mInDisplayPort; + } + MOZ_CRASH(); } - } + + // 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; - // A set of frames that were visible in the displayport the last time we painted. - VisibleFrames mInDisplayPortFrames; + bool mSuppressingVisibility; + }; + + VisibleFramesContainer mVisibleFrames; 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;