Changeset 107422 in webkit
- Timestamp:
- Feb 10, 2012 11:41:35 AM (12 years ago)
- Location:
- trunk
- Files:
-
- 12 added
- 14 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r107420 r107422 1 2012-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 1 26 2012-02-10 Mike Lawther <mikelawther@chromium.org> 2 27 -
trunk/Source/WebCore/ChangeLog
r107412 r107422 1 2012-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 1 95 2012-02-10 Peter Rybin <peter.rybin@gmail.com> 2 96 -
trunk/Source/WebCore/page/animation/AnimationBase.cpp
r107162 r107422 452 452 } 453 453 }; 454 455 #if ENABLE(CSS_FILTERS) 456 class PropertyWrapperAcceleratedFilter : public PropertyWrapper<const FilterOperations&> { 457 public: 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 454 471 #endif // USE(ACCELERATED_COMPOSITING) 455 472 … … 1026 1043 gPropertyWrappers->append(new PropertyWrapperAcceleratedOpacity()); 1027 1044 gPropertyWrappers->append(new PropertyWrapperAcceleratedTransform()); 1045 #if ENABLE(CSS_FILTERS) 1046 gPropertyWrappers->append(new PropertyWrapperAcceleratedFilter()); 1047 #endif 1028 1048 #else 1029 1049 gPropertyWrappers->append(new PropertyWrapper<float>(CSSPropertyOpacity, &RenderStyle::opacity, &RenderStyle::setOpacity)); 1030 1050 gPropertyWrappers->append(new PropertyWrapper<const TransformOperations&>(CSSPropertyWebkitTransform, &RenderStyle::transform, &RenderStyle::setTransform)); 1031 #endif1032 1033 1051 #if ENABLE(CSS_FILTERS) 1034 1052 gPropertyWrappers->append(new PropertyWrapper<const FilterOperations&>(CSSPropertyWebkitFilter, &RenderStyle::filter, &RenderStyle::setFilter)); 1053 #endif 1035 1054 #endif 1036 1055 -
trunk/Source/WebCore/platform/graphics/GraphicsLayer.cpp
r106304 r107422 381 381 #endif 382 382 383 #if ENABLE(CSS_FILTERS) 384 static inline const FilterOperations* filterOperationsAt(const KeyframeValueList& valueList, size_t index) 385 { 386 return static_cast<const FilterAnimationValue*>(valueList.at(index))->value(); 387 } 388 389 int 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 383 423 // An "invalid" list is one whose functions don't match, and therefore has to be animated as a Matrix 384 424 // The hasBigRotation flag will always return false if isValid is false. Otherwise hasBigRotation is -
trunk/Source/WebCore/platform/graphics/GraphicsLayer.h
r106385 r107422 154 154 }; 155 155 156 #if ENABLE(CSS_FILTERS) 157 // Used to store one filter value in a keyframe list. 158 class FilterAnimationValue : public AnimationValue { 159 public: 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 170 private: 171 FilterOperations m_value; 172 }; 173 #endif 174 156 175 // Used to store a series of values in a keyframe list. Values will all be of the same type, 157 176 // which can be inferred from the property. … … 425 444 // needs to notifiy the change to the platform layer as needed. 426 445 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&); 427 449 #endif 428 450 -
trunk/Source/WebCore/platform/graphics/GraphicsLayerClient.h
r105757 r107422 48 48 AnimatedPropertyWebkitTransform, 49 49 AnimatedPropertyOpacity, 50 AnimatedPropertyBackgroundColor 50 AnimatedPropertyBackgroundColor, 51 AnimatedPropertyWebkitFilter 51 52 }; 52 53 -
trunk/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp
r106482 r107422 212 212 case AnimatedPropertyBackgroundColor: 213 213 return "backgroundColor"; 214 case AnimatedPropertyWebkitFilter: 215 #if ENABLE(CSS_FILTERS) 216 return "filters"; 217 #else 218 ASSERT_NOT_REACHED(); 219 #endif 214 220 case AnimatedPropertyInvalid: 215 221 ASSERT_NOT_REACHED(); … … 445 451 } 446 452 447 void GraphicsLayerCA::moveOrCopyAnimations ForProperty(MoveOrCopy operation, AnimatedPropertyID property, PlatformCALayer *fromLayer, PlatformCALayer *toLayer)453 void GraphicsLayerCA::moveOrCopyAnimations(MoveOrCopy operation, PlatformCALayer *fromLayer, PlatformCALayer *toLayer) 448 454 { 449 455 // Look for running animations affecting this property. … … 454 460 for (size_t i = 0; i < numAnimations; ++i) { 455 461 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 ) 457 469 moveOrCopyLayerAnimation(operation, animationIdentifier(currAnimation.m_name, currAnimation.m_property, currAnimation.m_index), fromLayer, toLayer); 458 470 } … … 649 661 if (valueList.property() == AnimatedPropertyWebkitTransform) 650 662 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 651 667 else 652 668 createdAnimations = createAnimationFromKeyframes(valueList, anim, animationName, timeOffset); … … 1300 1316 m_structuralLayer->superlayer()->replaceSublayer(m_structuralLayer.get(), m_layer.get()); 1301 1317 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()); 1304 1319 1305 1320 // Release the structural layer. … … 1381 1396 m_structuralLayer->appendSublayer(m_layer.get()); 1382 1397 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()); 1385 1399 1386 1400 updateSublayerList(); … … 1745 1759 bool GraphicsLayerCA::createAnimationFromKeyframes(const KeyframeValueList& valueList, const Animation* animation, const String& animationName, double timeOffset) 1746 1760 { 1747 ASSERT(valueList.property() != AnimatedPropertyWebkitTransform );1761 ASSERT(valueList.property() != AnimatedPropertyWebkitTransform && valueList.property() != AnimatedPropertyWebkitFilter); 1748 1762 1749 1763 bool isKeyframe = valueList.size() > 2; … … 1756 1770 1757 1771 if (isKeyframe) { 1758 caAnimation = createKeyframeAnimation(animation, valueList.property(), additive);1772 caAnimation = createKeyframeAnimation(animation, propertyIdToString(valueList.property()), additive); 1759 1773 valuesOK = setAnimationKeyframes(valueList, animation, caAnimation.get()); 1760 1774 } else { 1761 caAnimation = createBasicAnimation(animation, valueList.property(), additive);1775 caAnimation = createBasicAnimation(animation, propertyIdToString(valueList.property()), additive); 1762 1776 valuesOK = setAnimationEndpoints(valueList, animation, caAnimation.get()); 1763 1777 } … … 1780 1794 bool validMatrices = true; 1781 1795 if (isKeyframe) { 1782 caAnimation = createKeyframeAnimation(animation, valueList.property(), additive);1796 caAnimation = createKeyframeAnimation(animation, propertyIdToString(valueList.property()), additive); 1783 1797 validMatrices = setTransformAnimationKeyframes(valueList, animation, caAnimation.get(), animationIndex, transformOp, isMatrixAnimation, boxSize); 1784 1798 } else { 1785 caAnimation = createBasicAnimation(animation, valueList.property(), additive);1799 caAnimation = createBasicAnimation(animation, propertyIdToString(valueList.property()), additive); 1786 1800 validMatrices = setTransformAnimationEndpoints(valueList, animation, caAnimation.get(), animationIndex, transformOp, isMatrixAnimation, boxSize); 1787 1801 } … … 1846 1860 } 1847 1861 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) 1863 bool 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 1898 bool 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 1925 PassRefPtr<PlatformCAAnimation> GraphicsLayerCA::createBasicAnimation(const Animation* anim, const String& keyPath, bool additive) 1926 { 1927 RefPtr<PlatformCAAnimation> basicAnim = PlatformCAAnimation::create(PlatformCAAnimation::Basic, keyPath); 1851 1928 setupAnimation(basicAnim.get(), anim, additive); 1852 1929 return basicAnim; 1853 1930 } 1854 1931 1855 PassRefPtr<PlatformCAAnimation>GraphicsLayerCA::createKeyframeAnimation(const Animation* anim, AnimatedPropertyID property, bool additive)1856 { 1857 RefPtr<PlatformCAAnimation> keyframeAnim = PlatformCAAnimation::create(PlatformCAAnimation::Keyframe, propertyIdToString(property));1932 PassRefPtr<PlatformCAAnimation>GraphicsLayerCA::createKeyframeAnimation(const Animation* anim, const String& keyPath, bool additive) 1933 { 1934 RefPtr<PlatformCAAnimation> keyframeAnim = PlatformCAAnimation::create(PlatformCAAnimation::Keyframe, keyPath); 1858 1935 setupAnimation(keyframeAnim.get(), anim, additive); 1859 1936 return keyframeAnim; … … 2082 2159 } 2083 2160 2161 #if ENABLE(CSS_FILTERS) 2162 bool 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 2197 bool 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 2084 2231 void GraphicsLayerCA::suspendAnimations(double time) 2085 2232 { … … 2270 2417 2271 2418 // 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()); 2275 2420 2276 2421 // need to tell new layer to draw itself … … 2492 2637 if (cloneLevel == IntermediateCloneLevel) { 2493 2638 newLayer->setOpacity(layer->opacity()); 2494 moveOrCopyAnimationsForProperty(Copy, AnimatedPropertyWebkitTransform, layer, newLayer.get()); 2495 moveOrCopyAnimationsForProperty(Copy, AnimatedPropertyOpacity, layer, newLayer.get()); 2639 moveOrCopyAnimations(Copy, layer, newLayer.get()); 2496 2640 } 2497 2641 -
trunk/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.h
r106494 r107422 180 180 bool createAnimationFromKeyframes(const KeyframeValueList&, const Animation*, const String& animationName, double timeOffset); 181 181 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 182 185 183 186 // 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); 186 189 void setupAnimation(PlatformCAAnimation*, const Animation*, bool additive); 187 190 … … 194 197 bool setTransformAnimationKeyframes(const KeyframeValueList&, const Animation*, PlatformCAAnimation*, int functionIndex, TransformOperation::OperationType, bool isMatrixAnimation, const IntSize& boxSize); 195 198 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 196 204 bool animationIsRunning(const String& animationName) const 197 205 { … … 323 331 enum MoveOrCopy { Move, Copy }; 324 332 static void moveOrCopyLayerAnimation(MoveOrCopy, const String& animationIdentifier, PlatformCALayer *fromLayer, PlatformCALayer *toLayer); 325 void moveOrCopyAnimations ForProperty(MoveOrCopy, AnimatedPropertyID, PlatformCALayer * fromLayer, PlatformCALayer * toLayer);333 void moveOrCopyAnimations(MoveOrCopy, PlatformCALayer * fromLayer, PlatformCALayer * toLayer); 326 334 327 335 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 328 339 329 340 enum LayerChange { -
trunk/Source/WebCore/platform/graphics/ca/PlatformCAAnimation.h
r105203 r107422 30 30 31 31 #include "Color.h" 32 #include "FilterOperation.h" 32 33 #include "FloatPoint3D.h" 33 34 #include "TransformationMatrix.h" … … 110 111 void setFromValue(const FloatPoint3D&); 111 112 void setFromValue(const WebCore::Color&); 113 #if ENABLE(CSS_FILTERS) 114 void setFromValue(const FilterOperation*, int internalFilterPropertyIndex); 115 #endif 112 116 void copyFromValueFrom(const PlatformCAAnimation*); 113 117 … … 116 120 void setToValue(const FloatPoint3D&); 117 121 void setToValue(const WebCore::Color&); 122 #if ENABLE(CSS_FILTERS) 123 void setToValue(const FilterOperation*, int internalFilterPropertyIndex); 124 #endif 118 125 void copyToValueFrom(const PlatformCAAnimation*); 119 126 … … 123 130 void setValues(const Vector<FloatPoint3D>&); 124 131 void setValues(const Vector<WebCore::Color>&); 132 #if ENABLE(CSS_FILTERS) 133 void setValues(const Vector<RefPtr<FilterOperation> >&, int internalFilterPropertyIndex); 134 #endif 125 135 void copyValuesFrom(const PlatformCAAnimation*); 126 136 … … 131 141 void copyTimingFunctionsFrom(const PlatformCAAnimation*); 132 142 143 #if ENABLE(CSS_FILTERS) 144 static int numAnimatedFilterProperties(FilterOperation::OperationType); 145 static const char* animatedFilterPropertyName(FilterOperation::OperationType, int internalFilterPropertyIndex); 146 #endif 147 133 148 protected: 134 149 PlatformCAAnimation(AnimationType, const String& keyPath); -
trunk/Source/WebCore/platform/graphics/ca/mac/PlatformCAAnimationMac.mm
r95901 r107422 397 397 } 398 398 399 #if ENABLE(CSS_FILTERS) 400 static 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 406 static double sepiaNoneConstants[3][3] = { 407 { 1, 0, 0 }, 408 { 0, 1, 0 }, 409 { 0, 0, 1 } 410 }; 411 412 static double invertConstants[3][3] = { 413 { 1, 0, 0 }, 414 { 0, 1, 0 }, 415 { 0, 0, 1 } 416 }; 417 418 static 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 517 void 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 399 524 void PlatformCAAnimation::copyFromValueFrom(const PlatformCAAnimation* value) 400 525 { … … 447 572 [static_cast<CABasicAnimation*>(m_animation.get()) setToValue:array]; 448 573 } 574 575 #if ENABLE(CSS_FILTERS) 576 void 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 449 582 450 583 void PlatformCAAnimation::copyToValueFrom(const PlatformCAAnimation* value) … … 520 653 } 521 654 655 #if ENABLE(CSS_FILTERS) 656 void 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 522 671 void PlatformCAAnimation::copyValuesFrom(const PlatformCAAnimation* value) 523 672 { … … 561 710 } 562 711 712 #if ENABLE(CSS_FILTERS) 713 int 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 729 const 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 563 759 #endif // USE(ACCELERATED_COMPOSITING) -
trunk/Source/WebCore/platform/graphics/ca/win/PlatformCAAnimationWin.cpp
r95901 r107422 369 369 } 370 370 371 #if ENABLE(CSS_FILTERS) 372 void PlatformCAAnimation::setFromValue(const FilterOperation*, int) 373 { 374 // FIXME: Hardware filter animation not implemented on Windows 375 } 376 #endif 377 371 378 void PlatformCAAnimation::copyFromValueFrom(const PlatformCAAnimation* value) 372 379 { … … 414 421 CACFAnimationSetToValue(m_animation.get(), v.get()); 415 422 } 423 424 #if ENABLE(CSS_FILTERS) 425 void PlatformCAAnimation::setToValue(const FilterOperation*, int) 426 { 427 // FIXME: Hardware filter animation not implemented on Windows 428 } 429 #endif 416 430 417 431 void PlatformCAAnimation::copyToValueFrom(const PlatformCAAnimation* value) … … 483 497 } 484 498 499 #if ENABLE(CSS_FILTERS) 500 void PlatformCAAnimation::setValues(const Vector<RefPtr<FilterOperation> >&, int) 501 { 502 // FIXME: Hardware filter animation not implemented on Windows 503 } 504 #endif 505 485 506 void PlatformCAAnimation::copyValuesFrom(const PlatformCAAnimation* value) 486 507 { … … 532 553 } 533 554 555 #if ENABLE(CSS_FILTERS) 556 int PlatformCAAnimation::numAnimatedFilterProperties(FilterOperation::OperationType) 557 { 558 // FIXME: Hardware filter animation not implemented on Windows 559 return 0; 560 } 561 562 const char* PlatformCAAnimation::animatedFilterPropertyName(FilterOperation::OperationType, int) 563 { 564 // FIXME: Hardware filter animation not implemented on Windows 565 return ""; 566 } 567 #endif 568 534 569 #endif // USE(ACCELERATED_COMPOSITING) -
trunk/Source/WebCore/platform/graphics/filters/FilterOperation.h
r103125 r107422 75 75 virtual OperationType getOperationType() const { return m_type; } 76 76 virtual bool isSameType(const FilterOperation& o) const { return o.getOperationType() == m_type; } 77 78 virtual bool isDefault() const { return false; } 77 79 78 80 protected: … … 83 85 84 86 OperationType m_type; 87 }; 88 89 class DefaultFilterOperation : public FilterOperation { 90 public: 91 static PassRefPtr<DefaultFilterOperation> create(OperationType type) 92 { 93 return adoptRef(new DefaultFilterOperation(type)); 94 } 95 96 private: 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 } 85 109 }; 86 110 -
trunk/Source/WebCore/rendering/RenderLayer.h
r107168 r107422 525 525 #if ENABLE(CSS_FILTERS) 526 526 virtual void filterNeedsRepaint(); 527 bool hasFilter() const { return renderer()->hasFilter(); } 528 #else 529 bool hasFilter() const { return false; } 527 530 #endif 528 531 -
trunk/Source/WebCore/rendering/RenderLayerBacking.cpp
r107296 r107422 1198 1198 bool hasOpacity = keyframes.containsProperty(CSSPropertyOpacity); 1199 1199 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) 1202 1207 return false; 1203 1208 1204 1209 KeyframeValueList transformVector(AnimatedPropertyWebkitTransform); 1205 1210 KeyframeValueList opacityVector(AnimatedPropertyOpacity); 1211 #if ENABLE(CSS_FILTERS) 1212 KeyframeValueList filterVector(AnimatedPropertyWebkitFilter); 1213 #endif 1206 1214 1207 1215 size_t numKeyframes = keyframes.size(); … … 1223 1231 if ((hasOpacity && isFirstOrLastKeyframe) || currentKeyframe.containsProperty(CSSPropertyOpacity)) 1224 1232 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 1225 1238 } 1226 1239 1227 1240 bool didAnimateTransform = false; 1228 1241 bool didAnimateOpacity = false; 1242 #if ENABLE(CSS_FILTERS) 1243 bool didAnimateFilter = false; 1244 #endif 1229 1245 1230 1246 if (hasTransform && m_graphicsLayer->addAnimation(transformVector, toRenderBox(renderer())->borderBoxRect().size(), anim, keyframes.animationName(), timeOffset)) { … … 1238 1254 } 1239 1255 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 1240 1266 return didAnimateTransform || didAnimateOpacity; 1267 #endif 1241 1268 } 1242 1269 … … 1255 1282 bool didAnimateOpacity = false; 1256 1283 bool didAnimateTransform = false; 1284 #if ENABLE(CSS_FILTERS) 1285 bool didAnimateFilter = false; 1286 #endif 1287 1257 1288 ASSERT(property != cAnimateAll); 1258 1289 … … 1279 1310 transformVector.insert(new TransformAnimationValue(1, &toStyle->transform())); 1280 1311 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. 1282 1313 updateLayerTransform(toStyle); 1283 1314 didAnimateTransform = true; … … 1286 1317 } 1287 1318 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 1288 1335 if (didAnimateOpacity) 1289 1336 compositor()->didStartAcceleratedAnimation(CSSPropertyOpacity); … … 1292 1339 compositor()->didStartAcceleratedAnimation(CSSPropertyWebkitTransform); 1293 1340 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 1294 1349 return didAnimateOpacity || didAnimateTransform; 1350 #endif 1295 1351 } 1296 1352 … … 1354 1410 cssProperty = CSSPropertyBackgroundColor; 1355 1411 break; 1412 case AnimatedPropertyWebkitFilter: 1413 #if ENABLE(CSS_FILTERS) 1414 cssProperty = CSSPropertyWebkitFilter; 1415 #else 1416 ASSERT_NOT_REACHED(); 1417 #endif 1418 break; 1356 1419 case AnimatedPropertyInvalid: 1357 1420 ASSERT_NOT_REACHED(); … … 1369 1432 case CSSPropertyBackgroundColor: 1370 1433 return AnimatedPropertyBackgroundColor; 1434 #if ENABLE(CSS_FILTERS) 1435 case CSSPropertyWebkitFilter: 1436 return AnimatedPropertyWebkitFilter; 1437 #endif 1371 1438 // It's fine if we see other css properties here; they are just not accelerated. 1372 1439 }
Note: See TracChangeset
for help on using the changeset viewer.