зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1004383 part 1 - Put StyleAnimation on the heap; r=dbaron
This patch takes StyleAnimation and makes it ref-counted heap object. This should allow us to store StyleAnimation and its subclasses (transitions only currently) in a consistent fashion (an array of base-class pointers). Furthermore, this will be helpful if we want these things to be pointed to from Javascript objects that may, for example, preserve their lifetime beyond that of the element that currently owns them. This patch also introduces a typedef for an array of refptrs to StyleAnimation objects (and similarly for the subclass ElementPropertyTransition) to simplify the code somewhat.
This commit is contained in:
Родитель
d9132dfd34
Коммит
7595a03399
|
@ -377,7 +377,7 @@ AddAnimationsForProperty(nsIFrame* aFrame, nsCSSProperty aProperty,
|
|||
mozilla::TimeStamp currentTime =
|
||||
aFrame->PresContext()->RefreshDriver()->MostRecentRefresh();
|
||||
for (uint32_t animIdx = 0; animIdx < aAnimations.Length(); animIdx++) {
|
||||
mozilla::StyleAnimation* anim = &aAnimations[animIdx];
|
||||
mozilla::StyleAnimation* anim = aAnimations[animIdx];
|
||||
if (!(anim->HasAnimationOfProperty(aProperty) &&
|
||||
anim->IsRunningAt(currentTime))) {
|
||||
continue;
|
||||
|
|
|
@ -391,9 +391,9 @@ nsLayoutUtils::ComputeSuitableScaleForAnimation(nsIContent* aContent)
|
|||
(aContent, nsGkAtoms::animationsProperty, eCSSProperty_transform);
|
||||
if (animations) {
|
||||
for (uint32_t animIdx = animations->mAnimations.Length(); animIdx-- != 0; ) {
|
||||
mozilla::StyleAnimation& anim = animations->mAnimations[animIdx];
|
||||
for (uint32_t propIdx = anim.mProperties.Length(); propIdx-- != 0; ) {
|
||||
AnimationProperty& prop = anim.mProperties[propIdx];
|
||||
mozilla::StyleAnimation* anim = animations->mAnimations[animIdx];
|
||||
for (uint32_t propIdx = anim->mProperties.Length(); propIdx-- != 0; ) {
|
||||
AnimationProperty& prop = anim->mProperties[propIdx];
|
||||
if (prop.mProperty == eCSSProperty_transform) {
|
||||
for (uint32_t segIdx = prop.mSegments.Length(); segIdx-- != 0; ) {
|
||||
AnimationPropertySegment& segment = prop.mSegments[segIdx];
|
||||
|
@ -420,17 +420,17 @@ nsLayoutUtils::ComputeSuitableScaleForAnimation(nsIContent* aContent)
|
|||
if (transitions) {
|
||||
for (uint32_t i = 0, i_end = transitions->mPropertyTransitions.Length();
|
||||
i < i_end; ++i){
|
||||
ElementPropertyTransition &pt = transitions->mPropertyTransitions[i];
|
||||
if (pt.IsRemovedSentinel()) {
|
||||
ElementPropertyTransition* pt = transitions->mPropertyTransitions[i];
|
||||
if (pt->IsRemovedSentinel()) {
|
||||
continue;
|
||||
}
|
||||
MOZ_ASSERT(pt.mProperties.Length() == 1,
|
||||
MOZ_ASSERT(pt->mProperties.Length() == 1,
|
||||
"Should have one animation property for a transition");
|
||||
MOZ_ASSERT(pt.mProperties[0].mSegments.Length() == 1,
|
||||
MOZ_ASSERT(pt->mProperties[0].mSegments.Length() == 1,
|
||||
"Animation property should have one segment for a transition");
|
||||
const AnimationPropertySegment& segment = pt.mProperties[0].mSegments[0];
|
||||
const AnimationPropertySegment& segment = pt->mProperties[0].mSegments[0];
|
||||
|
||||
if (pt.mProperties[0].mProperty == eCSSProperty_transform) {
|
||||
if (pt->mProperties[0].mProperty == eCSSProperty_transform) {
|
||||
gfxSize start = GetScaleForValue(segment.mFromValue,
|
||||
aContent->GetPrimaryFrame());
|
||||
maxScale.width = std::max<float>(maxScale.width, start.width);
|
||||
|
|
|
@ -278,8 +278,12 @@ struct StyleAnimation
|
|||
uint32_t mLastNotification;
|
||||
|
||||
InfallibleTArray<AnimationProperty> mProperties;
|
||||
|
||||
NS_INLINE_DECL_REFCOUNTING(StyleAnimation)
|
||||
};
|
||||
|
||||
typedef InfallibleTArray<nsRefPtr<StyleAnimation> > StyleAnimationPtrArray;
|
||||
|
||||
namespace css {
|
||||
|
||||
struct CommonElementAnimationData : public PRCList
|
||||
|
|
|
@ -179,22 +179,22 @@ ElementAnimations::EnsureStyleRuleFor(TimeStamp aRefreshTime,
|
|||
// the style recalculation if we find any.
|
||||
if (aIsThrottled) {
|
||||
for (uint32_t animIdx = mAnimations.Length(); animIdx-- != 0; ) {
|
||||
StyleAnimation &anim = mAnimations[animIdx];
|
||||
StyleAnimation* anim = mAnimations[animIdx];
|
||||
|
||||
if (anim.mProperties.Length() == 0 ||
|
||||
anim.mIterationDuration.ToMilliseconds() <= 0.0) {
|
||||
if (anim->mProperties.Length() == 0 ||
|
||||
anim->mIterationDuration.ToMilliseconds() <= 0.0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
uint32_t oldLastNotification = anim.mLastNotification;
|
||||
uint32_t oldLastNotification = anim->mLastNotification;
|
||||
|
||||
// We need to call GetPositionInIteration here to populate
|
||||
// aEventsToDispatch.
|
||||
// The ElapsedDurationAt() call here handles pausing. But:
|
||||
// FIXME: avoid recalculating every time when paused.
|
||||
GetPositionInIteration(anim.ElapsedDurationAt(aRefreshTime),
|
||||
anim.mIterationDuration, anim.mIterationCount,
|
||||
anim.mDirection, &anim, this, &aEventsToDispatch);
|
||||
GetPositionInIteration(anim->ElapsedDurationAt(aRefreshTime),
|
||||
anim->mIterationDuration, anim->mIterationCount,
|
||||
anim->mDirection, anim, this, &aEventsToDispatch);
|
||||
|
||||
// GetPositionInIteration just adjusted mLastNotification; check
|
||||
// its new value against the value before we called
|
||||
|
@ -203,9 +203,9 @@ ElementAnimations::EnsureStyleRuleFor(TimeStamp aRefreshTime,
|
|||
// indicator that the animation has finished, it should be reserved for
|
||||
// events. If we use it differently in the future this use might need
|
||||
// changing.
|
||||
if (!anim.mIsRunningOnCompositor ||
|
||||
(anim.mLastNotification != oldLastNotification &&
|
||||
anim.mLastNotification == StyleAnimation::LAST_NOTIFICATION_END)) {
|
||||
if (!anim->mIsRunningOnCompositor ||
|
||||
(anim->mLastNotification != oldLastNotification &&
|
||||
anim->mLastNotification == StyleAnimation::LAST_NOTIFICATION_END)) {
|
||||
aIsThrottled = false;
|
||||
break;
|
||||
}
|
||||
|
@ -230,10 +230,10 @@ ElementAnimations::EnsureStyleRuleFor(TimeStamp aRefreshTime,
|
|||
nsCSSPropertySet properties;
|
||||
|
||||
for (uint32_t animIdx = mAnimations.Length(); animIdx-- != 0; ) {
|
||||
StyleAnimation &anim = mAnimations[animIdx];
|
||||
StyleAnimation* anim = mAnimations[animIdx];
|
||||
|
||||
if (anim.mProperties.Length() == 0 ||
|
||||
anim.mIterationDuration.ToMilliseconds() <= 0.0) {
|
||||
if (anim->mProperties.Length() == 0 ||
|
||||
anim->mIterationDuration.ToMilliseconds() <= 0.0) {
|
||||
// No animation data.
|
||||
continue;
|
||||
}
|
||||
|
@ -241,9 +241,9 @@ ElementAnimations::EnsureStyleRuleFor(TimeStamp aRefreshTime,
|
|||
// The ElapsedDurationAt() call here handles pausing. But:
|
||||
// FIXME: avoid recalculating every time when paused.
|
||||
double positionInIteration =
|
||||
GetPositionInIteration(anim.ElapsedDurationAt(aRefreshTime),
|
||||
anim.mIterationDuration, anim.mIterationCount,
|
||||
anim.mDirection, &anim, this,
|
||||
GetPositionInIteration(anim->ElapsedDurationAt(aRefreshTime),
|
||||
anim->mIterationDuration, anim->mIterationCount,
|
||||
anim->mDirection, anim, this,
|
||||
&aEventsToDispatch);
|
||||
|
||||
// The position is -1 when we don't have fill data for the current time,
|
||||
|
@ -255,10 +255,10 @@ ElementAnimations::EnsureStyleRuleFor(TimeStamp aRefreshTime,
|
|||
positionInIteration <= 1.0,
|
||||
"position should be in [0-1]");
|
||||
|
||||
for (uint32_t propIdx = 0, propEnd = anim.mProperties.Length();
|
||||
for (uint32_t propIdx = 0, propEnd = anim->mProperties.Length();
|
||||
propIdx != propEnd; ++propIdx)
|
||||
{
|
||||
const AnimationProperty &prop = anim.mProperties[propIdx];
|
||||
const AnimationProperty &prop = anim->mProperties[propIdx];
|
||||
|
||||
NS_ABORT_IF_FALSE(prop.mSegments[0].mFromKey == 0.0,
|
||||
"incorrect first from key");
|
||||
|
@ -330,8 +330,8 @@ bool
|
|||
ElementAnimations::HasAnimationOfProperty(nsCSSProperty aProperty) const
|
||||
{
|
||||
for (uint32_t animIdx = mAnimations.Length(); animIdx-- != 0; ) {
|
||||
const StyleAnimation &anim = mAnimations[animIdx];
|
||||
if (anim.HasAnimationOfProperty(aProperty)) {
|
||||
const StyleAnimation* anim = mAnimations[animIdx];
|
||||
if (anim->HasAnimationOfProperty(aProperty)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -360,11 +360,11 @@ ElementAnimations::CanPerformOnCompositorThread(CanAnimateFlags aFlags) const
|
|||
TimeStamp now = frame->PresContext()->RefreshDriver()->MostRecentRefresh();
|
||||
|
||||
for (uint32_t animIdx = mAnimations.Length(); animIdx-- != 0; ) {
|
||||
const StyleAnimation& anim = mAnimations[animIdx];
|
||||
for (uint32_t propIdx = 0, propEnd = anim.mProperties.Length();
|
||||
const StyleAnimation* anim = mAnimations[animIdx];
|
||||
for (uint32_t propIdx = 0, propEnd = anim->mProperties.Length();
|
||||
propIdx != propEnd; ++propIdx) {
|
||||
if (IsGeometricProperty(anim.mProperties[propIdx].mProperty) &&
|
||||
anim.IsRunningAt(now)) {
|
||||
if (IsGeometricProperty(anim->mProperties[propIdx].mProperty) &&
|
||||
anim->IsRunningAt(now)) {
|
||||
aFlags = CanAnimateFlags(aFlags | CanAnimate_HasGeometricProperty);
|
||||
break;
|
||||
}
|
||||
|
@ -374,14 +374,14 @@ ElementAnimations::CanPerformOnCompositorThread(CanAnimateFlags aFlags) const
|
|||
bool hasOpacity = false;
|
||||
bool hasTransform = false;
|
||||
for (uint32_t animIdx = mAnimations.Length(); animIdx-- != 0; ) {
|
||||
const StyleAnimation& anim = mAnimations[animIdx];
|
||||
if (!anim.IsRunningAt(now)) {
|
||||
const StyleAnimation* anim = mAnimations[animIdx];
|
||||
if (!anim->IsRunningAt(now)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (uint32_t propIdx = 0, propEnd = anim.mProperties.Length();
|
||||
for (uint32_t propIdx = 0, propEnd = anim->mProperties.Length();
|
||||
propIdx != propEnd; ++propIdx) {
|
||||
const AnimationProperty& prop = anim.mProperties[propIdx];
|
||||
const AnimationProperty& prop = anim->mProperties[propIdx];
|
||||
if (!CanAnimatePropertyOnCompositor(mElement,
|
||||
prop.mProperty,
|
||||
aFlags) ||
|
||||
|
@ -547,7 +547,7 @@ nsAnimationManager::CheckAnimationRule(nsStyleContext* aStyleContext,
|
|||
}
|
||||
|
||||
// build the animations list
|
||||
InfallibleTArray<StyleAnimation> newAnimations;
|
||||
StyleAnimationPtrArray newAnimations;
|
||||
BuildAnimations(aStyleContext, newAnimations);
|
||||
|
||||
if (newAnimations.IsEmpty()) {
|
||||
|
@ -577,7 +577,7 @@ nsAnimationManager::CheckAnimationRule(nsStyleContext* aStyleContext,
|
|||
if (!ea->mAnimations.IsEmpty()) {
|
||||
for (uint32_t newIdx = 0, newEnd = newAnimations.Length();
|
||||
newIdx != newEnd; ++newIdx) {
|
||||
StyleAnimation *newAnim = &newAnimations[newIdx];
|
||||
nsRefPtr<StyleAnimation> newAnim = newAnimations[newIdx];
|
||||
|
||||
// Find the matching animation with this name in the old list
|
||||
// of animations. Because of this code, they must all have
|
||||
|
@ -587,9 +587,9 @@ nsAnimationManager::CheckAnimationRule(nsStyleContext* aStyleContext,
|
|||
// different pause states, they, well, get what they deserve.
|
||||
// We'll use the last one since it's more likely to be the one
|
||||
// doing something.
|
||||
const StyleAnimation *oldAnim = nullptr;
|
||||
const StyleAnimation* oldAnim = nullptr;
|
||||
for (uint32_t oldIdx = ea->mAnimations.Length(); oldIdx-- != 0; ) {
|
||||
const StyleAnimation *a = &ea->mAnimations[oldIdx];
|
||||
const StyleAnimation* a = ea->mAnimations[oldIdx];
|
||||
if (a->mName == newAnim->mName) {
|
||||
oldAnim = a;
|
||||
break;
|
||||
|
@ -717,8 +717,7 @@ ResolvedStyleCache::Get(nsPresContext *aPresContext,
|
|||
|
||||
void
|
||||
nsAnimationManager::BuildAnimations(nsStyleContext* aStyleContext,
|
||||
InfallibleTArray<StyleAnimation>&
|
||||
aAnimations)
|
||||
StyleAnimationPtrArray& aAnimations)
|
||||
{
|
||||
NS_ABORT_IF_FALSE(aAnimations.IsEmpty(), "expect empty array");
|
||||
|
||||
|
@ -728,27 +727,30 @@ nsAnimationManager::BuildAnimations(nsStyleContext* aStyleContext,
|
|||
TimeStamp now = mPresContext->RefreshDriver()->MostRecentRefresh();
|
||||
for (uint32_t animIdx = 0, animEnd = disp->mAnimationNameCount;
|
||||
animIdx != animEnd; ++animIdx) {
|
||||
const nsAnimation& aSrc = disp->mAnimations[animIdx];
|
||||
StyleAnimation& aDest = *aAnimations.AppendElement();
|
||||
const nsAnimation& src = disp->mAnimations[animIdx];
|
||||
nsRefPtr<StyleAnimation> dest =
|
||||
*aAnimations.AppendElement(new StyleAnimation());
|
||||
|
||||
aDest.mName = aSrc.GetName();
|
||||
aDest.mIterationCount = aSrc.GetIterationCount();
|
||||
aDest.mDirection = aSrc.GetDirection();
|
||||
aDest.mFillMode = aSrc.GetFillMode();
|
||||
aDest.mPlayState = aSrc.GetPlayState();
|
||||
dest->mName = src.GetName();
|
||||
dest->mIterationCount = src.GetIterationCount();
|
||||
dest->mDirection = src.GetDirection();
|
||||
dest->mFillMode = src.GetFillMode();
|
||||
dest->mPlayState = src.GetPlayState();
|
||||
|
||||
aDest.mDelay = TimeDuration::FromMilliseconds(aSrc.GetDelay());
|
||||
aDest.mStartTime = now;
|
||||
if (aDest.IsPaused()) {
|
||||
aDest.mPauseStart = now;
|
||||
dest->mDelay = TimeDuration::FromMilliseconds(src.GetDelay());
|
||||
dest->mStartTime = now;
|
||||
if (dest->IsPaused()) {
|
||||
dest->mPauseStart = now;
|
||||
} else {
|
||||
aDest.mPauseStart = TimeStamp();
|
||||
dest->mPauseStart = TimeStamp();
|
||||
}
|
||||
|
||||
aDest.mIterationDuration = TimeDuration::FromMilliseconds(aSrc.GetDuration());
|
||||
dest->mIterationDuration =
|
||||
TimeDuration::FromMilliseconds(src.GetDuration());
|
||||
|
||||
nsCSSKeyframesRule* rule =
|
||||
mPresContext->StyleSet()->KeyframesRuleForName(mPresContext, aDest.mName);
|
||||
mPresContext->StyleSet()->KeyframesRuleForName(mPresContext,
|
||||
dest->mName);
|
||||
if (!rule) {
|
||||
// no segments
|
||||
continue;
|
||||
|
@ -841,7 +843,7 @@ nsAnimationManager::BuildAnimations(nsStyleContext* aStyleContext,
|
|||
lastKey = kf.mKey;
|
||||
}
|
||||
|
||||
AnimationProperty &propData = *aDest.mProperties.AppendElement();
|
||||
AnimationProperty &propData = *dest->mProperties.AppendElement();
|
||||
propData.mProperty = prop;
|
||||
|
||||
KeyframeData *fromKeyframe = nullptr;
|
||||
|
@ -857,7 +859,7 @@ nsAnimationManager::BuildAnimations(nsStyleContext* aStyleContext,
|
|||
|
||||
if (fromKeyframe) {
|
||||
interpolated = interpolated &&
|
||||
BuildSegment(propData.mSegments, prop, aSrc,
|
||||
BuildSegment(propData.mSegments, prop, src,
|
||||
fromKeyframe->mKey, fromContext,
|
||||
fromKeyframe->mRule->Declaration(),
|
||||
toKeyframe.mKey, toContext);
|
||||
|
@ -866,7 +868,7 @@ nsAnimationManager::BuildAnimations(nsStyleContext* aStyleContext,
|
|||
// There's no data for this property at 0%, so use the
|
||||
// cascaded value above us.
|
||||
interpolated = interpolated &&
|
||||
BuildSegment(propData.mSegments, prop, aSrc,
|
||||
BuildSegment(propData.mSegments, prop, src,
|
||||
0.0f, aStyleContext, nullptr,
|
||||
toKeyframe.mKey, toContext);
|
||||
}
|
||||
|
@ -880,7 +882,7 @@ nsAnimationManager::BuildAnimations(nsStyleContext* aStyleContext,
|
|||
// There's no data for this property at 100%, so use the
|
||||
// cascaded value above us.
|
||||
interpolated = interpolated &&
|
||||
BuildSegment(propData.mSegments, prop, aSrc,
|
||||
BuildSegment(propData.mSegments, prop, src,
|
||||
fromKeyframe->mKey, fromContext,
|
||||
fromKeyframe->mRule->Declaration(),
|
||||
1.0f, aStyleContext);
|
||||
|
@ -893,9 +895,11 @@ nsAnimationManager::BuildAnimations(nsStyleContext* aStyleContext,
|
|||
// values (which?) or skip segments, so best to skip the whole
|
||||
// thing for now.)
|
||||
if (!interpolated) {
|
||||
aDest.mProperties.RemoveElementAt(aDest.mProperties.Length() - 1);
|
||||
dest->mProperties.RemoveElementAt(dest->mProperties.Length() - 1);
|
||||
}
|
||||
}
|
||||
|
||||
aAnimations.AppendElement(dest);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -127,7 +127,7 @@ struct ElementAnimations MOZ_FINAL
|
|||
// either completed or paused). May be invalidated by a style change.
|
||||
bool mNeedsRefreshes;
|
||||
|
||||
InfallibleTArray<mozilla::StyleAnimation> mAnimations;
|
||||
mozilla::StyleAnimationPtrArray mAnimations;
|
||||
};
|
||||
|
||||
class nsAnimationManager MOZ_FINAL
|
||||
|
@ -236,7 +236,7 @@ protected:
|
|||
|
||||
private:
|
||||
void BuildAnimations(nsStyleContext* aStyleContext,
|
||||
InfallibleTArray<mozilla::StyleAnimation>& aAnimations);
|
||||
mozilla::StyleAnimationPtrArray& aAnimations);
|
||||
bool BuildSegment(InfallibleTArray<mozilla::AnimationPropertySegment>&
|
||||
aSegments,
|
||||
nsCSSProperty aProperty, const nsAnimation& aAnimation,
|
||||
|
|
|
@ -105,18 +105,18 @@ ElementTransitions::EnsureStyleRuleFor(TimeStamp aRefreshTime)
|
|||
|
||||
for (uint32_t i = 0, i_end = mPropertyTransitions.Length(); i < i_end; ++i)
|
||||
{
|
||||
ElementPropertyTransition &pt = mPropertyTransitions[i];
|
||||
if (pt.IsRemovedSentinel()) {
|
||||
ElementPropertyTransition* pt = mPropertyTransitions[i];
|
||||
if (pt->IsRemovedSentinel()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(pt.mProperties.Length() == 1,
|
||||
MOZ_ASSERT(pt->mProperties.Length() == 1,
|
||||
"Should have one animation property for a transition");
|
||||
const AnimationProperty &prop = pt.mProperties[0];
|
||||
const AnimationProperty &prop = pt->mProperties[0];
|
||||
|
||||
nsStyleAnimation::Value *val = mStyleRule->AddEmptyValue(prop.mProperty);
|
||||
|
||||
double valuePortion = pt.ValuePortionFor(aRefreshTime);
|
||||
double valuePortion = pt->ValuePortionFor(aRefreshTime);
|
||||
|
||||
MOZ_ASSERT(prop.mSegments.Length() == 1,
|
||||
"Animation property should have one segment for a transition");
|
||||
|
@ -136,8 +136,8 @@ bool
|
|||
ElementTransitions::HasAnimationOfProperty(nsCSSProperty aProperty) const
|
||||
{
|
||||
for (uint32_t tranIdx = mPropertyTransitions.Length(); tranIdx-- != 0; ) {
|
||||
const ElementPropertyTransition& pt = mPropertyTransitions[tranIdx];
|
||||
if (pt.HasAnimationOfProperty(aProperty) && !pt.IsRemovedSentinel()) {
|
||||
const ElementPropertyTransition* pt = mPropertyTransitions[tranIdx];
|
||||
if (pt->HasAnimationOfProperty(aProperty) && !pt->IsRemovedSentinel()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -164,11 +164,11 @@ ElementTransitions::CanPerformOnCompositorThread(CanAnimateFlags aFlags) const
|
|||
TimeStamp now = frame->PresContext()->RefreshDriver()->MostRecentRefresh();
|
||||
|
||||
for (uint32_t i = 0, i_end = mPropertyTransitions.Length(); i < i_end; ++i) {
|
||||
const ElementPropertyTransition& pt = mPropertyTransitions[i];
|
||||
MOZ_ASSERT(pt.mProperties.Length() == 1,
|
||||
const ElementPropertyTransition* pt = mPropertyTransitions[i];
|
||||
MOZ_ASSERT(pt->mProperties.Length() == 1,
|
||||
"Should have one animation property for a transition");
|
||||
if (css::IsGeometricProperty(pt.mProperties[0].mProperty) &&
|
||||
pt.IsRunningAt(now)) {
|
||||
if (css::IsGeometricProperty(pt->mProperties[0].mProperty) &&
|
||||
pt->IsRunningAt(now)) {
|
||||
aFlags = CanAnimateFlags(aFlags | CanAnimate_HasGeometricProperty);
|
||||
break;
|
||||
}
|
||||
|
@ -178,16 +178,16 @@ ElementTransitions::CanPerformOnCompositorThread(CanAnimateFlags aFlags) const
|
|||
bool hasTransform = false;
|
||||
bool existsProperty = false;
|
||||
for (uint32_t i = 0, i_end = mPropertyTransitions.Length(); i < i_end; ++i) {
|
||||
const ElementPropertyTransition& pt = mPropertyTransitions[i];
|
||||
if (!pt.IsRunningAt(now)) {
|
||||
const ElementPropertyTransition* pt = mPropertyTransitions[i];
|
||||
if (!pt->IsRunningAt(now)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
existsProperty = true;
|
||||
|
||||
MOZ_ASSERT(pt.mProperties.Length() == 1,
|
||||
MOZ_ASSERT(pt->mProperties.Length() == 1,
|
||||
"Should have one animation property for a transition");
|
||||
const AnimationProperty& prop = pt.mProperties[0];
|
||||
const AnimationProperty& prop = pt->mProperties[0];
|
||||
|
||||
if (!css::CommonElementAnimationData::CanAnimatePropertyOnCompositor(
|
||||
mElement, prop.mProperty, aFlags) ||
|
||||
|
@ -449,18 +449,18 @@ nsTransitionManager::StyleContextChanged(dom::Element *aElement,
|
|||
}
|
||||
}
|
||||
|
||||
nsTArray<ElementPropertyTransition> &pts = et->mPropertyTransitions;
|
||||
ElementTransitions::TransitionPtrArray &pts = et->mPropertyTransitions;
|
||||
uint32_t i = pts.Length();
|
||||
NS_ABORT_IF_FALSE(i != 0, "empty transitions list?");
|
||||
nsStyleAnimation::Value currentValue;
|
||||
do {
|
||||
--i;
|
||||
ElementPropertyTransition &pt = pts[i];
|
||||
MOZ_ASSERT(pt.mProperties.Length() == 1,
|
||||
ElementPropertyTransition* pt = pts[i];
|
||||
MOZ_ASSERT(pt->mProperties.Length() == 1,
|
||||
"Should have one animation property for a transition");
|
||||
MOZ_ASSERT(pt.mProperties[0].mSegments.Length() == 1,
|
||||
MOZ_ASSERT(pt->mProperties[0].mSegments.Length() == 1,
|
||||
"Animation property should have one segment for a transition");
|
||||
const AnimationProperty& prop = pt.mProperties[0];
|
||||
const AnimationProperty& prop = pt->mProperties[0];
|
||||
const AnimationPropertySegment& segment = prop.mSegments[0];
|
||||
// properties no longer in 'transition-property'
|
||||
if ((checkProperties &&
|
||||
|
@ -506,14 +506,14 @@ nsTransitionManager::StyleContextChanged(dom::Element *aElement,
|
|||
|
||||
nsRefPtr<css::AnimValuesStyleRule> coverRule = new css::AnimValuesStyleRule;
|
||||
|
||||
nsTArray<ElementPropertyTransition> &pts = et->mPropertyTransitions;
|
||||
ElementTransitions::TransitionPtrArray &pts = et->mPropertyTransitions;
|
||||
for (uint32_t i = 0, i_end = pts.Length(); i < i_end; ++i) {
|
||||
ElementPropertyTransition &pt = pts[i];
|
||||
MOZ_ASSERT(pt.mProperties.Length() == 1,
|
||||
ElementPropertyTransition* pt = pts[i];
|
||||
MOZ_ASSERT(pt->mProperties.Length() == 1,
|
||||
"Should have one animation property for a transition");
|
||||
MOZ_ASSERT(pt.mProperties[0].mSegments.Length() == 1,
|
||||
MOZ_ASSERT(pt->mProperties[0].mSegments.Length() == 1,
|
||||
"Animation property should have one segment for a transition");
|
||||
AnimationProperty& prop = pt.mProperties[0];
|
||||
AnimationProperty& prop = pt->mProperties[0];
|
||||
AnimationPropertySegment& segment = prop.mSegments[0];
|
||||
if (whichStarted.HasProperty(prop.mProperty)) {
|
||||
coverRule->AddValue(prop.mProperty, segment.mFromValue);
|
||||
|
@ -553,7 +553,7 @@ nsTransitionManager::ConsiderStartingTransition(nsCSSProperty aProperty,
|
|||
return;
|
||||
}
|
||||
|
||||
ElementPropertyTransition pt;
|
||||
nsRefPtr<ElementPropertyTransition> pt = new ElementPropertyTransition();
|
||||
|
||||
nsStyleAnimation::Value startValue, endValue, dummyValue;
|
||||
bool haveValues =
|
||||
|
@ -577,15 +577,15 @@ nsTransitionManager::ConsiderStartingTransition(nsCSSProperty aProperty,
|
|||
size_t currentIndex = nsTArray<ElementPropertyTransition>::NoIndex;
|
||||
const ElementPropertyTransition *oldPT = nullptr;
|
||||
if (aElementTransitions) {
|
||||
nsTArray<ElementPropertyTransition> &pts =
|
||||
ElementTransitions::TransitionPtrArray &pts =
|
||||
aElementTransitions->mPropertyTransitions;
|
||||
for (size_t i = 0, i_end = pts.Length(); i < i_end; ++i) {
|
||||
MOZ_ASSERT(pts[i].mProperties.Length() == 1,
|
||||
MOZ_ASSERT(pts[i]->mProperties.Length() == 1,
|
||||
"Should have one animation property for a transition");
|
||||
if (pts[i].mProperties[0].mProperty == aProperty) {
|
||||
if (pts[i]->mProperties[0].mProperty == aProperty) {
|
||||
haveCurrentTransition = true;
|
||||
currentIndex = i;
|
||||
oldPT = &aElementTransitions->mPropertyTransitions[currentIndex];
|
||||
oldPT = aElementTransitions->mPropertyTransitions[currentIndex];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -618,7 +618,7 @@ nsTransitionManager::ConsiderStartingTransition(nsCSSProperty aProperty,
|
|||
// in-progress value (which is particularly easy to cause when we're
|
||||
// currently in the 'transition-delay'). It also might happen because we
|
||||
// just got a style change to a value that can't be interpolated.
|
||||
nsTArray<ElementPropertyTransition> &pts =
|
||||
ElementTransitions::TransitionPtrArray &pts =
|
||||
aElementTransitions->mPropertyTransitions;
|
||||
pts.RemoveElementAt(currentIndex);
|
||||
aElementTransitions->UpdateAnimationGeneration(mPresContext);
|
||||
|
@ -643,8 +643,8 @@ nsTransitionManager::ConsiderStartingTransition(nsCSSProperty aProperty,
|
|||
// The spec says a negative duration is treated as zero.
|
||||
duration = 0.0;
|
||||
}
|
||||
pt.mStartForReversingTest = startValue;
|
||||
pt.mReversePortion = 1.0;
|
||||
pt->mStartForReversingTest = startValue;
|
||||
pt->mReversePortion = 1.0;
|
||||
|
||||
// If the new transition reverses an existing one, we'll need to
|
||||
// handle the timing differently.
|
||||
|
@ -681,11 +681,11 @@ nsTransitionManager::ConsiderStartingTransition(nsCSSProperty aProperty,
|
|||
|
||||
duration *= valuePortion;
|
||||
|
||||
pt.mStartForReversingTest = oldPT->mProperties[0].mSegments[0].mToValue;
|
||||
pt.mReversePortion = valuePortion;
|
||||
pt->mStartForReversingTest = oldPT->mProperties[0].mSegments[0].mToValue;
|
||||
pt->mReversePortion = valuePortion;
|
||||
}
|
||||
|
||||
AnimationProperty& prop = *pt.mProperties.AppendElement();
|
||||
AnimationProperty& prop = *pt->mProperties.AppendElement();
|
||||
prop.mProperty = aProperty;
|
||||
|
||||
AnimationPropertySegment& segment = *prop.mSegments.AppendElement();
|
||||
|
@ -695,14 +695,14 @@ nsTransitionManager::ConsiderStartingTransition(nsCSSProperty aProperty,
|
|||
segment.mToKey = 1;
|
||||
segment.mTimingFunction.Init(tf);
|
||||
|
||||
pt.mStartTime = mostRecentRefresh;
|
||||
pt.mDelay = TimeDuration::FromMilliseconds(delay);
|
||||
pt.mIterationDuration = TimeDuration::FromMilliseconds(duration);
|
||||
pt.mIterationCount = 1;
|
||||
pt.mDirection = NS_STYLE_ANIMATION_DIRECTION_NORMAL;
|
||||
pt.mFillMode = NS_STYLE_ANIMATION_FILL_MODE_BACKWARDS;
|
||||
pt.mPlayState = NS_STYLE_ANIMATION_PLAY_STATE_RUNNING;
|
||||
pt.mPauseStart = TimeStamp();
|
||||
pt->mStartTime = mostRecentRefresh;
|
||||
pt->mDelay = TimeDuration::FromMilliseconds(delay);
|
||||
pt->mIterationDuration = TimeDuration::FromMilliseconds(duration);
|
||||
pt->mIterationCount = 1;
|
||||
pt->mDirection = NS_STYLE_ANIMATION_DIRECTION_NORMAL;
|
||||
pt->mFillMode = NS_STYLE_ANIMATION_FILL_MODE_BACKWARDS;
|
||||
pt->mPlayState = NS_STYLE_ANIMATION_PLAY_STATE_RUNNING;
|
||||
pt->mPauseStart = TimeStamp();
|
||||
|
||||
if (!aElementTransitions) {
|
||||
aElementTransitions =
|
||||
|
@ -714,14 +714,14 @@ nsTransitionManager::ConsiderStartingTransition(nsCSSProperty aProperty,
|
|||
}
|
||||
}
|
||||
|
||||
nsTArray<ElementPropertyTransition> &pts =
|
||||
ElementTransitions::TransitionPtrArray &pts =
|
||||
aElementTransitions->mPropertyTransitions;
|
||||
#ifdef DEBUG
|
||||
for (uint32_t i = 0, i_end = pts.Length(); i < i_end; ++i) {
|
||||
NS_ABORT_IF_FALSE(pts[i].mProperties.Length() == 1,
|
||||
NS_ABORT_IF_FALSE(pts[i]->mProperties.Length() == 1,
|
||||
"Should have one animation property for a transition");
|
||||
NS_ABORT_IF_FALSE(i == currentIndex ||
|
||||
pts[i].mProperties[0].mProperty != aProperty,
|
||||
pts[i]->mProperties[0].mProperty != aProperty,
|
||||
"duplicate transitions for property");
|
||||
}
|
||||
#endif
|
||||
|
@ -955,8 +955,8 @@ nsTransitionManager::FlushTransitions(FlushFlags aFlags)
|
|||
bool transitionStartedOrEnded = false;
|
||||
do {
|
||||
--i;
|
||||
ElementPropertyTransition &pt = et->mPropertyTransitions[i];
|
||||
if (pt.IsRemovedSentinel()) {
|
||||
ElementPropertyTransition* pt = et->mPropertyTransitions[i];
|
||||
if (pt->IsRemovedSentinel()) {
|
||||
// Actually remove transitions one throttle-able cycle after their
|
||||
// completion. We only clear on a throttle-able cycle because that
|
||||
// means it is a regular restyle tick and thus it is safe to discard
|
||||
|
@ -965,10 +965,11 @@ nsTransitionManager::FlushTransitions(FlushFlags aFlags)
|
|||
if (aFlags == Can_Throttle) {
|
||||
et->mPropertyTransitions.RemoveElementAt(i);
|
||||
}
|
||||
} else if (pt.mStartTime + pt.mDelay + pt.mIterationDuration <= now) {
|
||||
MOZ_ASSERT(pt.mProperties.Length() == 1,
|
||||
} else if (pt->mStartTime + pt->mDelay + pt->mIterationDuration <=
|
||||
now) {
|
||||
MOZ_ASSERT(pt->mProperties.Length() == 1,
|
||||
"Should have one animation property for a transition");
|
||||
nsCSSProperty prop = pt.mProperties[0].mProperty;
|
||||
nsCSSProperty prop = pt->mProperties[0].mProperty;
|
||||
if (nsCSSProps::PropHasFlags(prop, CSS_PROPERTY_REPORT_OTHER_NAME))
|
||||
{
|
||||
prop = nsCSSProps::OtherNameFor(prop);
|
||||
|
@ -977,7 +978,7 @@ nsTransitionManager::FlushTransitions(FlushFlags aFlags)
|
|||
NS_NAMED_LITERAL_STRING(before, "::before");
|
||||
NS_NAMED_LITERAL_STRING(after, "::after");
|
||||
events.AppendElement(
|
||||
TransitionEventInfo(et->mElement, prop, pt.mIterationDuration,
|
||||
TransitionEventInfo(et->mElement, prop, pt->mIterationDuration,
|
||||
ep == nsGkAtoms::transitionsProperty ?
|
||||
EmptyString() :
|
||||
ep == nsGkAtoms::transitionsOfBeforeProperty ?
|
||||
|
@ -991,11 +992,11 @@ nsTransitionManager::FlushTransitions(FlushFlags aFlags)
|
|||
// a non-animation style change that would affect it, we need
|
||||
// to know not to start a new transition for the transition
|
||||
// from the almost-completed value to the final value.
|
||||
pt.SetRemovedSentinel();
|
||||
pt->SetRemovedSentinel();
|
||||
et->UpdateAnimationGeneration(mPresContext);
|
||||
transitionStartedOrEnded = true;
|
||||
} else if (pt.mStartTime + pt.mDelay <= now && canThrottleTick &&
|
||||
!pt.mIsRunningOnCompositor) {
|
||||
} else if (pt->mStartTime + pt->mDelay <= now && canThrottleTick &&
|
||||
!pt->mIsRunningOnCompositor) {
|
||||
// Start a transition with a delay where we should start the
|
||||
// transition proper.
|
||||
et->UpdateAnimationGeneration(mPresContext);
|
||||
|
|
|
@ -87,8 +87,10 @@ struct ElementTransitions MOZ_FINAL
|
|||
// should probably move to the relevant callers.
|
||||
virtual bool CanPerformOnCompositorThread(CanAnimateFlags aFlags) const MOZ_OVERRIDE;
|
||||
|
||||
typedef InfallibleTArray<nsRefPtr<ElementPropertyTransition> >
|
||||
TransitionPtrArray;
|
||||
// Either zero or one for each CSS property:
|
||||
nsTArray<ElementPropertyTransition> mPropertyTransitions;
|
||||
TransitionPtrArray mPropertyTransitions;
|
||||
};
|
||||
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче