Title: [121844] trunk/Source
Revision
121844
Author
[email protected]
Date
2012-07-04 05:57:58 -0700 (Wed, 04 Jul 2012)

Log Message

[chromium] Correctly reject accelerated animations with certain rotations.
https://bugs.webkit.org/show_bug.cgi?id=89768

Reviewed by James Robinson.

Source/WebCore:

UnitTests:
  GraphicsLayerChromiumTest.createTransformAnimationWithBigRotation
  GraphicsLayerChromiumTest.createTransformAnimationWithRotationInvolvingNegativeAngles
  GraphicsLayerChromiumTest.createTransformAnimationWithSmallRotationInvolvingLargeAngles

* platform/graphics/chromium/AnimationTranslationUtil.cpp:
(WebCore::appendKeyframe):
(WebCore::isRotationType):
(WebCore):
(WebCore::causesRotationOfAtLeast180Degrees):
(WebCore::CCKeyframedTransformAnimationCurve):
(WebCore::createActiveAnimation):
* platform/graphics/chromium/GraphicsLayerChromium.cpp:
(WebCore::GraphicsLayerChromium::addAnimation):

Source/WebKit/chromium:

* tests/GraphicsLayerChromiumTest.cpp:
(WebKitTests::TEST_F):
(WebKitTests):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (121843 => 121844)


--- trunk/Source/WebCore/ChangeLog	2012-07-04 12:53:48 UTC (rev 121843)
+++ trunk/Source/WebCore/ChangeLog	2012-07-04 12:57:58 UTC (rev 121844)
@@ -1,3 +1,25 @@
+2012-07-04  Ian Vollick  <[email protected]>
+
+        [chromium] Correctly reject accelerated animations with certain rotations.
+        https://bugs.webkit.org/show_bug.cgi?id=89768
+
+        Reviewed by James Robinson.
+
+        UnitTests:
+          GraphicsLayerChromiumTest.createTransformAnimationWithBigRotation
+          GraphicsLayerChromiumTest.createTransformAnimationWithRotationInvolvingNegativeAngles
+          GraphicsLayerChromiumTest.createTransformAnimationWithSmallRotationInvolvingLargeAngles
+
+        * platform/graphics/chromium/AnimationTranslationUtil.cpp:
+        (WebCore::appendKeyframe):
+        (WebCore::isRotationType):
+        (WebCore):
+        (WebCore::causesRotationOfAtLeast180Degrees):
+        (WebCore::CCKeyframedTransformAnimationCurve):
+        (WebCore::createActiveAnimation):
+        * platform/graphics/chromium/GraphicsLayerChromium.cpp:
+        (WebCore::GraphicsLayerChromium::addAnimation):
+
 2012-07-04  Pavel Feldman  <[email protected]>
 
         Web Inspector: "Dock to right" shouldn't be in the settings dialog

Modified: trunk/Source/WebCore/platform/graphics/chromium/AnimationTranslationUtil.cpp (121843 => 121844)


--- trunk/Source/WebCore/platform/graphics/chromium/AnimationTranslationUtil.cpp	2012-07-04 12:53:48 UTC (rev 121843)
+++ trunk/Source/WebCore/platform/graphics/chromium/AnimationTranslationUtil.cpp	2012-07-04 12:57:58 UTC (rev 121844)
@@ -122,15 +122,54 @@
 }
 
 template <class Value, class Keyframe, class Curve>
-bool appendKeyframe(Curve& curve, double keyTime, const Value* value, PassOwnPtr<CCTimingFunction> timingFunction, const FloatSize&)
+bool appendKeyframe(Curve& curve, double keyTime, const Value* value, const Value* lastValue, PassOwnPtr<CCTimingFunction> timingFunction, const FloatSize&)
 {
     curve.addKeyframe(Keyframe::create(keyTime, value->value(), timingFunction));
     return true;
 }
 
+bool isRotationType(TransformOperation::OperationType transformType)
+{
+    return transformType == TransformOperation::ROTATE
+        || transformType == TransformOperation::ROTATE_X
+        || transformType == TransformOperation::ROTATE_Y
+        || transformType == TransformOperation::ROTATE_Z
+        || transformType == TransformOperation::ROTATE_3D;
+}
+
+bool causesRotationOfAtLeast180Degrees(const TransformAnimationValue* value, const TransformAnimationValue* lastValue)
+{
+    if (!lastValue)
+        return false;
+
+    const TransformOperations& operations = *value->value();
+    const TransformOperations& lastOperations = *lastValue->value();
+
+    // We'll be doing matrix interpolation in this case. No risk of incorrect
+    // rotations here.
+    if (!operations.operationsMatch(lastOperations))
+        return false;
+
+    for (size_t i = 0; i < operations.size(); ++i) {
+        if (!isRotationType(operations.operations()[i]->getOperationType()))
+            continue;
+
+        RotateTransformOperation* rotation = static_cast<RotateTransformOperation*>(operations.operations()[i].get());
+        RotateTransformOperation* lastRotation = static_cast<RotateTransformOperation*>(lastOperations.operations()[i].get());
+
+        if (fabs(rotation->angle() - lastRotation->angle()) >= 180)
+            return true;
+    }
+
+    return false;
+}
+
 template <>
-bool appendKeyframe<TransformAnimationValue, CCTransformKeyframe, CCKeyframedTransformAnimationCurve>(CCKeyframedTransformAnimationCurve& curve, double keyTime, const TransformAnimationValue* value, PassOwnPtr<CCTimingFunction> timingFunction, const FloatSize& boxSize)
+bool appendKeyframe<TransformAnimationValue, CCTransformKeyframe, CCKeyframedTransformAnimationCurve>(CCKeyframedTransformAnimationCurve& curve, double keyTime, const TransformAnimationValue* value, const TransformAnimationValue* lastValue, PassOwnPtr<CCTimingFunction> timingFunction, const FloatSize& boxSize)
 {
+    if (causesRotationOfAtLeast180Degrees(value, lastValue))
+        return false;
+
     WebTransformOperations operations = toWebTransformOperations(*value->value(), boxSize);
     if (operations.apply().isInvertible()) {
         curve.addKeyframe(CCTransformKeyframe::create(keyTime, operations, timingFunction));
@@ -159,6 +198,9 @@
         size_t index = reverse ? valueList.size() - i - 1 : i;
 
         const Value* originalValue = static_cast<const Value*>(valueList.at(index));
+        const Value* lastOriginalValue = 0;
+        if (valueList.size() > 1 && ((reverse && index + 1 < valueList.size()) || (!reverse && index > 0)))
+            lastOriginalValue = static_cast<const Value*>(valueList.at(reverse ? index + 1 : index - 1));
 
         OwnPtr<CCTimingFunction> timingFunction;
         const TimingFunction* originalTimingFunction = originalValue->timingFunction();
@@ -190,7 +232,7 @@
         if (reverse)
             keyTime = duration - keyTime;
 
-        bool addedKeyframe = appendKeyframe<Value, Keyframe, Curve>(*curve, keyTime, originalValue, timingFunction.release(), boxSize);
+        bool addedKeyframe = appendKeyframe<Value, Keyframe, Curve>(*curve, keyTime, originalValue, lastOriginalValue, timingFunction.release(), boxSize);
         if (!addedKeyframe)
             return nullptr;
     }

Modified: trunk/Source/WebCore/platform/graphics/chromium/GraphicsLayerChromium.cpp (121843 => 121844)


--- trunk/Source/WebCore/platform/graphics/chromium/GraphicsLayerChromium.cpp	2012-07-04 12:53:48 UTC (rev 121843)
+++ trunk/Source/WebCore/platform/graphics/chromium/GraphicsLayerChromium.cpp	2012-07-04 12:57:58 UTC (rev 121844)
@@ -509,14 +509,6 @@
 
 bool GraphicsLayerChromium::addAnimation(const KeyframeValueList& values, const IntSize& boxSize, const Animation* animation, const String& animationName, double timeOffset)
 {
-    // Bail early if we have a large rotation.
-    if (values.property() == AnimatedPropertyWebkitTransform) {
-        bool hasRotationOfMoreThan180Degrees = false;
-        validateTransformOperations(values, hasRotationOfMoreThan180Degrees);
-        if (hasRotationOfMoreThan180Degrees)
-            return false;
-    }
-
     primaryLayer().unwrap<LayerChromium>()->setLayerAnimationDelegate(this);
 
     int animationId = mapAnimationNameToId(animationName);

Modified: trunk/Source/WebKit/chromium/ChangeLog (121843 => 121844)


--- trunk/Source/WebKit/chromium/ChangeLog	2012-07-04 12:53:48 UTC (rev 121843)
+++ trunk/Source/WebKit/chromium/ChangeLog	2012-07-04 12:57:58 UTC (rev 121844)
@@ -1,3 +1,14 @@
+2012-07-04  Ian Vollick  <[email protected]>
+
+        [chromium] Correctly reject accelerated animations with certain rotations.
+        https://bugs.webkit.org/show_bug.cgi?id=89768
+
+        Reviewed by James Robinson.
+
+        * tests/GraphicsLayerChromiumTest.cpp:
+        (WebKitTests::TEST_F):
+        (WebKitTests):
+
 2012-07-03  Alex Sakhartchouk  <[email protected]>
 
         [chromium] Avoid calling getUniformLocation??() in the compositor startup

Modified: trunk/Source/WebKit/chromium/tests/GraphicsLayerChromiumTest.cpp (121843 => 121844)


--- trunk/Source/WebKit/chromium/tests/GraphicsLayerChromiumTest.cpp	2012-07-04 12:53:48 UTC (rev 121843)
+++ trunk/Source/WebKit/chromium/tests/GraphicsLayerChromiumTest.cpp	2012-07-04 12:57:58 UTC (rev 121844)
@@ -256,6 +256,50 @@
     EXPECT_FALSE(m_platformLayer->layerAnimationController()->hasActiveAnimation());
 }
 
+TEST_F(GraphicsLayerChromiumTest, createTransformAnimationWithRotationInvolvingNegativeAngles)
+{
+    const double duration = 1;
+    WebCore::KeyframeValueList values(AnimatedPropertyWebkitTransform);
+
+    TransformOperations operations1;
+    operations1.operations().append(RotateTransformOperation::create(-330, TransformOperation::ROTATE));
+    values.insert(new TransformAnimationValue(0, &operations1));
+
+    TransformOperations operations2;
+    operations2.operations().append(RotateTransformOperation::create(-320, TransformOperation::ROTATE));
+    values.insert(new TransformAnimationValue(duration, &operations2));
+
+    RefPtr<Animation> animation = Animation::create();
+    animation->setDuration(duration);
+
+    IntSize boxSize;
+    m_graphicsLayer->addAnimation(values, boxSize, animation.get(), "", 0);
+
+    EXPECT_TRUE(m_platformLayer->layerAnimationController()->hasActiveAnimation());
+}
+
+TEST_F(GraphicsLayerChromiumTest, createTransformAnimationWithSmallRotationInvolvingLargeAngles)
+{
+    const double duration = 1;
+    WebCore::KeyframeValueList values(AnimatedPropertyWebkitTransform);
+
+    TransformOperations operations1;
+    operations1.operations().append(RotateTransformOperation::create(270, TransformOperation::ROTATE));
+    values.insert(new TransformAnimationValue(0, &operations1));
+
+    TransformOperations operations2;
+    operations2.operations().append(RotateTransformOperation::create(360, TransformOperation::ROTATE));
+    values.insert(new TransformAnimationValue(duration, &operations2));
+
+    RefPtr<Animation> animation = Animation::create();
+    animation->setDuration(duration);
+
+    IntSize boxSize;
+    m_graphicsLayer->addAnimation(values, boxSize, animation.get(), "", 0);
+
+    EXPECT_TRUE(m_platformLayer->layerAnimationController()->hasActiveAnimation());
+}
+
 TEST_F(GraphicsLayerChromiumTest, createTransformAnimationWithSingularMatrix)
 {
     const double duration = 1;
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to