Bug 1226118 part 7 - Rename and rework KeyframeEffectReadOnly::CanAnimatePropertyOnCompositor to ShouldBlockCompositorAnimations; r=hiro

KeyframeEffectReadOnly::CanAnimatePropertyOnCompositor has a comment that says
it, "Returns true |aProperty| can be run on compositor for |aFrame|" but it
does nothing of the sort.

What it *does* do is check answer the question, "If there happened to be an
animation of |aProperty| on |aFrame|, should we still run animations on the
compositor for this element?".

This patch renames the method accordingly and moves the step where we iterate
over a given effect's animated properties from
AnimationCollection::CanPerformOnCompositor to inside this method, making this
method a class method rather than a static method at the same time.

As noted in the expanded comment, the approach of blocking opacity animations
in these situations seems unnecessary but for now this patch just preserves the
existing behavior.
This commit is contained in:
Brian Birtles 2015-12-04 08:32:53 +09:00
parent 52e54a7480
commit 01072f313f
3 changed files with 48 additions and 29 deletions

View File

@ -2022,30 +2022,42 @@ KeyframeEffectReadOnly::CanAnimateTransformOnCompositor(
return true;
}
/* static */ bool
KeyframeEffectReadOnly::CanAnimatePropertyOnCompositor(
const nsIFrame* aFrame,
nsCSSProperty aProperty)
bool
KeyframeEffectReadOnly::ShouldBlockCompositorAnimations(const nsIFrame*
aFrame) const
{
// We currently only expect this method to be called when this effect
// is attached to a playing Animation. If that ever changes we'll need
// to update this to only return true when that is the case since paused,
// filling, cancelled Animations etc. shouldn't stop other Animations from
// running on the compositor.
MOZ_ASSERT(mAnimation && mAnimation->IsPlaying());
bool shouldLog = nsLayoutUtils::IsAnimationLoggingEnabled();
if (IsGeometricProperty(aProperty)) {
if (shouldLog) {
nsCString message;
message.AppendLiteral("Performance warning: Async animation of "
"'transform' or 'opacity' not possible due to animation of geometric"
"properties on the same element");
AnimationUtils::LogAsyncAnimationFailure(message, aFrame->GetContent());
for (const AnimationProperty& property : mProperties) {
// Check for geometric properties
if (IsGeometricProperty(property.mProperty)) {
if (shouldLog) {
nsCString message;
message.AppendLiteral("Performance warning: Async animation of "
"'transform' or 'opacity' not possible due to animation of geometric"
"properties on the same element");
AnimationUtils::LogAsyncAnimationFailure(message, aFrame->GetContent());
}
return true;
}
return false;
}
if (aProperty == eCSSProperty_transform) {
if (!CanAnimateTransformOnCompositor(aFrame,
shouldLog ? aFrame->GetContent() : nullptr)) {
return false;
// Check for unsupported transform animations
if (property.mProperty == eCSSProperty_transform) {
if (!CanAnimateTransformOnCompositor(aFrame,
shouldLog ? aFrame->GetContent() : nullptr)) {
return true;
}
}
}
return true;
return false;
}
} // namespace dom

View File

@ -287,9 +287,22 @@ public:
bool CanThrottle() const;
// Returns true |aProperty| can be run on compositor for |aFrame|.
static bool CanAnimatePropertyOnCompositor(const nsIFrame* aFrame,
nsCSSProperty aProperty);
// Returns true if this effect, applied to |aFrame|, contains
// properties that mean we shouldn't run *any* compositor animations on this
// element.
//
// For example, if we have an animation of geometric properties like 'left'
// and 'top' on an element, we force all 'transform' and 'opacity' animations
// running at the same time on the same element to run on the main thread.
//
// Similarly, some transform animations cannot be run on the compositor and
// when that is the case we simply disable all compositor animations
// on the same element.
//
// Bug 1218620 - It seems like we don't need to be this restrictive. Wouldn't
// it be ok to do 'opacity' animations on the compositor in either case?
bool ShouldBlockCompositorAnimations(const nsIFrame* aFrame) const;
nsIDocument* GetRenderedDocument() const;
nsPresContext* GetPresContext() const;

View File

@ -456,14 +456,8 @@ AnimationCollection::CanPerformOnCompositorThread(const nsIFrame* aFrame) const
const KeyframeEffectReadOnly* effect = anim->GetEffect();
MOZ_ASSERT(effect, "A playing animation should have an effect");
for (size_t propIdx = 0, propEnd = effect->Properties().Length();
propIdx != propEnd; ++propIdx) {
const AnimationProperty& prop = effect->Properties()[propIdx];
if (!KeyframeEffectReadOnly::CanAnimatePropertyOnCompositor(
aFrame,
prop.mProperty)) {
return false;
}
if (effect->ShouldBlockCompositorAnimations(aFrame)) {
return false;
}
}