Bug 1334735 - Part 2: Add separate flag to track need to flush throttled animations. r?bz,birtles
MozReview-Commit-ID: Fil3uTYYz3P
--- a/dom/animation/EffectCompositor.cpp
+++ b/dom/animation/EffectCompositor.cpp
@@ -259,17 +259,17 @@ EffectCompositor::RequestRestyle(dom::El
auto& elementsToRestyle = mElementsToRestyle[aCascadeLevel];
PseudoElementHashEntry::KeyType key = { aElement, aPseudoType };
if (aRestyleType == RestyleType::Throttled) {
if (!elementsToRestyle.Contains(key)) {
elementsToRestyle.Put(key, false);
}
- mPresContext->PresShell()->SetNeedStyleFlush();
+ mPresContext->PresShell()->SetNeedThrottledAnimationFlush();
} else {
// Get() returns 0 if the element is not found. It will also return
// false if the element is found but does not have a pending restyle.
bool hasPendingRestyle = elementsToRestyle.Get(key);
if (!hasPendingRestyle) {
PostRestyleForAnimation(aElement, aPseudoType, aCascadeLevel);
}
elementsToRestyle.Put(key, true);
--- a/layout/base/PresShell.cpp
+++ b/layout/base/PresShell.cpp
@@ -793,16 +793,17 @@ nsIPresShell::nsIPresShell()
, mFrozen(false)
, mIsFirstPaint(false)
, mObservesMutationsForPrint(false)
, mReflowScheduled(false)
, mSuppressInterruptibleReflows(false)
, mScrollPositionClampingScrollPortSizeSet(false)
, mNeedLayoutFlush(true)
, mNeedStyleFlush(true)
+ , mNeedThrottledAnimationFlush(true)
, mPresShellId(0)
, mFontSizeInflationEmPerLine(0)
, mFontSizeInflationMinTwips(0)
, mFontSizeInflationLineThreshold(0)
, mFontSizeInflationForceEnabled(false)
, mFontSizeInflationDisabledInMasterProcess(false)
, mFontSizeInflationEnabled(false)
, mPaintingIsFrozen(false)
@@ -4108,16 +4109,18 @@ PresShell::FlushPendingNotifications(moz
// nsDocument::FlushPendingNotifications doesn't skip any re-entrant
// calls to us. Otherwise, we might miss some needed flushes, since
// we clear mNeedStyleFlush / mNeedLayoutFlush here at the top of
// the function but we might not have done the work yet.
AutoRestore<bool> guard(mInFlush);
mInFlush = true;
mNeedStyleFlush = false;
+ mNeedThrottledAnimationFlush =
+ mNeedThrottledAnimationFlush && !aFlush.mFlushAnimations;
mNeedLayoutFlush =
mNeedLayoutFlush && (flushType < FlushType::InterruptibleLayout);
bool isSafeToFlush = IsSafeToFlush();
// If layout could possibly trigger scripts, then it's only safe to flush if
// it's safe to run script.
bool hasHadScriptObject;
@@ -4235,16 +4238,19 @@ PresShell::FlushPendingNotifications(moz
if (!mIsDestroying) {
viewManager->UpdateWidgetGeometry();
}
}
}
if (!didStyleFlush && flushType >= FlushType::Style && !mIsDestroying) {
SetNeedStyleFlush();
+ if (aFlush.mFlushAnimations) {
+ SetNeedThrottledAnimationFlush();
+ }
}
if (!didLayoutFlush && !mIsDestroying &&
(flushType >=
(mSuppressInterruptibleReflows ? FlushType::Layout
: FlushType::InterruptibleLayout))) {
// We suppressed this flush due to mSuppressInterruptibleReflows or
// !isSafeToFlush, but now we think we don't need to flush any more.
--- a/layout/base/nsIPresShell.h
+++ b/layout/base/nsIPresShell.h
@@ -585,37 +585,40 @@ public:
virtual void FlushPendingNotifications(mozilla::FlushType aType) = 0;
virtual void FlushPendingNotifications(mozilla::ChangesToFlush aType) = 0;
/**
* Whether we might need a flush for the given flush type. If this
* function returns false, we definitely don't need to flush.
*
* @param aFlushType The flush type to check. This must be
- * >= FlushType::Style.
+ * >= FlushType::Style. We assume that throttled animations are to be
+ * flushed.
*/
bool NeedFlush(mozilla::FlushType aType) const
{
// We check mInFlush to handle re-entrant calls to FlushPendingNotifications
// by reporting that we always need a flush in that case. Otherwise,
- // we could end up missing needed flushes, since we clear mNeedStyleFlush
- // and mNeedLayoutFlush at the top of FlushPendingNotifications.
+ // we could end up missing needed flushes, since we clear the mNeedXXXFlush
+ // flags at the top of FlushPendingNotifications.
//
// XXXheycam Could we just clear those flags after the work has been
// done instead?
MOZ_ASSERT(aType >= mozilla::FlushType::Style);
return mNeedStyleFlush ||
(mNeedLayoutFlush &&
aType >= mozilla::FlushType::InterruptibleLayout) ||
aType >= mozilla::FlushType::Display ||
+ mNeedThrottledAnimationFlush ||
mInFlush;
}
inline void SetNeedStyleFlush();
inline void SetNeedLayoutFlush();
+ inline void SetNeedThrottledAnimationFlush();
/**
* Callbacks will be called even if reflow itself fails for
* some reason.
*/
virtual nsresult PostReflowCallback(nsIReflowCallback* aCallback) = 0;
virtual void CancelReflowCallback(nsIReflowCallback* aCallback) = 0;
@@ -1833,16 +1836,20 @@ protected:
bool mScrollPositionClampingScrollPortSizeSet : 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;
+
uint32_t mPresShellId;
// List of subtrees rooted at style scope roots that need to be restyled.
// When a change to a scoped style sheet is made, we add the style scope
// root to this array rather than setting mStylesHaveChanged = true, since
// we know we don't need to restyle the whole document. However, if in the
// same update block we have already had other changes that require
// the whole document to be restyled (i.e., mStylesHaveChanged is already
--- a/layout/base/nsIPresShellInlines.h
+++ b/layout/base/nsIPresShellInlines.h
@@ -20,9 +20,20 @@ nsIPresShell::SetNeedStyleFlush()
mNeedStyleFlush = true;
if (nsIDocument* doc = mDocument->GetDisplayDocument()) {
if (nsIPresShell* shell = doc->GetShell()) {
shell->mNeedStyleFlush = true;
}
}
}
+void
+nsIPresShell::SetNeedThrottledAnimationFlush()
+{
+ mNeedThrottledAnimationFlush = true;
+ if (nsIDocument* doc = mDocument->GetDisplayDocument()) {
+ if (nsIPresShell* shell = doc->GetShell()) {
+ shell->mNeedThrottledAnimationFlush = true;
+ }
+ }
+}
+
#endif // nsIPresShellInlines_h