Bug 960465 patch 5 - Make SMIL animations participate in the animation-only style flush. r=birtles

This is needed to prevent these reftests from failing:
  layout/reftests/svg/smil/smil-transitions-interaction-1a.svg
  layout/reftests/svg/smil/smil-transitions-interaction-1b.svg
  layout/reftests/svg/smil/smil-transitions-interaction-2a.svg
  layout/reftests/svg/smil/smil-transitions-interaction-2b.svg
  layout/reftests/svg/smil/smil-transitions-interaction-4a.svg
  layout/reftests/svg/smil/smil-transitions-interaction-4b.svg
The mIsCSS path fixes the a tests, and the !mIsCSS path fixes the b tests.

This is because this patch series changes the way in which transitions
interact with other types of animations to depend on those animations
being flushed in the animation-only style flush.  (The relevant call is
added in patch 6, though we don't really depend on it until patch 17.)
This commit is contained in:
L. David Baron 2015-02-17 11:15:02 +13:00
parent 3545426b12
commit b99c33a3b5
4 changed files with 68 additions and 8 deletions

View File

@ -67,6 +67,7 @@ FAIL_ON_WARNINGS = True
LOCAL_INCLUDES += [
'/dom/base',
'/dom/svg',
'/layout/base',
'/layout/style',
]

View File

@ -14,6 +14,7 @@
#include "nsSMILTimedElement.h"
#include <algorithm>
#include "mozilla/AutoRestore.h"
#include "RestyleTracker.h"
using namespace mozilla;
using namespace mozilla::dom;
@ -814,6 +815,36 @@ nsSMILAnimationController::GetTargetIdentifierForAnimation(
return true;
}
/*static*/ PLDHashOperator
nsSMILAnimationController::AddStyleUpdate(AnimationElementPtrKey* aKey,
void* aData)
{
SVGAnimationElement* animElement = aKey->GetKey();
RestyleTracker* restyleTracker = static_cast<RestyleTracker*>(aData);
nsSMILTargetIdentifier key;
if (!GetTargetIdentifierForAnimation(animElement, key)) {
// Something's wrong/missing about animation's target; skip this animation
return PL_DHASH_NEXT;
}
// mIsCSS true means that the rules are the ones returned from
// Element::GetSMILOverrideStyleRule (via nsSMILCSSProperty objects),
// and mIsCSS false means the rules are nsSMILMappedAttribute objects
// returned from nsSVGElement::GetAnimatedContentStyleRule.
nsRestyleHint rshint = key.mIsCSS ? eRestyle_StyleAttribute
: eRestyle_SVGAttrAnimations;
restyleTracker->AddPendingRestyle(key.mElement, rshint, nsChangeHint(0));
return PL_DHASH_NEXT;
}
void
nsSMILAnimationController::AddStyleUpdatesTo(RestyleTracker& aTracker)
{
mAnimationElementTable.EnumerateEntries(AddStyleUpdate, &aTracker);
}
//----------------------------------------------------------------------
// Add/remove child time containers

View File

@ -22,6 +22,7 @@ struct nsSMILTargetIdentifier;
class nsIDocument;
namespace mozilla {
class RestyleTracker;
namespace dom {
class SVGAnimationElement;
}
@ -105,6 +106,8 @@ public:
bool HasRegisteredAnimations()
{ return mAnimationElementTable.Count() != 0; }
void AddStyleUpdatesTo(mozilla::RestyleTracker& aTracker);
protected:
~nsSMILAnimationController();
@ -175,6 +178,9 @@ protected:
static bool GetTargetIdentifierForAnimation(
mozilla::dom::SVGAnimationElement* aAnimElem, nsSMILTargetIdentifier& aResult);
static PLDHashOperator
AddStyleUpdate(AnimationElementPtrKey* aKey, void* aData);
// Methods for adding/removing time containers
virtual nsresult AddChild(nsSMILTimeContainer& aChild) MOZ_OVERRIDE;
virtual void RemoveChild(nsSMILTimeContainer& aChild) MOZ_OVERRIDE;

View File

@ -40,6 +40,7 @@
#include "ActiveLayerTracker.h"
#include "nsDisplayList.h"
#include "RestyleTrackerInlines.h"
#include "nsSMILAnimationController.h"
#ifdef ACCESSIBILITY
#include "nsAccessibilityService.h"
@ -1744,10 +1745,25 @@ void
RestyleManager::UpdateOnlyAnimationStyles()
{
TimeStamp now = mPresContext->RefreshDriver()->MostRecentRefresh();
if (mLastUpdateForThrottledAnimations == now) {
bool doCSS = mLastUpdateForThrottledAnimations != now;
mLastUpdateForThrottledAnimations = now;
bool doSMIL = false;
nsIDocument* document = mPresContext->Document();
nsSMILAnimationController* animationController = nullptr;
if (document->HasAnimationController()) {
animationController = document->GetAnimationController();
// FIXME: Ideally, we only want to do this if animation timelines
// have advanced. However, different SMIL animations could be
// getting their time from different outermost SVG elements, so
// finding all of them might be a pain. So this could be optimized
// to set doSMIL to true in fewer cases.
doSMIL = true;
}
if (!doCSS && !doSMIL) {
return;
}
mLastUpdateForThrottledAnimations = now;
nsTransitionManager* transitionManager = mPresContext->TransitionManager();
nsAnimationManager* animationManager = mPresContext->AnimationManager();
@ -1758,12 +1774,18 @@ RestyleManager::UpdateOnlyAnimationStyles()
ELEMENT_IS_POTENTIAL_ANIMATION_ONLY_RESTYLE_ROOT);
tracker.Init(this);
// FIXME: We should have the transition manager and animation manager
// add only the elements for which animations are currently throttled
// (i.e., animating on the compositor with main-thread style updates
// suppressed).
transitionManager->AddStyleUpdatesTo(tracker);
animationManager->AddStyleUpdatesTo(tracker);
if (doCSS) {
// FIXME: We should have the transition manager and animation manager
// add only the elements for which animations are currently throttled
// (i.e., animating on the compositor with main-thread style updates
// suppressed).
transitionManager->AddStyleUpdatesTo(tracker);
animationManager->AddStyleUpdatesTo(tracker);
}
if (doSMIL) {
animationController->AddStyleUpdatesTo(tracker);
}
ProcessRestyles(tracker);