Changeset 40102 in webkit


Ignore:
Timestamp:
Jan 21, 2009 4:13:31 PM (15 years ago)
Author:
cmarrin@apple.com
Message:

Fix for https://bugs.webkit.org/show_bug.cgi?id=23317

The high CPU usage was really from repeatedly firing transitions caused
by a bug in the way we handle background-color animations. If animating
from a valid background color to no background color, we sometimes left
(based on timing) the background color as transparent black, but valid
rather than invalid, which it should be. Fixing that got rid of the
repeated firing.

But we really were doing more expensive iteration of all objects with
animations or transitions on them (running or not). So I added two
optimizations to quickly short circuit when an object had no running
animations or transitions. Things are now as zippy as ever.

Location:
trunk
Files:
2 added
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r40101 r40102  
     12009-01-19  Chris Marrin  <cmarrin@apple.com>
     2
     3        Reviewed by David Hyatt
     4
     5        Fix for https://bugs.webkit.org/show_bug.cgi?id=23317
     6
     7        * transitions/repeated-firing-background-color-expected.txt: Added.
     8        * transitions/repeated-firing-background-color.html: Added.
     9
    1102009-01-21  Eric Seidel  <eric@webkit.org>
    211
  • trunk/WebCore/ChangeLog

    r40101 r40102  
     12009-01-19  Chris Marrin  <cmarrin@apple.com>
     2
     3        Reviewed by David Hyatt.
     4
     5        Fix for https://bugs.webkit.org/show_bug.cgi?id=23317
     6
     7        The high CPU usage was really from repeatedly firing transitions caused
     8        by a bug in the way we handle background-color animations. If animating
     9        from a valid background color to no background color, we sometimes left
     10        (based on timing) the background color as transparent black, but valid
     11        rather than invalid, which it should be. Fixing that got rid of the
     12        repeated firing.
     13
     14        But we really were doing more expensive iteration of all objects with
     15        animations or transitions on them (running or not). So I added two
     16        optimizations to quickly short circuit when an object had no running
     17        animations or transitions. Things are now as zippy as ever.
     18
     19        Test: transitions/repeated-firing-background-color.html
     20
     21        * page/animation/AnimationBase.cpp:
     22        (WebCore::blendFunc):
     23        * page/animation/AnimationController.cpp:
     24        (WebCore::AnimationControllerPrivate::updateAnimationTimer):
     25        * page/animation/CompositeAnimation.cpp:
     26        (WebCore::CompositeAnimationPrivate::hasAnimations):
     27        (WebCore::CompositeAnimationPrivate::clearRenderer):
     28        (WebCore::CompositeAnimationPrivate::animate):
     29        (WebCore::CompositeAnimationPrivate::setAnimating):
     30        (WebCore::CompositeAnimationPrivate::willNeedService):
     31        (WebCore::CompositeAnimationPrivate::getAnimationForProperty):
     32        (WebCore::CompositeAnimationPrivate::cleanupFinishedAnimations):
     33        (WebCore::CompositeAnimationPrivate::setAnimationStartTime):
     34        (WebCore::CompositeAnimationPrivate::setTransitionStartTime):
     35        (WebCore::CompositeAnimationPrivate::suspendAnimations):
     36        (WebCore::CompositeAnimationPrivate::resumeAnimations):
     37        (WebCore::CompositeAnimationPrivate::overrideImplicitAnimations):
     38        (WebCore::CompositeAnimationPrivate::resumeOverriddenImplicitAnimations):
     39        (WebCore::CompositeAnimationPrivate::styleAvailable):
     40        (WebCore::CompositeAnimationPrivate::isAnimatingProperty):
     41        (WebCore::CompositeAnimationPrivate::numberOfActiveAnimations):
     42        (WebCore::CompositeAnimation::hasAnimations):
     43        * page/animation/CompositeAnimation.h:
     44
    1452009-01-21  Eric Seidel  <eric@webkit.org>
    246
  • trunk/WebCore/page/animation/AnimationBase.cpp

    r40039 r40102  
    8181
    8282static inline Color blendFunc(const AnimationBase* anim, const Color& from, const Color& to, double progress)
    83 
     83{
     84    // We need to preserve the state of the valid flag at the end of the animation
     85    if (progress == 1 && !to.isValid())
     86        return Color();
     87
    8488    return Color(blendFunc(anim, from.red(), to.red(), progress),
    8589                 blendFunc(anim, from.green(), to.green(), progress),
  • trunk/WebCore/page/animation/AnimationController.cpp

    r39974 r40102  
    159159    for (RenderObjectAnimationMap::const_iterator it = m_compositeAnimations.begin(); it != animationsEnd; ++it) {
    160160        RefPtr<CompositeAnimation> compAnim = it->second;
    161         if (!compAnim->isSuspended()) {
     161        if (!compAnim->isSuspended() && compAnim->hasAnimations()) {
    162162            double t = compAnim->willNeedService();
    163163            if (t != -1 && (t < needsService || needsService == -1))
  • trunk/WebCore/page/animation/CompositeAnimation.cpp

    r40039 r40102  
    7474    void resumeOverriddenImplicitAnimations(int property);
    7575
     76    bool hasAnimations() const  { return !m_transitions.isEmpty() || !m_keyframeAnimations.isEmpty(); }
     77
    7678    void styleAvailable();
    7779
     
    110112void CompositeAnimationPrivate::clearRenderer()
    111113{
    112     // Clear the renderers from all running animations, in case we are in the middle of
    113     // an animation callback (see https://bugs.webkit.org/show_bug.cgi?id=22052)
    114     CSSPropertyTransitionsMap::const_iterator transitionsEnd = m_transitions.end();
    115     for (CSSPropertyTransitionsMap::const_iterator it = m_transitions.begin(); it != transitionsEnd; ++it) {
    116         ImplicitAnimation* transition = it->second.get();
    117         transition->clearRenderer();
    118     }
    119 
    120     AnimationNameMap::const_iterator animationsEnd = m_keyframeAnimations.end();
    121     for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != animationsEnd; ++it) {
    122         KeyframeAnimation* anim = it->second.get();
    123         anim->clearRenderer();
    124     }
    125    
    126 
     114    if (!m_transitions.isEmpty()) {
     115        // Clear the renderers from all running animations, in case we are in the middle of
     116        // an animation callback (see https://bugs.webkit.org/show_bug.cgi?id=22052)
     117        CSSPropertyTransitionsMap::const_iterator transitionsEnd = m_transitions.end();
     118        for (CSSPropertyTransitionsMap::const_iterator it = m_transitions.begin(); it != transitionsEnd; ++it) {
     119            ImplicitAnimation* transition = it->second.get();
     120            transition->clearRenderer();
     121        }
     122    }
     123    if (!m_keyframeAnimations.isEmpty()) {
     124        AnimationNameMap::const_iterator animationsEnd = m_keyframeAnimations.end();
     125        for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != animationsEnd; ++it) {
     126            KeyframeAnimation* anim = it->second.get();
     127            anim->clearRenderer();
     128        }
     129    }
    127130}
    128131   
     
    267270        // Now that we have transition objects ready, let them know about the new goal state.  We want them
    268271        // to fill in a RenderStyle*& only if needed.
    269         CSSPropertyTransitionsMap::const_iterator end = m_transitions.end();
    270         for (CSSPropertyTransitionsMap::const_iterator it = m_transitions.begin(); it != end; ++it) {
    271             if (ImplicitAnimation* anim = it->second.get())
    272                 anim->animate(m_compositeAnimation, renderer, currentStyle, targetStyle, resultStyle);
     272        if (!m_transitions.isEmpty()) {
     273            CSSPropertyTransitionsMap::const_iterator end = m_transitions.end();
     274            for (CSSPropertyTransitionsMap::const_iterator it = m_transitions.begin(); it != end; ++it) {
     275                if (ImplicitAnimation* anim = it->second.get())
     276                    anim->animate(m_compositeAnimation, renderer, currentStyle, targetStyle, resultStyle);
     277            }
    273278        }
    274279    }
     
    297302void CompositeAnimationPrivate::setAnimating(bool animating)
    298303{
    299     CSSPropertyTransitionsMap::const_iterator transitionsEnd = m_transitions.end();
    300     for (CSSPropertyTransitionsMap::const_iterator it = m_transitions.begin(); it != transitionsEnd; ++it) {
    301         ImplicitAnimation* transition = it->second.get();
    302         transition->setAnimating(animating);
    303     }
    304 
    305     AnimationNameMap::const_iterator animationsEnd = m_keyframeAnimations.end();
    306     for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != animationsEnd; ++it) {
    307         KeyframeAnimation* anim = it->second.get();
    308         anim->setAnimating(animating);
     304    if (!m_transitions.isEmpty()) {
     305        CSSPropertyTransitionsMap::const_iterator transitionsEnd = m_transitions.end();
     306        for (CSSPropertyTransitionsMap::const_iterator it = m_transitions.begin(); it != transitionsEnd; ++it) {
     307            ImplicitAnimation* transition = it->second.get();
     308            transition->setAnimating(animating);
     309        }
     310    }
     311    if (!m_keyframeAnimations.isEmpty()) {
     312        AnimationNameMap::const_iterator animationsEnd = m_keyframeAnimations.end();
     313        for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != animationsEnd; ++it) {
     314            KeyframeAnimation* anim = it->second.get();
     315            anim->setAnimating(animating);
     316        }
    309317    }
    310318}
     
    316324    double minT = -1;
    317325   
    318     CSSPropertyTransitionsMap::const_iterator transitionsEnd = m_transitions.end();
    319     for (CSSPropertyTransitionsMap::const_iterator it = m_transitions.begin(); it != transitionsEnd; ++it) {
    320         ImplicitAnimation* transition = it->second.get();
    321         double t = transition ? transition->willNeedService() : -1;
    322         if (t < minT || minT == -1)
    323             minT = t;
    324         if (minT == 0)
    325             return 0;
    326     }
    327 
    328     AnimationNameMap::const_iterator animationsEnd = m_keyframeAnimations.end();
    329     for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != animationsEnd; ++it) {
    330         KeyframeAnimation* animation = it->second.get();
    331         double t = animation ? animation->willNeedService() : -1;
    332         if (t < minT || minT == -1)
    333             minT = t;
    334         if (minT == 0)
    335             return 0;
     326    if (!m_transitions.isEmpty()) {
     327        CSSPropertyTransitionsMap::const_iterator transitionsEnd = m_transitions.end();
     328        for (CSSPropertyTransitionsMap::const_iterator it = m_transitions.begin(); it != transitionsEnd; ++it) {
     329            ImplicitAnimation* transition = it->second.get();
     330            double t = transition ? transition->willNeedService() : -1;
     331            if (t < minT || minT == -1)
     332                minT = t;
     333            if (minT == 0)
     334                return 0;
     335        }
     336    }
     337    if (!m_keyframeAnimations.isEmpty()) {
     338        AnimationNameMap::const_iterator animationsEnd = m_keyframeAnimations.end();
     339        for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != animationsEnd; ++it) {
     340            KeyframeAnimation* animation = it->second.get();
     341            double t = animation ? animation->willNeedService() : -1;
     342            if (t < minT || minT == -1)
     343                minT = t;
     344            if (minT == 0)
     345                return 0;
     346        }
    336347    }
    337348
     
    345356    // We want to send back the last animation with the property if there are multiples.
    346357    // So we need to iterate through all animations
    347     AnimationNameMap::const_iterator animationsEnd = m_keyframeAnimations.end();
    348     for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != animationsEnd; ++it) {
    349         RefPtr<KeyframeAnimation> anim = it->second;
    350         if (anim->hasAnimationForProperty(property))
    351             retval = anim;
     358    if (!m_keyframeAnimations.isEmpty()) {
     359        AnimationNameMap::const_iterator animationsEnd = m_keyframeAnimations.end();
     360        for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != animationsEnd; ++it) {
     361            RefPtr<KeyframeAnimation> anim = it->second;
     362            if (anim->hasAnimationForProperty(property))
     363                retval = anim;
     364        }
    352365    }
    353366   
     
    362375    // Make a list of transitions to be deleted
    363376    Vector<int> finishedTransitions;
    364     CSSPropertyTransitionsMap::const_iterator transitionsEnd = m_transitions.end();
    365 
    366     for (CSSPropertyTransitionsMap::const_iterator it = m_transitions.begin(); it != transitionsEnd; ++it) {
    367         ImplicitAnimation* anim = it->second.get();
    368         if (!anim)
    369             continue;
    370         if (anim->postActive())
    371             finishedTransitions.append(anim->animatingProperty());
    372     }
    373 
    374     // Delete them
    375     size_t finishedTransitionCount = finishedTransitions.size();
    376     for (size_t i = 0; i < finishedTransitionCount; ++i)
    377         m_transitions.remove(finishedTransitions[i]);
     377    if (!m_transitions.isEmpty()) {
     378        CSSPropertyTransitionsMap::const_iterator transitionsEnd = m_transitions.end();
     379
     380        for (CSSPropertyTransitionsMap::const_iterator it = m_transitions.begin(); it != transitionsEnd; ++it) {
     381            ImplicitAnimation* anim = it->second.get();
     382            if (!anim)
     383                continue;
     384            if (anim->postActive())
     385                finishedTransitions.append(anim->animatingProperty());
     386        }
     387       
     388        // Delete them
     389        size_t finishedTransitionCount = finishedTransitions.size();
     390        for (size_t i = 0; i < finishedTransitionCount; ++i)
     391            m_transitions.remove(finishedTransitions[i]);
     392    }
    378393
    379394    // Make a list of animations to be deleted
    380395    Vector<AtomicStringImpl*> finishedAnimations;
    381     AnimationNameMap::const_iterator animationsEnd = m_keyframeAnimations.end();
    382 
    383     for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != animationsEnd; ++it) {
    384         KeyframeAnimation* anim = it->second.get();
    385         if (!anim)
    386             continue;
    387         if (anim->postActive())
    388             finishedAnimations.append(anim->name().impl());
    389     }
    390 
    391     // Delete them
    392     size_t finishedAnimationCount = finishedAnimations.size();
    393     for (size_t i = 0; i < finishedAnimationCount; ++i)
    394         m_keyframeAnimations.remove(finishedAnimations[i]);
     396    if (!m_keyframeAnimations.isEmpty()) {
     397        AnimationNameMap::const_iterator animationsEnd = m_keyframeAnimations.end();
     398
     399        for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != animationsEnd; ++it) {
     400            KeyframeAnimation* anim = it->second.get();
     401            if (!anim)
     402                continue;
     403            if (anim->postActive())
     404                finishedAnimations.append(anim->name().impl());
     405        }
     406
     407        // Delete them
     408        size_t finishedAnimationCount = finishedAnimations.size();
     409        for (size_t i = 0; i < finishedAnimationCount; ++i)
     410            m_keyframeAnimations.remove(finishedAnimations[i]);
     411    }
    395412}
    396413
     
    398415{
    399416    // Set start time on all animations waiting for it
    400     AnimationNameMap::const_iterator end = m_keyframeAnimations.end();
    401     for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != end; ++it) {
    402         KeyframeAnimation* anim = it->second.get();
    403         if (anim && anim->waitingForStartTime())
    404             anim->updateStateMachine(AnimationBase::AnimationStateInputStartTimeSet, t);
     417    if (!m_keyframeAnimations.isEmpty()) {
     418        AnimationNameMap::const_iterator end = m_keyframeAnimations.end();
     419        for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != end; ++it) {
     420            KeyframeAnimation* anim = it->second.get();
     421            if (anim && anim->waitingForStartTime())
     422                anim->updateStateMachine(AnimationBase::AnimationStateInputStartTimeSet, t);
     423        }
    405424    }
    406425}
     
    409428{
    410429    // Set the start time for given property transition
    411     CSSPropertyTransitionsMap::const_iterator end = m_transitions.end();
    412     for (CSSPropertyTransitionsMap::const_iterator it = m_transitions.begin(); it != end; ++it) {
    413         ImplicitAnimation* anim = it->second.get();
    414         if (anim && anim->waitingForStartTime() && anim->animatingProperty() == property)
    415             anim->updateStateMachine(AnimationBase::AnimationStateInputStartTimeSet, t);
     430    if (!m_transitions.isEmpty()) {
     431        CSSPropertyTransitionsMap::const_iterator end = m_transitions.end();
     432        for (CSSPropertyTransitionsMap::const_iterator it = m_transitions.begin(); it != end; ++it) {
     433            ImplicitAnimation* anim = it->second.get();
     434            if (anim && anim->waitingForStartTime() && anim->animatingProperty() == property)
     435                anim->updateStateMachine(AnimationBase::AnimationStateInputStartTimeSet, t);
     436        }
    416437    }
    417438}
     
    424445    m_isSuspended = true;
    425446
    426     AnimationNameMap::const_iterator animationsEnd = m_keyframeAnimations.end();
    427     for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != animationsEnd; ++it) {
    428         if (KeyframeAnimation* anim = it->second.get())
    429             anim->updatePlayState(false);
    430     }
    431 
    432     CSSPropertyTransitionsMap::const_iterator transitionsEnd = m_transitions.end();
    433     for (CSSPropertyTransitionsMap::const_iterator it = m_transitions.begin(); it != transitionsEnd; ++it) {
    434         ImplicitAnimation* anim = it->second.get();
    435         if (anim && anim->hasStyle())
    436             anim->updatePlayState(false);
     447    if (!m_keyframeAnimations.isEmpty()) {
     448        AnimationNameMap::const_iterator animationsEnd = m_keyframeAnimations.end();
     449        for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != animationsEnd; ++it) {
     450            if (KeyframeAnimation* anim = it->second.get())
     451                anim->updatePlayState(false);
     452        }
     453    }
     454    if (!m_transitions.isEmpty()) {
     455        CSSPropertyTransitionsMap::const_iterator transitionsEnd = m_transitions.end();
     456        for (CSSPropertyTransitionsMap::const_iterator it = m_transitions.begin(); it != transitionsEnd; ++it) {
     457            ImplicitAnimation* anim = it->second.get();
     458            if (anim && anim->hasStyle())
     459                anim->updatePlayState(false);
     460        }
    437461    }
    438462}
     
    445469    m_isSuspended = false;
    446470
    447     AnimationNameMap::const_iterator animationsEnd = m_keyframeAnimations.end();
    448     for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != animationsEnd; ++it) {
    449         KeyframeAnimation* anim = it->second.get();
    450         if (anim && anim->playStatePlaying())
    451             anim->updatePlayState(true);
    452     }
    453 
    454     CSSPropertyTransitionsMap::const_iterator transitionsEnd = m_transitions.end();
    455     for (CSSPropertyTransitionsMap::const_iterator it = m_transitions.begin(); it != transitionsEnd; ++it) {
    456         ImplicitAnimation* anim = it->second.get();
    457         if (anim && anim->hasStyle())
    458             anim->updatePlayState(true);
     471    if (!m_keyframeAnimations.isEmpty()) {
     472        AnimationNameMap::const_iterator animationsEnd = m_keyframeAnimations.end();
     473        for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != animationsEnd; ++it) {
     474            KeyframeAnimation* anim = it->second.get();
     475            if (anim && anim->playStatePlaying())
     476                anim->updatePlayState(true);
     477        }
     478    }
     479
     480    if (!m_transitions.isEmpty()) {
     481        CSSPropertyTransitionsMap::const_iterator transitionsEnd = m_transitions.end();
     482        for (CSSPropertyTransitionsMap::const_iterator it = m_transitions.begin(); it != transitionsEnd; ++it) {
     483            ImplicitAnimation* anim = it->second.get();
     484            if (anim && anim->hasStyle())
     485                anim->updatePlayState(true);
     486        }
    459487    }
    460488}
     
    463491{
    464492    CSSPropertyTransitionsMap::const_iterator end = m_transitions.end();
    465     for (CSSPropertyTransitionsMap::const_iterator it = m_transitions.begin(); it != end; ++it) {
    466         ImplicitAnimation* anim = it->second.get();
    467         if (anim && anim->animatingProperty() == property)
    468             anim->setOverridden(true);
     493    if (!m_transitions.isEmpty()) {
     494        for (CSSPropertyTransitionsMap::const_iterator it = m_transitions.begin(); it != end; ++it) {
     495            ImplicitAnimation* anim = it->second.get();
     496            if (anim && anim->animatingProperty() == property)
     497                anim->setOverridden(true);
     498        }
    469499    }
    470500}
     
    472502void CompositeAnimationPrivate::resumeOverriddenImplicitAnimations(int property)
    473503{
    474     CSSPropertyTransitionsMap::const_iterator end = m_transitions.end();
    475     for (CSSPropertyTransitionsMap::const_iterator it = m_transitions.begin(); it != end; ++it) {
    476         ImplicitAnimation* anim = it->second.get();
    477         if (anim && anim->animatingProperty() == property)
    478             anim->setOverridden(false);
     504    if (!m_transitions.isEmpty()) {
     505        CSSPropertyTransitionsMap::const_iterator end = m_transitions.end();
     506        for (CSSPropertyTransitionsMap::const_iterator it = m_transitions.begin(); it != end; ++it) {
     507            ImplicitAnimation* anim = it->second.get();
     508            if (anim && anim->animatingProperty() == property)
     509                anim->setOverridden(false);
     510        }
    479511    }
    480512}
     
    504536    }
    505537
    506     CSSPropertyTransitionsMap::const_iterator end = m_transitions.end();
    507     for (CSSPropertyTransitionsMap::const_iterator it = m_transitions.begin(); it != end; ++it) {
    508         ImplicitAnimation* anim = it->second.get();
    509         if (anim && anim->waitingForStyleAvailable())
    510             anim->updateStateMachine(AnimationBase::AnimationStateInputStyleAvailable, -1);
     538    if (!m_transitions.isEmpty()) {
     539        CSSPropertyTransitionsMap::const_iterator end = m_transitions.end();
     540        for (CSSPropertyTransitionsMap::const_iterator it = m_transitions.begin(); it != end; ++it) {
     541            ImplicitAnimation* anim = it->second.get();
     542            if (anim && anim->waitingForStyleAvailable())
     543                anim->updateStateMachine(AnimationBase::AnimationStateInputStyleAvailable, -1);
     544        }
    511545    }
    512546}
     
    514548bool CompositeAnimationPrivate::isAnimatingProperty(int property, bool isRunningNow) const
    515549{
    516     AnimationNameMap::const_iterator animationsEnd = m_keyframeAnimations.end();
    517     for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != animationsEnd; ++it) {
    518         KeyframeAnimation* anim = it->second.get();
    519         if (anim && anim->isAnimatingProperty(property, isRunningNow))
    520             return true;
    521     }
    522 
    523     CSSPropertyTransitionsMap::const_iterator transitionsEnd = m_transitions.end();
    524     for (CSSPropertyTransitionsMap::const_iterator it = m_transitions.begin(); it != transitionsEnd; ++it) {
    525         ImplicitAnimation* anim = it->second.get();
    526         if (anim && anim->isAnimatingProperty(property, isRunningNow))
    527             return true;
     550    if (!m_keyframeAnimations.isEmpty()) {
     551        AnimationNameMap::const_iterator animationsEnd = m_keyframeAnimations.end();
     552        for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != animationsEnd; ++it) {
     553            KeyframeAnimation* anim = it->second.get();
     554            if (anim && anim->isAnimatingProperty(property, isRunningNow))
     555                return true;
     556        }
     557    }
     558
     559    if (!m_transitions.isEmpty()) {
     560        CSSPropertyTransitionsMap::const_iterator transitionsEnd = m_transitions.end();
     561        for (CSSPropertyTransitionsMap::const_iterator it = m_transitions.begin(); it != transitionsEnd; ++it) {
     562            ImplicitAnimation* anim = it->second.get();
     563            if (anim && anim->isAnimatingProperty(property, isRunningNow))
     564                return true;
     565        }
    528566    }
    529567    return false;
     
    578616    unsigned count = 0;
    579617   
    580     AnimationNameMap::const_iterator animationsEnd = m_keyframeAnimations.end();
    581     for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != animationsEnd; ++it) {
    582         KeyframeAnimation* anim = it->second.get();
    583         if (anim->running())
    584             ++count;
    585     }
    586 
    587     CSSPropertyTransitionsMap::const_iterator transitionsEnd = m_transitions.end();
    588     for (CSSPropertyTransitionsMap::const_iterator it = m_transitions.begin(); it != transitionsEnd; ++it) {
    589         ImplicitAnimation* anim = it->second.get();
    590         if (anim->running())
    591             ++count;
     618    if (!m_keyframeAnimations.isEmpty()) {
     619        AnimationNameMap::const_iterator animationsEnd = m_keyframeAnimations.end();
     620        for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != animationsEnd; ++it) {
     621            KeyframeAnimation* anim = it->second.get();
     622            if (anim->running())
     623                ++count;
     624        }
     625    }
     626
     627    if (!m_transitions.isEmpty()) {
     628        CSSPropertyTransitionsMap::const_iterator transitionsEnd = m_transitions.end();
     629        for (CSSPropertyTransitionsMap::const_iterator it = m_transitions.begin(); it != transitionsEnd; ++it) {
     630            ImplicitAnimation* anim = it->second.get();
     631            if (anim->running())
     632                ++count;
     633        }
    592634    }
    593635   
     
    650692}
    651693
     694bool CompositeAnimation::hasAnimations() const
     695{
     696    return m_data->hasAnimations();
     697}
     698
    652699void CompositeAnimation::styleAvailable()
    653700{
  • trunk/WebCore/page/animation/CompositeAnimation.h

    r39669 r40102  
    6767    void resumeAnimations();
    6868    bool isSuspended() const;
     69   
     70    bool hasAnimations() const;
    6971
    7072    void styleAvailable();
Note: See TracChangeset for help on using the changeset viewer.