Bug 823460; start throttled transitions with delays; r=dbaron; a=blocking-basecamp

--HG--
extra : rebase_source : 8e57f7106fd8241556e63076f8dedc0cb72052e7
This commit is contained in:
Nicholas Cameron 2012-12-23 17:52:13 +13:00
Родитель 145ff8ddc1
Коммит 950053c77a
3 изменённых файлов: 38 добавлений и 24 удалений

Просмотреть файл

@ -425,6 +425,8 @@ AddAnimationsAndTransitionsToLayer(Layer* aLayer, nsDisplayListBuilder* aBuilder
AddAnimationsForProperty(frame, aProperty, &anim,
aLayer, data);
pt->mIsRunningOnCompositor = true;
}
aLayer->SetAnimationGeneration(et->mAnimationGeneration);
}

Просмотреть файл

@ -990,8 +990,8 @@ nsTransitionManager::FlushTransitions(FlushFlags aFlags)
nsTArray<TransitionEventInfo> events;
TimeStamp now = mPresContext->RefreshDriver()->MostRecentRefresh();
bool didThrottle = false;
// Trim transitions that have completed, and post restyle events for
// frames that are still transitioning.
// Trim transitions that have completed, post restyle events for frames that
// are still transitioning, and start transitions with delays.
{
PRCList *next = PR_LIST_HEAD(&mElementData);
while (next != &mElementData) {
@ -1010,7 +1010,7 @@ nsTransitionManager::FlushTransitions(FlushFlags aFlags)
uint32_t i = et->mPropertyTransitions.Length();
NS_ABORT_IF_FALSE(i != 0, "empty transitions list?");
bool transitionEnded = false;
bool transitionStartedOrEnded = false;
do {
--i;
ElementPropertyTransition &pt = et->mPropertyTransitions[i];
@ -1046,7 +1046,13 @@ nsTransitionManager::FlushTransitions(FlushFlags aFlags)
// from the almost-completed value to the final value.
pt.SetRemovedSentinel();
et->UpdateAnimationGeneration(mPresContext);
transitionEnded = true;
transitionStartedOrEnded = true;
} else if (pt.mStartTime <= now && canThrottleTick &&
!pt.mIsRunningOnCompositor) {
// Start a transition with a delay where we should start the
// transition proper.
et->UpdateAnimationGeneration(mPresContext);
transitionStartedOrEnded = true;
}
} while (i != 0);
@ -1056,7 +1062,7 @@ nsTransitionManager::FlushTransitions(FlushFlags aFlags)
et->mElementProperty == nsGkAtoms::transitionsOfBeforeProperty ||
et->mElementProperty == nsGkAtoms::transitionsOfAfterProperty,
"Unexpected element property; might restyle too much");
if (!canThrottleTick || transitionEnded) {
if (!canThrottleTick || transitionStartedOrEnded) {
nsRestyleHint hint = et->mElementProperty == nsGkAtoms::transitionsProperty ?
eRestyle_Self : eRestyle_Subtree;
mPresContext->PresShell()->RestyleForAnimation(et->mElement, hint);

Просмотреть файл

@ -24,7 +24,9 @@ struct ElementDependentRuleProcessorData;
struct ElementPropertyTransition
{
ElementPropertyTransition() {}
ElementPropertyTransition()
: mIsRunningOnCompositor(false)
{}
nsCSSProperty mProperty;
nsStyleAnimation::Value mStartValue, mEndValue;
@ -50,6 +52,10 @@ struct ElementPropertyTransition
// in again when the transition is back to 2px, the mReversePortion
// for the third transition (from 0px/2px to 10px) will be 0.8.
double mReversePortion;
// true when the transition is running on the compositor. In particular,
// mIsRunningOnCompositor will be false if the transition has a delay and we
// are not yet at mStartTime, so there is no animation on the layer.
bool mIsRunningOnCompositor;
// Compute the portion of the *value* space that we should be through
// at the given time. (The input to the transition timing function
@ -174,24 +180,24 @@ public:
void FlushTransitions(FlushFlags aFlags);
// Performs a 'mini-flush' to make styles from throttled transitions
// up-to-date prior to processing an unrelated style change, so that
// any transitions triggered by that style change produce correct
// results.
//
// In more detail: when we're able to run animations on the
// compositor, we sometimes "throttle" these animations by skipping
// updating style data on the main thread. However, whenever we
// process a normal (non-animation) style change, any changes in
// computed style on elements that have transition-* properties set
// may need to trigger new transitions; this process requires knowing
// both the old and new values of the property. To do this correctly,
// we need to have an up-to-date *old* value of the property on the
// primary frame. So the purpose of the mini-flush is to update the
// style for all throttled transitions and animations to the current
// animation state without making any other updates, so that when we
// process the queued style updates we'll have correct old data to
// compare against. When we do this, we don't bother touching frames
// Performs a 'mini-flush' to make styles from throttled transitions
// up-to-date prior to processing an unrelated style change, so that
// any transitions triggered by that style change produce correct
// results.
//
// In more detail: when we're able to run animations on the
// compositor, we sometimes "throttle" these animations by skipping
// updating style data on the main thread. However, whenever we
// process a normal (non-animation) style change, any changes in
// computed style on elements that have transition-* properties set
// may need to trigger new transitions; this process requires knowing
// both the old and new values of the property. To do this correctly,
// we need to have an up-to-date *old* value of the property on the
// primary frame. So the purpose of the mini-flush is to update the
// style for all throttled transitions and animations to the current
// animation state without making any other updates, so that when we
// process the queued style updates we'll have correct old data to
// compare against. When we do this, we don't bother touching frames
// other than primary frames.
void UpdateAllThrottledStyles();