We also want to cancel transitions with destroyed frames, so the simplest way
is to extend the ability of AnimationsWithDestroyFrame to cancel transitions as
well.
--HG--
extra : rebase_source : 87d09b6204240b51d425269cbdc07103df5d24ef
While processing restyles and starting transitions, we may trigger
a call to EffectCompositor::UpdateCascadeResults which may, in turn, call
EffectCompositor::RequestRestyle with RestyleType::Layer, which ultimately
results in a call to RestyleManager::IncrementAnimationGeneration().
Typically, nsTransitionManager::StyleContextChanged compares the animation
generation on its collection with that of the restyle manager and uses this
to ignore the restyle that it generates. However, given the sequence of events
above, that check may no longer help since the restyle manager's animation
generation will be out of step. As a result,
nsTransitionManager::StyleContextChanged will fail to ignore a subsequent
and redundant restyle. With certain combinations of content, this can mean that
restyles are posted in such a manner than an infinite cycle of restyles ensues.
This patch causes RestyleManager to ignore calls to IncrementAnimationGeneration
when it is already processing restyles such that the animation generation is
only ever updated once per restyle. This makes the check for a matching
animation generation in nsTransitionManager::StyleContextChanged work as
expected, preventing us from generating needless transitions which can produce
this endless loop.
MozReview-Commit-ID: 9HYDrknKPAI
--HG--
extra : rebase_source : f7d9f251d20805fcb4d0d9be04d4343336e69836
RestyleManager currently has a piece of state for tracking if throttled
animations are up-to-date or not. Actually, it's not so much about throttled
animations but really about outstanding changes to animation styles (which
is typically expected to be due to throttling animations but there are
other cases that invalidate the animation style rule that we should be
considering here).
We now have that same information stored in the EffectCompositor so we can
remove the redundant state from RestyleManager. Furthermore, the state stored
in EffectCompositor is more accurate since it captures the case when animation
style needs to be updated twice within a tick, or when nothing needs to be
updated within a tick.
This patch, therefore, introduces EffectCompositor::HasPendingStyleUpdates in
place of setting RestyleManager::mLastUpdateForThrottledAnimations.
nsTransitionManager also uses mLastUpdateForThrottledAnimations to warn if we
have not processed throttled animations. We can't use HasPendingStyleUpdates
here however, since it will return true in the case where we have triggered new
transitions in the process of restyling. However, any new transitions will
trigger "standard" (i.e. not throttled) restyles so we introduce another
method, HasThrottledStyleUpdates, that returns true only if we have outstanding
throttled updates and use this for the warning inside nsTransitionManager.
The bulk of this commit was generated with a script, executed at the top
level of a typical source code checkout. The only non-machine-generated
part was modifying MFBT's moz.build to reflect the new naming.
CLOSED TREE makes big refactorings like this a piece of cake.
# The main substitution.
find . -name '*.cpp' -o -name '*.cc' -o -name '*.h' -o -name '*.mm' -o -name '*.idl'| \
xargs perl -p -i -e '
s/nsRefPtr\.h/RefPtr\.h/g; # handle includes
s/nsRefPtr ?</RefPtr</g; # handle declarations and variables
'
# Handle a special friend declaration in gfx/layers/AtomicRefCountedWithFinalize.h.
perl -p -i -e 's/::nsRefPtr;/::RefPtr;/' gfx/layers/AtomicRefCountedWithFinalize.h
# Handle nsRefPtr.h itself, a couple places that define constructors
# from nsRefPtr, and code generators specially. We do this here, rather
# than indiscriminantly s/nsRefPtr/RefPtr/, because that would rename
# things like nsRefPtrHashtable.
perl -p -i -e 's/nsRefPtr/RefPtr/g' \
mfbt/nsRefPtr.h \
xpcom/glue/nsCOMPtr.h \
xpcom/base/OwningNonNull.h \
ipc/ipdl/ipdl/lower.py \
ipc/ipdl/ipdl/builtin.py \
dom/bindings/Codegen.py \
python/lldbutils/lldbutils/utils.py
# In our indiscriminate substitution above, we renamed
# nsRefPtrGetterAddRefs, the class behind getter_AddRefs. Fix that up.
find . -name '*.cpp' -o -name '*.h' -o -name '*.idl' | \
xargs perl -p -i -e 's/nsRefPtrGetterAddRefs/RefPtrGetterAddRefs/g'
if [ -d .git ]; then
git mv mfbt/nsRefPtr.h mfbt/RefPtr.h
else
hg mv mfbt/nsRefPtr.h mfbt/RefPtr.h
fi
--HG--
rename : mfbt/nsRefPtr.h => mfbt/RefPtr.h
It is not correct to stop restyling by leaving the old style context on
the frame and returning eRestyleResult_Stop when TryStartingTransition
provides a new, without-animations style context. This is at least
because the new new style context could have different styles from the
old new style context.
Note that this means that when we start transitions, we post restyles
that are processed during the current restyling operation, rather than
in a later phase. This depends on patch 11, which makes the transition
manager skip style changes that it posts while starting transitions, to
ensure that this doesn't lead to an infinite loop. This also depends on
patch 16, which only consumes restyle data for the primary frame, to
ensure that the animation restyles posted are processed properly. It
also depends on patch 14, which makes us retain data on finished
transitions, to avoid triggering extra transitions on descendants when
both an ancestor and a descendant transition an inherited property, and
the descendant does so faster.
This fixes a known failure in layout/style/test/test_animations.html and
test_animations_omta.html (as visible in the patch). I believe this is
because this patch changes us to compute keyframe values for animations
on top of a style context *with* animation data rather than one without,
which means what we're computing them on top of changes each time. (The
purpose of patch 3 was to avoid this in the case where avoiding it
matters, i.e., implicit 0% and 100% keyframes.)
This depends on bug 1087536 patch 3, which posts animation restyles
using the eRestyle_CSSTransitions and eRestyle_CSSAnimations hints.
This is used by patch 6.
I don't have any tests that exercise this code, and I can't even find a
codepath that demonstrates that it's needed, since the lazy
reconstruction that happens during style-triggered frame reconstruction
all appears to go through PostRestyleEvent rather than
MaybeConstructLazily.
But I think we should either do this or add an assertion that it's not
needed, and given that it's one line, it seems like we may as well just
do it. (Note also that we're currently calling CreateNeededFrames at
the start of style reresolution, in
RestyleManager::ProcessPendingRestyles; this adds a call at the end.)