Bug 1073336 part 16 - Factor out animation-layer related information to a common database; r=dbaron

This commit is contained in:
Brian Birtles 2014-11-17 13:46:00 +09:00
parent 48893c4454
commit 18c294458c
3 changed files with 52 additions and 31 deletions

View File

@ -12,6 +12,7 @@
#include "RestyleManager.h"
#include "mozilla/EventStates.h"
#include "nsLayoutUtils.h"
#include "AnimationCommon.h" // For GetLayerAnimationInfo
#include "FrameLayerBuilder.h"
#include "GeckoProfiler.h"
#include "nsStyleChangeList.h"
@ -2434,14 +2435,6 @@ ElementRestyler::ElementRestyler(ParentContextFromChildFrame,
void
ElementRestyler::AddLayerChangesForAnimation()
{
static const nsDisplayItem::Type sLayerTypes[] =
{ nsDisplayItem::TYPE_TRANSFORM,
nsDisplayItem::TYPE_OPACITY };
static const nsChangeHint sHints[] = { nsChangeHint_UpdateTransformLayer,
nsChangeHint_UpdateOpacityLayer };
static_assert(MOZ_ARRAY_LENGTH(sLayerTypes) == MOZ_ARRAY_LENGTH(sHints),
"Parallel layer type and hint arrays should have same length");
// Bug 847286 - We should have separate animation generation counters
// on layers for transitions and animations and use != comparison below
// rather than a > comparison.
@ -2449,9 +2442,10 @@ ElementRestyler::AddLayerChangesForAnimation()
RestyleManager::GetMaxAnimationGenerationForFrame(mFrame);
nsChangeHint hint = nsChangeHint(0);
for (size_t i = 0; i < MOZ_ARRAY_LENGTH(sLayerTypes); i++) {
const auto& layerInfo = css::CommonAnimationManager::sLayerAnimationInfo;
for (size_t i = 0; i < ArrayLength(layerInfo); i++) {
Layer* layer =
FrameLayerBuilder::GetDedicatedLayer(mFrame, sLayerTypes[i]);
FrameLayerBuilder::GetDedicatedLayer(mFrame, layerInfo[i].mLayerType);
if (layer && frameGeneration > layer->GetAnimationGeneration()) {
// If we have a transform layer but don't have any transform style, we
// probably just removed the transform but haven't destroyed the layer
@ -2460,11 +2454,11 @@ ElementRestyler::AddLayerChangesForAnimation()
// so we can skip adding any change hint here. (If we *were* to add
// nsChangeHint_UpdateTransformLayer, ApplyRenderingChangeToTree would
// complain that we're updating a transform layer without a transform).
if (sLayerTypes[i] == nsDisplayItem::TYPE_TRANSFORM &&
if (layerInfo[i].mLayerType == nsDisplayItem::TYPE_TRANSFORM &&
!mFrame->StyleDisplay()->HasTransformStyle()) {
continue;
}
NS_UpdateHint(hint, sHints[i]);
NS_UpdateHint(hint, layerInfo[i].mChangeHint);
}
}
if (hint) {

View File

@ -138,10 +138,12 @@ CommonAnimationManager::GetAnimationsForCompositor(nsIContent* aContent,
// Mark the frame as active, in case we are able to throttle this animation.
nsIFrame* frame = nsLayoutUtils::GetStyleFrame(collection->mElement);
if (frame) {
if (aProperty == eCSSProperty_opacity) {
ActiveLayerTracker::NotifyAnimated(frame, eCSSProperty_opacity);
} else if (aProperty == eCSSProperty_transform) {
ActiveLayerTracker::NotifyAnimated(frame, eCSSProperty_transform);
const auto& info = sLayerAnimationInfo;
for (size_t i = 0; i < ArrayLength(info); i++) {
if (aProperty == info[i].mProperty) {
ActiveLayerTracker::NotifyAnimated(frame, aProperty);
break;
}
}
}
@ -255,6 +257,15 @@ CommonAnimationManager::ExtractComputedValueForTransition(
return result;
}
/* static */ const CommonAnimationManager::LayerAnimationRecord
CommonAnimationManager::sLayerAnimationInfo[] =
{ { eCSSProperty_transform,
nsDisplayItem::TYPE_TRANSFORM,
nsChangeHint_UpdateTransformLayer },
{ eCSSProperty_opacity,
nsDisplayItem::TYPE_OPACITY,
nsChangeHint_UpdateOpacityLayer } };
NS_IMPL_ISUPPORTS(AnimValuesStyleRule, nsIStyleRule)
/* virtual */ void
@ -635,27 +646,27 @@ AnimationPlayerCollection::CanThrottleAnimation(TimeStamp aTime)
return false;
}
bool hasTransform = HasAnimationOfProperty(eCSSProperty_transform);
bool hasOpacity = HasAnimationOfProperty(eCSSProperty_opacity);
if (hasOpacity) {
const auto& info = css::CommonAnimationManager::sLayerAnimationInfo;
for (size_t i = 0; i < ArrayLength(info); i++) {
auto record = info[i];
if (!HasAnimationOfProperty(record.mProperty)) {
continue;
}
Layer* layer = FrameLayerBuilder::GetDedicatedLayer(
frame, nsDisplayItem::TYPE_OPACITY);
frame, record.mLayerType);
if (!layer || mAnimationGeneration > layer->GetAnimationGeneration()) {
return false;
}
if (record.mProperty == eCSSProperty_transform &&
!CanThrottleTransformChanges(aTime)) {
return false;
}
}
if (!hasTransform) {
return true;
}
Layer* layer = FrameLayerBuilder::GetDedicatedLayer(
frame, nsDisplayItem::TYPE_TRANSFORM);
if (!layer || mAnimationGeneration > layer->GetAnimationGeneration()) {
return false;
}
return CanThrottleTransformChanges(aTime);
return true;
}
void

View File

@ -10,7 +10,9 @@
#include "nsIStyleRule.h"
#include "nsRefreshDriver.h"
#include "prclist.h"
#include "nsChangeHint.h"
#include "nsCSSProperty.h"
#include "nsDisplayList.h" // For nsDisplayItem::Type
#include "mozilla/MemoryReporting.h"
#include "mozilla/StyleAnimationValue.h"
#include "mozilla/dom/AnimationPlayer.h"
@ -85,6 +87,20 @@ public:
nsStyleContext* aStyleContext,
mozilla::StyleAnimationValue& aComputedValue);
// For CSS properties that may be animated on a separate layer, represents
// a record of the corresponding layer type and change hint.
struct LayerAnimationRecord {
nsCSSProperty mProperty;
nsDisplayItem::Type mLayerType;
nsChangeHint mChangeHint;
};
protected:
static const size_t kLayerRecords = 2;
public:
static const LayerAnimationRecord sLayerAnimationInfo[kLayerRecords];
protected:
virtual ~CommonAnimationManager();