Diff
Modified: trunk/LayoutTests/ChangeLog (128379 => 128380)
--- trunk/LayoutTests/ChangeLog 2012-09-12 23:20:22 UTC (rev 128379)
+++ trunk/LayoutTests/ChangeLog 2012-09-12 23:33:41 UTC (rev 128380)
@@ -1,3 +1,24 @@
+2012-09-12 Alexandru Chiculita <[email protected]>
+
+ [CSS Shaders] Implement transform parameter animations for CSS Custom Filters
+ https://bugs.webkit.org/show_bug.cgi?id=94980
+
+ Reviewed by Dean Jackson.
+
+ Based on patch from Joshua Netterfield <[email protected]>.
+
+ Added test transform animations in css3/filters/custom/custom-filter-transform-animation.html.
+
+ * animations/resources/animation-test-helpers.js:
+ (customFilterParameterMatch): Extracted the parameter matching from filterParametersMatch and added function parameters matching.
+ This should work for all functions that have number parameters, ie. arrays, mat4 functions.
+
+ (filterParametersMatch):
+ * css3/filters/custom/custom-filter-transforms-animation-expected.txt: Added.
+ * css3/filters/custom/custom-filter-transforms-animation.html: Added.
+ * css3/filters/resources/custom-filter-parser.js: Fixed function parsing.
+ (TokenStream.prototype.skip):
+
2012-09-12 Chris Fleizach <[email protected]>
AX: svg:image not accessible
Modified: trunk/LayoutTests/animations/resources/animation-test-helpers.js (128379 => 128380)
--- trunk/LayoutTests/animations/resources/animation-test-helpers.js 2012-09-12 23:20:22 UTC (rev 128379)
+++ trunk/LayoutTests/animations/resources/animation-test-helpers.js 2012-09-12 23:33:41 UTC (rev 128380)
@@ -84,6 +84,45 @@
return paramList;
}
+function customFilterParameterMatch(param1, param2, tolerance)
+{
+ if (param1.type != "parameter") {
+ // Checking for shader uris and other keywords. They need to be exactly the same.
+ return (param1.type == param2.type && param1.value == param2.value);
+ }
+
+ if (param1.name != param2.name || param1.value.length != param2.value.length)
+ return false;
+
+ for (var j = 0; j < param1.value.length; ++j) {
+ var val1 = param1.value[j],
+ val2 = param2.value[j];
+ if (val1.type != val2.type)
+ return false;
+ switch (val1.type) {
+ case "function":
+ if (val1.name != val2.name)
+ return false;
+ for (var t = 0; t < val1.arguments.length; ++t) {
+ if (val1.arguments[t].type != "number" || val2.arguments[t].type != "number")
+ return false;
+ if (!isCloseEnough(val1.arguments[t].value, val2.arguments[t].value, tolerance))
+ return false;
+ }
+ break;
+ case "number":
+ if (!isCloseEnough(val1.value, val2.value, tolerance))
+ return false;
+ break;
+ default:
+ console.error("Unsupported parameter type ", val1.type);
+ return false;
+ }
+ }
+
+ return true;
+}
+
function filterParametersMatch(paramList1, paramList2, tolerance)
{
if (paramList1.length != paramList2.length)
@@ -93,21 +132,8 @@
param2 = paramList2[i];
if (typeof param1 == "object") {
// This is a custom filter parameter.
- if (param1.type != "parameter") {
- // Checking for shader uris and other keywords. They need to be exactly the same.
- if (param1.type != param2.type
- || param1.value != param2.value)
- return false;
- continue;
- }
- if (param1.name != param2.name
- || param1.value.length != param2.value.length)
+ if (!customFilterParameterMatch(param1, param2, tolerance))
return false;
- // For now we only support floats.
- for (var j = 0; j < param1.value.length; ++j) {
- if (!isCloseEnough(param1.value[j].value, param2.value[j].value, tolerance))
- return false;
- }
continue;
}
var match = isCloseEnough(param1, param2, tolerance);
Added: trunk/LayoutTests/css3/filters/custom/custom-filter-transforms-animation-expected.txt (0 => 128380)
--- trunk/LayoutTests/css3/filters/custom/custom-filter-transforms-animation-expected.txt (rev 0)
+++ trunk/LayoutTests/css3/filters/custom/custom-filter-transforms-animation-expected.txt 2012-09-12 23:33:41 UTC (rev 128380)
@@ -0,0 +1,9 @@
+
+PASS - "webkitFilter" property for "custom-mix-from-none-box" element at 1s saw something close to: custom(url(no-shader-needed.vs) none, 1 1 filter-box, transform matrix(30, 0, 0, 30, 0, 0))
+PASS - "webkitFilter" property for "custom-mix-to-none-box" element at 1s saw something close to: custom(url(no-shader-needed.vs) none, 1 1 filter-box, transform matrix(30, 0, 0, 30, 0, 0))
+PASS - "webkitFilter" property for "custom-mix-single-transform-box" element at 1s saw something close to: custom(url(no-shader-needed.vs) none, 1 1 filter-box, transform matrix(15, 0, 0, 15, 0, 0))
+PASS - "webkitFilter" property for "custom-mix-different-transforms-box" element at 1s saw something close to: custom(url(no-shader-needed.vs) none, 1 1 filter-box, transform matrix(100, 0, 0, 100, 0, 0))
+PASS - "webkitFilter" property for "custom-mix-multi-transform-box" element at 1s saw something close to: custom(url(no-shader-needed.vs) none, 1 1 filter-box, transform1 matrix(15, 0, 0, 15, 0, 0), transform2 matrix(100, 0, 0, 100, 0, 0))
+PASS - "webkitFilter" property for "custom-mix-different-transforms-count1-box" element at 1s saw something close to: custom(url(no-shader-needed.vs) none, 1 1 filter-box, transform matrix(50, 0, 0, 50, 0, 0))
+PASS - "webkitFilter" property for "custom-mix-different-transforms-count2-box" element at 1s saw something close to: custom(url(no-shader-needed.vs) none, 1 1 filter-box, transform matrix(50, 0, 0, 50, 0, 0))
+
Added: trunk/LayoutTests/css3/filters/custom/custom-filter-transforms-animation.html (0 => 128380)
--- trunk/LayoutTests/css3/filters/custom/custom-filter-transforms-animation.html (rev 0)
+++ trunk/LayoutTests/css3/filters/custom/custom-filter-transforms-animation.html 2012-09-12 23:33:41 UTC (rev 128380)
@@ -0,0 +1,110 @@
+<!DOCTYPE html>
+
+<html>
+<head>
+ <script>
+ if (window.testRunner) {
+ window.testRunner.overridePreference("WebKitCSSCustomFilterEnabled", "1");
+ window.testRunner.overridePreference("WebKitWebGLEnabled", "1");
+ }
+ </script>
+ <style>
+ .box {
+ height: 100px;
+ width: 100px;
+ margin: 10px;
+ background-color: blue;
+ display: inline-block;
+ }
+
+ #custom-mix-from-none-box {
+ -webkit-animation: custom-mix-from-none-anim 2s linear;
+ }
+
+ #custom-mix-to-none-box {
+ -webkit-animation: custom-mix-to-none-anim 2s linear;
+ }
+
+ #custom-mix-single-transform-box {
+ -webkit-animation: custom-mix-single-transform-anim 2s linear;
+ }
+
+ #custom-mix-different-transforms-box {
+ -webkit-animation: custom-mix-different-transforms-anim 2s linear;
+ }
+
+ #custom-mix-multi-transform-box {
+ -webkit-animation: custom-mix-multi-transform-anim 2s linear;
+ }
+
+ #custom-mix-different-transforms-count1-box {
+ -webkit-animation: custom-mix-different-transforms-count1-anim 2s linear;
+ }
+
+ #custom-mix-different-transforms-count2-box {
+ -webkit-animation: custom-mix-different-transforms-count2-anim 2s linear;
+ }
+
+ @-webkit-keyframes custom-mix-from-none-anim {
+ from { -webkit-filter: custom(url(no-shader-needed.vs)); }
+ to { -webkit-filter: custom(url(no-shader-needed.vs), transform scale(30)); }
+ }
+
+ @-webkit-keyframes custom-mix-to-none-anim {
+ from { -webkit-filter: custom(url(no-shader-needed.vs), transform scale(30)); }
+ to { -webkit-filter: custom(url(no-shader-needed.vs)); }
+ }
+
+ @-webkit-keyframes custom-mix-single-transform-anim {
+ from { -webkit-filter: custom(url(no-shader-needed.vs), transform scale(0)); }
+ to { -webkit-filter: custom(url(no-shader-needed.vs), transform scale(30)); }
+ }
+
+ @-webkit-keyframes custom-mix-different-transforms-anim {
+ from { -webkit-filter: custom(url(no-shader-needed.vs), transform scale(100) rotate(0deg)); }
+ to { -webkit-filter: custom(url(no-shader-needed.vs), transform rotate(0deg) scale(100)); }
+ }
+
+ @-webkit-keyframes custom-mix-multi-transform-anim {
+ from { -webkit-filter: custom(url(no-shader-needed.vs), transform1 scale(0), transform2 scale(100) rotate(0deg)); }
+ to { -webkit-filter: custom(url(no-shader-needed.vs), transform1 scale(30), transform2 rotate(0deg) scale(100)); }
+ }
+
+ @-webkit-keyframes custom-mix-different-transforms-count1-anim {
+ from { -webkit-filter: custom(url(no-shader-needed.vs), transform scale(1)); }
+ to { -webkit-filter: custom(url(no-shader-needed.vs), transform rotate(0deg) scale(100)); }
+ }
+
+ @-webkit-keyframes custom-mix-different-transforms-count2-anim {
+ from { -webkit-filter: custom(url(no-shader-needed.vs), transform rotate(0deg) scale(100)); }
+ to { -webkit-filter: custom(url(no-shader-needed.vs), transform scale(1)); }
+ }
+ </style>
+ <script src=""
+ <script src=""
+ <script type="text/_javascript_">
+ const expectedValues = [
+ // [animation-name, time, element-id, property, expected-value, tolerance]
+ ["custom-mix-from-none-anim", 1, "custom-mix-from-none-box", "webkitFilter", 'custom(url(no-shader-needed.vs) none, 1 1 filter-box, transform matrix(30, 0, 0, 30, 0, 0))', 2],
+ ["custom-mix-to-none-anim", 1, "custom-mix-to-none-box", "webkitFilter", 'custom(url(no-shader-needed.vs) none, 1 1 filter-box, transform matrix(30, 0, 0, 30, 0, 0))', 2],
+ ["custom-mix-single-transform-anim", 1, "custom-mix-single-transform-box", "webkitFilter", 'custom(url(no-shader-needed.vs) none, 1 1 filter-box, transform matrix(15, 0, 0, 15, 0, 0))', 2],
+ ["custom-mix-different-transforms-anim", 1, "custom-mix-different-transforms-box", "webkitFilter", 'custom(url(no-shader-needed.vs) none, 1 1 filter-box, transform matrix(100, 0, 0, 100, 0, 0))', 0],
+ ["custom-mix-multi-transform-anim", 1, "custom-mix-multi-transform-box", "webkitFilter", 'custom(url(no-shader-needed.vs) none, 1 1 filter-box, transform1 matrix(15, 0, 0, 15, 0, 0), transform2 matrix(100, 0, 0, 100, 0, 0))', 2],
+ ["custom-mix-different-transforms-count1-anim", 1, "custom-mix-different-transforms-count1-box", "webkitFilter", 'custom(url(no-shader-needed.vs) none, 1 1 filter-box, transform matrix(50, 0, 0, 50, 0, 0))', 2],
+ ["custom-mix-different-transforms-count2-anim", 1, "custom-mix-different-transforms-count2-box", "webkitFilter", 'custom(url(no-shader-needed.vs) none, 1 1 filter-box, transform matrix(50, 0, 0, 50, 0, 0))', 2]
+ ];
+ runAnimationTest(expectedValues);
+ </script>
+</head>
+<body>
+ <div class="box" id="custom-mix-from-none-box"></div>
+ <div class="box" id="custom-mix-to-none-box"></div>
+ <div class="box" id="custom-mix-single-transform-box"></div>
+ <div class="box" id="custom-mix-different-transforms-box"></div>
+ <div class="box" id="custom-mix-multi-transform-box"></div>
+ <div class="box" id="custom-mix-different-transforms-count1-box"></div>
+ <div class="box" id="custom-mix-different-transforms-count2-box"></div>
+ <div id="result">
+ </div>
+</body>
+</html>
Modified: trunk/LayoutTests/css3/filters/resources/custom-filter-parser.js (128379 => 128380)
--- trunk/LayoutTests/css3/filters/resources/custom-filter-parser.js 2012-09-12 23:20:22 UTC (rev 128379)
+++ trunk/LayoutTests/css3/filters/resources/custom-filter-parser.js 2012-09-12 23:33:41 UTC (rev 128380)
@@ -86,7 +86,7 @@
// Skips the current token only if it matches the "typeMatcher". Otherwise it throws an error.
TokenStream.prototype.skip = function(typeMatcher)
{
- if (!typeMatcher || this.ahead().isA(typeMatcher)) {
+ if (!typeMatcher || this.current().isA(typeMatcher)) {
var token = this.current();
++this.tokenIndex;
return token;
Modified: trunk/Source/WebCore/ChangeLog (128379 => 128380)
--- trunk/Source/WebCore/ChangeLog 2012-09-12 23:20:22 UTC (rev 128379)
+++ trunk/Source/WebCore/ChangeLog 2012-09-12 23:33:41 UTC (rev 128380)
@@ -1,3 +1,50 @@
+2012-09-12 Alexandru Chiculita <[email protected]>
+
+ [CSS Shaders] Implement transform parameter animations for CSS Custom Filters
+ https://bugs.webkit.org/show_bug.cgi?id=94980
+
+ Reviewed by Dean Jackson.
+
+ Based on patch from Joshua Netterfield <[email protected]>.
+
+ According to Section 39.2 of Filter Effects 1.0 Editor's draft
+ (https://dvcs.w3.org/hg/FXTF/raw-file/tip/filters/index.html), animations
+ of transforms should be handled following the CSS3 transform interpolation
+ rules. This patch implements this functionality.
+
+ Test: css3/filters/custom/custom-filter-transforms-animation.html
+
+ * page/animation/CSSPropertyAnimation.cpp:
+ (WebCore::blendFunc):
+ (WebCore):
+ * platform/graphics/filters/CustomFilterNumberParameter.h:
+ (WebCore::CustomFilterNumberParameter::blend):
+ * platform/graphics/filters/CustomFilterOperation.cpp:
+ (WebCore::blendCustomFilterParameters):
+ (WebCore::CustomFilterOperation::blend):
+ * platform/graphics/filters/CustomFilterOperation.h:
+ (WebCore):
+ (WebCore::CustomFilterOperation::blendingNeedsRendererSize): Some filters need the box size, so that they could compute
+ Transforms. Right now only the CustomFilterOperation needs that, but I've implemented using this generic function.
+ (CustomFilterOperation):
+ * platform/graphics/filters/CustomFilterParameter.h:
+ (CustomFilterParameter):
+ * platform/graphics/filters/CustomFilterTransformParameter.h:
+ (CustomFilterTransformParameter):
+ (WebCore::CustomFilterTransformParameter::blend):
+ * platform/graphics/filters/FilterOperation.h:
+ (WebCore::FilterOperation::FilterOperation::blend):
+ (FilterOperation):
+ (WebCore::FilterOperation::FilterOperation::blendingNeedsRendererSize):
+ * platform/graphics/transforms/TransformOperations.cpp: Extracted the blending functions from CSSPropertyAnimation.cpp
+ so that they could be reused from other classes.
+ (WebCore::TransformOperations::blendByMatchingOperations):
+ (WebCore):
+ (WebCore::TransformOperations::blendByUsingMatrixInterpolation): Used when the TransformOperations do not match.
+ (WebCore::TransformOperations::blend): Uses when the caller doesn't know whether the TransformOperations match or not.
+ * platform/graphics/transforms/TransformOperations.h:
+ (TransformOperations):
+
2012-09-12 Alec Flett <[email protected]>
IndexedDB: Use ScriptValue instead of SerializedScriptValue when possible
Modified: trunk/Source/WebCore/page/animation/CSSPropertyAnimation.cpp (128379 => 128380)
--- trunk/Source/WebCore/page/animation/CSSPropertyAnimation.cpp 2012-09-12 23:20:22 UTC (rev 128379)
+++ trunk/Source/WebCore/page/animation/CSSPropertyAnimation.cpp 2012-09-12 23:33:41 UTC (rev 128380)
@@ -120,44 +120,22 @@
static inline TransformOperations blendFunc(const AnimationBase* anim, const TransformOperations& from, const TransformOperations& to, double progress)
{
- TransformOperations result;
+ if (anim->isTransformFunctionListValid())
+ return to.blendByMatchingOperations(from, progress);
+ return to.blendByUsingMatrixInterpolation(from, progress, anim->renderer()->isBox() ? toRenderBox(anim->renderer())->borderBoxRect().size() : LayoutSize());
+}
- // If we have a transform function list, use that to do a per-function animation. Otherwise do a Matrix animation
- if (anim->isTransformFunctionListValid()) {
- unsigned fromSize = from.operations().size();
- unsigned toSize = to.operations().size();
- unsigned size = max(fromSize, toSize);
- for (unsigned i = 0; i < size; i++) {
- RefPtr<TransformOperation> fromOp = (i < fromSize) ? from.operations()[i].get() : 0;
- RefPtr<TransformOperation> toOp = (i < toSize) ? to.operations()[i].get() : 0;
- RefPtr<TransformOperation> blendedOp = toOp ? toOp->blend(fromOp.get(), progress) : (fromOp ? fromOp->blend(0, progress, true) : PassRefPtr<TransformOperation>(0));
- if (blendedOp)
- result.operations().append(blendedOp);
- else {
- RefPtr<TransformOperation> identityOp = IdentityTransformOperation::create();
- if (progress > 0.5)
- result.operations().append(toOp ? toOp : identityOp);
- else
- result.operations().append(fromOp ? fromOp : identityOp);
- }
- }
- } else {
- // Convert the TransformOperations into matrices
+#if ENABLE(CSS_FILTERS)
+static inline PassRefPtr<FilterOperation> blendFunc(const AnimationBase* anim, FilterOperation* fromOp, FilterOperation* toOp, double progress, bool blendToPassthrough = false)
+{
+ ASSERT(toOp);
+ if (toOp->blendingNeedsRendererSize()) {
LayoutSize size = anim->renderer()->isBox() ? toRenderBox(anim->renderer())->borderBoxRect().size() : LayoutSize();
- TransformationMatrix fromT;
- TransformationMatrix toT;
- from.apply(size, fromT);
- to.apply(size, toT);
-
- toT.blend(fromT, progress);
-
- // Append the result
- result.operations().append(Matrix3DTransformOperation::create(toT));
+ return toOp->blend(fromOp, progress, size, blendToPassthrough);
}
- return result;
+ return toOp->blend(fromOp, progress, blendToPassthrough);
}
-#if ENABLE(CSS_FILTERS)
static inline FilterOperations blendFunc(const AnimationBase* anim, const FilterOperations& from, const FilterOperations& to, double progress)
{
FilterOperations result;
@@ -170,7 +148,7 @@
for (size_t i = 0; i < size; i++) {
RefPtr<FilterOperation> fromOp = (i < fromSize) ? from.operations()[i].get() : 0;
RefPtr<FilterOperation> toOp = (i < toSize) ? to.operations()[i].get() : 0;
- RefPtr<FilterOperation> blendedOp = toOp ? toOp->blend(fromOp.get(), progress) : (fromOp ? fromOp->blend(0, progress, true) : PassRefPtr<FilterOperation>(0));
+ RefPtr<FilterOperation> blendedOp = toOp ? blendFunc(anim, fromOp.get(), toOp.get(), progress) : (fromOp ? blendFunc(anim, 0, fromOp.get(), progress, true) : 0);
if (blendedOp)
result.operations().append(blendedOp);
else {
Modified: trunk/Source/WebCore/platform/graphics/filters/CustomFilterNumberParameter.h (128379 => 128380)
--- trunk/Source/WebCore/platform/graphics/filters/CustomFilterNumberParameter.h 2012-09-12 23:20:22 UTC (rev 128379)
+++ trunk/Source/WebCore/platform/graphics/filters/CustomFilterNumberParameter.h 2012-09-12 23:33:41 UTC (rev 128380)
@@ -48,7 +48,7 @@
void addValue(double value) { m_data.append(value); }
- virtual PassRefPtr<CustomFilterParameter> blend(const CustomFilterParameter* from, double progress)
+ virtual PassRefPtr<CustomFilterParameter> blend(const CustomFilterParameter* from, double progress, const LayoutSize&)
{
if (!from || !isSameType(*from))
return this;
Modified: trunk/Source/WebCore/platform/graphics/filters/CustomFilterOperation.cpp (128379 => 128380)
--- trunk/Source/WebCore/platform/graphics/filters/CustomFilterOperation.cpp 2012-09-12 23:20:22 UTC (rev 128379)
+++ trunk/Source/WebCore/platform/graphics/filters/CustomFilterOperation.cpp 2012-09-12 23:33:41 UTC (rev 128380)
@@ -64,7 +64,8 @@
}
#endif
-void blendCustomFilterParameters(const CustomFilterParameterList& fromList, const CustomFilterParameterList& toList, double progress, CustomFilterParameterList& resultList)
+void blendCustomFilterParameters(const CustomFilterParameterList& fromList, const CustomFilterParameterList& toList,
+ double progress, const LayoutSize& size, CustomFilterParameterList& resultList)
{
// This method expects both lists to be sorted by parameter name and the result list is also sorted.
ASSERT(checkCustomFilterParametersOrder(fromList));
@@ -74,7 +75,7 @@
CustomFilterParameter* paramFrom = fromList.at(fromListIndex).get();
CustomFilterParameter* paramTo = toList.at(toListIndex).get();
if (paramFrom->name() == paramTo->name()) {
- resultList.append(paramTo->blend(paramFrom, progress));
+ resultList.append(paramTo->blend(paramFrom, progress, size));
++fromListIndex;
++toListIndex;
continue;
@@ -111,7 +112,7 @@
{
}
-PassRefPtr<FilterOperation> CustomFilterOperation::blend(const FilterOperation* from, double progress, bool blendToPassthrough)
+PassRefPtr<FilterOperation> CustomFilterOperation::blend(const FilterOperation* from, double progress, const LayoutSize& size, bool blendToPassthrough)
{
// FIXME: There's no way to decide what is the "passthrough filter" for shaders using the current CSS Syntax.
// https://bugs.webkit.org/show_bug.cgi?id=84903
@@ -128,7 +129,7 @@
return this;
CustomFilterParameterList animatedParameters;
- blendCustomFilterParameters(fromOp->m_parameters, m_parameters, progress, animatedParameters);
+ blendCustomFilterParameters(fromOp->m_parameters, m_parameters, progress, size, animatedParameters);
return CustomFilterOperation::create(m_program, animatedParameters, m_meshRows, m_meshColumns, m_meshBoxType, m_meshType);
}
Modified: trunk/Source/WebCore/platform/graphics/filters/CustomFilterOperation.h (128379 => 128380)
--- trunk/Source/WebCore/platform/graphics/filters/CustomFilterOperation.h 2012-09-12 23:20:22 UTC (rev 128379)
+++ trunk/Source/WebCore/platform/graphics/filters/CustomFilterOperation.h 2012-09-12 23:33:41 UTC (rev 128380)
@@ -33,6 +33,7 @@
#if ENABLE(CSS_SHADERS)
#include "CustomFilterProgram.h"
#include "FilterOperation.h"
+#include "LayoutTypes.h"
#include <wtf/text/WTFString.h>
@@ -44,7 +45,8 @@
typedef Vector<RefPtr<CustomFilterParameter> > CustomFilterParameterList;
bool customFilterParametersEqual(const CustomFilterParameterList&, const CustomFilterParameterList&);
-void blendCustomFilterParameters(const CustomFilterParameterList& listFrom, const CustomFilterParameterList& listTo, double progress, CustomFilterParameterList& resultList);
+void blendCustomFilterParameters(const CustomFilterParameterList& listFrom, const CustomFilterParameterList& listTo,
+ double progress, const LayoutSize&, CustomFilterParameterList& resultList);
class CustomFilterOperation : public FilterOperation {
public:
@@ -79,8 +81,9 @@
virtual bool affectsOpacity() const { return true; }
virtual bool movesPixels() const { return true; }
+ virtual bool blendingNeedsRendererSize() const { return true; }
- virtual PassRefPtr<FilterOperation> blend(const FilterOperation* from, double progress, bool blendToPassthrough = false);
+ virtual PassRefPtr<FilterOperation> blend(const FilterOperation* from, double progress, const LayoutSize&, bool blendToPassthrough = false);
private:
virtual bool operator==(const FilterOperation& o) const
{
Modified: trunk/Source/WebCore/platform/graphics/filters/CustomFilterParameter.h (128379 => 128380)
--- trunk/Source/WebCore/platform/graphics/filters/CustomFilterParameter.h 2012-09-12 23:20:22 UTC (rev 128379)
+++ trunk/Source/WebCore/platform/graphics/filters/CustomFilterParameter.h 2012-09-12 23:33:41 UTC (rev 128380)
@@ -56,7 +56,7 @@
bool isSameType(const CustomFilterParameter& other) const { return parameterType() == other.parameterType(); }
- virtual PassRefPtr<CustomFilterParameter> blend(const CustomFilterParameter*, double progress) = 0;
+ virtual PassRefPtr<CustomFilterParameter> blend(const CustomFilterParameter*, double progress, const LayoutSize&) = 0;
virtual bool operator==(const CustomFilterParameter&) const = 0;
bool operator!=(const CustomFilterParameter& o) const { return !(*this == o); }
protected:
Modified: trunk/Source/WebCore/platform/graphics/filters/CustomFilterTransformParameter.h (128379 => 128380)
--- trunk/Source/WebCore/platform/graphics/filters/CustomFilterTransformParameter.h 2012-09-12 23:20:22 UTC (rev 128379)
+++ trunk/Source/WebCore/platform/graphics/filters/CustomFilterTransformParameter.h 2012-09-12 23:33:41 UTC (rev 128380)
@@ -46,14 +46,26 @@
{
return adoptRef(new CustomFilterTransformParameter(name));
}
-
- virtual PassRefPtr<CustomFilterParameter> blend(const CustomFilterParameter*, double)
+
+ virtual PassRefPtr<CustomFilterParameter> blend(const CustomFilterParameter* fromParameter, double progress, const LayoutSize& size)
{
- // FIXME: Implement animations support.
- // https://bugs.webkit.org/show_bug.cgi?id=94980
- return this;
+ if (!fromParameter || !isSameType(*fromParameter))
+ return this;
+
+ const CustomFilterTransformParameter* fromTransformParameter = static_cast<const CustomFilterTransformParameter*>(fromParameter);
+ const TransformOperations& from = fromTransformParameter->operations();
+ const TransformOperations& to = operations();
+ if (from == to)
+ return this;
+
+ RefPtr<CustomFilterTransformParameter> result = CustomFilterTransformParameter::create(name());
+ if (from.size() && to.size())
+ result->setOperations(to.blend(from, progress, size));
+ else
+ result->setOperations(progress > 0.5 ? to : from);
+ return result;
}
-
+
virtual bool operator==(const CustomFilterParameter& o) const
{
if (!isSameType(o))
Modified: trunk/Source/WebCore/platform/graphics/filters/FilterOperation.h (128379 => 128380)
--- trunk/Source/WebCore/platform/graphics/filters/FilterOperation.h 2012-09-12 23:20:22 UTC (rev 128379)
+++ trunk/Source/WebCore/platform/graphics/filters/FilterOperation.h 2012-09-12 23:33:41 UTC (rev 128380)
@@ -29,6 +29,7 @@
#if ENABLE(CSS_FILTERS)
#include "Color.h"
+#include "LayoutTypes.h"
#include "Length.h"
#include <wtf/OwnPtr.h>
#include <wtf/PassOwnPtr.h>
@@ -78,8 +79,18 @@
virtual bool operator==(const FilterOperation&) const = 0;
bool operator!=(const FilterOperation& o) const { return !(*this == o); }
- virtual PassRefPtr<FilterOperation> blend(const FilterOperation* /*from*/, double /*progress*/, bool /*blendToPassthrough*/ = false) { return 0; }
+ virtual PassRefPtr<FilterOperation> blend(const FilterOperation* /*from*/, double /*progress*/, bool /*blendToPassthrough*/ = false)
+ {
+ ASSERT(!blendingNeedsRendererSize());
+ return 0;
+ }
+ virtual PassRefPtr<FilterOperation> blend(const FilterOperation* /*from*/, double /*progress*/, const LayoutSize&, bool /*blendToPassthrough*/ = false)
+ {
+ ASSERT(blendingNeedsRendererSize());
+ return 0;
+ }
+
virtual OperationType getOperationType() const { return m_type; }
virtual bool isSameType(const FilterOperation& o) const { return o.getOperationType() == m_type; }
@@ -89,6 +100,8 @@
virtual bool affectsOpacity() const { return false; }
// True if the the value of one pixel can affect the value of another pixel under this operation, such as blur.
virtual bool movesPixels() const { return false; }
+ // True if the filter needs the size of the box in order to calculate the animations.
+ virtual bool blendingNeedsRendererSize() const { return false; }
protected:
FilterOperation(OperationType type)
Modified: trunk/Source/WebCore/platform/graphics/transforms/TransformOperations.cpp (128379 => 128380)
--- trunk/Source/WebCore/platform/graphics/transforms/TransformOperations.cpp 2012-09-12 23:20:22 UTC (rev 128379)
+++ trunk/Source/WebCore/platform/graphics/transforms/TransformOperations.cpp 2012-09-12 23:33:41 UTC (rev 128380)
@@ -23,7 +23,11 @@
#include "TransformOperations.h"
#include "IdentityTransformOperation.h"
+#include "Matrix3DTransformOperation.h"
+#include <algorithm>
+using namespace std;
+
namespace WebCore {
TransformOperations::TransformOperations(bool makeIdentity)
@@ -61,4 +65,58 @@
return true;
}
+TransformOperations TransformOperations::blendByMatchingOperations(const TransformOperations& from, const double& progress) const
+{
+ TransformOperations result;
+
+ unsigned fromSize = from.operations().size();
+ unsigned toSize = operations().size();
+ unsigned size = max(fromSize, toSize);
+ for (unsigned i = 0; i < size; i++) {
+ RefPtr<TransformOperation> fromOperation = (i < fromSize) ? from.operations()[i].get() : 0;
+ RefPtr<TransformOperation> toOperation = (i < toSize) ? operations()[i].get() : 0;
+ RefPtr<TransformOperation> blendedOperation = toOperation ? toOperation->blend(fromOperation.get(), progress) : (fromOperation ? fromOperation->blend(0, progress, true) : 0);
+ if (blendedOperation)
+ result.operations().append(blendedOperation);
+ else {
+ RefPtr<TransformOperation> identityOperation = IdentityTransformOperation::create();
+ if (progress > 0.5)
+ result.operations().append(toOperation ? toOperation : identityOperation);
+ else
+ result.operations().append(fromOperation ? fromOperation : identityOperation);
+ }
+ }
+
+ return result;
+}
+
+TransformOperations TransformOperations::blendByUsingMatrixInterpolation(const TransformOperations& from, double progress, const LayoutSize& size) const
+{
+ TransformOperations result;
+
+ // Convert the TransformOperations into matrices
+ TransformationMatrix fromTransform;
+ TransformationMatrix toTransform;
+ from.apply(size, fromTransform);
+ apply(size, toTransform);
+
+ toTransform.blend(fromTransform, progress);
+
+ // Append the result
+ result.operations().append(Matrix3DTransformOperation::create(toTransform));
+
+ return result;
+}
+
+TransformOperations TransformOperations::blend(const TransformOperations& from, double progress, const LayoutSize& size) const
+{
+ if (from == *this)
+ return *this;
+
+ if (from.size() && from.operationsMatch(*this))
+ return blendByMatchingOperations(from, progress);
+
+ return blendByUsingMatrixInterpolation(from, progress, size);
+}
+
} // namespace WebCore
Modified: trunk/Source/WebCore/platform/graphics/transforms/TransformOperations.h (128379 => 128380)
--- trunk/Source/WebCore/platform/graphics/transforms/TransformOperations.h 2012-09-12 23:20:22 UTC (rev 128379)
+++ trunk/Source/WebCore/platform/graphics/transforms/TransformOperations.h 2012-09-12 23:33:41 UTC (rev 128380)
@@ -25,6 +25,7 @@
#ifndef TransformOperations_h
#define TransformOperations_h
+#include "LayoutTypes.h"
#include "TransformOperation.h"
#include <wtf/RefPtr.h>
#include <wtf/Vector.h>
@@ -71,6 +72,10 @@
size_t size() const { return m_operations.size(); }
const TransformOperation* at(size_t index) const { return index < m_operations.size() ? m_operations.at(index).get() : 0; }
+ TransformOperations blendByMatchingOperations(const TransformOperations& from, const double& progress) const;
+ TransformOperations blendByUsingMatrixInterpolation(const TransformOperations& from, double progress, const LayoutSize&) const;
+ TransformOperations blend(const TransformOperations& from, double progress, const LayoutSize&) const;
+
private:
Vector<RefPtr<TransformOperation> > m_operations;
};