Changeset 86351 in webkit


Ignore:
Timestamp:
May 12, 2011 9:38:22 AM (13 years ago)
Author:
Simon Fraser
Message:

2011-05-12 Simon Fraser <Simon Fraser>

Reviewed by Dan Bernstein.

Mismatched multiple box-shadows do not transition as expected
https://bugs.webkit.org/show_bug.cgi?id=60137

When animating between two sets of shadows of different lengths, we need
to walk the ShadowData list backwards, since it stores the shadows in
reverse order relative to the CSS (so that painting is back-to-front).

This progresses the behavior of the transitions/multiple-shadow-transitions.html
test, which is given new expected results.

Test: transitions/mismatched-shadow-transitions.html

  • page/animation/AnimationBase.cpp: (WebCore::shadowListLength): Utility to walk the list of ShadowData and count the number of shadows. (WebCore::shadowForBlending): Return a ShadowData* that is useful as a blending target, based on the shadow type, and whether it's a -webkit-box-shadow. (WebCore::PropertyWrapperShadow::blend): Call one of the specialized blend methods. (WebCore::PropertyWrapperShadow::blendSimpleOrMatchedShadowLists): Fast path for shadow blending, when the list lengths match, or both are single or null shadows. (WebCore::PropertyWrapperShadow::blendMismatchedShadowLists): Slower path that builds vectors for each list to reverse them.
Location:
trunk
Files:
2 added
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r86350 r86351  
     12011-05-12  Simon Fraser  <simon.fraser@apple.com>
     2
     3        Reviewed by Dan Bernstein.
     4
     5        Mismatched multiple box-shadows do not transition as expected
     6        https://bugs.webkit.org/show_bug.cgi?id=60137
     7       
     8        New test for animating between mismatched lists of shadows.
     9        Update the test and result for multiple-shadow-transition.html,
     10        as this change fixes its behavior.
     11
     12        * transitions/mismatched-shadow-transitions-expected.txt: Added.
     13        * transitions/mismatched-shadow-transitions.html: Added.
     14        * transitions/multiple-shadow-transitions-expected.txt:
     15        * transitions/multiple-shadow-transitions.html:
     16
    1172011-05-12  Anton Muhin  <antonnm@chromium.org>
    218
  • trunk/LayoutTests/transitions/multiple-shadow-transitions-expected.txt

    r47332 r86351  
    33BOX
    44PASS - "-webkit-box-shadow" property for "box" element at 0.5s saw something close to: 0,0,0,0
    5 PASS - "-webkit-box-shadow" property for "box2" element at 0.5s saw something close to: 0,-10,0,0
    6 PASS - "-webkit-box-shadow" property for "box3" element at 0.5s saw something close to: 0,-10,0,20
     5PASS - "-webkit-box-shadow" property for "box2" element at 0.5s saw something close to: 0,-20,0,10
     6PASS - "-webkit-box-shadow" property for "box3" element at 0.5s saw something close to: 0,0,0,10
    77
  • trunk/LayoutTests/transitions/multiple-shadow-transitions.html

    r84875 r86351  
    5555      // [time, element-id, property, expected-value, tolerance]
    5656      [0.5, 'box', '-webkit-box-shadow', [0, 0, 0, 0], 4],
    57       [0.5, 'box2', '-webkit-box-shadow', [0, -10, 0, 0], 4],
    58       [0.5, 'box3', '-webkit-box-shadow', [0, -10, 0, 20], 4],
     57      [0.5, 'box2', '-webkit-box-shadow', [0, -20, 0, 10], 4],
     58      [0.5, 'box3', '-webkit-box-shadow', [0, 0, 0, 10], 4],
    5959    ];
    6060 
  • trunk/Source/WebCore/ChangeLog

    r86343 r86351  
     12011-05-12  Simon Fraser  <simon.fraser@apple.com>
     2
     3        Reviewed by Dan Bernstein.
     4
     5        Mismatched multiple box-shadows do not transition as expected
     6        https://bugs.webkit.org/show_bug.cgi?id=60137
     7       
     8        When animating between two sets of shadows of different lengths, we need
     9        to walk the ShadowData list backwards, since it stores the shadows in
     10        reverse order relative to the CSS (so that painting is back-to-front).
     11       
     12        This progresses the behavior of the transitions/multiple-shadow-transitions.html
     13        test, which is given new expected results.
     14
     15        Test: transitions/mismatched-shadow-transitions.html
     16
     17        * page/animation/AnimationBase.cpp:
     18        (WebCore::shadowListLength): Utility to walk the list of ShadowData and count the number
     19        of shadows.
     20        (WebCore::shadowForBlending): Return a ShadowData* that is useful as a blending target,
     21        based on the shadow type, and whether it's a -webkit-box-shadow.
     22        (WebCore::PropertyWrapperShadow::blend): Call one of the specialized blend methods.
     23        (WebCore::PropertyWrapperShadow::blendSimpleOrMatchedShadowLists): Fast path
     24        for shadow blending, when the list lengths match, or both are single or null shadows.
     25        (WebCore::PropertyWrapperShadow::blendMismatchedShadowLists): Slower path that builds
     26        vectors for each list to reverse them.
     27
    1282011-05-12  Adam Roben  <aroben@apple.com>
    229
  • trunk/Source/WebCore/page/animation/AnimationBase.cpp

    r85027 r86351  
    328328#endif // USE(ACCELERATED_COMPOSITING)
    329329
     330static inline size_t shadowListLength(const ShadowData* shadow)
     331{
     332    size_t count;
     333    for (count = 0; shadow; shadow = shadow->next())
     334        ++count;
     335    return count;
     336}
     337
     338static inline const ShadowData* shadowForBlending(const ShadowData* srcShadow, const ShadowData* otherShadow)
     339{
     340    DEFINE_STATIC_LOCAL(ShadowData, defaultShadowData, (0, 0, 0, 0, Normal, false, Color::transparent));
     341    DEFINE_STATIC_LOCAL(ShadowData, defaultInsetShadowData, (0, 0, 0, 0, Inset, false, Color::transparent));
     342
     343    DEFINE_STATIC_LOCAL(ShadowData, defaultWebKitBoxShadowData, (0, 0, 0, 0, Normal, true, Color::transparent));
     344    DEFINE_STATIC_LOCAL(ShadowData, defaultInsetWebKitBoxShadowData, (0, 0, 0, 0, Inset, true, Color::transparent));
     345
     346    if (srcShadow)
     347        return srcShadow;
     348
     349    if (otherShadow->style() == Inset)
     350        return otherShadow->isWebkitBoxShadow() ? &defaultInsetWebKitBoxShadowData : &defaultInsetShadowData;
     351   
     352    return otherShadow->isWebkitBoxShadow() ? &defaultWebKitBoxShadowData : &defaultShadowData;
     353}
     354
    330355class PropertyWrapperShadow : public PropertyWrapperBase {
    331356public:
     
    363388        const ShadowData* shadowA = (a->*m_getter)();
    364389        const ShadowData* shadowB = (b->*m_getter)();
    365         ShadowData defaultShadowData(0, 0, 0, 0, Normal, property() == CSSPropertyWebkitBoxShadow, Color::transparent);
    366         ShadowData defaultInsetShadowData(0, 0, 0, 0, Inset, property() == CSSPropertyWebkitBoxShadow, Color::transparent);
    367 
     390
     391        int fromLength = shadowListLength(shadowA);
     392        int toLength = shadowListLength(shadowB);
     393
     394        if (fromLength == toLength || (fromLength <= 1 && toLength <= 1)) {
     395            (dst->*m_setter)(blendSimpleOrMatchedShadowLists(anim, progress, shadowA, shadowB), false);
     396            return;
     397        }
     398
     399        (dst->*m_setter)(blendMismatchedShadowLists(anim, progress, shadowA, shadowB, fromLength, toLength), false);
     400    }
     401
     402private:
     403    PassOwnPtr<ShadowData*> blendSimpleOrMatchedShadowLists(const AnimationBase* anim, double progress, const ShadowData* shadowA, const ShadowData* shadowB) const
     404    {
    368405        OwnPtr<ShadowData> newShadowData;
    369406        ShadowData* lastShadow = 0;
    370407       
    371408        while (shadowA || shadowB) {
    372             const ShadowData* srcShadow = shadowA ? shadowA : (shadowB->style() == Inset ? &defaultInsetShadowData : &defaultShadowData);
    373             const ShadowData* dstShadow = shadowB ? shadowB : (shadowA->style() == Inset ? &defaultInsetShadowData : &defaultShadowData);
     409            const ShadowData* srcShadow = shadowForBlending(shadowA, shadowB);
     410            const ShadowData* dstShadow = shadowForBlending(shadowB, shadowA);
    374411
    375412            OwnPtr<ShadowData> blendedShadow = blendFunc(anim, srcShadow, dstShadow, progress);
     
    387424        }
    388425       
    389         (dst->*m_setter)(newShadowData.release(), false);
    390     }
    391 
    392 private:
     426        return newShadowData.release();
     427    }
     428
     429    PassOwnPtr<ShadowData*> blendMismatchedShadowLists(const AnimationBase* anim, double progress, const ShadowData* shadowA, const ShadowData* shadowB, int fromLength, int toLength) const
     430    {
     431        // The shadows in ShadowData are stored in reverse order, so when animating mismatched lists,
     432        // reverse them and match from the end.
     433        Vector<const ShadowData*> fromShadows(fromLength);
     434        for (int i = fromLength - 1; i >= 0; --i) {
     435            fromShadows[i] = shadowA;
     436            shadowA = shadowA->next();
     437        }
     438
     439        Vector<const ShadowData*> toShadows(toLength);
     440        for (int i = toLength - 1; i >= 0; --i) {
     441            toShadows[i] = shadowB;
     442            shadowB = shadowB->next();
     443        }
     444
     445        OwnPtr<ShadowData> newShadowData;
     446       
     447        int maxLength = max(fromLength, toLength);
     448        for (int i = 0; i < maxLength; ++i) {
     449            const ShadowData* fromShadow = i < fromLength ? fromShadows[i] : 0;
     450            const ShadowData* toShadow = i < toLength ? toShadows[i] : 0;
     451           
     452            const ShadowData* srcShadow = shadowForBlending(fromShadow, toShadow);
     453            const ShadowData* dstShadow = shadowForBlending(toShadow, fromShadow);
     454
     455            OwnPtr<ShadowData> blendedShadow = blendFunc(anim, srcShadow, dstShadow, progress);
     456            // Insert at the start of the list to preserve the order.
     457            blendedShadow->setNext(newShadowData.release());
     458            newShadowData = blendedShadow.release();
     459        }
     460
     461        return newShadowData.release();
     462    }
     463
    393464    const ShadowData* (RenderStyle::*m_getter)() const;
    394465    void (RenderStyle::*m_setter)(PassOwnPtr<ShadowData>, bool);
Note: See TracChangeset for help on using the changeset viewer.