Bug 1073336 part 1 - Move CheckNeedsRefreshes to CommonAnimationManager; r=dbaron

In order to add AnimationPlayerCollection::NotifyPlayerUpdated, collections
need a way of updating their managers to inform them that their mNeedsRefreshes
flag has changed and hence the manager may need to resume observing the refresh
driver.

Currently, only nsAnimationManager makes use of mNeedsRefreshes and provides
a CheckNeedsRefresh method. In order to allow AnimationPlayerCollection to
operate independently of the type of manager it is attached to (and because
there's a lot of similar code here that we eventually want to move to a common
manager anyway), this patch moves CheckNeedsRefreshes and associated
machinery to CommonAnimationManager.
This commit is contained in:
Brian Birtles 2014-11-17 13:45:56 +09:00
parent 8e167728ed
commit 89f4908fb5
6 changed files with 45 additions and 86 deletions

View File

@ -52,6 +52,7 @@ namespace css {
CommonAnimationManager::CommonAnimationManager(nsPresContext *aPresContext)
: mPresContext(aPresContext)
, mIsObservingRefreshDriver(false)
{
PR_INIT_CLIST(&mElementCollections);
}
@ -70,6 +71,21 @@ CommonAnimationManager::Disconnect()
mPresContext = nullptr;
}
void
CommonAnimationManager::AddElementCollection(AnimationPlayerCollection*
aCollection)
{
if (!mIsObservingRefreshDriver) {
NS_ASSERTION(aCollection->mNeedsRefreshes,
"Added data which doesn't need refreshing?");
// We need to observe the refresh driver.
mPresContext->RefreshDriver()->AddRefreshObserver(this, Flush_Style);
mIsObservingRefreshDriver = true;
}
PR_INSERT_BEFORE(aCollection, &mElementCollections);
}
void
CommonAnimationManager::RemoveAllElementCollections()
{
@ -81,6 +97,26 @@ CommonAnimationManager::RemoveAllElementCollections()
}
}
void
CommonAnimationManager::CheckNeedsRefresh()
{
for (PRCList *l = PR_LIST_HEAD(&mElementCollections);
l != &mElementCollections;
l = PR_NEXT_LINK(l)) {
if (static_cast<AnimationPlayerCollection*>(l)->mNeedsRefreshes) {
if (!mIsObservingRefreshDriver) {
mPresContext->RefreshDriver()->AddRefreshObserver(this, Flush_Style);
mIsObservingRefreshDriver = true;
}
return;
}
}
if (mIsObservingRefreshDriver) {
mIsObservingRefreshDriver = false;
mPresContext->RefreshDriver()->RemoveRefreshObserver(this, Flush_Style);
}
}
AnimationPlayerCollection*
CommonAnimationManager::GetAnimationsForCompositor(nsIContent* aContent,
nsIAtom* aElementProperty,

View File

@ -75,17 +75,20 @@ public:
nsCSSProperty aProperty,
nsStyleContext* aStyleContext,
mozilla::StyleAnimationValue& aComputedValue);
protected:
virtual ~CommonAnimationManager();
// For ElementCollectionRemoved
friend struct mozilla::AnimationPlayerCollection;
virtual void
AddElementCollection(AnimationPlayerCollection* aCollection) = 0;
virtual void ElementCollectionRemoved() = 0;
void AddElementCollection(AnimationPlayerCollection* aCollection);
void ElementCollectionRemoved() { CheckNeedsRefresh(); }
void RemoveAllElementCollections();
// Check to see if we should stop or start observing the refresh driver
void CheckNeedsRefresh();
// When this returns a value other than nullptr, it also,
// as a side-effect, notifies the ActiveLayerTracker.
static AnimationPlayerCollection*
@ -95,6 +98,7 @@ protected:
PRCList mElementCollections;
nsPresContext *mPresContext; // weak (non-null from ctor to Disconnect)
bool mIsObservingRefreshDriver;
};
/**
@ -185,9 +189,8 @@ struct AnimationPlayerCollection : public PRCList
void Tick();
// This updates mNeedsRefreshes so the caller may need to check
// for changes to values (for example, nsAnimationManager provides
// CheckNeedsRefresh to register or unregister from observing the refresh
// driver when this value changes).
// for changes to values (for example, calling CheckNeedsRefresh to register
// or unregister from observing the refresh driver when this value changes).
void EnsureStyleRuleFor(TimeStamp aRefreshTime, EnsureStyleRuleFlags aFlags);
bool CanThrottleTransformChanges(mozilla::TimeStamp aTime);

View File

@ -760,42 +760,6 @@ nsAnimationManager::WillRefresh(mozilla::TimeStamp aTime)
FlushAnimations(Can_Throttle);
}
void
nsAnimationManager::AddElementCollection(
AnimationPlayerCollection* aCollection)
{
if (!mObservingRefreshDriver) {
NS_ASSERTION(
static_cast<AnimationPlayerCollection*>(aCollection)->mNeedsRefreshes,
"Added data which doesn't need refreshing?");
// We need to observe the refresh driver.
mPresContext->RefreshDriver()->AddRefreshObserver(this, Flush_Style);
mObservingRefreshDriver = true;
}
PR_INSERT_BEFORE(aCollection, &mElementCollections);
}
void
nsAnimationManager::CheckNeedsRefresh()
{
for (PRCList *l = PR_LIST_HEAD(&mElementCollections);
l != &mElementCollections;
l = PR_NEXT_LINK(l)) {
if (static_cast<AnimationPlayerCollection*>(l)->mNeedsRefreshes) {
if (!mObservingRefreshDriver) {
mPresContext->RefreshDriver()->AddRefreshObserver(this, Flush_Style);
mObservingRefreshDriver = true;
}
return;
}
}
if (mObservingRefreshDriver) {
mObservingRefreshDriver = false;
mPresContext->RefreshDriver()->RemoveRefreshObserver(this, Flush_Style);
}
}
void
nsAnimationManager::FlushAnimations(FlushFlags aFlags)
{

View File

@ -147,7 +147,6 @@ class nsAnimationManager MOZ_FINAL
public:
explicit nsAnimationManager(nsPresContext *aPresContext)
: mozilla::css::CommonAnimationManager(aPresContext)
, mObservingRefreshDriver(false)
{
}
@ -227,19 +226,6 @@ public:
nsIStyleRule* GetAnimationRule(mozilla::dom::Element* aElement,
nsCSSPseudoElements::Type aPseudoType);
protected:
virtual void ElementCollectionRemoved() MOZ_OVERRIDE
{
CheckNeedsRefresh();
}
virtual void
AddElementCollection(mozilla::AnimationPlayerCollection* aData) MOZ_OVERRIDE;
/**
* Check to see if we should stop or start observing the refresh driver
*/
void CheckNeedsRefresh();
private:
void BuildAnimations(nsStyleContext* aStyleContext,
mozilla::dom::Element* aTarget,
@ -257,8 +243,6 @@ private:
void DoDispatchEvents();
mozilla::EventArray mPendingEvents;
bool mObservingRefreshDriver;
};
#endif /* !defined(nsAnimationManager_h_) */

View File

@ -74,29 +74,6 @@ ElementPropertyTransition::CurrentValuePortion() const
* nsTransitionManager *
*****************************************************************************/
void
nsTransitionManager::ElementCollectionRemoved()
{
// If we have no transitions or animations left, remove ourselves from
// the refresh driver.
if (PR_CLIST_IS_EMPTY(&mElementCollections)) {
mPresContext->RefreshDriver()->RemoveRefreshObserver(this, Flush_Style);
}
}
void
nsTransitionManager::AddElementCollection(
AnimationPlayerCollection* aCollection)
{
if (PR_CLIST_IS_EMPTY(&mElementCollections)) {
// We need to observe the refresh driver.
nsRefreshDriver *rd = mPresContext->RefreshDriver();
rd->AddRefreshObserver(this, Flush_Style);
}
PR_INSERT_BEFORE(aCollection, &mElementCollections);
}
already_AddRefed<nsIStyleRule>
nsTransitionManager::StyleContextChanged(dom::Element *aElement,
nsStyleContext *aOldStyleContext,

View File

@ -152,11 +152,6 @@ public:
nsCSSPseudoElements::Type aPseudoType,
nsRuleWalker* aRuleWalker);
protected:
virtual void ElementCollectionRemoved() MOZ_OVERRIDE;
virtual void
AddElementCollection(AnimationPlayerCollection* aCollection) MOZ_OVERRIDE;
private:
void
ConsiderStartingTransition(nsCSSProperty aProperty,