Changeset 107422 in webkit


Ignore:
Timestamp:
Feb 10, 2012 11:41:35 AM (12 years ago)
Author:
cmarrin@apple.com
Message:

Implement hardware animation of CSS filters
https://bugs.webkit.org/show_bug.cgi?id=78155

Source/WebCore:

Added logic to PlatformCAAnimation to return enough information
to GraphicsLayerCA to be able to construct a keyPath animation
for each filter property. Some filters need to animate multiple
properties per filter, so PlatformCAAnimation also returns the number
of properties per filter and then an animation is constructed for
each one. Also added all the support logic to handle hardware filter
animation in the higher level logic, just like we do for transforms and
opacity.

Also stubbed out new PlatformCAAnimation functions for Windows. We don't yet
support hardware filters on Windows.

Reviewed by Dean Jackson.

Tests: css3/filters/filter-animation-from-none-hw.html

css3/filters/filter-animation-from-none-multi-hw.html
css3/filters/filter-animation-from-none-multi.html
css3/filters/filter-animation-hw.html
css3/filters/filter-animation-multi-hw.html
css3/filters/filter-animation-multi.html

  • page/animation/AnimationBase.cpp:

(WebCore):
(PropertyWrapperAcceleratedFilter):
(WebCore::PropertyWrapperAcceleratedFilter::PropertyWrapperAcceleratedFilter):
(WebCore::PropertyWrapperAcceleratedFilter::animationIsAccelerated):
(WebCore::PropertyWrapperAcceleratedFilter::blend):
(WebCore::AnimationBase::ensurePropertyMap):

  • platform/graphics/GraphicsLayer.cpp:

(WebCore):
(WebCore::filterOperationsAt):
(WebCore::GraphicsLayer::validateFilterOperations):

  • platform/graphics/GraphicsLayer.h:

(WebCore):
(FilterAnimationValue):
(WebCore::FilterAnimationValue::FilterAnimationValue):
(WebCore::FilterAnimationValue::clone):
(WebCore::FilterAnimationValue::value):
(GraphicsLayer):

  • platform/graphics/GraphicsLayerClient.h:
  • platform/graphics/ca/GraphicsLayerCA.cpp:

(WebCore::propertyIdToString):
(WebCore::GraphicsLayerCA::moveOrCopyAnimations):
(WebCore::GraphicsLayerCA::addAnimation):
(WebCore::GraphicsLayerCA::ensureStructuralLayer):
(WebCore::GraphicsLayerCA::createAnimationFromKeyframes):
(WebCore::GraphicsLayerCA::appendToUncommittedAnimations):
(WebCore):
(WebCore::GraphicsLayerCA::createFilterAnimationsFromKeyframes):
(WebCore::GraphicsLayerCA::createBasicAnimation):
(WebCore::GraphicsLayerCA::createKeyframeAnimation):
(WebCore::GraphicsLayerCA::setFilterAnimationEndpoints):
(WebCore::GraphicsLayerCA::setFilterAnimationKeyframes):
(WebCore::GraphicsLayerCA::swapFromOrToTiledLayer):
(WebCore::GraphicsLayerCA::cloneLayer):

  • platform/graphics/ca/GraphicsLayerCA.h:

(GraphicsLayerCA):

  • platform/graphics/ca/PlatformCAAnimation.h:

(PlatformCAAnimation):

  • platform/graphics/ca/mac/PlatformCAAnimationMac.mm:

(PlatformCAAnimation::setFromValue):
(PlatformCAAnimation::setToValue):
(PlatformCAAnimation::setValues):
(PlatformCAAnimation::numAnimatedFilterProperties):
(PlatformCAAnimation::animatedFilterPropertyName):

  • platform/graphics/ca/win/PlatformCAAnimationWin.cpp:

(PlatformCAAnimation::setFromValue):
(PlatformCAAnimation::setToValue):
(PlatformCAAnimation::setValues):
(PlatformCAAnimation::numAnimatedFilterProperties):
(PlatformCAAnimation::animatedFilterPropertyName):

  • platform/graphics/filters/FilterOperation.h:

(FilterOperation):
(WebCore::FilterOperation::isDefault):
(DefaultFilterOperation):
(WebCore::DefaultFilterOperation::create):
(WebCore::DefaultFilterOperation::operator==):
(WebCore::DefaultFilterOperation::isDefault):
(WebCore::DefaultFilterOperation::DefaultFilterOperation):
(WebCore):

  • rendering/RenderLayer.h:

(WebCore::RenderLayer::hasFilter):
(RenderLayer):

  • rendering/RenderLayerBacking.cpp:

(WebCore::RenderLayerBacking::startAnimation):
(WebCore::RenderLayerBacking::startTransition):
(WebCore::RenderLayerBacking::graphicsLayerToCSSProperty):
(WebCore::RenderLayerBacking::cssToGraphicsLayerProperty):

LayoutTests:

New tests for hardware animated filters, cribbed from software animation tests.
Also added a -multi test, which uses 3 keyframes for each filter. Hardware animations
use the same logic for 2 keyframe animations and transitions, so this exercises the
other logic path.

Reviewed by Dean Jackson.

  • css3/filters/filter-animation-from-none-hw-expected.txt: Added.
  • css3/filters/filter-animation-from-none-hw.html: Added.
  • css3/filters/filter-animation-from-none-multi-expected.txt: Added.
  • css3/filters/filter-animation-from-none-multi-hw-expected.txt: Added.
  • css3/filters/filter-animation-from-none-multi-hw.html: Added.
  • css3/filters/filter-animation-from-none-multi.html: Added.
  • css3/filters/filter-animation-hw-expected.txt: Added.
  • css3/filters/filter-animation-hw.html: Added.
  • css3/filters/filter-animation-multi-expected.txt: Added.
  • css3/filters/filter-animation-multi-hw-expected.txt: Added.
  • css3/filters/filter-animation-multi-hw.html: Added.
  • css3/filters/filter-animation-multi.html: Added.
Location:
trunk
Files:
12 added
14 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r107420 r107422  
     12012-02-09  Chris Marrin  <cmarrin@apple.com>
     2
     3        Implement hardware animation of CSS filters
     4        https://bugs.webkit.org/show_bug.cgi?id=78155
     5
     6        New tests for hardware animated filters, cribbed from software animation tests.
     7        Also added a -multi test, which uses 3 keyframes for each filter. Hardware animations
     8        use the same logic for 2 keyframe animations and transitions, so this exercises the
     9        other logic path.
     10
     11        Reviewed by Dean Jackson.
     12
     13        * css3/filters/filter-animation-from-none-hw-expected.txt: Added.
     14        * css3/filters/filter-animation-from-none-hw.html: Added.
     15        * css3/filters/filter-animation-from-none-multi-expected.txt: Added.
     16        * css3/filters/filter-animation-from-none-multi-hw-expected.txt: Added.
     17        * css3/filters/filter-animation-from-none-multi-hw.html: Added.
     18        * css3/filters/filter-animation-from-none-multi.html: Added.
     19        * css3/filters/filter-animation-hw-expected.txt: Added.
     20        * css3/filters/filter-animation-hw.html: Added.
     21        * css3/filters/filter-animation-multi-expected.txt: Added.
     22        * css3/filters/filter-animation-multi-hw-expected.txt: Added.
     23        * css3/filters/filter-animation-multi-hw.html: Added.
     24        * css3/filters/filter-animation-multi.html: Added.
     25
    1262012-02-10  Mike Lawther  <mikelawther@chromium.org>
    227
  • trunk/Source/WebCore/ChangeLog

    r107412 r107422  
     12012-02-09  Chris Marrin  <cmarrin@apple.com>
     2
     3        Implement hardware animation of CSS filters
     4        https://bugs.webkit.org/show_bug.cgi?id=78155
     5
     6        Added logic to PlatformCAAnimation to return enough information
     7        to GraphicsLayerCA to be able to construct a keyPath animation
     8        for each filter property. Some filters need to animate multiple
     9        properties per filter, so PlatformCAAnimation also returns the number
     10        of properties per filter and then an animation is constructed for
     11        each one. Also added all the support logic to handle hardware filter
     12        animation in the higher level logic, just like we do for transforms and
     13        opacity.
     14
     15        Also stubbed out new PlatformCAAnimation functions for Windows. We don't yet
     16        support hardware filters on Windows.
     17
     18        Reviewed by Dean Jackson.
     19
     20        Tests: css3/filters/filter-animation-from-none-hw.html
     21               css3/filters/filter-animation-from-none-multi-hw.html
     22               css3/filters/filter-animation-from-none-multi.html
     23               css3/filters/filter-animation-hw.html
     24               css3/filters/filter-animation-multi-hw.html
     25               css3/filters/filter-animation-multi.html
     26
     27        * page/animation/AnimationBase.cpp:
     28        (WebCore):
     29        (PropertyWrapperAcceleratedFilter):
     30        (WebCore::PropertyWrapperAcceleratedFilter::PropertyWrapperAcceleratedFilter):
     31        (WebCore::PropertyWrapperAcceleratedFilter::animationIsAccelerated):
     32        (WebCore::PropertyWrapperAcceleratedFilter::blend):
     33        (WebCore::AnimationBase::ensurePropertyMap):
     34        * platform/graphics/GraphicsLayer.cpp:
     35        (WebCore):
     36        (WebCore::filterOperationsAt):
     37        (WebCore::GraphicsLayer::validateFilterOperations):
     38        * platform/graphics/GraphicsLayer.h:
     39        (WebCore):
     40        (FilterAnimationValue):
     41        (WebCore::FilterAnimationValue::FilterAnimationValue):
     42        (WebCore::FilterAnimationValue::clone):
     43        (WebCore::FilterAnimationValue::value):
     44        (GraphicsLayer):
     45        * platform/graphics/GraphicsLayerClient.h:
     46        * platform/graphics/ca/GraphicsLayerCA.cpp:
     47        (WebCore::propertyIdToString):
     48        (WebCore::GraphicsLayerCA::moveOrCopyAnimations):
     49        (WebCore::GraphicsLayerCA::addAnimation):
     50        (WebCore::GraphicsLayerCA::ensureStructuralLayer):
     51        (WebCore::GraphicsLayerCA::createAnimationFromKeyframes):
     52        (WebCore::GraphicsLayerCA::appendToUncommittedAnimations):
     53        (WebCore):
     54        (WebCore::GraphicsLayerCA::createFilterAnimationsFromKeyframes):
     55        (WebCore::GraphicsLayerCA::createBasicAnimation):
     56        (WebCore::GraphicsLayerCA::createKeyframeAnimation):
     57        (WebCore::GraphicsLayerCA::setFilterAnimationEndpoints):
     58        (WebCore::GraphicsLayerCA::setFilterAnimationKeyframes):
     59        (WebCore::GraphicsLayerCA::swapFromOrToTiledLayer):
     60        (WebCore::GraphicsLayerCA::cloneLayer):
     61        * platform/graphics/ca/GraphicsLayerCA.h:
     62        (GraphicsLayerCA):
     63        * platform/graphics/ca/PlatformCAAnimation.h:
     64        (PlatformCAAnimation):
     65        * platform/graphics/ca/mac/PlatformCAAnimationMac.mm:
     66        (PlatformCAAnimation::setFromValue):
     67        (PlatformCAAnimation::setToValue):
     68        (PlatformCAAnimation::setValues):
     69        (PlatformCAAnimation::numAnimatedFilterProperties):
     70        (PlatformCAAnimation::animatedFilterPropertyName):
     71        * platform/graphics/ca/win/PlatformCAAnimationWin.cpp:
     72        (PlatformCAAnimation::setFromValue):
     73        (PlatformCAAnimation::setToValue):
     74        (PlatformCAAnimation::setValues):
     75        (PlatformCAAnimation::numAnimatedFilterProperties):
     76        (PlatformCAAnimation::animatedFilterPropertyName):
     77        * platform/graphics/filters/FilterOperation.h:
     78        (FilterOperation):
     79        (WebCore::FilterOperation::isDefault):
     80        (DefaultFilterOperation):
     81        (WebCore::DefaultFilterOperation::create):
     82        (WebCore::DefaultFilterOperation::operator==):
     83        (WebCore::DefaultFilterOperation::isDefault):
     84        (WebCore::DefaultFilterOperation::DefaultFilterOperation):
     85        (WebCore):
     86        * rendering/RenderLayer.h:
     87        (WebCore::RenderLayer::hasFilter):
     88        (RenderLayer):
     89        * rendering/RenderLayerBacking.cpp:
     90        (WebCore::RenderLayerBacking::startAnimation):
     91        (WebCore::RenderLayerBacking::startTransition):
     92        (WebCore::RenderLayerBacking::graphicsLayerToCSSProperty):
     93        (WebCore::RenderLayerBacking::cssToGraphicsLayerProperty):
     94
    1952012-02-10  Peter Rybin  <peter.rybin@gmail.com>
    296
  • trunk/Source/WebCore/page/animation/AnimationBase.cpp

    r107162 r107422  
    452452    }
    453453};
     454
     455#if ENABLE(CSS_FILTERS)
     456class PropertyWrapperAcceleratedFilter : public PropertyWrapper<const FilterOperations&> {
     457public:
     458    PropertyWrapperAcceleratedFilter()
     459        : PropertyWrapper<const FilterOperations&>(CSSPropertyWebkitFilter, &RenderStyle::filter, &RenderStyle::setFilter)
     460    {
     461    }
     462   
     463    virtual bool animationIsAccelerated() const { return true; }
     464
     465    virtual void blend(const AnimationBase* anim, RenderStyle* dst, const RenderStyle* a, const RenderStyle* b, double progress) const
     466    {
     467        dst->setFilter(blendFunc(anim, a->filter(), b->filter(), progress));
     468    }
     469};
     470#endif
    454471#endif // USE(ACCELERATED_COMPOSITING)
    455472
     
    10261043        gPropertyWrappers->append(new PropertyWrapperAcceleratedOpacity());
    10271044        gPropertyWrappers->append(new PropertyWrapperAcceleratedTransform());
     1045#if ENABLE(CSS_FILTERS)
     1046        gPropertyWrappers->append(new PropertyWrapperAcceleratedFilter());
     1047#endif
    10281048#else
    10291049        gPropertyWrappers->append(new PropertyWrapper<float>(CSSPropertyOpacity, &RenderStyle::opacity, &RenderStyle::setOpacity));
    10301050        gPropertyWrappers->append(new PropertyWrapper<const TransformOperations&>(CSSPropertyWebkitTransform, &RenderStyle::transform, &RenderStyle::setTransform));
    1031 #endif
    1032 
    10331051#if ENABLE(CSS_FILTERS)
    10341052        gPropertyWrappers->append(new PropertyWrapper<const FilterOperations&>(CSSPropertyWebkitFilter, &RenderStyle::filter, &RenderStyle::setFilter));
     1053#endif
    10351054#endif
    10361055
  • trunk/Source/WebCore/platform/graphics/GraphicsLayer.cpp

    r106304 r107422  
    381381#endif
    382382
     383#if ENABLE(CSS_FILTERS)
     384static inline const FilterOperations* filterOperationsAt(const KeyframeValueList& valueList, size_t index)
     385{
     386    return static_cast<const FilterAnimationValue*>(valueList.at(index))->value();
     387}
     388
     389int GraphicsLayer::validateFilterOperations(const KeyframeValueList& valueList)
     390{
     391    ASSERT(valueList.property() == AnimatedPropertyWebkitFilter);
     392
     393    if (valueList.size() < 2)
     394        return -1;
     395
     396    // Empty filters match anything, so find the first non-empty entry as the reference
     397    size_t firstIndex = 0;
     398    for ( ; firstIndex < valueList.size(); ++firstIndex) {
     399        if (filterOperationsAt(valueList, firstIndex)->operations().size() > 0)
     400            break;
     401    }
     402
     403    if (firstIndex >= valueList.size())
     404        return -1;
     405
     406    const FilterOperations* firstVal = filterOperationsAt(valueList, firstIndex);
     407   
     408    for (size_t i = firstIndex + 1; i < valueList.size(); ++i) {
     409        const FilterOperations* val = filterOperationsAt(valueList, i);
     410       
     411        // An emtpy filter list matches anything.
     412        if (val->operations().isEmpty())
     413            continue;
     414       
     415        if (!firstVal->operationsMatch(*val))
     416            return -1;
     417    }
     418   
     419    return firstIndex;
     420}
     421#endif
     422
    383423// An "invalid" list is one whose functions don't match, and therefore has to be animated as a Matrix
    384424// The hasBigRotation flag will always return false if isValid is false. Otherwise hasBigRotation is
  • trunk/Source/WebCore/platform/graphics/GraphicsLayer.h

    r106385 r107422  
    154154};
    155155
     156#if ENABLE(CSS_FILTERS)
     157// Used to store one filter value in a keyframe list.
     158class FilterAnimationValue : public AnimationValue {
     159public:
     160    FilterAnimationValue(float keyTime, const FilterOperations* value = 0, PassRefPtr<TimingFunction> timingFunction = 0)
     161        : AnimationValue(keyTime, timingFunction)
     162    {
     163        if (value)
     164            m_value = *value;
     165    }
     166    virtual AnimationValue* clone() const { return new FilterAnimationValue(*this); }
     167
     168    const FilterOperations* value() const { return &m_value; }
     169
     170private:
     171    FilterOperations m_value;
     172};
     173#endif
     174
    156175// Used to store a series of values in a keyframe list. Values will all be of the same type,
    157176// which can be inferred from the property.
     
    425444    // needs to notifiy the change to the platform layer as needed.
    426445    void clearFilters() { m_filters.clear(); }
     446
     447    // Given a KeyframeValueList containing filterOperations, return true if the operations are valid.
     448    static int validateFilterOperations(const KeyframeValueList&);
    427449#endif
    428450
  • trunk/Source/WebCore/platform/graphics/GraphicsLayerClient.h

    r105757 r107422  
    4848    AnimatedPropertyWebkitTransform,
    4949    AnimatedPropertyOpacity,
    50     AnimatedPropertyBackgroundColor
     50    AnimatedPropertyBackgroundColor,
     51    AnimatedPropertyWebkitFilter
    5152};
    5253
  • trunk/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp

    r106482 r107422  
    212212    case AnimatedPropertyBackgroundColor:
    213213        return "backgroundColor";
     214    case AnimatedPropertyWebkitFilter:
     215#if ENABLE(CSS_FILTERS)
     216        return "filters";
     217#else
     218        ASSERT_NOT_REACHED();
     219#endif
    214220    case AnimatedPropertyInvalid:
    215221        ASSERT_NOT_REACHED();
     
    445451}
    446452
    447 void GraphicsLayerCA::moveOrCopyAnimationsForProperty(MoveOrCopy operation, AnimatedPropertyID property, PlatformCALayer *fromLayer, PlatformCALayer *toLayer)
     453void GraphicsLayerCA::moveOrCopyAnimations(MoveOrCopy operation, PlatformCALayer *fromLayer, PlatformCALayer *toLayer)
    448454{
    449455    // Look for running animations affecting this property.
     
    454460        for (size_t i = 0; i < numAnimations; ++i) {
    455461            const LayerPropertyAnimation& currAnimation = propertyAnimations[i];
    456             if (currAnimation.m_property == property)
     462           
     463            if (currAnimation.m_property == AnimatedPropertyWebkitTransform || currAnimation.m_property == AnimatedPropertyOpacity
     464                    || currAnimation.m_property == AnimatedPropertyBackgroundColor
     465#if ENABLE(CSS_FILTERS)
     466                    || currAnimation.m_property == AnimatedPropertyWebkitFilter
     467#endif
     468                )
    457469                moveOrCopyLayerAnimation(operation, animationIdentifier(currAnimation.m_name, currAnimation.m_property, currAnimation.m_index), fromLayer, toLayer);
    458470        }
     
    649661    if (valueList.property() == AnimatedPropertyWebkitTransform)
    650662        createdAnimations = createTransformAnimationsFromKeyframes(valueList, anim, animationName, timeOffset, boxSize);
     663#if ENABLE(CSS_FILTERS)
     664    else if (valueList.property() == AnimatedPropertyWebkitFilter)
     665        createdAnimations = createFilterAnimationsFromKeyframes(valueList, anim, animationName, timeOffset);
     666#endif
    651667    else
    652668        createdAnimations = createAnimationFromKeyframes(valueList, anim, animationName, timeOffset);
     
    13001316            m_structuralLayer->superlayer()->replaceSublayer(m_structuralLayer.get(), m_layer.get());
    13011317
    1302             moveOrCopyAnimationsForProperty(Move, AnimatedPropertyWebkitTransform, m_structuralLayer.get(), m_layer.get());
    1303             moveOrCopyAnimationsForProperty(Move, AnimatedPropertyOpacity, m_structuralLayer.get(), m_layer.get());
     1318            moveOrCopyAnimations(Move, m_structuralLayer.get(), m_layer.get());
    13041319
    13051320            // Release the structural layer.
     
    13811396    m_structuralLayer->appendSublayer(m_layer.get());
    13821397
    1383     moveOrCopyAnimationsForProperty(Move, AnimatedPropertyWebkitTransform, m_layer.get(), m_structuralLayer.get());
    1384     moveOrCopyAnimationsForProperty(Move, AnimatedPropertyOpacity, m_layer.get(), m_structuralLayer.get());
     1398    moveOrCopyAnimations(Move, m_layer.get(), m_structuralLayer.get());
    13851399   
    13861400    updateSublayerList();
     
    17451759bool GraphicsLayerCA::createAnimationFromKeyframes(const KeyframeValueList& valueList, const Animation* animation, const String& animationName, double timeOffset)
    17461760{
    1747     ASSERT(valueList.property() != AnimatedPropertyWebkitTransform);
     1761    ASSERT(valueList.property() != AnimatedPropertyWebkitTransform && valueList.property() != AnimatedPropertyWebkitFilter);
    17481762   
    17491763    bool isKeyframe = valueList.size() > 2;
     
    17561770   
    17571771    if (isKeyframe) {
    1758         caAnimation = createKeyframeAnimation(animation, valueList.property(), additive);
     1772        caAnimation = createKeyframeAnimation(animation, propertyIdToString(valueList.property()), additive);
    17591773        valuesOK = setAnimationKeyframes(valueList, animation, caAnimation.get());
    17601774    } else {
    1761         caAnimation = createBasicAnimation(animation, valueList.property(), additive);
     1775        caAnimation = createBasicAnimation(animation, propertyIdToString(valueList.property()), additive);
    17621776        valuesOK = setAnimationEndpoints(valueList, animation, caAnimation.get());
    17631777    }
     
    17801794    bool validMatrices = true;
    17811795    if (isKeyframe) {
    1782         caAnimation = createKeyframeAnimation(animation, valueList.property(), additive);
     1796        caAnimation = createKeyframeAnimation(animation, propertyIdToString(valueList.property()), additive);
    17831797        validMatrices = setTransformAnimationKeyframes(valueList, animation, caAnimation.get(), animationIndex, transformOp, isMatrixAnimation, boxSize);
    17841798    } else {
    1785         caAnimation = createBasicAnimation(animation, valueList.property(), additive);
     1799        caAnimation = createBasicAnimation(animation, propertyIdToString(valueList.property()), additive);
    17861800        validMatrices = setTransformAnimationEndpoints(valueList, animation, caAnimation.get(), animationIndex, transformOp, isMatrixAnimation, boxSize);
    17871801    }
     
    18461860}
    18471861
    1848 PassRefPtr<PlatformCAAnimation> GraphicsLayerCA::createBasicAnimation(const Animation* anim, AnimatedPropertyID property, bool additive)
    1849 {
    1850     RefPtr<PlatformCAAnimation> basicAnim = PlatformCAAnimation::create(PlatformCAAnimation::Basic, propertyIdToString(property));
     1862#if ENABLE(CSS_FILTERS)
     1863bool GraphicsLayerCA::appendToUncommittedAnimations(const KeyframeValueList& valueList, const FilterOperation* operation, const Animation* animation, const String& animationName, int animationIndex, double timeOffset)
     1864{
     1865    bool isKeyframe = valueList.size() > 2;
     1866   
     1867    FilterOperation::OperationType filterOp = operation->getOperationType();
     1868    int numAnimatedProperties = PlatformCAAnimation::numAnimatedFilterProperties(filterOp);
     1869   
     1870    // Each filter might need to animate multiple properties, each with their own keyPath. The keyPath is always of the form:
     1871    //
     1872    //      filter.filter_<animationIndex>.<filterPropertyName>
     1873    //
     1874    // PlatformCAAnimation tells us how many properties each filter has and we iterate that many times and create an animation
     1875    // for each. This internalFilterPropertyIndex gets passed to PlatformCAAnimation so it can properly create the property animation
     1876    // values.
     1877    for (int internalFilterPropertyIndex = 0; internalFilterPropertyIndex < numAnimatedProperties; ++internalFilterPropertyIndex) {
     1878        bool valuesOK;
     1879        RefPtr<PlatformCAAnimation> caAnimation;
     1880        String keyPath = String::format("filters.filter_%d.%s", animationIndex, PlatformCAAnimation::animatedFilterPropertyName(filterOp, internalFilterPropertyIndex));
     1881       
     1882        if (isKeyframe) {
     1883            caAnimation = createKeyframeAnimation(animation, keyPath, false);
     1884            valuesOK = setFilterAnimationKeyframes(valueList, animation, caAnimation.get(), animationIndex, internalFilterPropertyIndex, filterOp);
     1885        } else {
     1886            caAnimation = createBasicAnimation(animation, keyPath, false);
     1887            valuesOK = setFilterAnimationEndpoints(valueList, animation, caAnimation.get(), animationIndex, internalFilterPropertyIndex);
     1888        }
     1889       
     1890        ASSERT(valuesOK);
     1891
     1892        m_uncomittedAnimations.append(LayerPropertyAnimation(caAnimation, animationName, valueList.property(), animationIndex, timeOffset));
     1893    }
     1894
     1895    return true;
     1896}
     1897
     1898bool GraphicsLayerCA::createFilterAnimationsFromKeyframes(const KeyframeValueList& valueList, const Animation* animation, const String& animationName, double timeOffset)
     1899{
     1900    ASSERT(valueList.property() == AnimatedPropertyWebkitFilter);
     1901
     1902    int listIndex = validateFilterOperations(valueList);
     1903    if (listIndex < 0)
     1904        return false;
     1905       
     1906    const FilterOperations* operations = static_cast<const FilterAnimationValue*>(valueList.at(listIndex))->value();
     1907    int numAnimations = operations->size();
     1908
     1909    // FIXME: We can't currently hardware animate shadows. There is an open question about removing shadows from filters
     1910    // entirely, in which case this issue is moot.
     1911    for (int i = 0; i < numAnimations; ++i) {
     1912        if (operations->at(i)->getOperationType() == FilterOperation::DROP_SHADOW)
     1913            return false;
     1914    }
     1915
     1916    for (int animationIndex = 0; animationIndex < numAnimations; ++animationIndex) {
     1917        if (!appendToUncommittedAnimations(valueList, operations->operations().at(animationIndex).get(), animation, animationName, animationIndex, timeOffset))
     1918            return false;
     1919    }
     1920
     1921    return true;
     1922}
     1923#endif
     1924
     1925PassRefPtr<PlatformCAAnimation> GraphicsLayerCA::createBasicAnimation(const Animation* anim, const String& keyPath, bool additive)
     1926{
     1927    RefPtr<PlatformCAAnimation> basicAnim = PlatformCAAnimation::create(PlatformCAAnimation::Basic, keyPath);
    18511928    setupAnimation(basicAnim.get(), anim, additive);
    18521929    return basicAnim;
    18531930}
    18541931
    1855 PassRefPtr<PlatformCAAnimation>GraphicsLayerCA::createKeyframeAnimation(const Animation* anim, AnimatedPropertyID property, bool additive)
    1856 {
    1857     RefPtr<PlatformCAAnimation> keyframeAnim = PlatformCAAnimation::create(PlatformCAAnimation::Keyframe, propertyIdToString(property));
     1932PassRefPtr<PlatformCAAnimation>GraphicsLayerCA::createKeyframeAnimation(const Animation* anim, const String& keyPath, bool additive)
     1933{
     1934    RefPtr<PlatformCAAnimation> keyframeAnim = PlatformCAAnimation::create(PlatformCAAnimation::Keyframe, keyPath);
    18581935    setupAnimation(keyframeAnim.get(), anim, additive);
    18591936    return keyframeAnim;
     
    20822159}
    20832160
     2161#if ENABLE(CSS_FILTERS)
     2162bool GraphicsLayerCA::setFilterAnimationEndpoints(const KeyframeValueList& valueList, const Animation* animation, PlatformCAAnimation* basicAnim, int functionIndex, int internalFilterPropertyIndex)
     2163{
     2164    ASSERT(valueList.size() == 2);
     2165   
     2166    const FilterAnimationValue* fromValue = static_cast<const FilterAnimationValue*>(valueList.at(0));
     2167    const FilterAnimationValue* toValue = static_cast<const FilterAnimationValue*>(valueList.at(1));
     2168   
     2169    const FilterOperation* fromOperation = fromValue->value()->at(functionIndex);
     2170    const FilterOperation* toOperation = toValue->value()->at(functionIndex);
     2171   
     2172    RefPtr<DefaultFilterOperation> defaultFromOperation;
     2173    RefPtr<DefaultFilterOperation> defaultToOperation;
     2174   
     2175    ASSERT(fromOperation || toOperation);
     2176   
     2177    if (!fromOperation) {
     2178        defaultFromOperation = DefaultFilterOperation::create(toOperation->getOperationType());
     2179        fromOperation = defaultFromOperation.get();
     2180    }
     2181   
     2182    if (!toOperation) {
     2183        defaultToOperation = DefaultFilterOperation::create(fromOperation->getOperationType());
     2184        toOperation = defaultToOperation.get();
     2185    }
     2186   
     2187    basicAnim->setFromValue(fromOperation, internalFilterPropertyIndex);
     2188    basicAnim->setToValue(toOperation, internalFilterPropertyIndex);
     2189   
     2190    // This codepath is used for 2-keyframe animations, so we still need to look in the start for a timing function.
     2191    const TimingFunction* timingFunction = timingFunctionForAnimationValue(valueList.at(0), animation);
     2192    basicAnim->setTimingFunction(timingFunction);
     2193
     2194    return true;
     2195}
     2196
     2197bool GraphicsLayerCA::setFilterAnimationKeyframes(const KeyframeValueList& valueList, const Animation* animation, PlatformCAAnimation* keyframeAnim, int functionIndex, int internalFilterPropertyIndex, FilterOperation::OperationType filterOp)
     2198{
     2199    Vector<float> keyTimes;
     2200    Vector<RefPtr<FilterOperation> > values;
     2201    Vector<const TimingFunction*> timingFunctions;
     2202    RefPtr<DefaultFilterOperation> defaultOperation;
     2203
     2204    for (unsigned i = 0; i < valueList.size(); ++i) {
     2205        const FilterAnimationValue* curValue = static_cast<const FilterAnimationValue*>(valueList.at(i));
     2206        keyTimes.append(curValue->keyTime());
     2207
     2208        if (curValue->value()->operations().size() > static_cast<size_t>(functionIndex))
     2209            values.append(curValue->value()->operations()[functionIndex]);
     2210        else {
     2211            if (!defaultOperation)
     2212                defaultOperation = DefaultFilterOperation::create(filterOp);
     2213            values.append(defaultOperation);
     2214        }
     2215
     2216        const TimingFunction* timingFunction = timingFunctionForAnimationValue(curValue, animation);
     2217        timingFunctions.append(timingFunction);
     2218    }
     2219   
     2220    // We toss the last timing function because it has to be one shorter than the others.
     2221    timingFunctions.removeLast();
     2222
     2223    keyframeAnim->setKeyTimes(keyTimes);
     2224    keyframeAnim->setValues(values, internalFilterPropertyIndex);
     2225    keyframeAnim->setTimingFunctions(timingFunctions);
     2226
     2227    return true;
     2228}
     2229#endif
     2230
    20842231void GraphicsLayerCA::suspendAnimations(double time)
    20852232{
     
    22702417
    22712418    // move over animations
    2272     moveOrCopyAnimationsForProperty(Move, AnimatedPropertyWebkitTransform, oldLayer.get(), m_layer.get());
    2273     moveOrCopyAnimationsForProperty(Move, AnimatedPropertyOpacity, oldLayer.get(), m_layer.get());
    2274     moveOrCopyAnimationsForProperty(Move, AnimatedPropertyBackgroundColor, oldLayer.get(), m_layer.get());
     2419    moveOrCopyAnimations(Move, oldLayer.get(), m_layer.get());
    22752420   
    22762421    // need to tell new layer to draw itself
     
    24922637    if (cloneLevel == IntermediateCloneLevel) {
    24932638        newLayer->setOpacity(layer->opacity());
    2494         moveOrCopyAnimationsForProperty(Copy, AnimatedPropertyWebkitTransform, layer, newLayer.get());
    2495         moveOrCopyAnimationsForProperty(Copy, AnimatedPropertyOpacity, layer, newLayer.get());
     2639        moveOrCopyAnimations(Copy, layer, newLayer.get());
    24962640    }
    24972641   
  • trunk/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.h

    r106494 r107422  
    180180    bool createAnimationFromKeyframes(const KeyframeValueList&, const Animation*, const String& animationName, double timeOffset);
    181181    bool createTransformAnimationsFromKeyframes(const KeyframeValueList&, const Animation*, const String& animationName, double timeOffset, const IntSize& boxSize);
     182#if ENABLE(CSS_FILTERS)
     183    bool createFilterAnimationsFromKeyframes(const KeyframeValueList&, const Animation*, const String& animationName, double timeOffset);
     184#endif
    182185
    183186    // Return autoreleased animation (use RetainPtr?)
    184     PassRefPtr<PlatformCAAnimation> createBasicAnimation(const Animation*, AnimatedPropertyID, bool additive);
    185     PassRefPtr<PlatformCAAnimation> createKeyframeAnimation(const Animation*, AnimatedPropertyID, bool additive);
     187    PassRefPtr<PlatformCAAnimation> createBasicAnimation(const Animation*, const String& keyPath, bool additive);
     188    PassRefPtr<PlatformCAAnimation> createKeyframeAnimation(const Animation*, const String&, bool additive);
    186189    void setupAnimation(PlatformCAAnimation*, const Animation*, bool additive);
    187190   
     
    194197    bool setTransformAnimationKeyframes(const KeyframeValueList&, const Animation*, PlatformCAAnimation*, int functionIndex, TransformOperation::OperationType, bool isMatrixAnimation, const IntSize& boxSize);
    195198   
     199#if ENABLE(CSS_FILTERS)
     200    bool setFilterAnimationEndpoints(const KeyframeValueList&, const Animation*, PlatformCAAnimation*, int functionIndex, int internalFilterPropertyIndex);
     201    bool setFilterAnimationKeyframes(const KeyframeValueList&, const Animation*, PlatformCAAnimation*, int functionIndex, int internalFilterPropertyIndex, FilterOperation::OperationType);
     202#endif
     203
    196204    bool animationIsRunning(const String& animationName) const
    197205    {
     
    323331    enum MoveOrCopy { Move, Copy };
    324332    static void moveOrCopyLayerAnimation(MoveOrCopy, const String& animationIdentifier, PlatformCALayer *fromLayer, PlatformCALayer *toLayer);
    325     void moveOrCopyAnimationsForProperty(MoveOrCopy, AnimatedPropertyID, PlatformCALayer * fromLayer, PlatformCALayer * toLayer);
     333    void moveOrCopyAnimations(MoveOrCopy, PlatformCALayer * fromLayer, PlatformCALayer * toLayer);
    326334   
    327335    bool appendToUncommittedAnimations(const KeyframeValueList&, const TransformOperations*, const Animation*, const String& animationName, const IntSize& boxSize, int animationIndex, double timeOffset, bool isMatrixAnimation);
     336#if ENABLE(CSS_FILTERS)
     337    bool appendToUncommittedAnimations(const KeyframeValueList&, const FilterOperation*, const Animation*, const String& animationName, int animationIndex, double timeOffset);
     338#endif
    328339   
    329340    enum LayerChange {
  • trunk/Source/WebCore/platform/graphics/ca/PlatformCAAnimation.h

    r105203 r107422  
    3030
    3131#include "Color.h"
     32#include "FilterOperation.h"
    3233#include "FloatPoint3D.h"
    3334#include "TransformationMatrix.h"
     
    110111    void setFromValue(const FloatPoint3D&);
    111112    void setFromValue(const WebCore::Color&);
     113#if ENABLE(CSS_FILTERS)
     114    void setFromValue(const FilterOperation*, int internalFilterPropertyIndex);
     115#endif
    112116    void copyFromValueFrom(const PlatformCAAnimation*);
    113117
     
    116120    void setToValue(const FloatPoint3D&);
    117121    void setToValue(const WebCore::Color&);
     122#if ENABLE(CSS_FILTERS)
     123    void setToValue(const FilterOperation*, int internalFilterPropertyIndex);
     124#endif
    118125    void copyToValueFrom(const PlatformCAAnimation*);
    119126
     
    123130    void setValues(const Vector<FloatPoint3D>&);
    124131    void setValues(const Vector<WebCore::Color>&);
     132#if ENABLE(CSS_FILTERS)
     133    void setValues(const Vector<RefPtr<FilterOperation> >&, int internalFilterPropertyIndex);
     134#endif
    125135    void copyValuesFrom(const PlatformCAAnimation*);
    126136
     
    131141    void copyTimingFunctionsFrom(const PlatformCAAnimation*);
    132142   
     143#if ENABLE(CSS_FILTERS)
     144    static int numAnimatedFilterProperties(FilterOperation::OperationType);
     145    static const char* animatedFilterPropertyName(FilterOperation::OperationType, int internalFilterPropertyIndex);
     146#endif
     147
    133148protected:
    134149    PlatformCAAnimation(AnimationType, const String& keyPath);
  • trunk/Source/WebCore/platform/graphics/ca/mac/PlatformCAAnimationMac.mm

    r95901 r107422  
    397397}
    398398
     399#if ENABLE(CSS_FILTERS)
     400static double sepiaFullConstants[3][3] = {
     401    { 0.393, 0.769, 0.189 },
     402    { 0.349, 0.686, 0.168 },
     403    { 0.272, 0.534, 0.131 }
     404};
     405
     406static double sepiaNoneConstants[3][3] = {
     407    { 1, 0, 0 },
     408    { 0, 1, 0 },
     409    { 0, 0, 1 }
     410};
     411
     412static double invertConstants[3][3] = {
     413    { 1, 0, 0 },
     414    { 0, 1, 0 },
     415    { 0, 0, 1 }
     416};
     417
     418static RetainPtr<id> filterValueForOperation(const FilterOperation* operation, int internalFilterPropertyIndex)
     419{
     420    FilterOperation::OperationType type = operation->getOperationType();
     421    RetainPtr<id> value;
     422   
     423    switch(type) {
     424    case FilterOperation::GRAYSCALE:
     425    case FilterOperation::SATURATE:
     426    case FilterOperation::HUE_ROTATE: {
     427        double amount = 0;
     428       
     429        if (!operation->isDefault()) {
     430            const BasicColorMatrixFilterOperation* op = static_cast<const BasicColorMatrixFilterOperation*>(operation);
     431            amount = op->amount();
     432        }
     433       
     434        if (type == FilterOperation::HUE_ROTATE)
     435            amount = deg2rad(amount);
     436
     437        value.adoptNS([[NSNumber numberWithDouble:amount] retain]);
     438        break;
     439    }
     440    case FilterOperation::SEPIA: {
     441        double amount = 0;
     442
     443        if (!operation->isDefault()) {
     444            const BasicColorMatrixFilterOperation* op = static_cast<const BasicColorMatrixFilterOperation*>(operation);
     445            amount = op->amount();
     446        }
     447       
     448        value.adoptNS([[NSArray arrayWithObjects:
     449            [NSNumber numberWithDouble:WebCore::blend(sepiaNoneConstants[internalFilterPropertyIndex][0], sepiaFullConstants[0][internalFilterPropertyIndex], amount)],
     450            [NSNumber numberWithDouble:WebCore::blend(sepiaNoneConstants[internalFilterPropertyIndex][1], sepiaFullConstants[1][internalFilterPropertyIndex], amount)],
     451            [NSNumber numberWithDouble:WebCore::blend(sepiaNoneConstants[internalFilterPropertyIndex][2], sepiaFullConstants[2][internalFilterPropertyIndex], amount)],
     452            [NSNumber numberWithDouble:0],
     453            nil] retain]);
     454        break;
     455    }
     456    case FilterOperation::INVERT: {
     457        double amount = 0;
     458
     459        if (!operation->isDefault()) {
     460            const BasicComponentTransferFilterOperation* op = static_cast<const BasicComponentTransferFilterOperation*>(operation);
     461            amount = op->amount();
     462        }
     463       
     464        // The color matrix animation for invert does a scale of each color component by a value that goes from
     465        // 1 (when amount is 0) to -1 (when amount is 1). Then the color values are offset by amount. This has the
     466        // effect of performing the operation: c' = c * -1 + 1, which inverts the color.
     467        if (internalFilterPropertyIndex < 3) {
     468            // the first 3 properties are the red, green and blue multipliers
     469            double multiplier = 1 - amount * 2;
     470            value.adoptNS([[NSArray arrayWithObjects:
     471                [NSNumber numberWithDouble:invertConstants[internalFilterPropertyIndex][0] * multiplier],
     472                [NSNumber numberWithDouble:invertConstants[internalFilterPropertyIndex][1] * multiplier],
     473                [NSNumber numberWithDouble:invertConstants[internalFilterPropertyIndex][2] * multiplier],
     474                [NSNumber numberWithDouble:0],
     475                nil] retain]);
     476        } else {
     477            // the last property is the color offset
     478            value.adoptNS([[NSArray arrayWithObjects:
     479                [NSNumber numberWithDouble:amount],
     480                [NSNumber numberWithDouble:amount],
     481                [NSNumber numberWithDouble:amount],
     482                [NSNumber numberWithDouble:0],
     483                nil] retain]);
     484        }
     485        break;
     486    }
     487    case FilterOperation::OPACITY:
     488    case FilterOperation::CONTRAST:
     489    case FilterOperation::BRIGHTNESS: {
     490        double amount = 0;
     491
     492        if (!operation->isDefault()) {
     493            const BasicComponentTransferFilterOperation* op = static_cast<const BasicComponentTransferFilterOperation*>(operation);
     494            amount = op->amount();
     495        }
     496       
     497        value.adoptNS([[NSNumber numberWithDouble:amount] retain]);
     498        break;
     499    }
     500    case FilterOperation::BLUR: {
     501        double amount = 0;
     502
     503        if (!operation->isDefault()) {
     504            const BlurFilterOperation* op = static_cast<const BlurFilterOperation*>(operation);
     505            amount = op->stdDeviation().calcFloatValue(0);
     506        }
     507       
     508        value.adoptNS([[NSNumber numberWithDouble:amount] retain]);
     509        break;
     510    }
     511    default: break;
     512    }
     513   
     514    return value;
     515}
     516
     517void PlatformCAAnimation::setFromValue(const FilterOperation* operation, int internalFilterPropertyIndex)
     518{
     519    RetainPtr<id> value = filterValueForOperation(operation, internalFilterPropertyIndex);
     520    [static_cast<CABasicAnimation*>(m_animation.get()) setFromValue:value.get()];
     521}
     522#endif
     523
    399524void PlatformCAAnimation::copyFromValueFrom(const PlatformCAAnimation* value)
    400525{
     
    447572    [static_cast<CABasicAnimation*>(m_animation.get()) setToValue:array];
    448573}
     574
     575#if ENABLE(CSS_FILTERS)
     576void PlatformCAAnimation::setToValue(const FilterOperation* operation, int internalFilterPropertyIndex)
     577{
     578    RetainPtr<id> value = filterValueForOperation(operation, internalFilterPropertyIndex);
     579    [static_cast<CABasicAnimation*>(m_animation.get()) setToValue:value.get()];
     580}
     581#endif
    449582
    450583void PlatformCAAnimation::copyToValueFrom(const PlatformCAAnimation* value)
     
    520653}
    521654
     655#if ENABLE(CSS_FILTERS)
     656void PlatformCAAnimation::setValues(const Vector<RefPtr<FilterOperation> >& values, int internalFilterPropertyIndex)
     657{
     658    if (animationType() != Keyframe)
     659        return;
     660       
     661    NSMutableArray* array = [NSMutableArray array];
     662
     663    for (size_t i = 0; i < values.size(); ++i) {
     664        RetainPtr<id> value = filterValueForOperation(values[i].get(), internalFilterPropertyIndex);
     665        [array addObject:value.get()];
     666    }
     667    [static_cast<CAKeyframeAnimation*>(m_animation.get()) setValues:array];
     668}
     669#endif
     670
    522671void PlatformCAAnimation::copyValuesFrom(const PlatformCAAnimation* value)
    523672{
     
    561710}
    562711
     712#if ENABLE(CSS_FILTERS)
     713int PlatformCAAnimation::numAnimatedFilterProperties(FilterOperation::OperationType type)
     714{
     715    switch(type) {
     716    case FilterOperation::GRAYSCALE: return 1;
     717    case FilterOperation::SEPIA: return 3;
     718    case FilterOperation::SATURATE: return 1;
     719    case FilterOperation::HUE_ROTATE: return 1;
     720    case FilterOperation::INVERT: return 4;
     721    case FilterOperation::OPACITY: return 1;
     722    case FilterOperation::BLUR: return 1;
     723    case FilterOperation::CONTRAST: return 1;
     724    case FilterOperation::BRIGHTNESS: return 1;
     725    default: return 0;
     726    }
     727}
     728
     729const char* PlatformCAAnimation::animatedFilterPropertyName(FilterOperation::OperationType type, int internalFilterPropertyIndex)
     730{
     731    switch(type) {
     732    case FilterOperation::GRAYSCALE: return "inputIntensity";
     733    case FilterOperation::SEPIA:
     734        switch(internalFilterPropertyIndex) {
     735        case 0: return "inputRVector";
     736        case 1: return "inputGVector";
     737        case 2: return "inputBVector";
     738        default: return "";
     739        }
     740    case FilterOperation::SATURATE: return "inputSaturation";
     741    case FilterOperation::HUE_ROTATE: return "inputAngle";
     742    case FilterOperation::INVERT:
     743        switch(internalFilterPropertyIndex) {
     744        case 0: return "inputRVector";
     745        case 1: return "inputGVector";
     746        case 2: return "inputBVector";
     747        case 3: return "inputBiasVector";
     748        default: return "";
     749        }
     750    case FilterOperation::OPACITY: return "inputAVector";
     751    case FilterOperation::BLUR: return "inputRadius";
     752    case FilterOperation::CONTRAST: return "inputContrast";
     753    case FilterOperation::BRIGHTNESS: return "inputBrightness";
     754    default: return "";
     755    }
     756}
     757#endif
     758
    563759#endif // USE(ACCELERATED_COMPOSITING)
  • trunk/Source/WebCore/platform/graphics/ca/win/PlatformCAAnimationWin.cpp

    r95901 r107422  
    369369}
    370370
     371#if ENABLE(CSS_FILTERS)
     372void PlatformCAAnimation::setFromValue(const FilterOperation*, int)
     373{
     374    // FIXME: Hardware filter animation not implemented on Windows
     375}
     376#endif
     377
    371378void PlatformCAAnimation::copyFromValueFrom(const PlatformCAAnimation* value)
    372379{
     
    414421    CACFAnimationSetToValue(m_animation.get(), v.get());
    415422}
     423
     424#if ENABLE(CSS_FILTERS)
     425void PlatformCAAnimation::setToValue(const FilterOperation*, int)
     426{
     427    // FIXME: Hardware filter animation not implemented on Windows
     428}
     429#endif
    416430
    417431void PlatformCAAnimation::copyToValueFrom(const PlatformCAAnimation* value)
     
    483497}
    484498
     499#if ENABLE(CSS_FILTERS)
     500void PlatformCAAnimation::setValues(const Vector<RefPtr<FilterOperation> >&, int)
     501{
     502    // FIXME: Hardware filter animation not implemented on Windows
     503}
     504#endif
     505
    485506void PlatformCAAnimation::copyValuesFrom(const PlatformCAAnimation* value)
    486507{
     
    532553}
    533554
     555#if ENABLE(CSS_FILTERS)
     556int PlatformCAAnimation::numAnimatedFilterProperties(FilterOperation::OperationType)
     557{
     558    // FIXME: Hardware filter animation not implemented on Windows
     559    return 0;
     560}
     561
     562const char* PlatformCAAnimation::animatedFilterPropertyName(FilterOperation::OperationType, int)
     563{
     564    // FIXME: Hardware filter animation not implemented on Windows
     565    return "";
     566}
     567#endif
     568
    534569#endif // USE(ACCELERATED_COMPOSITING)
  • trunk/Source/WebCore/platform/graphics/filters/FilterOperation.h

    r103125 r107422  
    7575    virtual OperationType getOperationType() const { return m_type; }
    7676    virtual bool isSameType(const FilterOperation& o) const { return o.getOperationType() == m_type; }
     77   
     78    virtual bool isDefault() const { return false; }
    7779
    7880protected:
     
    8385
    8486    OperationType m_type;
     87};
     88
     89class DefaultFilterOperation : public FilterOperation {
     90public:
     91    static PassRefPtr<DefaultFilterOperation> create(OperationType type)
     92    {
     93        return adoptRef(new DefaultFilterOperation(type));
     94    }
     95
     96private:
     97
     98    virtual bool operator==(const FilterOperation& o) const
     99    {
     100        return isSameType(o);
     101    }
     102
     103    virtual bool isDefault() const { return true; }
     104
     105    DefaultFilterOperation(OperationType type)
     106        : FilterOperation(type)
     107    {
     108    }
    85109};
    86110
  • trunk/Source/WebCore/rendering/RenderLayer.h

    r107168 r107422  
    525525#if ENABLE(CSS_FILTERS)
    526526    virtual void filterNeedsRepaint();
     527    bool hasFilter() const { return renderer()->hasFilter(); }
     528#else
     529    bool hasFilter() const { return false; }
    527530#endif
    528531
  • trunk/Source/WebCore/rendering/RenderLayerBacking.cpp

    r107296 r107422  
    11981198    bool hasOpacity = keyframes.containsProperty(CSSPropertyOpacity);
    11991199    bool hasTransform = renderer()->isBox() && keyframes.containsProperty(CSSPropertyWebkitTransform);
    1200    
    1201     if (!hasOpacity && !hasTransform)
     1200#if ENABLE(CSS_FILTERS)
     1201    bool hasFilter = keyframes.containsProperty(CSSPropertyWebkitFilter);
     1202#else
     1203    bool hasFilter = false;
     1204#endif
     1205
     1206    if (!hasOpacity && !hasTransform && !hasFilter)
    12021207        return false;
    12031208   
    12041209    KeyframeValueList transformVector(AnimatedPropertyWebkitTransform);
    12051210    KeyframeValueList opacityVector(AnimatedPropertyOpacity);
     1211#if ENABLE(CSS_FILTERS)
     1212    KeyframeValueList filterVector(AnimatedPropertyWebkitFilter);
     1213#endif
    12061214
    12071215    size_t numKeyframes = keyframes.size();
     
    12231231        if ((hasOpacity && isFirstOrLastKeyframe) || currentKeyframe.containsProperty(CSSPropertyOpacity))
    12241232            opacityVector.insert(new FloatAnimationValue(key, keyframeStyle->opacity(), tf));
     1233
     1234#if ENABLE(CSS_FILTERS)
     1235        if ((hasFilter && isFirstOrLastKeyframe) || currentKeyframe.containsProperty(CSSPropertyWebkitFilter))
     1236            filterVector.insert(new FilterAnimationValue(key, &(keyframeStyle->filter()), tf));
     1237#endif
    12251238    }
    12261239
    12271240    bool didAnimateTransform = false;
    12281241    bool didAnimateOpacity = false;
     1242#if ENABLE(CSS_FILTERS)
     1243    bool didAnimateFilter = false;
     1244#endif
    12291245   
    12301246    if (hasTransform && m_graphicsLayer->addAnimation(transformVector, toRenderBox(renderer())->borderBoxRect().size(), anim, keyframes.animationName(), timeOffset)) {
     
    12381254    }
    12391255
     1256#if ENABLE(CSS_FILTERS)
     1257    if (hasFilter && m_graphicsLayer->addAnimation(filterVector, LayoutSize(), anim, keyframes.animationName(), timeOffset)) {
     1258        didAnimateFilter = true;
     1259        compositor()->didStartAcceleratedAnimation(CSSPropertyWebkitFilter);
     1260    }
     1261#endif
     1262
     1263#if ENABLE(CSS_FILTERS)
     1264    return didAnimateTransform || didAnimateOpacity || didAnimateFilter;
     1265#else
    12401266    return didAnimateTransform || didAnimateOpacity;
     1267#endif
    12411268}
    12421269
     
    12551282    bool didAnimateOpacity = false;
    12561283    bool didAnimateTransform = false;
     1284#if ENABLE(CSS_FILTERS)
     1285    bool didAnimateFilter = false;
     1286#endif
     1287
    12571288    ASSERT(property != cAnimateAll);
    12581289
     
    12791310            transformVector.insert(new TransformAnimationValue(1, &toStyle->transform()));
    12801311            if (m_graphicsLayer->addAnimation(transformVector, toRenderBox(renderer())->borderBoxRect().size(), transformAnim, GraphicsLayer::animationNameForTransition(AnimatedPropertyWebkitTransform), timeOffset)) {
    1281                 // To ensure that the correct transform is visible when the animation ends, also set the final opacity.
     1312                // To ensure that the correct transform is visible when the animation ends, also set the final transform.
    12821313                updateLayerTransform(toStyle);
    12831314                didAnimateTransform = true;
     
    12861317    }
    12871318
     1319#if ENABLE(CSS_FILTERS)
     1320    if (property == (int)CSSPropertyWebkitFilter && m_owningLayer->hasFilter()) {
     1321        const Animation* filterAnim = toStyle->transitionForProperty(CSSPropertyWebkitFilter);
     1322        if (filterAnim && !filterAnim->isEmptyOrZeroDuration()) {
     1323            KeyframeValueList filterVector(AnimatedPropertyWebkitFilter);
     1324            filterVector.insert(new FilterAnimationValue(0, &fromStyle->filter()));
     1325            filterVector.insert(new FilterAnimationValue(1, &toStyle->filter()));
     1326            if (m_graphicsLayer->addAnimation(filterVector, LayoutSize(), filterAnim, GraphicsLayer::animationNameForTransition(AnimatedPropertyWebkitFilter), timeOffset)) {
     1327                // To ensure that the correct filter is visible when the animation ends, also set the final filter.
     1328                updateLayerFilters(toStyle);
     1329                didAnimateFilter = true;
     1330            }
     1331        }
     1332    }
     1333#endif
     1334
    12881335    if (didAnimateOpacity)
    12891336        compositor()->didStartAcceleratedAnimation(CSSPropertyOpacity);
     
    12921339        compositor()->didStartAcceleratedAnimation(CSSPropertyWebkitTransform);
    12931340   
     1341#if ENABLE(CSS_FILTERS)
     1342    if (didAnimateFilter)
     1343        compositor()->didStartAcceleratedAnimation(CSSPropertyWebkitFilter);
     1344#endif
     1345
     1346#if ENABLE(CSS_FILTERS)
     1347    return didAnimateOpacity || didAnimateTransform || didAnimateFilter;
     1348#else
    12941349    return didAnimateOpacity || didAnimateTransform;
     1350#endif
    12951351}
    12961352
     
    13541410            cssProperty = CSSPropertyBackgroundColor;
    13551411            break;
     1412        case AnimatedPropertyWebkitFilter:
     1413#if ENABLE(CSS_FILTERS)
     1414            cssProperty = CSSPropertyWebkitFilter;
     1415#else
     1416            ASSERT_NOT_REACHED();
     1417#endif
     1418            break;
    13561419        case AnimatedPropertyInvalid:
    13571420            ASSERT_NOT_REACHED();
     
    13691432        case CSSPropertyBackgroundColor:
    13701433            return AnimatedPropertyBackgroundColor;
     1434#if ENABLE(CSS_FILTERS)
     1435        case CSSPropertyWebkitFilter:
     1436            return AnimatedPropertyWebkitFilter;
     1437#endif
    13711438        // It's fine if we see other css properties here; they are just not accelerated.
    13721439    }
Note: See TracChangeset for help on using the changeset viewer.