Changeset 121844 in webkit


Ignore:
Timestamp:
Jul 4, 2012 5:57:58 AM (12 years ago)
Author:
vollick@chromium.org
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):

Location:
trunk/Source
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r121843 r121844  
     12012-07-04  Ian Vollick  <vollick@chromium.org>
     2
     3        [chromium] Correctly reject accelerated animations with certain rotations.
     4        https://bugs.webkit.org/show_bug.cgi?id=89768
     5
     6        Reviewed by James Robinson.
     7
     8        UnitTests:
     9          GraphicsLayerChromiumTest.createTransformAnimationWithBigRotation
     10          GraphicsLayerChromiumTest.createTransformAnimationWithRotationInvolvingNegativeAngles
     11          GraphicsLayerChromiumTest.createTransformAnimationWithSmallRotationInvolvingLargeAngles
     12
     13        * platform/graphics/chromium/AnimationTranslationUtil.cpp:
     14        (WebCore::appendKeyframe):
     15        (WebCore::isRotationType):
     16        (WebCore):
     17        (WebCore::causesRotationOfAtLeast180Degrees):
     18        (WebCore::CCKeyframedTransformAnimationCurve):
     19        (WebCore::createActiveAnimation):
     20        * platform/graphics/chromium/GraphicsLayerChromium.cpp:
     21        (WebCore::GraphicsLayerChromium::addAnimation):
     22
    1232012-07-04  Pavel Feldman  <pfeldman@chromium.org>
    224
  • trunk/Source/WebCore/platform/graphics/chromium/AnimationTranslationUtil.cpp

    r119850 r121844  
    123123
    124124template <class Value, class Keyframe, class Curve>
    125 bool appendKeyframe(Curve& curve, double keyTime, const Value* value, PassOwnPtr<CCTimingFunction> timingFunction, const FloatSize&)
     125bool appendKeyframe(Curve& curve, double keyTime, const Value* value, const Value* lastValue, PassOwnPtr<CCTimingFunction> timingFunction, const FloatSize&)
    126126{
    127127    curve.addKeyframe(Keyframe::create(keyTime, value->value(), timingFunction));
     
    129129}
    130130
     131bool isRotationType(TransformOperation::OperationType transformType)
     132{
     133    return transformType == TransformOperation::ROTATE
     134        || transformType == TransformOperation::ROTATE_X
     135        || transformType == TransformOperation::ROTATE_Y
     136        || transformType == TransformOperation::ROTATE_Z
     137        || transformType == TransformOperation::ROTATE_3D;
     138}
     139
     140bool causesRotationOfAtLeast180Degrees(const TransformAnimationValue* value, const TransformAnimationValue* lastValue)
     141{
     142    if (!lastValue)
     143        return false;
     144
     145    const TransformOperations& operations = *value->value();
     146    const TransformOperations& lastOperations = *lastValue->value();
     147
     148    // We'll be doing matrix interpolation in this case. No risk of incorrect
     149    // rotations here.
     150    if (!operations.operationsMatch(lastOperations))
     151        return false;
     152
     153    for (size_t i = 0; i < operations.size(); ++i) {
     154        if (!isRotationType(operations.operations()[i]->getOperationType()))
     155            continue;
     156
     157        RotateTransformOperation* rotation = static_cast<RotateTransformOperation*>(operations.operations()[i].get());
     158        RotateTransformOperation* lastRotation = static_cast<RotateTransformOperation*>(lastOperations.operations()[i].get());
     159
     160        if (fabs(rotation->angle() - lastRotation->angle()) >= 180)
     161            return true;
     162    }
     163
     164    return false;
     165}
     166
    131167template <>
    132 bool appendKeyframe<TransformAnimationValue, CCTransformKeyframe, CCKeyframedTransformAnimationCurve>(CCKeyframedTransformAnimationCurve& curve, double keyTime, const TransformAnimationValue* value, PassOwnPtr<CCTimingFunction> timingFunction, const FloatSize& boxSize)
    133 {
     168bool appendKeyframe<TransformAnimationValue, CCTransformKeyframe, CCKeyframedTransformAnimationCurve>(CCKeyframedTransformAnimationCurve& curve, double keyTime, const TransformAnimationValue* value, const TransformAnimationValue* lastValue, PassOwnPtr<CCTimingFunction> timingFunction, const FloatSize& boxSize)
     169{
     170    if (causesRotationOfAtLeast180Degrees(value, lastValue))
     171        return false;
     172
    134173    WebTransformOperations operations = toWebTransformOperations(*value->value(), boxSize);
    135174    if (operations.apply().isInvertible()) {
     
    160199
    161200        const Value* originalValue = static_cast<const Value*>(valueList.at(index));
     201        const Value* lastOriginalValue = 0;
     202        if (valueList.size() > 1 && ((reverse && index + 1 < valueList.size()) || (!reverse && index > 0)))
     203            lastOriginalValue = static_cast<const Value*>(valueList.at(reverse ? index + 1 : index - 1));
    162204
    163205        OwnPtr<CCTimingFunction> timingFunction;
     
    191233            keyTime = duration - keyTime;
    192234
    193         bool addedKeyframe = appendKeyframe<Value, Keyframe, Curve>(*curve, keyTime, originalValue, timingFunction.release(), boxSize);
     235        bool addedKeyframe = appendKeyframe<Value, Keyframe, Curve>(*curve, keyTime, originalValue, lastOriginalValue, timingFunction.release(), boxSize);
    194236        if (!addedKeyframe)
    195237            return nullptr;
  • trunk/Source/WebCore/platform/graphics/chromium/GraphicsLayerChromium.cpp

    r120966 r121844  
    510510bool GraphicsLayerChromium::addAnimation(const KeyframeValueList& values, const IntSize& boxSize, const Animation* animation, const String& animationName, double timeOffset)
    511511{
    512     // Bail early if we have a large rotation.
    513     if (values.property() == AnimatedPropertyWebkitTransform) {
    514         bool hasRotationOfMoreThan180Degrees = false;
    515         validateTransformOperations(values, hasRotationOfMoreThan180Degrees);
    516         if (hasRotationOfMoreThan180Degrees)
    517             return false;
    518     }
    519 
    520512    primaryLayer().unwrap<LayerChromium>()->setLayerAnimationDelegate(this);
    521513
  • trunk/Source/WebKit/chromium/ChangeLog

    r121823 r121844  
     12012-07-04  Ian Vollick  <vollick@chromium.org>
     2
     3        [chromium] Correctly reject accelerated animations with certain rotations.
     4        https://bugs.webkit.org/show_bug.cgi?id=89768
     5
     6        Reviewed by James Robinson.
     7
     8        * tests/GraphicsLayerChromiumTest.cpp:
     9        (WebKitTests::TEST_F):
     10        (WebKitTests):
     11
    1122012-07-03  Alex Sakhartchouk  <alexst@chromium.org>
    213
  • trunk/Source/WebKit/chromium/tests/GraphicsLayerChromiumTest.cpp

    r121204 r121844  
    257257}
    258258
     259TEST_F(GraphicsLayerChromiumTest, createTransformAnimationWithRotationInvolvingNegativeAngles)
     260{
     261    const double duration = 1;
     262    WebCore::KeyframeValueList values(AnimatedPropertyWebkitTransform);
     263
     264    TransformOperations operations1;
     265    operations1.operations().append(RotateTransformOperation::create(-330, TransformOperation::ROTATE));
     266    values.insert(new TransformAnimationValue(0, &operations1));
     267
     268    TransformOperations operations2;
     269    operations2.operations().append(RotateTransformOperation::create(-320, TransformOperation::ROTATE));
     270    values.insert(new TransformAnimationValue(duration, &operations2));
     271
     272    RefPtr<Animation> animation = Animation::create();
     273    animation->setDuration(duration);
     274
     275    IntSize boxSize;
     276    m_graphicsLayer->addAnimation(values, boxSize, animation.get(), "", 0);
     277
     278    EXPECT_TRUE(m_platformLayer->layerAnimationController()->hasActiveAnimation());
     279}
     280
     281TEST_F(GraphicsLayerChromiumTest, createTransformAnimationWithSmallRotationInvolvingLargeAngles)
     282{
     283    const double duration = 1;
     284    WebCore::KeyframeValueList values(AnimatedPropertyWebkitTransform);
     285
     286    TransformOperations operations1;
     287    operations1.operations().append(RotateTransformOperation::create(270, TransformOperation::ROTATE));
     288    values.insert(new TransformAnimationValue(0, &operations1));
     289
     290    TransformOperations operations2;
     291    operations2.operations().append(RotateTransformOperation::create(360, TransformOperation::ROTATE));
     292    values.insert(new TransformAnimationValue(duration, &operations2));
     293
     294    RefPtr<Animation> animation = Animation::create();
     295    animation->setDuration(duration);
     296
     297    IntSize boxSize;
     298    m_graphicsLayer->addAnimation(values, boxSize, animation.get(), "", 0);
     299
     300    EXPECT_TRUE(m_platformLayer->layerAnimationController()->hasActiveAnimation());
     301}
     302
    259303TEST_F(GraphicsLayerChromiumTest, createTransformAnimationWithSingularMatrix)
    260304{
Note: See TracChangeset for help on using the changeset viewer.