Implement animation for color-filter
authorsimon.fraser@apple.com <simon.fraser@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 28 Apr 2018 00:27:29 +0000 (00:27 +0000)
committersimon.fraser@apple.com <simon.fraser@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 28 Apr 2018 00:27:29 +0000 (00:27 +0000)
https://bugs.webkit.org/show_bug.cgi?id=185092
rdar://problem/39773810

Reviewed by Tim Horton.

Source/WebCore:

Implement animation of color-filter.

This requires tracking whether the color-filter function lists match for both old and new
animation code paths.

The filter-related ProperyWappers in CSSPropertyAnimation are cleaned up to use a single wrapper,
which has to pass the propertyID to the blend function so we know which "lists match" to check.
This wrapper reports that its accelerated for filter and backdrop-filter, but not color-filter.

Test: css3/color-filters/color-filter-animation.html

* animation/CSSPropertyBlendingClient.h:
* animation/KeyframeEffectReadOnly.cpp:
(WebCore::KeyframeEffectReadOnly::setBlendingKeyframes):
(WebCore::KeyframeEffectReadOnly::checkForMatchingColorFilterFunctionLists):
* animation/KeyframeEffectReadOnly.h:
* page/animation/AnimationBase.h:
* page/animation/CSSPropertyAnimation.cpp:
(WebCore::blendFunc):
(WebCore::PropertyWrapperFilter::PropertyWrapperFilter):
(WebCore::CSSPropertyAnimationWrapperMap::CSSPropertyAnimationWrapperMap):
(WebCore::PropertyWrapperAcceleratedFilter::PropertyWrapperAcceleratedFilter): Deleted.
(WebCore::PropertyWrapperAcceleratedBackdropFilter::PropertyWrapperAcceleratedBackdropFilter): Deleted.
(WebCore::PropertyWrapperAcceleratedBackdropFilter::animationIsAccelerated const): Deleted.
(WebCore::PropertyWrapperAcceleratedBackdropFilter::blend const): Deleted.
* page/animation/ImplicitAnimation.cpp:
(WebCore::ImplicitAnimation::reset):
(WebCore::ImplicitAnimation::checkForMatchingColorFilterFunctionLists):
* page/animation/ImplicitAnimation.h:
* page/animation/KeyframeAnimation.cpp:
(WebCore::KeyframeAnimation::KeyframeAnimation):
(WebCore::KeyframeAnimation::checkForMatchingColorFilterFunctionLists):
* page/animation/KeyframeAnimation.h:

LayoutTests:

Fix the testing to recognize unprefixed filter, and color-filter.

Add a color-filter animation test.

* animations/resources/animation-test-helpers.js:
(getPropertyValue):
(comparePropertyValue):
* css3/color-filters/color-filter-animation-expected.txt: Added.
* css3/color-filters/color-filter-animation.html: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@231123 268f45cc-cd09-0410-ab3c-d52691b4dbfc

14 files changed:
LayoutTests/ChangeLog
LayoutTests/animations/resources/animation-test-helpers.js
LayoutTests/css3/color-filters/color-filter-animation-expected.txt [new file with mode: 0644]
LayoutTests/css3/color-filters/color-filter-animation.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/animation/CSSPropertyBlendingClient.h
Source/WebCore/animation/KeyframeEffectReadOnly.cpp
Source/WebCore/animation/KeyframeEffectReadOnly.h
Source/WebCore/page/animation/AnimationBase.h
Source/WebCore/page/animation/CSSPropertyAnimation.cpp
Source/WebCore/page/animation/ImplicitAnimation.cpp
Source/WebCore/page/animation/ImplicitAnimation.h
Source/WebCore/page/animation/KeyframeAnimation.cpp
Source/WebCore/page/animation/KeyframeAnimation.h

index 1197684..c44cf86 100644 (file)
@@ -1,3 +1,21 @@
+2018-04-27  Simon Fraser  <simon.fraser@apple.com>
+
+        Implement animation for color-filter
+        https://bugs.webkit.org/show_bug.cgi?id=185092
+        rdar://problem/39773810
+
+        Reviewed by Tim Horton.
+        
+        Fix the testing to recognize unprefixed filter, and color-filter.
+        
+        Add a color-filter animation test.
+
+        * animations/resources/animation-test-helpers.js:
+        (getPropertyValue):
+        (comparePropertyValue):
+        * css3/color-filters/color-filter-animation-expected.txt: Added.
+        * css3/color-filters/color-filter-animation.html: Added.
+
 2018-04-27  Ryan Haddad  <ryanhaddad@apple.com>
 
         Update TestExpectations for fast/loader/submit-form-while-parsing-2.html.
index 85c9828..aac905d 100644 (file)
@@ -430,6 +430,8 @@ function getPropertyValue(property, elementId, iframeId)
                || property == "listStyleImage"
                || property == "webkitMaskImage"
                || property == "webkitMaskBoxImage"
+               || property == "filter"
+               || property == "colorFilter"
                || property == "webkitFilter"
                || property == "webkitBackdropFilter"
                || property == "webkitClipPath"
@@ -469,7 +471,7 @@ function comparePropertyValue(property, computedValue, expectedValue, tolerance)
                     break;
             }
         }
-    } else if (property == "webkitFilter" || property == "webkitBackdropFilter") {
+    } else if (property == "webkitFilter" || property == "webkitBackdropFilter" || property == "filter" || property == "colorFilter") {
         var filterParameters = parseFilterFunctionList(computedValue);
         var filter2Parameters = parseFilterFunctionList(expectedValue);
         result = compareFilterFunctions(filterParameters, filter2Parameters, tolerance);
diff --git a/LayoutTests/css3/color-filters/color-filter-animation-expected.txt b/LayoutTests/css3/color-filters/color-filter-animation-expected.txt
new file mode 100644 (file)
index 0000000..7bb0c87
--- /dev/null
@@ -0,0 +1,10 @@
+       
+PASS - "colorFilter" property for "grayscale-box" element at 1s saw something close to: grayscale(0.5)
+PASS - "colorFilter" property for "sepia-box" element at 1s saw something close to: sepia(0.5)
+PASS - "colorFilter" property for "saturate-box" element at 1s saw something close to: saturate(0.5)
+PASS - "colorFilter" property for "huerotate-box" element at 1s saw something close to: hue-rotate(90deg)
+PASS - "colorFilter" property for "invert-box" element at 1s saw something close to: invert(0.5)
+PASS - "colorFilter" property for "opacity-box" element at 1s saw something close to: opacity(0.5)
+PASS - "colorFilter" property for "brightness-box" element at 1s saw something close to: brightness(0.5)
+PASS - "colorFilter" property for "contrast-box" element at 1s saw something close to: contrast(0.5)
+
diff --git a/LayoutTests/css3/color-filters/color-filter-animation.html b/LayoutTests/css3/color-filters/color-filter-animation.html
new file mode 100644 (file)
index 0000000..f1ed9fe
--- /dev/null
@@ -0,0 +1,119 @@
+<!DOCTYPE html>
+
+<html>
+<head>
+  <style>
+    .box {
+        height: 100px;
+        width: 100px;
+        margin: 10px;
+        background-color: blue;
+        display: inline-block;
+    }
+
+    #grayscale-box {
+      animation: grayscale-anim 2s linear
+    }
+
+    #sepia-box {
+      animation: sepia-anim 2s linear
+    }
+
+    #saturate-box {
+      animation: saturate-anim 2s linear
+    }
+
+    #huerotate-box {
+      animation: huerotate-anim 2s linear
+    }
+
+    #invert-box {
+      animation: invert-anim 2s linear
+    }
+
+    #opacity-box {
+      animation: opacity-anim 2s linear
+    }
+
+    #brightness-box {
+      animation: brightness-anim 2s linear
+    }
+
+    #contrast-box {
+      animation: contrast-anim 2s linear
+    }
+
+
+    @keyframes grayscale-anim {
+        from { color-filter: grayscale(0); }
+        to   { color-filter: grayscale(1); }
+    }
+
+    @keyframes sepia-anim {
+        from { color-filter: sepia(0); }
+        to   { color-filter: sepia(1); }
+    }
+
+    @keyframes saturate-anim {
+        from { color-filter: saturate(0); }
+        to   { color-filter: saturate(1); }
+    }
+
+    @keyframes huerotate-anim {
+        from { color-filter: hue-rotate(0); }
+        to   { color-filter: hue-rotate(180deg); }
+    }
+
+    @keyframes invert-anim {
+        from { color-filter: invert(0); }
+        to   { color-filter: invert(1); }
+    }
+
+    @keyframes opacity-anim {
+        from { color-filter: opacity(1); }
+        to   { color-filter: opacity(0); }
+    }
+
+    @keyframes brightness-anim {
+        from { color-filter: brightness(1); }
+        to   { color-filter: brightness(0); }
+    }
+
+    @keyframes contrast-anim {
+        from { color-filter: contrast(1); }
+        to   { color-filter: contrast(0); }
+    }
+
+  </style>
+  <script src="../../animations/resources/animation-test-helpers.js"></script>
+  <script type="text/javascript">
+    const expectedValues = [
+      // [animation-name, time, element-id, property, expected-value, tolerance]
+      ["grayscale-anim",  1, "grayscale-box", "colorFilter", 'grayscale(0.5)', 0.05],
+      ["sepia-anim",  1, "sepia-box", "colorFilter", 'sepia(0.5)', 0.05],
+      ["saturate-anim",  1, "saturate-box", "colorFilter", 'saturate(0.5)', 0.05],
+      ["huerotate-anim",  1, "huerotate-box", "colorFilter", 'hue-rotate(90deg)', 2],
+      ["invert-anim",  1, "invert-box", "colorFilter", 'invert(0.5)', 0.05],
+      ["opacity-anim",  1, "opacity-box", "colorFilter", 'opacity(0.5)', 0.05],
+      ["brightness-anim",  1, "brightness-box", "colorFilter", 'brightness(0.5)', 0.05],
+      ["contrast-anim",  1, "contrast-box", "colorFilter", 'contrast(0.5)', 0.05],
+    ];
+    
+    runAnimationTest(expectedValues);
+  </script>
+</head>
+<body>
+
+<div class="box" id="grayscale-box"></div>
+<div class="box" id="sepia-box"></div>
+<div class="box" id="saturate-box"></div>
+<div class="box" id="huerotate-box"></div>
+<div class="box" id="invert-box"></div>
+<div class="box" id="opacity-box"></div>
+<div class="box" id="brightness-box"></div>
+<div class="box" id="contrast-box"></div>
+
+<div id="result">
+</div>
+</body>
+</html>
index 2f8f5a1..e3dd00d 100644 (file)
@@ -1,3 +1,45 @@
+2018-04-27  Simon Fraser  <simon.fraser@apple.com>
+
+        Implement animation for color-filter
+        https://bugs.webkit.org/show_bug.cgi?id=185092
+        rdar://problem/39773810
+
+        Reviewed by Tim Horton.
+        
+        Implement animation of color-filter.
+        
+        This requires tracking whether the color-filter function lists match for both old and new
+        animation code paths.
+        
+        The filter-related ProperyWappers in CSSPropertyAnimation are cleaned up to use a single wrapper,
+        which has to pass the propertyID to the blend function so we know which "lists match" to check.
+        This wrapper reports that its accelerated for filter and backdrop-filter, but not color-filter.
+
+        Test: css3/color-filters/color-filter-animation.html
+
+        * animation/CSSPropertyBlendingClient.h:
+        * animation/KeyframeEffectReadOnly.cpp:
+        (WebCore::KeyframeEffectReadOnly::setBlendingKeyframes):
+        (WebCore::KeyframeEffectReadOnly::checkForMatchingColorFilterFunctionLists):
+        * animation/KeyframeEffectReadOnly.h:
+        * page/animation/AnimationBase.h:
+        * page/animation/CSSPropertyAnimation.cpp:
+        (WebCore::blendFunc):
+        (WebCore::PropertyWrapperFilter::PropertyWrapperFilter):
+        (WebCore::CSSPropertyAnimationWrapperMap::CSSPropertyAnimationWrapperMap):
+        (WebCore::PropertyWrapperAcceleratedFilter::PropertyWrapperAcceleratedFilter): Deleted.
+        (WebCore::PropertyWrapperAcceleratedBackdropFilter::PropertyWrapperAcceleratedBackdropFilter): Deleted.
+        (WebCore::PropertyWrapperAcceleratedBackdropFilter::animationIsAccelerated const): Deleted.
+        (WebCore::PropertyWrapperAcceleratedBackdropFilter::blend const): Deleted.
+        * page/animation/ImplicitAnimation.cpp:
+        (WebCore::ImplicitAnimation::reset):
+        (WebCore::ImplicitAnimation::checkForMatchingColorFilterFunctionLists):
+        * page/animation/ImplicitAnimation.h:
+        * page/animation/KeyframeAnimation.cpp:
+        (WebCore::KeyframeAnimation::KeyframeAnimation):
+        (WebCore::KeyframeAnimation::checkForMatchingColorFilterFunctionLists):
+        * page/animation/KeyframeAnimation.h:
+
 2018-04-27  Zalan Bujtas  <zalan@apple.com>
 
         [LFC] Add FormattingContext::computeWidth/computeHeight logic.
index 429c3bb..0d7747e 100644 (file)
@@ -41,6 +41,7 @@ public:
 #if ENABLE(FILTERS_LEVEL_2)
     virtual bool backdropFilterFunctionListsMatch() const = 0;
 #endif
+    virtual bool colorFilterFunctionListsMatch() const = 0;
 
     virtual ~CSSPropertyBlendingClient() = default;
 };
index efad647..54fad57 100644 (file)
@@ -724,6 +724,7 @@ void KeyframeEffectReadOnly::setBlendingKeyframes(KeyframeList& blendingKeyframe
 #if ENABLE(FILTERS_LEVEL_2)
     checkForMatchingBackdropFilterFunctionLists();
 #endif
+    checkForMatchingColorFilterFunctionLists();
 }
 
 void KeyframeEffectReadOnly::checkForMatchingTransformFunctionLists()
@@ -814,6 +815,13 @@ void KeyframeEffectReadOnly::checkForMatchingBackdropFilterFunctionLists()
 }
 #endif
 
+void KeyframeEffectReadOnly::checkForMatchingColorFilterFunctionLists()
+{
+    m_colorFilterFunctionListsMatch = checkForMatchingFilterFunctionLists(CSSPropertyColorFilter, [] (const RenderStyle& style) -> const FilterOperations& {
+        return style.colorFilter();
+    });
+}
+
 void KeyframeEffectReadOnly::computeDeclarativeAnimationBlendingKeyframes(const RenderStyle* oldStyle, const RenderStyle& newStyle)
 {
     ASSERT(is<DeclarativeAnimation>(animation()));
index 59d2229..4cf8353 100644 (file)
@@ -111,6 +111,7 @@ public:
 #if ENABLE(FILTERS_LEVEL_2)
     bool backdropFilterFunctionListsMatch() const override { return m_backdropFilterFunctionListsMatch; }
 #endif
+    bool colorFilterFunctionListsMatch() const override { return m_colorFilterFunctionListsMatch; }
 
     void computeDeclarativeAnimationBlendingKeyframes(const RenderStyle* oldStyle, const RenderStyle& newStyle);
     bool stylesWouldYieldNewCSSTransitionsBlendingKeyframes(const RenderStyle& oldStyle, const RenderStyle& newStyle) const;
@@ -149,6 +150,7 @@ private:
 #if ENABLE(FILTERS_LEVEL_2)
     void checkForMatchingBackdropFilterFunctionLists();
 #endif
+    void checkForMatchingColorFilterFunctionLists();
 
     bool checkForMatchingFilterFunctionLists(CSSPropertyID, const std::function<const FilterOperations& (const RenderStyle&)>&) const;
 
@@ -162,6 +164,7 @@ private:
 #if ENABLE(FILTERS_LEVEL_2)
     bool m_backdropFilterFunctionListsMatch { false };
 #endif
+    bool m_colorFilterFunctionListsMatch { false };
 
     RefPtr<Element> m_target;
     KeyframeList m_blendingKeyframes;
index 4c733f1..b4d3743 100644 (file)
@@ -186,6 +186,7 @@ public:
 #if ENABLE(FILTERS_LEVEL_2)
     bool backdropFilterFunctionListsMatch() const override { return m_backdropFilterFunctionListsMatch; }
 #endif
+    bool colorFilterFunctionListsMatch() const override { return m_colorFilterFunctionListsMatch; }
 
     // Freeze the animation; used by DumpRenderTree.
     void freezeAtTime(double t);
@@ -260,6 +261,7 @@ protected:
 #if ENABLE(FILTERS_LEVEL_2)
     bool m_backdropFilterFunctionListsMatch { false };
 #endif
+    bool m_colorFilterFunctionListsMatch { false };
 };
 
 } // namespace WebCore
index 7efcb54..8820d38 100644 (file)
@@ -200,18 +200,30 @@ static inline FilterOperations blendFilterOperations(const CSSPropertyBlendingCl
     return result;
 }
 
-static inline FilterOperations blendFunc(const CSSPropertyBlendingClient* anim, const FilterOperations& from, const FilterOperations& to, double progress, bool animatingBackdropFilter = false)
+static inline FilterOperations blendFunc(const CSSPropertyBlendingClient* anim, const FilterOperations& from, const FilterOperations& to, double progress, CSSPropertyID propertyID = CSSPropertyFilter)
 {
     FilterOperations result;
 
     // If we have a filter function list, use that to do a per-function animation.
+    
+    bool listsMatch = false;
+    switch (propertyID) {
+    case CSSPropertyFilter:
+        listsMatch = anim->filterFunctionListsMatch();
+        break;
 #if ENABLE(FILTERS_LEVEL_2)
-    if ((!animatingBackdropFilter && anim->filterFunctionListsMatch()) || (animatingBackdropFilter && anim->backdropFilterFunctionListsMatch()))
-#else
-    UNUSED_PARAM(animatingBackdropFilter);
-    if (anim->filterFunctionListsMatch())
+    case CSSPropertyWebkitBackdropFilter:
+        listsMatch = anim->backdropFilterFunctionListsMatch();
+        break;
 #endif
-
+    case CSSPropertyColorFilter:
+        listsMatch = anim->colorFilterFunctionListsMatch();
+        break;
+    default:
+        break;
+    }
+    
+    if (listsMatch)
         result = blendFilterOperations(anim, from, to, progress);
     else {
         // If the filter function lists don't match, we could try to cross-fade, but don't yet have a way to represent that in CSS.
@@ -670,39 +682,28 @@ public:
     }
 };
 
-class PropertyWrapperAcceleratedFilter : public PropertyWrapper<const FilterOperations&> {
+class PropertyWrapperFilter : public PropertyWrapper<const FilterOperations&> {
     WTF_MAKE_FAST_ALLOCATED;
 public:
-    PropertyWrapperAcceleratedFilter()
-        : PropertyWrapper<const FilterOperations&>(CSSPropertyFilter, &RenderStyle::filter, &RenderStyle::setFilter)
+    PropertyWrapperFilter(CSSPropertyID propertyID, const FilterOperations& (RenderStyle::*getter)() const, void (RenderStyle::*setter)(const FilterOperations&))
+        : PropertyWrapper<const FilterOperations&>(propertyID, getter, setter)
     {
     }
 
-    bool animationIsAccelerated() const override { return true; }
-
-    void blend(const CSSPropertyBlendingClient* anim, RenderStyle* dst, const RenderStyle* a, const RenderStyle* b, double progress) const override
+    bool animationIsAccelerated() const override
     {
-        dst->setFilter(blendFunc(anim, a->filter(), b->filter(), progress));
-    }
-};
-
+        return property() == CSSPropertyFilter
 #if ENABLE(FILTERS_LEVEL_2)
-class PropertyWrapperAcceleratedBackdropFilter : public PropertyWrapper<const FilterOperations&> {
-    WTF_MAKE_FAST_ALLOCATED;
-public:
-    PropertyWrapperAcceleratedBackdropFilter()
-        : PropertyWrapper<const FilterOperations&>(CSSPropertyWebkitBackdropFilter, &RenderStyle::backdropFilter, &RenderStyle::setBackdropFilter)
-    {
+            || property() == CSSPropertyWebkitBackdropFilter
+#endif
+            ;
     }
 
-    virtual bool animationIsAccelerated() const { return true; }
-
-    virtual void blend(const CSSPropertyBlendingClient* anim, RenderStyle* dst, const RenderStyle* a, const RenderStyle* b, double progress) const
+    void blend(const CSSPropertyBlendingClient* anim, RenderStyle* dst, const RenderStyle* a, const RenderStyle* b, double progress) const override
     {
-        dst->setBackdropFilter(blendFunc(anim, a->backdropFilter(), b->backdropFilter(), progress, true));
+        (dst->*m_setter)(blendFunc(anim, (a->*PropertyWrapperGetter<const FilterOperations&>::m_getter)(), (b->*PropertyWrapperGetter<const FilterOperations&>::m_getter)(), progress, property()));
     }
 };
-#endif
 
 static inline size_t shadowListLength(const ShadowData* shadow)
 {
@@ -1558,10 +1559,13 @@ CSSPropertyAnimationWrapperMap::CSSPropertyAnimationWrapperMap()
 
         new PropertyWrapperAcceleratedOpacity(),
         new PropertyWrapperAcceleratedTransform(),
-        new PropertyWrapperAcceleratedFilter(),
+        
+        new PropertyWrapperFilter(CSSPropertyFilter, &RenderStyle::filter, &RenderStyle::setFilter),
 #if ENABLE(FILTERS_LEVEL_2)
-        new PropertyWrapperAcceleratedBackdropFilter(),
+        new PropertyWrapperFilter(CSSPropertyWebkitBackdropFilter, &RenderStyle::backdropFilter, &RenderStyle::setBackdropFilter),
 #endif
+        new PropertyWrapperFilter(CSSPropertyColorFilter, &RenderStyle::colorFilter, &RenderStyle::setColorFilter),
+
         new PropertyWrapperClipPath(CSSPropertyWebkitClipPath, &RenderStyle::clipPath, &RenderStyle::setClipPath),
 
         new PropertyWrapperShape(CSSPropertyShapeOutside, &RenderStyle::shapeOutside, &RenderStyle::setShapeOutside),
index c6c7d18..080cfcc 100644 (file)
@@ -215,6 +215,7 @@ void ImplicitAnimation::reset(const RenderStyle& to, CompositeAnimation& composi
 #if ENABLE(FILTERS_LEVEL_2)
     checkForMatchingBackdropFilterFunctionLists();
 #endif
+    checkForMatchingColorFilterFunctionLists();
 }
 
 void ImplicitAnimation::setOverridden(bool b)
@@ -311,6 +312,16 @@ void ImplicitAnimation::checkForMatchingBackdropFilterFunctionLists()
 }
 #endif
 
+void ImplicitAnimation::checkForMatchingColorFilterFunctionLists()
+{
+    m_filterFunctionListsMatch = false;
+
+    if (!m_fromStyle || !m_toStyle)
+        return;
+
+    m_colorFilterFunctionListsMatch = filterOperationsMatch(&m_fromStyle->colorFilter(), m_toStyle->colorFilter());
+}
+
 std::optional<Seconds> ImplicitAnimation::timeToNextService()
 {
     std::optional<Seconds> t = AnimationBase::timeToNextService();
index b28115c..921ef78 100644 (file)
@@ -86,6 +86,7 @@ protected:
 #if ENABLE(FILTERS_LEVEL_2)
     void checkForMatchingBackdropFilterFunctionLists();
 #endif
+    void checkForMatchingColorFilterFunctionLists();
 
 private:
     ImplicitAnimation(const Animation&, CSSPropertyID, Element&, CompositeAnimation&, const RenderStyle&);
index 564f489..73a6f38 100644 (file)
@@ -58,6 +58,8 @@ KeyframeAnimation::KeyframeAnimation(const Animation& animation, Element& elemen
 #if ENABLE(FILTERS_LEVEL_2)
     checkForMatchingBackdropFilterFunctionLists();
 #endif
+    checkForMatchingColorFilterFunctionLists();
+
     computeStackingContextImpact();
     computeLayoutDependency();
 }
@@ -493,6 +495,13 @@ void KeyframeAnimation::checkForMatchingBackdropFilterFunctionLists()
 }
 #endif
 
+void KeyframeAnimation::checkForMatchingColorFilterFunctionLists()
+{
+    m_colorFilterFunctionListsMatch = checkForMatchingFilterFunctionLists(CSSPropertyColorFilter, [] (const RenderStyle& style) -> const FilterOperations& {
+        return style.colorFilter();
+    });
+}
+
 std::optional<Seconds> KeyframeAnimation::timeToNextService()
 {
     std::optional<Seconds> t = AnimationBase::timeToNextService();
index 208aa6f..d180c0e 100644 (file)
@@ -91,6 +91,7 @@ protected:
 #if ENABLE(FILTERS_LEVEL_2)
     void checkForMatchingBackdropFilterFunctionLists();
 #endif
+    void checkForMatchingColorFilterFunctionLists();
     bool checkForMatchingFilterFunctionLists(CSSPropertyID, const std::function<const FilterOperations& (const RenderStyle&)>&) const;
 
 private: