Changeset 261756 in webkit


Ignore:
Timestamp:
May 15, 2020 1:07:26 PM (4 years ago)
Author:
graouts@webkit.org
Message:

[Web Animations] Animation with a single keyframe is not accelerated
https://bugs.webkit.org/show_bug.cgi?id=188730
<rdar://problem/43481113>

Reviewed by Dean Jackson.

Source/WebCore:

Test: webanimations/accelerated-animation-single-keyframe.html

Prior to attempting to run an accelerated effect, ensure that the KeyframeList passed to
RenderLayerModelObject::startAnimation() does not have implicit keyframes since eventually
GraphicsLayerCA::animationCanBeAccelerated() would be called and would reject a single-keyframe
animation. To do this, we use the same code used in Style::Resolver::keyframeStylesForAnimation()
which we refactor in the new KeyframeList::fillImplicitKeyframes() method.

  • animation/KeyframeEffect.cpp:

(WebCore::KeyframeEffect::copyPropertiesFromSource):
(WebCore::KeyframeEffect::applyPendingAcceleratedActions):

  • rendering/style/KeyframeList.cpp:

(WebCore::KeyframeList::hasImplicitKeyframes const):
(WebCore::KeyframeList::copyKeyframes):
(WebCore::zeroPercentKeyframe):
(WebCore::hundredPercentKeyframe):
(WebCore::KeyframeList::fillImplicitKeyframes):

  • rendering/style/KeyframeList.h:
  • style/StyleResolver.cpp:

(WebCore::Style::Resolver::keyframeStylesForAnimation):

LayoutTests:

Add a new test that runs a single-keyframe transform animation and checks that it runs accelerated.

  • webanimations/accelerated-animation-single-keyframe-expected.txt: Added.
  • webanimations/accelerated-animation-single-keyframe.html: Added.
Location:
trunk
Files:
2 added
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r261753 r261756  
     12020-05-15  Antoine Quint  <graouts@apple.com>
     2
     3        [Web Animations] Animation with a single keyframe is not accelerated
     4        https://bugs.webkit.org/show_bug.cgi?id=188730
     5        <rdar://problem/43481113>
     6
     7        Reviewed by Dean Jackson.
     8
     9        Add a new test that runs a single-keyframe transform animation and checks that it runs accelerated.
     10
     11        * webanimations/accelerated-animation-single-keyframe-expected.txt: Added.
     12        * webanimations/accelerated-animation-single-keyframe.html: Added.
     13
    1142020-05-15  Eric Carlson  <eric.carlson@apple.com>
    215
  • trunk/Source/WebCore/ChangeLog

    r261752 r261756  
     12020-05-15  Antoine Quint  <graouts@apple.com>
     2
     3        [Web Animations] Animation with a single keyframe is not accelerated
     4        https://bugs.webkit.org/show_bug.cgi?id=188730
     5        <rdar://problem/43481113>
     6
     7        Reviewed by Dean Jackson.
     8
     9        Test: webanimations/accelerated-animation-single-keyframe.html
     10
     11        Prior to attempting to run an accelerated effect, ensure that the KeyframeList passed to
     12        RenderLayerModelObject::startAnimation() does not have implicit keyframes since eventually
     13        GraphicsLayerCA::animationCanBeAccelerated() would be called and would reject a single-keyframe
     14        animation. To do this, we use the same code used in Style::Resolver::keyframeStylesForAnimation()
     15        which we refactor in the new KeyframeList::fillImplicitKeyframes() method.
     16
     17        * animation/KeyframeEffect.cpp:
     18        (WebCore::KeyframeEffect::copyPropertiesFromSource):
     19        (WebCore::KeyframeEffect::applyPendingAcceleratedActions):
     20        * rendering/style/KeyframeList.cpp:
     21        (WebCore::KeyframeList::hasImplicitKeyframes const):
     22        (WebCore::KeyframeList::copyKeyframes):
     23        (WebCore::zeroPercentKeyframe):
     24        (WebCore::hundredPercentKeyframe):
     25        (WebCore::KeyframeList::fillImplicitKeyframes):
     26        * rendering/style/KeyframeList.h:
     27        * style/StyleResolver.cpp:
     28        (WebCore::Style::Resolver::keyframeStylesForAnimation):
     29
    1302020-05-15  Said Abou-Hallawa  <sabouhallawa@apple.com>
    231
  • trunk/Source/WebCore/animation/KeyframeEffect.cpp

    r261637 r261756  
    566566
    567567    KeyframeList keyframeList("keyframe-effect-" + createCanonicalUUIDString());
    568     for (auto& keyframe : source->m_blendingKeyframes.keyframes()) {
    569         KeyframeValue keyframeValue(keyframe.key(), RenderStyle::clonePtr(*keyframe.style()));
    570         for (auto propertyId : keyframe.properties())
    571             keyframeValue.addProperty(propertyId);
    572         keyframeList.insert(WTFMove(keyframeValue));
    573     }
     568    keyframeList.copyKeyframes(source->m_blendingKeyframes);
    574569    setBlendingKeyframes(keyframeList);
    575570}
     
    15791574    auto timeOffset = animation()->currentTime().valueOr(0_s).seconds() - delay().seconds();
    15801575
     1576    auto startAnimation = [&]() -> bool {
     1577        renderer->animationFinished(m_blendingKeyframes.animationName());
     1578
     1579        if (!m_blendingKeyframes.hasImplicitKeyframes())
     1580            return renderer->startAnimation(timeOffset, backingAnimationForCompositedRenderer(), m_blendingKeyframes);
     1581
     1582        ASSERT(m_unanimatedStyle);
     1583        ASSERT(m_target);
     1584        KeyframeList explicitKeyframes(m_blendingKeyframes.animationName());
     1585        explicitKeyframes.copyKeyframes(m_blendingKeyframes);
     1586        explicitKeyframes.fillImplicitKeyframes(*m_target, m_target->styleResolver(), m_unanimatedStyle.get());
     1587        return renderer->startAnimation(timeOffset, backingAnimationForCompositedRenderer(), explicitKeyframes);
     1588    };
     1589
    15811590    for (const auto& action : pendingAcceleratedActions) {
    15821591        switch (action) {
    15831592        case AcceleratedAction::Play:
    1584             renderer->animationFinished(m_blendingKeyframes.animationName());
    1585             m_isRunningAccelerated = renderer->startAnimation(timeOffset, backingAnimationForCompositedRenderer(), m_blendingKeyframes);
     1593            m_isRunningAccelerated = startAnimation();
    15861594            if (!m_isRunningAccelerated) {
    15871595                m_lastRecordedAcceleratedAction = AcceleratedAction::Stop;
     
    15931601            break;
    15941602        case AcceleratedAction::UpdateTiming:
    1595             renderer->animationFinished(m_blendingKeyframes.animationName());
    1596             renderer->startAnimation(timeOffset, backingAnimationForCompositedRenderer(), m_blendingKeyframes);
     1603            startAnimation();
    15971604            if (animation()->playState() == WebAnimation::PlayState::Paused)
    15981605                renderer->animationPaused(timeOffset, m_blendingKeyframes.animationName());
  • trunk/Source/WebCore/rendering/style/KeyframeList.cpp

    r233666 r261756  
    2424
    2525#include "Animation.h"
     26#include "CSSKeyframeRule.h"
    2627#include "RenderObject.h"
     28#include "StyleResolver.h"
    2729
    2830namespace WebCore {
     
    7577}
    7678
     79bool KeyframeList::hasImplicitKeyframes() const
     80{
     81    return size() && (m_keyframes[0].key() || m_keyframes[size() - 1].key() != 1);
     82}
     83
     84void KeyframeList::copyKeyframes(KeyframeList& other)
     85{
     86    for (auto& keyframe : other.keyframes()) {
     87        KeyframeValue keyframeValue(keyframe.key(), RenderStyle::clonePtr(*keyframe.style()));
     88        for (auto propertyId : keyframe.properties())
     89            keyframeValue.addProperty(propertyId);
     90        insert(WTFMove(keyframeValue));
     91    }
     92}
     93
     94static const StyleRuleKeyframe& zeroPercentKeyframe()
     95{
     96    static LazyNeverDestroyed<Ref<StyleRuleKeyframe>> rule;
     97    static std::once_flag onceFlag;
     98    std::call_once(onceFlag, [] {
     99        rule.construct(StyleRuleKeyframe::create(MutableStyleProperties::create()));
     100        rule.get()->setKey(0);
     101    });
     102    return rule.get().get();
     103}
     104
     105static const StyleRuleKeyframe& hundredPercentKeyframe()
     106{
     107    static LazyNeverDestroyed<Ref<StyleRuleKeyframe>> rule;
     108    static std::once_flag onceFlag;
     109    std::call_once(onceFlag, [] {
     110        rule.construct(StyleRuleKeyframe::create(MutableStyleProperties::create()));
     111        rule.get()->setKey(1);
     112    });
     113    return rule.get().get();
     114}
     115
     116void KeyframeList::fillImplicitKeyframes(const Element& element, Style::Resolver& styleResolver, const RenderStyle* elementStyle)
     117{
     118    // If the 0% keyframe is missing, create it (but only if there is at least one other keyframe).
     119    auto initialSize = size();
     120    if (initialSize > 0 && m_keyframes[0].key()) {
     121        KeyframeValue keyframeValue(0, nullptr);
     122        keyframeValue.setStyle(styleResolver.styleForKeyframe(element, elementStyle, &zeroPercentKeyframe(), keyframeValue));
     123        insert(WTFMove(keyframeValue));
     124    }
     125
     126    // If the 100% keyframe is missing, create it (but only if there is at least one other keyframe).
     127    if (initialSize > 0 && (m_keyframes[size() - 1].key() != 1)) {
     128        KeyframeValue keyframeValue(1, nullptr);
     129        keyframeValue.setStyle(styleResolver.styleForKeyframe(element, elementStyle, &hundredPercentKeyframe(), keyframeValue));
     130        insert(WTFMove(keyframeValue));
     131    }
     132}
     133
    77134} // namespace WebCore
  • trunk/Source/WebCore/rendering/style/KeyframeList.h

    r246490 r261756  
    3535class TimingFunction;
    3636
     37namespace Style {
     38class Resolver;
     39}
     40
    3741class KeyframeValue {
    3842public:
     
    5559    TimingFunction* timingFunction() const { return m_timingFunction.get(); }
    5660    void setTimingFunction(const RefPtr<TimingFunction>& timingFunction) { m_timingFunction = timingFunction; }
    57    
     61
    5862private:
    5963    double m_key;
     
    8993    const Vector<KeyframeValue>& keyframes() const { return m_keyframes; }
    9094
     95    void copyKeyframes(KeyframeList&);
     96    bool hasImplicitKeyframes() const;
     97    void fillImplicitKeyframes(const Element&, Style::Resolver&, const RenderStyle*);
     98
    9199private:
    92100    AtomString m_animationName;
  • trunk/Source/WebCore/style/StyleResolver.cpp

    r260951 r261756  
    360360    }
    361361
    362     // If the 0% keyframe is missing, create it (but only if there is at least one other keyframe).
    363     int initialListSize = list.size();
    364     if (initialListSize > 0 && list[0].key()) {
    365         static StyleRuleKeyframe* zeroPercentKeyframe;
    366         if (!zeroPercentKeyframe) {
    367             zeroPercentKeyframe = &StyleRuleKeyframe::create(MutableStyleProperties::create()).leakRef();
    368             zeroPercentKeyframe->setKey(0);
    369         }
    370         KeyframeValue keyframeValue(0, nullptr);
    371         keyframeValue.setStyle(styleForKeyframe(element, elementStyle, zeroPercentKeyframe, keyframeValue));
    372         list.insert(WTFMove(keyframeValue));
    373     }
    374 
    375     // If the 100% keyframe is missing, create it (but only if there is at least one other keyframe).
    376     if (initialListSize > 0 && (list[list.size() - 1].key() != 1)) {
    377         static StyleRuleKeyframe* hundredPercentKeyframe;
    378         if (!hundredPercentKeyframe) {
    379             hundredPercentKeyframe = &StyleRuleKeyframe::create(MutableStyleProperties::create()).leakRef();
    380             hundredPercentKeyframe->setKey(1);
    381         }
    382         KeyframeValue keyframeValue(1, nullptr);
    383         keyframeValue.setStyle(styleForKeyframe(element, elementStyle, hundredPercentKeyframe, keyframeValue));
    384         list.insert(WTFMove(keyframeValue));
    385     }
     362    list.fillImplicitKeyframes(element, *this, elementStyle);
    386363}
    387364
Note: See TracChangeset for help on using the changeset viewer.