Diff
Modified: trunk/LayoutTests/ChangeLog (184907 => 184908)
--- trunk/LayoutTests/ChangeLog 2015-05-27 17:12:14 UTC (rev 184907)
+++ trunk/LayoutTests/ChangeLog 2015-05-27 18:15:08 UTC (rev 184908)
@@ -1,3 +1,21 @@
+2015-05-26 Dean Jackson <[email protected]>
+
+ Backdrop filters don't animate
+ https://bugs.webkit.org/show_bug.cgi?id=145386
+ <rdar://problem/21110037>
+
+ 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.
+
2015-05-27 Matt Baker <[email protected]>
[iOS] Rebaseline expected results for tests in LayoutTests/compositing
Modified: trunk/LayoutTests/animations/resources/animation-test-helpers.js (184907 => 184908)
--- 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)
@@ -126,19 +126,19 @@
// Separate image value from filter function list.
var matches = s.match("([\\-\\w]+\\(.*\\))\\s*,\\s*(.*)\\s*");
if (!matches) {
- console.error("Parsing error on 'fitler()' ", s);
+ console.error("Parsing error on 'filter()' ", s);
return false;
}
var image = parseCSSImage(matches[1]);
if (!image) {
- console.error("Parsing error on image passed to 'fitler()' ", s);
+ console.error("Parsing error on image passed to 'filter()' ", s);
return false;
}
var filterFunctionList = parseFilterFunctionList(matches[2]);
if (!filterFunctionList) {
- console.error("Parsing error on filter function list passed to 'fitler()' ", s);
+ console.error("Parsing error on filter function list passed to 'filter()' ", s);
return false;
}
@@ -395,6 +395,7 @@
|| property == "webkitMaskImage"
|| property == "webkitMaskBoxImage"
|| property == "webkitFilter"
+ || property == "webkitBackdropFilter"
|| property == "webkitClipPath"
|| property == "webkitShapeInside"
|| property == "webkitShapeOutside"
@@ -426,7 +427,7 @@
break;
}
}
- } else if (property == "webkitFilter") {
+ } else if (property == "webkitFilter" || property == "webkitBackdropFilter") {
var filterParameters = parseFilterFunctionList(computedValue);
var filter2Parameters = parseFilterFunctionList(expectedValue);
result = compareFilterFunctions(filterParameters, filter2Parameters, tolerance);
Added: trunk/LayoutTests/css3/filters/backdrop/animation-expected.txt (0 => 184908)
--- 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)
@@ -0,0 +1,11 @@
+
+PASS - "webkitBackdropFilter" property for "grayscale-box" element at 1s saw something close to: grayscale(0.5)
+PASS - "webkitBackdropFilter" property for "sepia-box" element at 1s saw something close to: sepia(0.5)
+PASS - "webkitBackdropFilter" property for "saturate-box" element at 1s saw something close to: saturate(0.5)
+PASS - "webkitBackdropFilter" property for "huerotate-box" element at 1s saw something close to: hue-rotate(90deg)
+PASS - "webkitBackdropFilter" property for "invert-box" element at 1s saw something close to: invert(0.5)
+PASS - "webkitBackdropFilter" property for "opacity-box" element at 1s saw something close to: opacity(0.5)
+PASS - "webkitBackdropFilter" property for "brightness-box" element at 1s saw something close to: brightness(0.5)
+PASS - "webkitBackdropFilter" property for "contrast-box" element at 1s saw something close to: contrast(0.5)
+PASS - "webkitBackdropFilter" property for "blur-box" element at 1s saw something close to: blur(10px)
+
Property changes on: trunk/LayoutTests/css3/filters/backdrop/animation-expected.txt
___________________________________________________________________
Added: svn:mime-type
Added: svn:keywords
Added: svn:eol-style
Added: trunk/LayoutTests/css3/filters/backdrop/animation.html (0 => 184908)
--- 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)
@@ -0,0 +1,148 @@
+<!DOCTYPE html>
+
+<html>
+<head>
+ <style>
+ .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); }
+ }
+
+ </style>
+ <script src=""
+ <script type="text/_javascript_">
+ var expectedValues = [
+ // [animation-name, time, element-id, property, expected-value, tolerance]
+ ["grayscale-anim", 1, "grayscale-box", "webkitBackdropFilter", 'grayscale(0.5)', 0.1],
+ ["sepia-anim", 1, "sepia-box", "webkitBackdropFilter", 'sepia(0.5)', 0.1],
+ ["saturate-anim", 1, "saturate-box", "webkitBackdropFilter", 'saturate(0.5)', 0.1],
+ ["huerotate-anim", 1, "huerotate-box", "webkitBackdropFilter", 'hue-rotate(90deg)', 10],
+ ["invert-anim", 1, "invert-box", "webkitBackdropFilter", 'invert(0.5)', 0.1],
+ ["opacity-anim", 1, "opacity-box", "webkitBackdropFilter", 'opacity(0.5)', 0.1],
+ ["brightness-anim", 1, "brightness-box", "webkitBackdropFilter", 'brightness(0.5)', 0.1],
+ ["contrast-anim", 1, "contrast-box", "webkitBackdropFilter", 'contrast(0.5)', 0.1],
+ ["blur-anim", 1, "blur-box", "webkitBackdropFilter", 'blur(10px)', 2],
+ ];
+
+ runAnimationTest(expectedValues);
+ </script>
+</head>
+<body>
+
+<div class="bg"><div class="box" id="grayscale-box"></div></div>
+<div class="bg"><div class="box" id="sepia-box"></div></div>
+<div class="bg"><div class="box" id="saturate-box"></div></div>
+<div class="bg"><div class="box" id="huerotate-box"></div></div>
+<div class="bg"><div class="box" id="invert-box"></div></div>
+<div class="bg"><div class="box" id="opacity-box"></div></div>
+<div class="bg"><div class="box" id="brightness-box"></div></div>
+<div class="bg"><div class="box" id="contrast-box"></div></div>
+<div class="bg"><div class="box" id="blur-box"></div></div>
+
+<div id="result">
+</div>
+</body>
+</html>
Property changes on: trunk/LayoutTests/css3/filters/backdrop/animation.html
___________________________________________________________________
Added: svn:mime-type
Added: svn:keywords
Added: svn:eol-style
Modified: trunk/Source/WebCore/ChangeLog (184907 => 184908)
--- 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)
@@ -1,3 +1,67 @@
+2015-05-26 Dean Jackson <[email protected]>
+
+ Backdrop filters don't animate
+ https://bugs.webkit.org/show_bug.cgi?id=145386
+ <rdar://problem/21110037>
+
+ 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):
+
2015-05-27 Jeremy Jones <[email protected]>
Handle case where -startOptimizedFullscreen fails.
Modified: trunk/Source/WebCore/page/animation/AnimationBase.h (184907 => 184908)
--- 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)
@@ -192,6 +192,9 @@
// FIXME: rename this using the "lists match" terminology.
bool isTransformFunctionListValid() const { return m_transformFunctionListValid; }
bool filterFunctionListsMatch() const { return m_filterFunctionListsMatch; }
+#if ENABLE(FILTERS_LEVEL_2)
+ bool backdropFilterFunctionListsMatch() const { return m_backdropFilterFunctionListsMatch; }
+#endif
// Freeze the animation; used by DumpRenderTree.
void freezeAtTime(double t);
@@ -259,6 +262,9 @@
bool m_isAccelerated { false };
bool m_transformFunctionListValid { false };
bool m_filterFunctionListsMatch { false };
+#if ENABLE(FILTERS_LEVEL_2)
+ bool m_backdropFilterFunctionListsMatch { false };
+#endif
};
} // namespace WebCore
Modified: trunk/Source/WebCore/page/animation/CSSPropertyAnimation.cpp (184907 => 184908)
--- 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)
@@ -195,12 +195,18 @@
return result;
}
-static inline FilterOperations blendFunc(const AnimationBase* anim, const FilterOperations& from, const FilterOperations& to, double progress)
+static inline FilterOperations blendFunc(const AnimationBase* anim, const FilterOperations& from, const FilterOperations& to, double progress, bool animatingBackdropFilter = false)
{
FilterOperations result;
// If we have a filter function list, use that to do a per-function animation.
+#if ENABLE(FILTERS_LEVEL_2)
+ if ((!animatingBackdropFilter && anim->filterFunctionListsMatch()) || (animatingBackdropFilter && anim->backdropFilterFunctionListsMatch()))
+#else
+ UNUSED_PARAM(animatingBackdropFilter);
if (anim->filterFunctionListsMatch())
+#endif
+
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.
@@ -616,6 +622,24 @@
}
};
+#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)
+ {
+ }
+
+ virtual bool animationIsAccelerated() const { return true; }
+
+ virtual void blend(const AnimationBase* anim, RenderStyle* dst, const RenderStyle* a, const RenderStyle* b, double progress) const
+ {
+ dst->setBackdropFilter(blendFunc(anim, a->backdropFilter(), b->backdropFilter(), progress, true));
+ }
+};
+#endif
+
static inline size_t shadowListLength(const ShadowData* shadow)
{
size_t count;
@@ -1280,6 +1304,9 @@
new PropertyWrapperAcceleratedOpacity(),
new PropertyWrapperAcceleratedTransform(),
new PropertyWrapperAcceleratedFilter(),
+#if ENABLE(FILTERS_LEVEL_2)
+ new PropertyWrapperAcceleratedBackdropFilter(),
+#endif
new PropertyWrapperClipPath(CSSPropertyWebkitClipPath, &RenderStyle::clipPath, &RenderStyle::setClipPath),
#if ENABLE(CSS_SHAPES)
Modified: trunk/Source/WebCore/page/animation/ImplicitAnimation.cpp (184907 => 184908)
--- 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)
@@ -219,6 +219,9 @@
// set the transform animation list
validateTransformFunctionList();
checkForMatchingFilterFunctionLists();
+#if ENABLE(FILTERS_LEVEL_2)
+ checkForMatchingBackdropFilterFunctionLists();
+#endif
}
void ImplicitAnimation::setOverridden(bool b)
@@ -271,7 +274,7 @@
if (val->operations().isEmpty())
return;
- // An emtpy transform list matches anything.
+ // An empty transform list matches anything.
if (val != toVal && !toVal->operations().isEmpty() && !val->operationsMatch(*toVal))
return;
@@ -279,29 +282,41 @@
m_transformFunctionListValid = true;
}
+static bool filterOperationsMatch(const FilterOperations* fromOperations, const FilterOperations& toOperations)
+{
+ if (fromOperations->operations().isEmpty())
+ fromOperations = &toOperations;
+
+ if (fromOperations->operations().isEmpty())
+ return false;
+
+ if (fromOperations != &toOperations && !toOperations.operations().isEmpty() && !fromOperations->operationsMatch(toOperations))
+ return false;
+
+ return true;
+}
+
void ImplicitAnimation::checkForMatchingFilterFunctionLists()
{
m_filterFunctionListsMatch = false;
-
+
if (!m_fromStyle || !m_toStyle)
return;
-
- const FilterOperations* val = &m_fromStyle->filter();
- const FilterOperations* toVal = &m_toStyle->filter();
- if (val->operations().isEmpty())
- val = toVal;
+ m_filterFunctionListsMatch = filterOperationsMatch(&m_fromStyle->filter(), m_toStyle->filter());
+}
- if (val->operations().isEmpty())
+#if ENABLE(FILTERS_LEVEL_2)
+void ImplicitAnimation::checkForMatchingBackdropFilterFunctionLists()
+{
+ m_backdropFilterFunctionListsMatch = false;
+
+ if (!m_fromStyle || !m_toStyle)
return;
-
- // An emtpy filter list matches anything.
- if (val != toVal && !toVal->operations().isEmpty() && !val->operationsMatch(*toVal))
- return;
- // Filter lists match.
- m_filterFunctionListsMatch = true;
+ m_backdropFilterFunctionListsMatch = filterOperationsMatch(&m_fromStyle->backdropFilter(), m_toStyle->backdropFilter());
}
+#endif
double ImplicitAnimation::timeToNextService()
{
Modified: trunk/Source/WebCore/page/animation/ImplicitAnimation.h (184907 => 184908)
--- 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)
@@ -82,6 +82,9 @@
void validateTransformFunctionList();
void checkForMatchingFilterFunctionLists();
+#if ENABLE(FILTERS_LEVEL_2)
+ void checkForMatchingBackdropFilterFunctionLists();
+#endif
private:
ImplicitAnimation(Animation&, CSSPropertyID, RenderElement*, CompositeAnimation*, RenderStyle*);
Modified: trunk/Source/WebCore/page/animation/KeyframeAnimation.cpp (184907 => 184908)
--- 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)
@@ -54,6 +54,9 @@
// Update the m_transformFunctionListValid flag based on whether the function lists in the keyframes match.
validateTransformFunctionList();
checkForMatchingFilterFunctionLists();
+#if ENABLE(FILTERS_LEVEL_2)
+ checkForMatchingBackdropFilterFunctionLists();
+#endif
}
KeyframeAnimation::~KeyframeAnimation()
@@ -397,11 +400,7 @@
{
m_filterFunctionListsMatch = false;
-#if ENABLE(FILTERS_LEVEL_2)
- if (m_keyframes.size() < 2 || (!m_keyframes.containsProperty(CSSPropertyWebkitFilter) && !m_keyframes.containsProperty(CSSPropertyWebkitBackdropFilter)))
-#else
if (m_keyframes.size() < 2 || !m_keyframes.containsProperty(CSSPropertyWebkitFilter))
-#endif
return;
// Empty filters match anything, so find the first non-empty entry as the reference
@@ -409,8 +408,7 @@
size_t firstNonEmptyFilterKeyframeIndex = numKeyframes;
for (size_t i = 0; i < numKeyframes; ++i) {
- const KeyframeValue& currentKeyframe = m_keyframes[i];
- if (currentKeyframe.style()->filter().operations().size()) {
+ if (m_keyframes[i].style()->filter().operations().size()) {
firstNonEmptyFilterKeyframeIndex = i;
break;
}
@@ -418,24 +416,62 @@
if (firstNonEmptyFilterKeyframeIndex == numKeyframes)
return;
-
- const FilterOperations* firstVal = &m_keyframes[firstNonEmptyFilterKeyframeIndex].style()->filter();
+
+ auto& firstVal = m_keyframes[firstNonEmptyFilterKeyframeIndex].style()->filter();
for (size_t i = firstNonEmptyFilterKeyframeIndex + 1; i < numKeyframes; ++i) {
- const KeyframeValue& currentKeyframe = m_keyframes[i];
- const FilterOperations* val = ¤tKeyframe.style()->filter();
-
+ auto& value = m_keyframes[i].style()->filter();
+
// An emtpy filter list matches anything.
- if (val->operations().isEmpty())
+ if (value.operations().isEmpty())
continue;
-
- if (!firstVal->operationsMatch(*val))
+
+ if (!firstVal.operationsMatch(value))
return;
}
-
+
m_filterFunctionListsMatch = true;
}
+#if ENABLE(FILTERS_LEVEL_2)
+void KeyframeAnimation::checkForMatchingBackdropFilterFunctionLists()
+{
+ m_backdropFilterFunctionListsMatch = false;
+
+ if (m_keyframes.size() < 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 < numKeyframes; ++i) {
+ if (m_keyframes[i].style()->backdropFilter().operations().size()) {
+ firstNonEmptyFilterKeyframeIndex = i;
+ break;
+ }
+ }
+
+ if (firstNonEmptyFilterKeyframeIndex == numKeyframes)
+ return;
+
+ auto& firstVal = m_keyframes[firstNonEmptyFilterKeyframeIndex].style()->backdropFilter();
+
+ for (size_t i = firstNonEmptyFilterKeyframeIndex + 1; i < numKeyframes; ++i) {
+ auto& value = m_keyframes[i].style()->backdropFilter();
+
+ // An emtpy filter list matches anything.
+ if (value.operations().isEmpty())
+ continue;
+
+ if (!firstVal.operationsMatch(value))
+ return;
+ }
+
+ m_backdropFilterFunctionListsMatch = true;
+}
+#endif
+
double KeyframeAnimation::timeToNextService()
{
double t = AnimationBase::timeToNextService();
Modified: trunk/Source/WebCore/page/animation/KeyframeAnimation.h (184907 => 184908)
--- 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)
@@ -85,6 +85,9 @@
void validateTransformFunctionList();
void checkForMatchingFilterFunctionLists();
+#if ENABLE(FILTERS_LEVEL_2)
+ void checkForMatchingBackdropFilterFunctionLists();
+#endif
private:
KeyframeAnimation(Animation&, RenderElement*, int index, CompositeAnimation*, RenderStyle* unanimatedStyle);
Modified: trunk/Source/WebCore/platform/graphics/GraphicsLayer.cpp (184907 => 184908)
--- 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)
@@ -509,7 +509,11 @@
int GraphicsLayer::validateFilterOperations(const KeyframeValueList& valueList)
{
+#if ENABLE(FILTERS_LEVEL_2)
+ ASSERT(valueList.property() == AnimatedPropertyWebkitFilter || valueList.property() == AnimatedPropertyWebkitBackdropFilter);
+#else
ASSERT(valueList.property() == AnimatedPropertyWebkitFilter);
+#endif
if (valueList.size() < 2)
return -1;
Modified: trunk/Source/WebCore/platform/graphics/GraphicsLayerClient.h (184907 => 184908)
--- 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)
@@ -56,6 +56,9 @@
AnimatedPropertyOpacity,
AnimatedPropertyBackgroundColor,
AnimatedPropertyWebkitFilter
+#if ENABLE(FILTERS_LEVEL_2)
+ , AnimatedPropertyWebkitBackdropFilter
+#endif
};
enum LayerTreeAsTextBehaviorFlags {
Modified: trunk/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp (184907 => 184908)
--- 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)
@@ -229,22 +229,26 @@
}
}
-static String propertyIdToString(AnimatedPropertyID property)
+static ASCIILiteral propertyIdToString(AnimatedPropertyID property)
{
switch (property) {
case AnimatedPropertyTransform:
- return "transform";
+ return ASCIILiteral("transform");
case AnimatedPropertyOpacity:
- return "opacity";
+ return ASCIILiteral("opacity");
case AnimatedPropertyBackgroundColor:
- return "backgroundColor";
+ return ASCIILiteral("backgroundColor");
case AnimatedPropertyWebkitFilter:
- return "filters";
+ return ASCIILiteral("filters");
+#if ENABLE(FILTERS_LEVEL_2)
+ case AnimatedPropertyWebkitBackdropFilter:
+ return ASCIILiteral("backdropFilters");
+#endif
case AnimatedPropertyInvalid:
ASSERT_NOT_REACHED();
}
ASSERT_NOT_REACHED();
- return "";
+ return ASCIILiteral("");
}
static String animationIdentifier(const String& animationName, AnimatedPropertyID property, int index, int subIndex)
@@ -885,6 +889,12 @@
if (supportsAcceleratedFilterAnimations())
createdAnimations = createFilterAnimationsFromKeyframes(valueList, anim, animationName, timeOffset);
}
+#if ENABLE(FILTERS_LEVEL_2)
+ else if (valueList.property() == AnimatedPropertyWebkitBackdropFilter) {
+ if (supportsAcceleratedFilterAnimations())
+ createdAnimations = createFilterAnimationsFromKeyframes(valueList, anim, animationName, timeOffset);
+ }
+#endif
else
createdAnimations = createAnimationFromKeyframes(valueList, anim, animationName, timeOffset);
@@ -2462,7 +2472,6 @@
Vector<LayerPropertyAnimation> animations;
animations.append(pendingAnimation);
m_runningAnimations.add(pendingAnimation.m_name, animations);
-
} else {
Vector<LayerPropertyAnimation>& animations = it->value;
animations.append(pendingAnimation);
@@ -2738,7 +2747,11 @@
bool GraphicsLayerCA::createFilterAnimationsFromKeyframes(const KeyframeValueList& valueList, const Animation* animation, const String& animationName, double timeOffset)
{
+#if ENABLE(FILTERS_LEVEL_2)
+ ASSERT(valueList.property() == AnimatedPropertyWebkitFilter || valueList.property() == AnimatedPropertyWebkitBackdropFilter);
+#else
ASSERT(valueList.property() == AnimatedPropertyWebkitFilter);
+#endif
int listIndex = validateFilterOperations(valueList);
if (listIndex < 0)
@@ -3130,7 +3143,17 @@
PlatformCALayer* GraphicsLayerCA::animatedLayer(AnimatedPropertyID property) const
{
- return (property == AnimatedPropertyBackgroundColor) ? m_contentsLayer.get() : primaryLayer();
+ 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();
+ }
}
GraphicsLayerCA::LayerMap* GraphicsLayerCA::animatedLayerClones(AnimatedPropertyID property) const
Modified: trunk/Source/WebCore/rendering/RenderLayerBacking.cpp (184907 => 184908)
--- 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)
@@ -2455,12 +2455,20 @@
bool hasTransform = renderer().isBox() && keyframes.containsProperty(CSSPropertyTransform);
bool hasFilter = keyframes.containsProperty(CSSPropertyWebkitFilter);
- if (!hasOpacity && !hasTransform && !hasFilter)
+ bool hasBackdropFilter = false;
+#if ENABLE(FILTERS_LEVEL_2)
+ hasBackdropFilter = keyframes.containsProperty(CSSPropertyWebkitBackdropFilter);
+#endif
+
+ if (!hasOpacity && !hasTransform && !hasFilter && !hasBackdropFilter)
return false;
-
+
KeyframeValueList transformVector(AnimatedPropertyTransform);
KeyframeValueList opacityVector(AnimatedPropertyOpacity);
KeyframeValueList filterVector(AnimatedPropertyWebkitFilter);
+#if ENABLE(FILTERS_LEVEL_2)
+ KeyframeValueList backdropFilterVector(AnimatedPropertyWebkitBackdropFilter);
+#endif
size_t numKeyframes = keyframes.size();
for (size_t i = 0; i < numKeyframes; ++i) {
@@ -2482,6 +2490,11 @@
if ((hasFilter && isFirstOrLastKeyframe) || currentKeyframe.containsProperty(CSSPropertyWebkitFilter))
filterVector.insert(std::make_unique<FilterAnimationValue>(key, keyframeStyle->filter(), tf));
+
+#if ENABLE(FILTERS_LEVEL_2)
+ if ((hasBackdropFilter && isFirstOrLastKeyframe) || currentKeyframe.containsProperty(CSSPropertyWebkitBackdropFilter))
+ backdropFilterVector.insert(std::make_unique<FilterAnimationValue>(key, keyframeStyle->backdropFilter(), tf));
+#endif
}
if (renderer().frame().page() && !renderer().frame().page()->settings().acceleratedCompositedAnimationsEnabled())
@@ -2498,6 +2511,11 @@
if (hasFilter && m_graphicsLayer->addAnimation(filterVector, IntSize(), anim, keyframes.animationName(), timeOffset))
didAnimate = true;
+#if ENABLE(FILTERS_LEVEL_2)
+ if (hasBackdropFilter && m_graphicsLayer->addAnimation(backdropFilterVector, IntSize(), anim, keyframes.animationName(), timeOffset))
+ didAnimate = true;
+#endif
+
return didAnimate;
}
@@ -2560,6 +2578,22 @@
}
}
+#if ENABLE(FILTERS_LEVEL_2)
+ if (property == CSSPropertyWebkitBackdropFilter && m_owningLayer.hasBackdropFilter()) {
+ const Animation* backdropFilterAnim = toStyle->transitionForProperty(CSSPropertyWebkitBackdropFilter);
+ if (backdropFilterAnim && !backdropFilterAnim->isEmptyOrZeroDuration()) {
+ KeyframeValueList backdropFilterVector(AnimatedPropertyWebkitBackdropFilter);
+ backdropFilterVector.insert(std::make_unique<FilterAnimationValue>(0, fromStyle->backdropFilter()));
+ backdropFilterVector.insert(std::make_unique<FilterAnimationValue>(1, toStyle->backdropFilter()));
+ if (m_graphicsLayer->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
+
return didAnimate;
}
@@ -2647,6 +2681,11 @@
case AnimatedPropertyWebkitFilter:
cssProperty = CSSPropertyWebkitFilter;
break;
+#if ENABLE(FILTERS_LEVEL_2)
+ case AnimatedPropertyWebkitBackdropFilter:
+ cssProperty = CSSPropertyWebkitBackdropFilter;
+ break;
+#endif
case AnimatedPropertyInvalid:
ASSERT_NOT_REACHED();
}
@@ -2664,6 +2703,10 @@
return AnimatedPropertyBackgroundColor;
case CSSPropertyWebkitFilter:
return AnimatedPropertyWebkitFilter;
+#if ENABLE(FILTERS_LEVEL_2)
+ case CSSPropertyWebkitBackdropFilter:
+ return AnimatedPropertyWebkitBackdropFilter;
+#endif
default:
// It's fine if we see other css properties here; they are just not accelerated.
break;
Modified: trunk/Source/WebCore/rendering/RenderLayerCompositor.cpp (184907 => 184908)
--- 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)
@@ -2574,6 +2574,9 @@
return (animController.isRunningAnimationOnRenderer(renderer, CSSPropertyOpacity, activeAnimationState)
&& (inCompositingMode() || (m_compositingTriggers & ChromeClient::AnimatedOpacityTrigger)))
|| animController.isRunningAnimationOnRenderer(renderer, CSSPropertyWebkitFilter, activeAnimationState)
+#if ENABLE(FILTERS_LEVEL_2)
+ || animController.isRunningAnimationOnRenderer(renderer, CSSPropertyWebkitBackdropFilter, activeAnimationState)
+#endif
|| animController.isRunningAnimationOnRenderer(renderer, CSSPropertyTransform, activeAnimationState);
}