<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[184908] trunk</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/184908">184908</a></dd>
<dt>Author</dt> <dd>dino@apple.com</dd>
<dt>Date</dt> <dd>2015-05-27 11:15:08 -0700 (Wed, 27 May 2015)</dd>
</dl>

<h3>Log Message</h3>
<pre>Backdrop filters don't animate
https://bugs.webkit.org/show_bug.cgi?id=145386
&lt;rdar://problem/21110037&gt;

Reviewed by Simon Fraser.

Source/WebCore:

Add support for animation of backdrop filters.

Note that, at the moment, we can only animate/transition
backdrop-filter if it is already present on the element. See
https://bugs.webkit.org/show_bug.cgi?id=145107

Test: css3/filters/backdrop/animation.html

* page/animation/AnimationBase.h: Add m_backdropFilterFunctionListsMatch and backdropFilterFunctionListsMatch.
(WebCore::AnimationBase::backdropFilterFunctionListsMatch):

* page/animation/CSSPropertyAnimation.cpp:
(WebCore::blendFunc): backdrop-filter is also supported.
(WebCore::PropertyWrapperAcceleratedBackdropFilter::PropertyWrapperAcceleratedBackdropFilter): Added. Works
similarly to the PropertyWrapperAcceleratedFilter.
(WebCore::PropertyWrapperAcceleratedBackdropFilter::animationIsAccelerated):
(WebCore::PropertyWrapperAcceleratedBackdropFilter::blend):
(WebCore::CSSPropertyAnimationWrapperMap::CSSPropertyAnimationWrapperMap): Construct the
PropertyWrapperAcceleratedBackdropFilter.

* page/animation/ImplicitAnimation.cpp:
(WebCore::ImplicitAnimation::reset): Call checkForMatchingBackdropFilterFunctionLists.
(WebCore::ImplicitAnimation::validateTransformFunctionList): Fix typo.
(WebCore::ImplicitAnimation::checkForMatchingFilterFunctionLists): Remove whitespace.
(WebCore::ImplicitAnimation::checkForMatchingBackdropFilterFunctionLists): New method that
checks if the individual filters in a filter list match.
* page/animation/ImplicitAnimation.h: Add checkForMatchingBackdropFilterFunctionLists.

* page/animation/KeyframeAnimation.cpp:
(WebCore::KeyframeAnimation::KeyframeAnimation): Call checkForMatchingBackdropFilterFunctionLists.
(WebCore::KeyframeAnimation::checkForMatchingBackdropFilterFunctionLists): Copied from
checkForMatchingFilterFunctionLists, but calls backdropFilter() instead of filter().
(WebCore::KeyframeAnimation::checkForMatchingFilterFunctionLists): This was accidentally checking
for backdrop filters as well, but it wouldn't have worked.
* page/animation/KeyframeAnimation.h: Add checkForMatchingBackdropFilterFunctionLists.

* platform/graphics/GraphicsLayer.cpp:
(WebCore::GraphicsLayer::validateFilterOperations): Modify the ASSERT to allow AnimatedPropertyWebkitBackdropFilter.
* platform/graphics/GraphicsLayerClient.h: Add AnimatedPropertyWebkitBackdropFilter to the enum.

* platform/graphics/ca/GraphicsLayerCA.cpp:
(WebCore::propertyIdToString): Support new enum.
(WebCore::GraphicsLayerCA::addAnimation): Support AnimatedPropertyWebkitBackdropFilter.
(WebCore::GraphicsLayerCA::createFilterAnimationsFromKeyframes): Ditto.
(WebCore::GraphicsLayerCA::animatedLayer): Use a switch statement now that we have more than
two options, and handle AnimatedPropertyWebkitBackdropFilter.
(WebCore::GraphicsLayerCA::updateAnimations): Deleted a blank line.

* rendering/RenderLayerBacking.cpp:
(WebCore::RenderLayerBacking::startAnimation): Support animation of backdrop-filter.
(WebCore::RenderLayerBacking::startTransition): Ditto. Copied the code from the filter transition.
(WebCore::RenderLayerBacking::graphicsLayerToCSSProperty):
(WebCore::RenderLayerBacking::cssToGraphicsLayerProperty):
* rendering/RenderLayerCompositor.cpp:
(WebCore::RenderLayerCompositor::requiresCompositingForAnimation):

LayoutTests:

Add a test for animation of backdrop-filter, and do some
minor cleanups in related files.

* animations/resources/animation-test-helpers.js:
(parseFilterImage): Fix a typo.
(getPropertyValue): Support webkitBackdropFilter.
(comparePropertyValue): Ditto.
* css3/filters/backdrop/animation-expected.txt: Added.
* css3/filters/backdrop/animation.html: Added.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkLayoutTestsanimationsresourcesanimationtesthelpersjs">trunk/LayoutTests/animations/resources/animation-test-helpers.js</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCorepageanimationAnimationBaseh">trunk/Source/WebCore/page/animation/AnimationBase.h</a></li>
<li><a href="#trunkSourceWebCorepageanimationCSSPropertyAnimationcpp">trunk/Source/WebCore/page/animation/CSSPropertyAnimation.cpp</a></li>
<li><a href="#trunkSourceWebCorepageanimationImplicitAnimationcpp">trunk/Source/WebCore/page/animation/ImplicitAnimation.cpp</a></li>
<li><a href="#trunkSourceWebCorepageanimationImplicitAnimationh">trunk/Source/WebCore/page/animation/ImplicitAnimation.h</a></li>
<li><a href="#trunkSourceWebCorepageanimationKeyframeAnimationcpp">trunk/Source/WebCore/page/animation/KeyframeAnimation.cpp</a></li>
<li><a href="#trunkSourceWebCorepageanimationKeyframeAnimationh">trunk/Source/WebCore/page/animation/KeyframeAnimation.h</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsGraphicsLayercpp">trunk/Source/WebCore/platform/graphics/GraphicsLayer.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsGraphicsLayerClienth">trunk/Source/WebCore/platform/graphics/GraphicsLayerClient.h</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicscaGraphicsLayerCAcpp">trunk/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp</a></li>
<li><a href="#trunkSourceWebCorerenderingRenderLayerBackingcpp">trunk/Source/WebCore/rendering/RenderLayerBacking.cpp</a></li>
<li><a href="#trunkSourceWebCorerenderingRenderLayerCompositorcpp">trunk/Source/WebCore/rendering/RenderLayerCompositor.cpp</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkLayoutTestscss3filtersbackdropanimationexpectedtxt">trunk/LayoutTests/css3/filters/backdrop/animation-expected.txt</a></li>
<li><a href="#trunkLayoutTestscss3filtersbackdropanimationhtml">trunk/LayoutTests/css3/filters/backdrop/animation.html</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (184907 => 184908)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2015-05-27 17:12:14 UTC (rev 184907)
+++ trunk/LayoutTests/ChangeLog        2015-05-27 18:15:08 UTC (rev 184908)
</span><span class="lines">@@ -1,3 +1,21 @@
</span><ins>+2015-05-26  Dean Jackson  &lt;dino@apple.com&gt;
+
+        Backdrop filters don't animate
+        https://bugs.webkit.org/show_bug.cgi?id=145386
+        &lt;rdar://problem/21110037&gt;
+
+        Reviewed by Simon Fraser.
+
+        Add a test for animation of backdrop-filter, and do some
+        minor cleanups in related files.
+
+        * animations/resources/animation-test-helpers.js:
+        (parseFilterImage): Fix a typo.
+        (getPropertyValue): Support webkitBackdropFilter.
+        (comparePropertyValue): Ditto.
+        * css3/filters/backdrop/animation-expected.txt: Added.
+        * css3/filters/backdrop/animation.html: Added.
+
</ins><span class="cx"> 2015-05-27  Matt Baker  &lt;mattbaker@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         [iOS] Rebaseline expected results for tests in LayoutTests/compositing
</span></span></pre></div>
<a id="trunkLayoutTestsanimationsresourcesanimationtesthelpersjs"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/animations/resources/animation-test-helpers.js (184907 => 184908)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/animations/resources/animation-test-helpers.js        2015-05-27 17:12:14 UTC (rev 184907)
+++ trunk/LayoutTests/animations/resources/animation-test-helpers.js        2015-05-27 18:15:08 UTC (rev 184908)
</span><span class="lines">@@ -126,19 +126,19 @@
</span><span class="cx">     // Separate image value from filter function list.
</span><span class="cx">     var matches = s.match(&quot;([\\-\\w]+\\(.*\\))\\s*,\\s*(.*)\\s*&quot;);
</span><span class="cx">     if (!matches) {
</span><del>-        console.error(&quot;Parsing error on 'fitler()' &quot;, s);
</del><ins>+        console.error(&quot;Parsing error on 'filter()' &quot;, s);
</ins><span class="cx">         return false;
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     var image = parseCSSImage(matches[1]);
</span><span class="cx">     if (!image) {
</span><del>-        console.error(&quot;Parsing error on image passed to 'fitler()' &quot;, s);
</del><ins>+        console.error(&quot;Parsing error on image passed to 'filter()' &quot;, s);
</ins><span class="cx">         return false;
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     var filterFunctionList = parseFilterFunctionList(matches[2]);
</span><span class="cx">     if (!filterFunctionList) {
</span><del>-        console.error(&quot;Parsing error on filter function list passed to 'fitler()' &quot;, s);
</del><ins>+        console.error(&quot;Parsing error on filter function list passed to 'filter()' &quot;, s);
</ins><span class="cx">         return false;
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="lines">@@ -395,6 +395,7 @@
</span><span class="cx">                || property == &quot;webkitMaskImage&quot;
</span><span class="cx">                || property == &quot;webkitMaskBoxImage&quot;
</span><span class="cx">                || property == &quot;webkitFilter&quot;
</span><ins>+               || property == &quot;webkitBackdropFilter&quot;
</ins><span class="cx">                || property == &quot;webkitClipPath&quot;
</span><span class="cx">                || property == &quot;webkitShapeInside&quot;
</span><span class="cx">                || property == &quot;webkitShapeOutside&quot;
</span><span class="lines">@@ -426,7 +427,7 @@
</span><span class="cx">                     break;
</span><span class="cx">             }
</span><span class="cx">         }
</span><del>-    } else if (property == &quot;webkitFilter&quot;) {
</del><ins>+    } else if (property == &quot;webkitFilter&quot; || property == &quot;webkitBackdropFilter&quot;) {
</ins><span class="cx">         var filterParameters = parseFilterFunctionList(computedValue);
</span><span class="cx">         var filter2Parameters = parseFilterFunctionList(expectedValue);
</span><span class="cx">         result = compareFilterFunctions(filterParameters, filter2Parameters, tolerance);
</span></span></pre></div>
<a id="trunkLayoutTestscss3filtersbackdropanimationexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/css3/filters/backdrop/animation-expected.txt (0 => 184908)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/css3/filters/backdrop/animation-expected.txt                                (rev 0)
+++ trunk/LayoutTests/css3/filters/backdrop/animation-expected.txt        2015-05-27 18:15:08 UTC (rev 184908)
</span><span class="lines">@@ -0,0 +1,11 @@
</span><ins>+        
+PASS - &quot;webkitBackdropFilter&quot; property for &quot;grayscale-box&quot; element at 1s saw something close to: grayscale(0.5)
+PASS - &quot;webkitBackdropFilter&quot; property for &quot;sepia-box&quot; element at 1s saw something close to: sepia(0.5)
+PASS - &quot;webkitBackdropFilter&quot; property for &quot;saturate-box&quot; element at 1s saw something close to: saturate(0.5)
+PASS - &quot;webkitBackdropFilter&quot; property for &quot;huerotate-box&quot; element at 1s saw something close to: hue-rotate(90deg)
+PASS - &quot;webkitBackdropFilter&quot; property for &quot;invert-box&quot; element at 1s saw something close to: invert(0.5)
+PASS - &quot;webkitBackdropFilter&quot; property for &quot;opacity-box&quot; element at 1s saw something close to: opacity(0.5)
+PASS - &quot;webkitBackdropFilter&quot; property for &quot;brightness-box&quot; element at 1s saw something close to: brightness(0.5)
+PASS - &quot;webkitBackdropFilter&quot; property for &quot;contrast-box&quot; element at 1s saw something close to: contrast(0.5)
+PASS - &quot;webkitBackdropFilter&quot; property for &quot;blur-box&quot; element at 1s saw something close to: blur(10px)
+
</ins><span class="cx">Property changes on: trunk/LayoutTests/css3/filters/backdrop/animation-expected.txt
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnmimetype"></a>
<div class="addfile"><h4>Added: svn:mime-type</h4></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkLayoutTestscss3filtersbackdropanimationhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/css3/filters/backdrop/animation.html (0 => 184908)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/css3/filters/backdrop/animation.html                                (rev 0)
+++ trunk/LayoutTests/css3/filters/backdrop/animation.html        2015-05-27 18:15:08 UTC (rev 184908)
</span><span class="lines">@@ -0,0 +1,148 @@
</span><ins>+&lt;!DOCTYPE html&gt;
+
+&lt;html&gt;
+&lt;head&gt;
+  &lt;style&gt;
+    .bg {
+        height: 100px;
+        width: 100px;
+        margin: 10px;
+        position: relative;
+        background-image: url('../resources/reference.png');
+        display: inline-block;
+        -webkit-transform: translateZ(0);
+        -webkit-animation-duration:2s !important;
+    }
+
+    .box {
+        position: absolute;
+        top: 0;
+        left: 0;
+        height: 100px;
+        width: 100px;
+        -webkit-transform: translateZ(0);
+        -webkit-animation-duration: 2s !important;
+        -webkit-backdrop-filter: invert(0);
+    }
+
+    #grayscale-box {
+      -webkit-animation: grayscale-anim 2s linear
+    }
+
+    #sepia-box {
+      -webkit-animation: sepia-anim 2s linear
+    }
+
+    #saturate-box {
+      -webkit-animation: saturate-anim 2s linear
+    }
+
+    #huerotate-box {
+      -webkit-animation: huerotate-anim 2s linear
+    }
+
+    #invert-box {
+      -webkit-animation: invert-anim 2s linear
+    }
+
+    #opacity-box {
+      -webkit-animation: opacity-anim 2s linear
+    }
+
+    #brightness-box {
+      -webkit-animation: brightness-anim 2s linear
+    }
+
+    #contrast-box {
+      -webkit-animation: contrast-anim 2s linear
+    }
+
+    #blur-box {
+      -webkit-animation: blur-anim 2s linear
+    }
+
+    #dropshadow-box {
+      -webkit-animation: dropshadow-anim 2s linear
+    }
+
+
+    @-webkit-keyframes grayscale-anim {
+        from { -webkit-backdrop-filter: grayscale(0); }
+        to   { -webkit-backdrop-filter: grayscale(1); }
+    }
+
+    @-webkit-keyframes sepia-anim {
+        from { -webkit-backdrop-filter: sepia(0); }
+        to   { -webkit-backdrop-filter: sepia(1); }
+    }
+
+    @-webkit-keyframes saturate-anim {
+        from { -webkit-backdrop-filter: saturate(0); }
+        to   { -webkit-backdrop-filter: saturate(1); }
+    }
+
+    @-webkit-keyframes huerotate-anim {
+        from { -webkit-backdrop-filter: hue-rotate(0); }
+        to   { -webkit-backdrop-filter: hue-rotate(180deg); }
+    }
+
+    @-webkit-keyframes invert-anim {
+        from { -webkit-backdrop-filter: invert(0); }
+        to   { -webkit-backdrop-filter: invert(1); }
+    }
+
+    @-webkit-keyframes opacity-anim {
+        from { -webkit-backdrop-filter: opacity(1); }
+        to   { -webkit-backdrop-filter: opacity(0); }
+    }
+
+    @-webkit-keyframes brightness-anim {
+        from { -webkit-backdrop-filter: brightness(1); }
+        to   { -webkit-backdrop-filter: brightness(0); }
+    }
+
+    @-webkit-keyframes contrast-anim {
+        from { -webkit-backdrop-filter: contrast(1); }
+        to   { -webkit-backdrop-filter: contrast(0); }
+    }
+
+    @-webkit-keyframes blur-anim {
+        from { -webkit-backdrop-filter: blur(0); }
+        to   { -webkit-backdrop-filter: blur(20px); }
+    }
+
+  &lt;/style&gt;
+  &lt;script src=&quot;../../../animations/resources/animation-test-helpers.js&quot;&gt;&lt;/script&gt;
+  &lt;script type=&quot;text/javascript&quot;&gt;
+    var expectedValues = [
+      // [animation-name, time, element-id, property, expected-value, tolerance]
+      [&quot;grayscale-anim&quot;,  1, &quot;grayscale-box&quot;, &quot;webkitBackdropFilter&quot;, 'grayscale(0.5)', 0.1],
+      [&quot;sepia-anim&quot;,  1, &quot;sepia-box&quot;, &quot;webkitBackdropFilter&quot;, 'sepia(0.5)', 0.1],
+      [&quot;saturate-anim&quot;,  1, &quot;saturate-box&quot;, &quot;webkitBackdropFilter&quot;, 'saturate(0.5)', 0.1],
+      [&quot;huerotate-anim&quot;,  1, &quot;huerotate-box&quot;, &quot;webkitBackdropFilter&quot;, 'hue-rotate(90deg)', 10],
+      [&quot;invert-anim&quot;,  1, &quot;invert-box&quot;, &quot;webkitBackdropFilter&quot;, 'invert(0.5)', 0.1],
+      [&quot;opacity-anim&quot;,  1, &quot;opacity-box&quot;, &quot;webkitBackdropFilter&quot;, 'opacity(0.5)', 0.1],
+      [&quot;brightness-anim&quot;,  1, &quot;brightness-box&quot;, &quot;webkitBackdropFilter&quot;, 'brightness(0.5)', 0.1],
+      [&quot;contrast-anim&quot;,  1, &quot;contrast-box&quot;, &quot;webkitBackdropFilter&quot;, 'contrast(0.5)', 0.1],
+      [&quot;blur-anim&quot;,  1, &quot;blur-box&quot;, &quot;webkitBackdropFilter&quot;, 'blur(10px)', 2],
+    ];
+
+    runAnimationTest(expectedValues);
+  &lt;/script&gt;
+&lt;/head&gt;
+&lt;body&gt;
+
+&lt;div class=&quot;bg&quot;&gt;&lt;div class=&quot;box&quot; id=&quot;grayscale-box&quot;&gt;&lt;/div&gt;&lt;/div&gt;
+&lt;div class=&quot;bg&quot;&gt;&lt;div class=&quot;box&quot; id=&quot;sepia-box&quot;&gt;&lt;/div&gt;&lt;/div&gt;
+&lt;div class=&quot;bg&quot;&gt;&lt;div class=&quot;box&quot; id=&quot;saturate-box&quot;&gt;&lt;/div&gt;&lt;/div&gt;
+&lt;div class=&quot;bg&quot;&gt;&lt;div class=&quot;box&quot; id=&quot;huerotate-box&quot;&gt;&lt;/div&gt;&lt;/div&gt;
+&lt;div class=&quot;bg&quot;&gt;&lt;div class=&quot;box&quot; id=&quot;invert-box&quot;&gt;&lt;/div&gt;&lt;/div&gt;
+&lt;div class=&quot;bg&quot;&gt;&lt;div class=&quot;box&quot; id=&quot;opacity-box&quot;&gt;&lt;/div&gt;&lt;/div&gt;
+&lt;div class=&quot;bg&quot;&gt;&lt;div class=&quot;box&quot; id=&quot;brightness-box&quot;&gt;&lt;/div&gt;&lt;/div&gt;
+&lt;div class=&quot;bg&quot;&gt;&lt;div class=&quot;box&quot; id=&quot;contrast-box&quot;&gt;&lt;/div&gt;&lt;/div&gt;
+&lt;div class=&quot;bg&quot;&gt;&lt;div class=&quot;box&quot; id=&quot;blur-box&quot;&gt;&lt;/div&gt;&lt;/div&gt;
+
+&lt;div id=&quot;result&quot;&gt;
+&lt;/div&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</ins><span class="cx">Property changes on: trunk/LayoutTests/css3/filters/backdrop/animation.html
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnmimetype"></a>
<div class="addfile"><h4>Added: svn:mime-type</h4></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (184907 => 184908)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2015-05-27 17:12:14 UTC (rev 184907)
+++ trunk/Source/WebCore/ChangeLog        2015-05-27 18:15:08 UTC (rev 184908)
</span><span class="lines">@@ -1,3 +1,67 @@
</span><ins>+2015-05-26  Dean Jackson  &lt;dino@apple.com&gt;
+
+        Backdrop filters don't animate
+        https://bugs.webkit.org/show_bug.cgi?id=145386
+        &lt;rdar://problem/21110037&gt;
+
+        Reviewed by Simon Fraser.
+
+        Add support for animation of backdrop filters.
+
+        Note that, at the moment, we can only animate/transition
+        backdrop-filter if it is already present on the element. See
+        https://bugs.webkit.org/show_bug.cgi?id=145107
+
+        Test: css3/filters/backdrop/animation.html
+
+        * page/animation/AnimationBase.h: Add m_backdropFilterFunctionListsMatch and backdropFilterFunctionListsMatch.
+        (WebCore::AnimationBase::backdropFilterFunctionListsMatch):
+
+        * page/animation/CSSPropertyAnimation.cpp:
+        (WebCore::blendFunc): backdrop-filter is also supported.
+        (WebCore::PropertyWrapperAcceleratedBackdropFilter::PropertyWrapperAcceleratedBackdropFilter): Added. Works
+        similarly to the PropertyWrapperAcceleratedFilter.
+        (WebCore::PropertyWrapperAcceleratedBackdropFilter::animationIsAccelerated):
+        (WebCore::PropertyWrapperAcceleratedBackdropFilter::blend):
+        (WebCore::CSSPropertyAnimationWrapperMap::CSSPropertyAnimationWrapperMap): Construct the
+        PropertyWrapperAcceleratedBackdropFilter.
+
+        * page/animation/ImplicitAnimation.cpp:
+        (WebCore::ImplicitAnimation::reset): Call checkForMatchingBackdropFilterFunctionLists.
+        (WebCore::ImplicitAnimation::validateTransformFunctionList): Fix typo.
+        (WebCore::ImplicitAnimation::checkForMatchingFilterFunctionLists): Remove whitespace.
+        (WebCore::ImplicitAnimation::checkForMatchingBackdropFilterFunctionLists): New method that
+        checks if the individual filters in a filter list match.
+        * page/animation/ImplicitAnimation.h: Add checkForMatchingBackdropFilterFunctionLists.
+
+        * page/animation/KeyframeAnimation.cpp:
+        (WebCore::KeyframeAnimation::KeyframeAnimation): Call checkForMatchingBackdropFilterFunctionLists.
+        (WebCore::KeyframeAnimation::checkForMatchingBackdropFilterFunctionLists): Copied from
+        checkForMatchingFilterFunctionLists, but calls backdropFilter() instead of filter().
+        (WebCore::KeyframeAnimation::checkForMatchingFilterFunctionLists): This was accidentally checking
+        for backdrop filters as well, but it wouldn't have worked.
+        * page/animation/KeyframeAnimation.h: Add checkForMatchingBackdropFilterFunctionLists.
+
+        * platform/graphics/GraphicsLayer.cpp:
+        (WebCore::GraphicsLayer::validateFilterOperations): Modify the ASSERT to allow AnimatedPropertyWebkitBackdropFilter.
+        * platform/graphics/GraphicsLayerClient.h: Add AnimatedPropertyWebkitBackdropFilter to the enum.
+
+        * platform/graphics/ca/GraphicsLayerCA.cpp:
+        (WebCore::propertyIdToString): Support new enum.
+        (WebCore::GraphicsLayerCA::addAnimation): Support AnimatedPropertyWebkitBackdropFilter.
+        (WebCore::GraphicsLayerCA::createFilterAnimationsFromKeyframes): Ditto.
+        (WebCore::GraphicsLayerCA::animatedLayer): Use a switch statement now that we have more than
+        two options, and handle AnimatedPropertyWebkitBackdropFilter.
+        (WebCore::GraphicsLayerCA::updateAnimations): Deleted a blank line.
+
+        * rendering/RenderLayerBacking.cpp:
+        (WebCore::RenderLayerBacking::startAnimation): Support animation of backdrop-filter.
+        (WebCore::RenderLayerBacking::startTransition): Ditto. Copied the code from the filter transition.
+        (WebCore::RenderLayerBacking::graphicsLayerToCSSProperty):
+        (WebCore::RenderLayerBacking::cssToGraphicsLayerProperty):
+        * rendering/RenderLayerCompositor.cpp:
+        (WebCore::RenderLayerCompositor::requiresCompositingForAnimation):
+
</ins><span class="cx"> 2015-05-27  Jeremy Jones  &lt;jeremyj@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Handle case where -startOptimizedFullscreen fails.
</span></span></pre></div>
<a id="trunkSourceWebCorepageanimationAnimationBaseh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/page/animation/AnimationBase.h (184907 => 184908)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/page/animation/AnimationBase.h        2015-05-27 17:12:14 UTC (rev 184907)
+++ trunk/Source/WebCore/page/animation/AnimationBase.h        2015-05-27 18:15:08 UTC (rev 184908)
</span><span class="lines">@@ -192,6 +192,9 @@
</span><span class="cx">     // FIXME: rename this using the &quot;lists match&quot; terminology.
</span><span class="cx">     bool isTransformFunctionListValid() const { return m_transformFunctionListValid; }
</span><span class="cx">     bool filterFunctionListsMatch() const { return m_filterFunctionListsMatch; }
</span><ins>+#if ENABLE(FILTERS_LEVEL_2)
+    bool backdropFilterFunctionListsMatch() const { return m_backdropFilterFunctionListsMatch; }
+#endif
</ins><span class="cx"> 
</span><span class="cx">     // Freeze the animation; used by DumpRenderTree.
</span><span class="cx">     void freezeAtTime(double t);
</span><span class="lines">@@ -259,6 +262,9 @@
</span><span class="cx">     bool m_isAccelerated { false };
</span><span class="cx">     bool m_transformFunctionListValid { false };
</span><span class="cx">     bool m_filterFunctionListsMatch { false };
</span><ins>+#if ENABLE(FILTERS_LEVEL_2)
+    bool m_backdropFilterFunctionListsMatch { false };
+#endif
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } // namespace WebCore
</span></span></pre></div>
<a id="trunkSourceWebCorepageanimationCSSPropertyAnimationcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/page/animation/CSSPropertyAnimation.cpp (184907 => 184908)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/page/animation/CSSPropertyAnimation.cpp        2015-05-27 17:12:14 UTC (rev 184907)
+++ trunk/Source/WebCore/page/animation/CSSPropertyAnimation.cpp        2015-05-27 18:15:08 UTC (rev 184908)
</span><span class="lines">@@ -195,12 +195,18 @@
</span><span class="cx">     return result;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-static inline FilterOperations blendFunc(const AnimationBase* anim, const FilterOperations&amp; from, const FilterOperations&amp; to, double progress)
</del><ins>+static inline FilterOperations blendFunc(const AnimationBase* anim, const FilterOperations&amp; from, const FilterOperations&amp; to, double progress, bool animatingBackdropFilter = false)
</ins><span class="cx"> {
</span><span class="cx">     FilterOperations result;
</span><span class="cx"> 
</span><span class="cx">     // If we have a filter function list, use that to do a per-function animation.
</span><ins>+#if ENABLE(FILTERS_LEVEL_2)
+    if ((!animatingBackdropFilter &amp;&amp; anim-&gt;filterFunctionListsMatch()) || (animatingBackdropFilter &amp;&amp; anim-&gt;backdropFilterFunctionListsMatch()))
+#else
+    UNUSED_PARAM(animatingBackdropFilter);
</ins><span class="cx">     if (anim-&gt;filterFunctionListsMatch())
</span><ins>+#endif
+
</ins><span class="cx">         result = blendFilterOperations(anim, from, to, progress);
</span><span class="cx">     else {
</span><span class="cx">         // 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.
</span><span class="lines">@@ -616,6 +622,24 @@
</span><span class="cx">     }
</span><span class="cx"> };
</span><span class="cx"> 
</span><ins>+#if ENABLE(FILTERS_LEVEL_2)
+class PropertyWrapperAcceleratedBackdropFilter : public PropertyWrapper&lt;const FilterOperations&amp;&gt; {
+    WTF_MAKE_FAST_ALLOCATED;
+public:
+    PropertyWrapperAcceleratedBackdropFilter()
+        : PropertyWrapper&lt;const FilterOperations&amp;&gt;(CSSPropertyWebkitBackdropFilter, &amp;RenderStyle::backdropFilter, &amp;RenderStyle::setBackdropFilter)
+    {
+    }
+
+    virtual bool animationIsAccelerated() const { return true; }
+
+    virtual void blend(const AnimationBase* anim, RenderStyle* dst, const RenderStyle* a, const RenderStyle* b, double progress) const
+    {
+        dst-&gt;setBackdropFilter(blendFunc(anim, a-&gt;backdropFilter(), b-&gt;backdropFilter(), progress, true));
+    }
+};
+#endif
+
</ins><span class="cx"> static inline size_t shadowListLength(const ShadowData* shadow)
</span><span class="cx"> {
</span><span class="cx">     size_t count;
</span><span class="lines">@@ -1280,6 +1304,9 @@
</span><span class="cx">         new PropertyWrapperAcceleratedOpacity(),
</span><span class="cx">         new PropertyWrapperAcceleratedTransform(),
</span><span class="cx">         new PropertyWrapperAcceleratedFilter(),
</span><ins>+#if ENABLE(FILTERS_LEVEL_2)
+        new PropertyWrapperAcceleratedBackdropFilter(),
+#endif
</ins><span class="cx">         new PropertyWrapperClipPath(CSSPropertyWebkitClipPath, &amp;RenderStyle::clipPath, &amp;RenderStyle::setClipPath),
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(CSS_SHAPES)
</span></span></pre></div>
<a id="trunkSourceWebCorepageanimationImplicitAnimationcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/page/animation/ImplicitAnimation.cpp (184907 => 184908)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/page/animation/ImplicitAnimation.cpp        2015-05-27 17:12:14 UTC (rev 184907)
+++ trunk/Source/WebCore/page/animation/ImplicitAnimation.cpp        2015-05-27 18:15:08 UTC (rev 184908)
</span><span class="lines">@@ -219,6 +219,9 @@
</span><span class="cx">     // set the transform animation list
</span><span class="cx">     validateTransformFunctionList();
</span><span class="cx">     checkForMatchingFilterFunctionLists();
</span><ins>+#if ENABLE(FILTERS_LEVEL_2)
+    checkForMatchingBackdropFilterFunctionLists();
+#endif
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void ImplicitAnimation::setOverridden(bool b)
</span><span class="lines">@@ -271,7 +274,7 @@
</span><span class="cx">     if (val-&gt;operations().isEmpty())
</span><span class="cx">         return;
</span><span class="cx">         
</span><del>-    // An emtpy transform list matches anything.
</del><ins>+    // An empty transform list matches anything.
</ins><span class="cx">     if (val != toVal &amp;&amp; !toVal-&gt;operations().isEmpty() &amp;&amp; !val-&gt;operationsMatch(*toVal))
</span><span class="cx">         return;
</span><span class="cx"> 
</span><span class="lines">@@ -279,29 +282,41 @@
</span><span class="cx">     m_transformFunctionListValid = true;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+static bool filterOperationsMatch(const FilterOperations* fromOperations, const FilterOperations&amp; toOperations)
+{
+    if (fromOperations-&gt;operations().isEmpty())
+        fromOperations = &amp;toOperations;
+
+    if (fromOperations-&gt;operations().isEmpty())
+        return false;
+
+    if (fromOperations != &amp;toOperations &amp;&amp; !toOperations.operations().isEmpty() &amp;&amp; !fromOperations-&gt;operationsMatch(toOperations))
+        return false;
+
+    return true;
+}
+
</ins><span class="cx"> void ImplicitAnimation::checkForMatchingFilterFunctionLists()
</span><span class="cx"> {
</span><span class="cx">     m_filterFunctionListsMatch = false;
</span><del>-    
</del><ins>+
</ins><span class="cx">     if (!m_fromStyle || !m_toStyle)
</span><span class="cx">         return;
</span><del>-        
-    const FilterOperations* val = &amp;m_fromStyle-&gt;filter();
-    const FilterOperations* toVal = &amp;m_toStyle-&gt;filter();
</del><span class="cx"> 
</span><del>-    if (val-&gt;operations().isEmpty())
-        val = toVal;
</del><ins>+    m_filterFunctionListsMatch = filterOperationsMatch(&amp;m_fromStyle-&gt;filter(), m_toStyle-&gt;filter());
+}
</ins><span class="cx"> 
</span><del>-    if (val-&gt;operations().isEmpty())
</del><ins>+#if ENABLE(FILTERS_LEVEL_2)
+void ImplicitAnimation::checkForMatchingBackdropFilterFunctionLists()
+{
+    m_backdropFilterFunctionListsMatch = false;
+
+    if (!m_fromStyle || !m_toStyle)
</ins><span class="cx">         return;
</span><del>-        
-    // An emtpy filter list matches anything.
-    if (val != toVal &amp;&amp; !toVal-&gt;operations().isEmpty() &amp;&amp; !val-&gt;operationsMatch(*toVal))
-        return;
</del><span class="cx"> 
</span><del>-    // Filter lists match.
-    m_filterFunctionListsMatch = true;
</del><ins>+    m_backdropFilterFunctionListsMatch = filterOperationsMatch(&amp;m_fromStyle-&gt;backdropFilter(), m_toStyle-&gt;backdropFilter());
</ins><span class="cx"> }
</span><ins>+#endif
</ins><span class="cx"> 
</span><span class="cx"> double ImplicitAnimation::timeToNextService()
</span><span class="cx"> {
</span></span></pre></div>
<a id="trunkSourceWebCorepageanimationImplicitAnimationh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/page/animation/ImplicitAnimation.h (184907 => 184908)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/page/animation/ImplicitAnimation.h        2015-05-27 17:12:14 UTC (rev 184907)
+++ trunk/Source/WebCore/page/animation/ImplicitAnimation.h        2015-05-27 18:15:08 UTC (rev 184908)
</span><span class="lines">@@ -82,6 +82,9 @@
</span><span class="cx"> 
</span><span class="cx">     void validateTransformFunctionList();
</span><span class="cx">     void checkForMatchingFilterFunctionLists();
</span><ins>+#if ENABLE(FILTERS_LEVEL_2)
+    void checkForMatchingBackdropFilterFunctionLists();
+#endif
</ins><span class="cx"> 
</span><span class="cx"> private:
</span><span class="cx">     ImplicitAnimation(Animation&amp;, CSSPropertyID, RenderElement*, CompositeAnimation*, RenderStyle*);
</span></span></pre></div>
<a id="trunkSourceWebCorepageanimationKeyframeAnimationcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/page/animation/KeyframeAnimation.cpp (184907 => 184908)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/page/animation/KeyframeAnimation.cpp        2015-05-27 17:12:14 UTC (rev 184907)
+++ trunk/Source/WebCore/page/animation/KeyframeAnimation.cpp        2015-05-27 18:15:08 UTC (rev 184908)
</span><span class="lines">@@ -54,6 +54,9 @@
</span><span class="cx">     // Update the m_transformFunctionListValid flag based on whether the function lists in the keyframes match.
</span><span class="cx">     validateTransformFunctionList();
</span><span class="cx">     checkForMatchingFilterFunctionLists();
</span><ins>+#if ENABLE(FILTERS_LEVEL_2)
+    checkForMatchingBackdropFilterFunctionLists();
+#endif
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> KeyframeAnimation::~KeyframeAnimation()
</span><span class="lines">@@ -397,11 +400,7 @@
</span><span class="cx"> {
</span><span class="cx">     m_filterFunctionListsMatch = false;
</span><span class="cx"> 
</span><del>-#if ENABLE(FILTERS_LEVEL_2)
-    if (m_keyframes.size() &lt; 2 || (!m_keyframes.containsProperty(CSSPropertyWebkitFilter) &amp;&amp; !m_keyframes.containsProperty(CSSPropertyWebkitBackdropFilter)))
-#else
</del><span class="cx">     if (m_keyframes.size() &lt; 2 || !m_keyframes.containsProperty(CSSPropertyWebkitFilter))
</span><del>-#endif
</del><span class="cx">         return;
</span><span class="cx"> 
</span><span class="cx">     // Empty filters match anything, so find the first non-empty entry as the reference
</span><span class="lines">@@ -409,8 +408,7 @@
</span><span class="cx">     size_t firstNonEmptyFilterKeyframeIndex = numKeyframes;
</span><span class="cx"> 
</span><span class="cx">     for (size_t i = 0; i &lt; numKeyframes; ++i) {
</span><del>-        const KeyframeValue&amp; currentKeyframe = m_keyframes[i];
-        if (currentKeyframe.style()-&gt;filter().operations().size()) {
</del><ins>+        if (m_keyframes[i].style()-&gt;filter().operations().size()) {
</ins><span class="cx">             firstNonEmptyFilterKeyframeIndex = i;
</span><span class="cx">             break;
</span><span class="cx">         }
</span><span class="lines">@@ -418,24 +416,62 @@
</span><span class="cx">     
</span><span class="cx">     if (firstNonEmptyFilterKeyframeIndex == numKeyframes)
</span><span class="cx">         return;
</span><del>-        
-    const FilterOperations* firstVal = &amp;m_keyframes[firstNonEmptyFilterKeyframeIndex].style()-&gt;filter();
</del><ins>+
+    auto&amp; firstVal = m_keyframes[firstNonEmptyFilterKeyframeIndex].style()-&gt;filter();
</ins><span class="cx">     
</span><span class="cx">     for (size_t i = firstNonEmptyFilterKeyframeIndex + 1; i &lt; numKeyframes; ++i) {
</span><del>-        const KeyframeValue&amp; currentKeyframe = m_keyframes[i];
-        const FilterOperations* val = &amp;currentKeyframe.style()-&gt;filter();
-        
</del><ins>+        auto&amp; value = m_keyframes[i].style()-&gt;filter();
+
</ins><span class="cx">         // An emtpy filter list matches anything.
</span><del>-        if (val-&gt;operations().isEmpty())
</del><ins>+        if (value.operations().isEmpty())
</ins><span class="cx">             continue;
</span><del>-        
-        if (!firstVal-&gt;operationsMatch(*val))
</del><ins>+
+        if (!firstVal.operationsMatch(value))
</ins><span class="cx">             return;
</span><span class="cx">     }
</span><del>-    
</del><ins>+
</ins><span class="cx">     m_filterFunctionListsMatch = true;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+#if ENABLE(FILTERS_LEVEL_2)
+void KeyframeAnimation::checkForMatchingBackdropFilterFunctionLists()
+{
+    m_backdropFilterFunctionListsMatch = false;
+
+    if (m_keyframes.size() &lt; 2 || !m_keyframes.containsProperty(CSSPropertyWebkitBackdropFilter))
+        return;
+
+    // Empty filters match anything, so find the first non-empty entry as the reference
+    size_t numKeyframes = m_keyframes.size();
+    size_t firstNonEmptyFilterKeyframeIndex = numKeyframes;
+
+    for (size_t i = 0; i &lt; numKeyframes; ++i) {
+        if (m_keyframes[i].style()-&gt;backdropFilter().operations().size()) {
+            firstNonEmptyFilterKeyframeIndex = i;
+            break;
+        }
+    }
+
+    if (firstNonEmptyFilterKeyframeIndex == numKeyframes)
+        return;
+
+    auto&amp; firstVal = m_keyframes[firstNonEmptyFilterKeyframeIndex].style()-&gt;backdropFilter();
+
+    for (size_t i = firstNonEmptyFilterKeyframeIndex + 1; i &lt; numKeyframes; ++i) {
+        auto&amp; value = m_keyframes[i].style()-&gt;backdropFilter();
+
+        // An emtpy filter list matches anything.
+        if (value.operations().isEmpty())
+            continue;
+
+        if (!firstVal.operationsMatch(value))
+            return;
+    }
+
+    m_backdropFilterFunctionListsMatch = true;
+}
+#endif
+
</ins><span class="cx"> double KeyframeAnimation::timeToNextService()
</span><span class="cx"> {
</span><span class="cx">     double t = AnimationBase::timeToNextService();
</span></span></pre></div>
<a id="trunkSourceWebCorepageanimationKeyframeAnimationh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/page/animation/KeyframeAnimation.h (184907 => 184908)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/page/animation/KeyframeAnimation.h        2015-05-27 17:12:14 UTC (rev 184907)
+++ trunk/Source/WebCore/page/animation/KeyframeAnimation.h        2015-05-27 18:15:08 UTC (rev 184908)
</span><span class="lines">@@ -85,6 +85,9 @@
</span><span class="cx"> 
</span><span class="cx">     void validateTransformFunctionList();
</span><span class="cx">     void checkForMatchingFilterFunctionLists();
</span><ins>+#if ENABLE(FILTERS_LEVEL_2)
+    void checkForMatchingBackdropFilterFunctionLists();
+#endif
</ins><span class="cx"> 
</span><span class="cx"> private:
</span><span class="cx">     KeyframeAnimation(Animation&amp;, RenderElement*, int index, CompositeAnimation*, RenderStyle* unanimatedStyle);
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsGraphicsLayercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/GraphicsLayer.cpp (184907 => 184908)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/GraphicsLayer.cpp        2015-05-27 17:12:14 UTC (rev 184907)
+++ trunk/Source/WebCore/platform/graphics/GraphicsLayer.cpp        2015-05-27 18:15:08 UTC (rev 184908)
</span><span class="lines">@@ -509,7 +509,11 @@
</span><span class="cx"> 
</span><span class="cx"> int GraphicsLayer::validateFilterOperations(const KeyframeValueList&amp; valueList)
</span><span class="cx"> {
</span><ins>+#if ENABLE(FILTERS_LEVEL_2)
+    ASSERT(valueList.property() == AnimatedPropertyWebkitFilter || valueList.property() == AnimatedPropertyWebkitBackdropFilter);
+#else
</ins><span class="cx">     ASSERT(valueList.property() == AnimatedPropertyWebkitFilter);
</span><ins>+#endif
</ins><span class="cx"> 
</span><span class="cx">     if (valueList.size() &lt; 2)
</span><span class="cx">         return -1;
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsGraphicsLayerClienth"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/GraphicsLayerClient.h (184907 => 184908)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/GraphicsLayerClient.h        2015-05-27 17:12:14 UTC (rev 184907)
+++ trunk/Source/WebCore/platform/graphics/GraphicsLayerClient.h        2015-05-27 18:15:08 UTC (rev 184908)
</span><span class="lines">@@ -56,6 +56,9 @@
</span><span class="cx">     AnimatedPropertyOpacity,
</span><span class="cx">     AnimatedPropertyBackgroundColor,
</span><span class="cx">     AnimatedPropertyWebkitFilter
</span><ins>+#if ENABLE(FILTERS_LEVEL_2)
+    , AnimatedPropertyWebkitBackdropFilter
+#endif
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> enum LayerTreeAsTextBehaviorFlags {
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicscaGraphicsLayerCAcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp (184907 => 184908)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp        2015-05-27 17:12:14 UTC (rev 184907)
+++ trunk/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp        2015-05-27 18:15:08 UTC (rev 184908)
</span><span class="lines">@@ -229,22 +229,26 @@
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-static String propertyIdToString(AnimatedPropertyID property)
</del><ins>+static ASCIILiteral propertyIdToString(AnimatedPropertyID property)
</ins><span class="cx"> {
</span><span class="cx">     switch (property) {
</span><span class="cx">     case AnimatedPropertyTransform:
</span><del>-        return &quot;transform&quot;;
</del><ins>+        return ASCIILiteral(&quot;transform&quot;);
</ins><span class="cx">     case AnimatedPropertyOpacity:
</span><del>-        return &quot;opacity&quot;;
</del><ins>+        return ASCIILiteral(&quot;opacity&quot;);
</ins><span class="cx">     case AnimatedPropertyBackgroundColor:
</span><del>-        return &quot;backgroundColor&quot;;
</del><ins>+        return ASCIILiteral(&quot;backgroundColor&quot;);
</ins><span class="cx">     case AnimatedPropertyWebkitFilter:
</span><del>-        return &quot;filters&quot;;
</del><ins>+        return ASCIILiteral(&quot;filters&quot;);
+#if ENABLE(FILTERS_LEVEL_2)
+    case AnimatedPropertyWebkitBackdropFilter:
+        return ASCIILiteral(&quot;backdropFilters&quot;);
+#endif
</ins><span class="cx">     case AnimatedPropertyInvalid:
</span><span class="cx">         ASSERT_NOT_REACHED();
</span><span class="cx">     }
</span><span class="cx">     ASSERT_NOT_REACHED();
</span><del>-    return &quot;&quot;;
</del><ins>+    return ASCIILiteral(&quot;&quot;);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> static String animationIdentifier(const String&amp; animationName, AnimatedPropertyID property, int index, int subIndex)
</span><span class="lines">@@ -885,6 +889,12 @@
</span><span class="cx">         if (supportsAcceleratedFilterAnimations())
</span><span class="cx">             createdAnimations = createFilterAnimationsFromKeyframes(valueList, anim, animationName, timeOffset);
</span><span class="cx">     }
</span><ins>+#if ENABLE(FILTERS_LEVEL_2)
+    else if (valueList.property() == AnimatedPropertyWebkitBackdropFilter) {
+        if (supportsAcceleratedFilterAnimations())
+            createdAnimations = createFilterAnimationsFromKeyframes(valueList, anim, animationName, timeOffset);
+    }
+#endif
</ins><span class="cx">     else
</span><span class="cx">         createdAnimations = createAnimationFromKeyframes(valueList, anim, animationName, timeOffset);
</span><span class="cx"> 
</span><span class="lines">@@ -2462,7 +2472,6 @@
</span><span class="cx">                 Vector&lt;LayerPropertyAnimation&gt; animations;
</span><span class="cx">                 animations.append(pendingAnimation);
</span><span class="cx">                 m_runningAnimations.add(pendingAnimation.m_name, animations);
</span><del>-
</del><span class="cx">             } else {
</span><span class="cx">                 Vector&lt;LayerPropertyAnimation&gt;&amp; animations = it-&gt;value;
</span><span class="cx">                 animations.append(pendingAnimation);
</span><span class="lines">@@ -2738,7 +2747,11 @@
</span><span class="cx"> 
</span><span class="cx"> bool GraphicsLayerCA::createFilterAnimationsFromKeyframes(const KeyframeValueList&amp; valueList, const Animation* animation, const String&amp; animationName, double timeOffset)
</span><span class="cx"> {
</span><ins>+#if ENABLE(FILTERS_LEVEL_2)
+    ASSERT(valueList.property() == AnimatedPropertyWebkitFilter || valueList.property() == AnimatedPropertyWebkitBackdropFilter);
+#else
</ins><span class="cx">     ASSERT(valueList.property() == AnimatedPropertyWebkitFilter);
</span><ins>+#endif
</ins><span class="cx"> 
</span><span class="cx">     int listIndex = validateFilterOperations(valueList);
</span><span class="cx">     if (listIndex &lt; 0)
</span><span class="lines">@@ -3130,7 +3143,17 @@
</span><span class="cx"> 
</span><span class="cx"> PlatformCALayer* GraphicsLayerCA::animatedLayer(AnimatedPropertyID property) const
</span><span class="cx"> {
</span><del>-    return (property == AnimatedPropertyBackgroundColor) ? m_contentsLayer.get() : primaryLayer();
</del><ins>+    switch (property) {
+    case AnimatedPropertyBackgroundColor:
+        return m_contentsLayer.get();
+#if ENABLE(FILTERS_LEVEL_2)
+    case AnimatedPropertyWebkitBackdropFilter:
+        // FIXME: Should be just m_backdropLayer.get(). Also, add an ASSERT(m_backdropLayer) here when https://bugs.webkit.org/show_bug.cgi?id=145322 is fixed.
+        return m_backdropLayer ? m_backdropLayer.get() : primaryLayer();
+#endif
+    default:
+        return primaryLayer();
+    }
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> GraphicsLayerCA::LayerMap* GraphicsLayerCA::animatedLayerClones(AnimatedPropertyID property) const
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingRenderLayerBackingcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/RenderLayerBacking.cpp (184907 => 184908)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/RenderLayerBacking.cpp        2015-05-27 17:12:14 UTC (rev 184907)
+++ trunk/Source/WebCore/rendering/RenderLayerBacking.cpp        2015-05-27 18:15:08 UTC (rev 184908)
</span><span class="lines">@@ -2455,12 +2455,20 @@
</span><span class="cx">     bool hasTransform = renderer().isBox() &amp;&amp; keyframes.containsProperty(CSSPropertyTransform);
</span><span class="cx">     bool hasFilter = keyframes.containsProperty(CSSPropertyWebkitFilter);
</span><span class="cx"> 
</span><del>-    if (!hasOpacity &amp;&amp; !hasTransform &amp;&amp; !hasFilter)
</del><ins>+    bool hasBackdropFilter = false;
+#if ENABLE(FILTERS_LEVEL_2)
+    hasBackdropFilter = keyframes.containsProperty(CSSPropertyWebkitBackdropFilter);
+#endif
+
+    if (!hasOpacity &amp;&amp; !hasTransform &amp;&amp; !hasFilter &amp;&amp; !hasBackdropFilter)
</ins><span class="cx">         return false;
</span><del>-    
</del><ins>+
</ins><span class="cx">     KeyframeValueList transformVector(AnimatedPropertyTransform);
</span><span class="cx">     KeyframeValueList opacityVector(AnimatedPropertyOpacity);
</span><span class="cx">     KeyframeValueList filterVector(AnimatedPropertyWebkitFilter);
</span><ins>+#if ENABLE(FILTERS_LEVEL_2)
+    KeyframeValueList backdropFilterVector(AnimatedPropertyWebkitBackdropFilter);
+#endif
</ins><span class="cx"> 
</span><span class="cx">     size_t numKeyframes = keyframes.size();
</span><span class="cx">     for (size_t i = 0; i &lt; numKeyframes; ++i) {
</span><span class="lines">@@ -2482,6 +2490,11 @@
</span><span class="cx"> 
</span><span class="cx">         if ((hasFilter &amp;&amp; isFirstOrLastKeyframe) || currentKeyframe.containsProperty(CSSPropertyWebkitFilter))
</span><span class="cx">             filterVector.insert(std::make_unique&lt;FilterAnimationValue&gt;(key, keyframeStyle-&gt;filter(), tf));
</span><ins>+
+#if ENABLE(FILTERS_LEVEL_2)
+        if ((hasBackdropFilter &amp;&amp; isFirstOrLastKeyframe) || currentKeyframe.containsProperty(CSSPropertyWebkitBackdropFilter))
+            backdropFilterVector.insert(std::make_unique&lt;FilterAnimationValue&gt;(key, keyframeStyle-&gt;backdropFilter(), tf));
+#endif
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     if (renderer().frame().page() &amp;&amp; !renderer().frame().page()-&gt;settings().acceleratedCompositedAnimationsEnabled())
</span><span class="lines">@@ -2498,6 +2511,11 @@
</span><span class="cx">     if (hasFilter &amp;&amp; m_graphicsLayer-&gt;addAnimation(filterVector, IntSize(), anim, keyframes.animationName(), timeOffset))
</span><span class="cx">         didAnimate = true;
</span><span class="cx"> 
</span><ins>+#if ENABLE(FILTERS_LEVEL_2)
+    if (hasBackdropFilter &amp;&amp; m_graphicsLayer-&gt;addAnimation(backdropFilterVector, IntSize(), anim, keyframes.animationName(), timeOffset))
+        didAnimate = true;
+#endif
+
</ins><span class="cx">     return didAnimate;
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -2560,6 +2578,22 @@
</span><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+#if ENABLE(FILTERS_LEVEL_2)
+    if (property == CSSPropertyWebkitBackdropFilter &amp;&amp; m_owningLayer.hasBackdropFilter()) {
+        const Animation* backdropFilterAnim = toStyle-&gt;transitionForProperty(CSSPropertyWebkitBackdropFilter);
+        if (backdropFilterAnim &amp;&amp; !backdropFilterAnim-&gt;isEmptyOrZeroDuration()) {
+            KeyframeValueList backdropFilterVector(AnimatedPropertyWebkitBackdropFilter);
+            backdropFilterVector.insert(std::make_unique&lt;FilterAnimationValue&gt;(0, fromStyle-&gt;backdropFilter()));
+            backdropFilterVector.insert(std::make_unique&lt;FilterAnimationValue&gt;(1, toStyle-&gt;backdropFilter()));
+            if (m_graphicsLayer-&gt;addAnimation(backdropFilterVector, FloatSize(), backdropFilterAnim, GraphicsLayer::animationNameForTransition(AnimatedPropertyWebkitBackdropFilter), timeOffset)) {
+                // To ensure that the correct backdrop filter is visible when the animation ends, also set the final backdrop filter.
+                updateBackdropFilters(*toStyle);
+                didAnimate = true;
+            }
+        }
+    }
+#endif
+
</ins><span class="cx">     return didAnimate;
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -2647,6 +2681,11 @@
</span><span class="cx">     case AnimatedPropertyWebkitFilter:
</span><span class="cx">         cssProperty = CSSPropertyWebkitFilter;
</span><span class="cx">         break;
</span><ins>+#if ENABLE(FILTERS_LEVEL_2)
+    case AnimatedPropertyWebkitBackdropFilter:
+        cssProperty = CSSPropertyWebkitBackdropFilter;
+        break;
+#endif
</ins><span class="cx">     case AnimatedPropertyInvalid:
</span><span class="cx">         ASSERT_NOT_REACHED();
</span><span class="cx">     }
</span><span class="lines">@@ -2664,6 +2703,10 @@
</span><span class="cx">         return AnimatedPropertyBackgroundColor;
</span><span class="cx">     case CSSPropertyWebkitFilter:
</span><span class="cx">         return AnimatedPropertyWebkitFilter;
</span><ins>+#if ENABLE(FILTERS_LEVEL_2)
+    case CSSPropertyWebkitBackdropFilter:
+        return AnimatedPropertyWebkitBackdropFilter;
+#endif
</ins><span class="cx">     default:
</span><span class="cx">         // It's fine if we see other css properties here; they are just not accelerated.
</span><span class="cx">         break;
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingRenderLayerCompositorcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/RenderLayerCompositor.cpp (184907 => 184908)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/RenderLayerCompositor.cpp        2015-05-27 17:12:14 UTC (rev 184907)
+++ trunk/Source/WebCore/rendering/RenderLayerCompositor.cpp        2015-05-27 18:15:08 UTC (rev 184908)
</span><span class="lines">@@ -2574,6 +2574,9 @@
</span><span class="cx">     return (animController.isRunningAnimationOnRenderer(renderer, CSSPropertyOpacity, activeAnimationState)
</span><span class="cx">             &amp;&amp; (inCompositingMode() || (m_compositingTriggers &amp; ChromeClient::AnimatedOpacityTrigger)))
</span><span class="cx">             || animController.isRunningAnimationOnRenderer(renderer, CSSPropertyWebkitFilter, activeAnimationState)
</span><ins>+#if ENABLE(FILTERS_LEVEL_2)
+            || animController.isRunningAnimationOnRenderer(renderer, CSSPropertyWebkitBackdropFilter, activeAnimationState)
+#endif
</ins><span class="cx">             || animController.isRunningAnimationOnRenderer(renderer, CSSPropertyTransform, activeAnimationState);
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre>
</div>
</div>

</body>
</html>