Handle direction control in compositor Animations

This patch is the blink side. The chromium side is handled on issue #180153010

It doesn't revert functions anymore in blink. Instead, it sets the direction parameter to WebAnimation, which will in turn pass it to the compositor.

BUG=348071

Review URL: https://codereview.chromium.org/225183014

git-svn-id: svn://svn.chromium.org/blink/trunk@181945 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent 5c649087
<html>
<style>
div {
position: relative;
height: 100px;
width: 100px;
background: blue;
-webkit-transform: translateZ(0);
-webkit-animation-duration: 2s;
-webkit-animation-timing-function: linear;
-webkit-animation-fill-mode: both;
-webkit-animation-iteration-count: 2;
}
.test0 {
-webkit-animation-direction: normal;
}
.test1 {
-webkit-animation-direction: reverse;
}
.test2 {
-webkit-animation-direction: alternate;
}
.test3 {
-webkit-animation-direction: reverse;
}
.anim-left {
-webkit-animation-name: anim-left;
z-index: 100;
}
.anim-transform {
-webkit-animation-name: anim-transform;
z-index: 200;
}
@-webkit-keyframes anim-left {
0% {
left: 0px;
}
100% {
left: 300px;
}
}
@-webkit-keyframes anim-transform {
0% {
-webkit-transform: translateX(0px);
}
100% {
-webkit-transform: translateX(300px);
}
}
</style>
<body>
<p>
Each section below has two boxes, the top runs on the main thread, the bottom
on the compositor. The animations should be identical but start at different
times.
</p><p>
This test is successful if the boxes are mostly in sync (there might be a small
offset between them).
</p>
<hr>
Direction normal
<br>
<div class='test0 anim-left'></div>
<div class='test0 anim-transform'></div>
Direction reverse
<br>
<div class='test1 anim-left'></div>
<div class='test1 anim-transform'></div>
Direction alternate
<br>
<div class='test2 anim-left'></div>
<div class='test2 anim-transform'></div>
Direction alternate-reverse
<br>
<div class='test3 anim-left'></div>
<div class='test3 anim-transform'></div>
</body>
</html>
......@@ -59,71 +59,17 @@ namespace blink {
namespace {
void getKeyframeValuesForProperty(const KeyframeEffectModelBase* effect, CSSPropertyID id, double scale, bool reverse, PropertySpecificKeyframeVector& values)
void getKeyframeValuesForProperty(const KeyframeEffectModelBase* effect, CSSPropertyID id, double scale, PropertySpecificKeyframeVector& values)
{
ASSERT(values.isEmpty());
const PropertySpecificKeyframeVector& group = effect->getPropertySpecificKeyframes(id);
if (reverse) {
for (size_t i = group.size(); i--;) {
double offset = (1 - group[i]->offset()) * scale;
values.append(group[i]->cloneWithOffset(offset));
}
} else {
for (size_t i = 0; i < group.size(); ++i) {
double offset = group[i]->offset() * scale;
values.append(group[i]->cloneWithOffset(offset));
}
}
}
}
// -----------------------------------------------------------------------
// TimingFunctionReverser methods
// -----------------------------------------------------------------------
PassRefPtr<TimingFunction> CompositorAnimationsTimingFunctionReverser::reverse(const LinearTimingFunction& timefunc)
{
return const_cast<LinearTimingFunction*>(&timefunc);
}
PassRefPtr<TimingFunction> CompositorAnimationsTimingFunctionReverser::reverse(const CubicBezierTimingFunction& timefunc)
{
switch (timefunc.subType()) {
case CubicBezierTimingFunction::EaseIn:
return CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseOut);
case CubicBezierTimingFunction::EaseOut:
return CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseIn);
case CubicBezierTimingFunction::EaseInOut:
return const_cast<CubicBezierTimingFunction*>(&timefunc);
case CubicBezierTimingFunction::Ease: // Ease is not symmetrical
case CubicBezierTimingFunction::Custom:
return CubicBezierTimingFunction::create(1 - timefunc.x2(), 1 - timefunc.y2(), 1 - timefunc.x1(), 1 - timefunc.y1());
default:
ASSERT_NOT_REACHED();
return PassRefPtr<TimingFunction>();
for (size_t i = 0; i < group.size(); ++i) {
double offset = group[i]->offset() * scale;
values.append(group[i]->cloneWithOffset(offset));
}
}
PassRefPtr<TimingFunction> CompositorAnimationsTimingFunctionReverser::reverse(const TimingFunction& timefunc)
{
switch (timefunc.type()) {
case TimingFunction::LinearFunction: {
const LinearTimingFunction& linear = toLinearTimingFunction(timefunc);
return reverse(linear);
}
case TimingFunction::CubicBezierFunction: {
const CubicBezierTimingFunction& cubic = toCubicBezierTimingFunction(timefunc);
return reverse(cubic);
}
// Steps function can not be reversed.
case TimingFunction::StepsFunction:
default:
ASSERT_NOT_REACHED();
return PassRefPtr<TimingFunction>();
}
}
bool CompositorAnimations::getAnimatedBoundingBox(FloatBox& box, const AnimationEffect& effect, double minValue, double maxValue) const
......@@ -340,10 +286,7 @@ bool CompositorAnimationsImpl::convertTimingForCompositor(const Timing& timing,
if (scaledStartDelay > 0 && scaledStartDelay > out.scaledDuration * timing.iterationCount)
return false;
out.reverse = (timing.direction == Timing::PlaybackDirectionReverse
|| timing.direction == Timing::PlaybackDirectionAlternateReverse);
out.alternate = (timing.direction == Timing::PlaybackDirectionAlternate
|| timing.direction == Timing::PlaybackDirectionAlternateReverse);
out.direction = timing.direction;
if (!std::isfinite(timing.iterationCount)) {
out.adjustedIterationCount = -1;
......@@ -415,26 +358,15 @@ void addKeyframeWithTimingFunction(PlatformAnimationCurveType& curve, const Plat
} // namespace anoymous
void CompositorAnimationsImpl::addKeyframesToCurve(WebCompositorAnimationCurve& curve, const PropertySpecificKeyframeVector& keyframes, const Timing& timing, bool reverse)
void CompositorAnimationsImpl::addKeyframesToCurve(WebCompositorAnimationCurve& curve, const PropertySpecificKeyframeVector& keyframes, const Timing& timing)
{
for (size_t i = 0; i < keyframes.size(); i++) {
RefPtr<TimingFunction> reversedTimingFunction;
const TimingFunction* keyframeTimingFunction = 0;
if (i < keyframes.size() - 1) { // Ignore timing function of last frame.
if (keyframes.size() == 2 && keyframes[0]->easing().type() == TimingFunction::LinearFunction) {
if (reverse) {
reversedTimingFunction = CompositorAnimationsTimingFunctionReverser::reverse(*timing.timingFunction.get());
keyframeTimingFunction = reversedTimingFunction.get();
} else {
keyframeTimingFunction = timing.timingFunction.get();
}
keyframeTimingFunction = timing.timingFunction.get();
} else {
if (reverse) {
reversedTimingFunction = CompositorAnimationsTimingFunctionReverser::reverse(keyframes[i + 1]->easing());
keyframeTimingFunction = reversedTimingFunction.get();
} else {
keyframeTimingFunction = &keyframes[i]->easing();
}
keyframeTimingFunction = &keyframes[i]->easing();
}
}
......@@ -486,7 +418,7 @@ void CompositorAnimationsImpl::getAnimationOnCompositor(const Timing& timing, do
for (PropertySet::iterator it = properties.begin(); it != properties.end(); ++it) {
PropertySpecificKeyframeVector values;
getKeyframeValuesForProperty(&effect, *it, compositorTiming.scaledDuration, compositorTiming.reverse, values);
getKeyframeValuesForProperty(&effect, *it, compositorTiming.scaledDuration, values);
WebCompositorAnimation::TargetProperty targetProperty;
OwnPtr<WebCompositorAnimationCurve> curve;
......@@ -495,21 +427,21 @@ void CompositorAnimationsImpl::getAnimationOnCompositor(const Timing& timing, do
targetProperty = WebCompositorAnimation::TargetPropertyOpacity;
WebFloatAnimationCurve* floatCurve = Platform::current()->compositorSupport()->createFloatAnimationCurve();
addKeyframesToCurve(*floatCurve, values, timing, compositorTiming.reverse);
addKeyframesToCurve(*floatCurve, values, timing);
curve = adoptPtr(floatCurve);
break;
}
case CSSPropertyWebkitFilter: {
targetProperty = WebCompositorAnimation::TargetPropertyFilter;
WebFilterAnimationCurve* filterCurve = Platform::current()->compositorSupport()->createFilterAnimationCurve();
addKeyframesToCurve(*filterCurve, values, timing, compositorTiming.reverse);
addKeyframesToCurve(*filterCurve, values, timing);
curve = adoptPtr(filterCurve);
break;
}
case CSSPropertyTransform: {
targetProperty = WebCompositorAnimation::TargetPropertyTransform;
WebTransformAnimationCurve* transformCurve = Platform::current()->compositorSupport()->createTransformAnimationCurve();
addKeyframesToCurve(*transformCurve, values, timing, compositorTiming.reverse);
addKeyframesToCurve(*transformCurve, values, timing);
curve = adoptPtr(transformCurve);
break;
}
......@@ -526,7 +458,23 @@ void CompositorAnimationsImpl::getAnimationOnCompositor(const Timing& timing, do
animation->setIterations(compositorTiming.adjustedIterationCount);
animation->setTimeOffset(compositorTiming.scaledTimeOffset);
animation->setAlternatesDirection(compositorTiming.alternate);
switch (compositorTiming.direction) {
case Timing::PlaybackDirectionNormal:
animation->setDirection(blink::WebCompositorAnimation::DirectionNormal);
break;
case Timing::PlaybackDirectionReverse:
animation->setDirection(blink::WebCompositorAnimation::DirectionReverse);
break;
case Timing::PlaybackDirectionAlternate:
animation->setDirection(blink::WebCompositorAnimation::DirectionAlternate);
break;
case Timing::PlaybackDirectionAlternateReverse:
animation->setDirection(blink::WebCompositorAnimation::DirectionAlternateReverse);
break;
default:
ASSERT_NOT_REACHED();
}
animations.append(animation.release());
}
......
......@@ -41,18 +41,6 @@ namespace blink {
class Element;
class FloatBox;
// Given an input timing function between keyframe at 0 and keyframe at 1.0, we
// need a timing function such that the behavior with the keyframes swapped is
// equivalent to reversing time with the input timing function and keyframes.
// This means flipping the timing function about x=0.5 and about y=0.5.
// FIXME: Remove once the Compositor natively understands reversing time.
class CompositorAnimationsTimingFunctionReverser {
public:
static PassRefPtr<TimingFunction> reverse(const LinearTimingFunction& timefunc);
static PassRefPtr<TimingFunction> reverse(const CubicBezierTimingFunction& timefunc);
static PassRefPtr<TimingFunction> reverse(const TimingFunction& timefunc);
};
class CompositorAnimations {
public:
static CompositorAnimations* instance() { return instance(0); }
......
......@@ -41,8 +41,7 @@ class WebCompositorAnimationCurve;
class CompositorAnimationsImpl {
private:
struct CompositorTiming {
bool reverse;
bool alternate;
Timing::PlaybackDirection direction;
double scaledDuration;
double scaledTimeOffset;
double adjustedIterationCount;
......@@ -52,7 +51,7 @@ private:
static void getAnimationOnCompositor(const Timing&, double startTime, double timeOffset, const KeyframeEffectModelBase&, Vector<OwnPtr<WebCompositorAnimation> >& animations);
static void addKeyframesToCurve(WebCompositorAnimationCurve&, const AnimatableValuePropertySpecificKeyframeVector&, const Timing&, bool reverse);
static void addKeyframesToCurve(WebCompositorAnimationCurve&, const AnimatableValuePropertySpecificKeyframeVector&, const Timing&);
friend class CompositorAnimations;
friend class AnimationCompositorAnimationsTest;
......
......@@ -392,20 +392,21 @@ TEST_F(AnimationCompositorAnimationsTest, ConvertTimingForCompositorPlaybackRate
TEST_F(AnimationCompositorAnimationsTest, ConvertTimingForCompositorDirection)
{
m_timing.direction = Timing::PlaybackDirectionNormal;
EXPECT_TRUE(convertTimingForCompositor(m_timing, m_compositorTiming));
EXPECT_EQ(m_compositorTiming.direction, Timing::PlaybackDirectionNormal);
m_timing.direction = Timing::PlaybackDirectionAlternate;
EXPECT_TRUE(convertTimingForCompositor(m_timing, m_compositorTiming));
EXPECT_TRUE(m_compositorTiming.alternate);
EXPECT_FALSE(m_compositorTiming.reverse);
EXPECT_EQ(m_compositorTiming.direction, Timing::PlaybackDirectionAlternate);
m_timing.direction = Timing::PlaybackDirectionAlternateReverse;
EXPECT_TRUE(convertTimingForCompositor(m_timing, m_compositorTiming));
EXPECT_TRUE(m_compositorTiming.alternate);
EXPECT_TRUE(m_compositorTiming.reverse);
EXPECT_EQ(m_compositorTiming.direction, Timing::PlaybackDirectionAlternateReverse);
m_timing.direction = Timing::PlaybackDirectionReverse;
EXPECT_TRUE(convertTimingForCompositor(m_timing, m_compositorTiming));
EXPECT_FALSE(m_compositorTiming.alternate);
EXPECT_TRUE(m_compositorTiming.reverse);
EXPECT_EQ(m_compositorTiming.direction, Timing::PlaybackDirectionReverse);
}
TEST_F(AnimationCompositorAnimationsTest, ConvertTimingForCompositorDirectionIterationsAndStartDelay)
......@@ -417,8 +418,7 @@ TEST_F(AnimationCompositorAnimationsTest, ConvertTimingForCompositorDirectionIte
EXPECT_TRUE(convertTimingForCompositor(m_timing, m_compositorTiming));
EXPECT_DOUBLE_EQ(6.0, m_compositorTiming.scaledTimeOffset);
EXPECT_EQ(4, m_compositorTiming.adjustedIterationCount);
EXPECT_TRUE(m_compositorTiming.alternate);
EXPECT_FALSE(m_compositorTiming.reverse);
EXPECT_EQ(m_compositorTiming.direction, Timing::PlaybackDirectionAlternate);
m_timing.direction = Timing::PlaybackDirectionAlternate;
m_timing.iterationCount = 4.0;
......@@ -427,8 +427,7 @@ TEST_F(AnimationCompositorAnimationsTest, ConvertTimingForCompositorDirectionIte
EXPECT_TRUE(convertTimingForCompositor(m_timing, m_compositorTiming));
EXPECT_DOUBLE_EQ(11.0, m_compositorTiming.scaledTimeOffset);
EXPECT_EQ(4, m_compositorTiming.adjustedIterationCount);
EXPECT_TRUE(m_compositorTiming.alternate);
EXPECT_FALSE(m_compositorTiming.reverse);
EXPECT_EQ(m_compositorTiming.direction, Timing::PlaybackDirectionAlternate);
m_timing.direction = Timing::PlaybackDirectionAlternateReverse;
m_timing.iterationCount = 4.0;
......@@ -437,8 +436,7 @@ TEST_F(AnimationCompositorAnimationsTest, ConvertTimingForCompositorDirectionIte
EXPECT_TRUE(convertTimingForCompositor(m_timing, m_compositorTiming));
EXPECT_DOUBLE_EQ(6.0, m_compositorTiming.scaledTimeOffset);
EXPECT_EQ(4, m_compositorTiming.adjustedIterationCount);
EXPECT_TRUE(m_compositorTiming.alternate);
EXPECT_TRUE(m_compositorTiming.reverse);
EXPECT_EQ(m_compositorTiming.direction, Timing::PlaybackDirectionAlternateReverse);
m_timing.direction = Timing::PlaybackDirectionAlternateReverse;
m_timing.iterationCount = 4.0;
......@@ -447,8 +445,7 @@ TEST_F(AnimationCompositorAnimationsTest, ConvertTimingForCompositorDirectionIte
EXPECT_TRUE(convertTimingForCompositor(m_timing, m_compositorTiming));
EXPECT_DOUBLE_EQ(11.0, m_compositorTiming.scaledTimeOffset);
EXPECT_EQ(4, m_compositorTiming.adjustedIterationCount);
EXPECT_TRUE(m_compositorTiming.alternate);
EXPECT_TRUE(m_compositorTiming.reverse);
EXPECT_EQ(m_compositorTiming.direction, Timing::PlaybackDirectionAlternateReverse);
}
TEST_F(AnimationCompositorAnimationsTest, isCandidateForAnimationOnCompositorTimingTimingFunctionPassThru)
......@@ -613,7 +610,7 @@ TEST_F(AnimationCompositorAnimationsTest, createSimpleOpacityAnimation)
usesMockAnimation += EXPECT_CALL(*mockAnimationPtr, setIterations(1));
usesMockAnimation += EXPECT_CALL(*mockAnimationPtr, setTimeOffset(0.0));
usesMockAnimation += EXPECT_CALL(*mockAnimationPtr, setAlternatesDirection(false));
usesMockAnimation += EXPECT_CALL(*mockAnimationPtr, setDirection(blink::WebCompositorAnimation::DirectionNormal));
EXPECT_CALL(*mockAnimationPtr, delete_())
.Times(1)
......@@ -660,7 +657,7 @@ TEST_F(AnimationCompositorAnimationsTest, createSimpleOpacityAnimationDuration)
usesMockAnimation += EXPECT_CALL(*mockAnimationPtr, setIterations(1));
usesMockAnimation += EXPECT_CALL(*mockAnimationPtr, setTimeOffset(0.0));
usesMockAnimation += EXPECT_CALL(*mockAnimationPtr, setAlternatesDirection(false));
usesMockAnimation += EXPECT_CALL(*mockAnimationPtr, setDirection(blink::WebCompositorAnimation::DirectionNormal));
EXPECT_CALL(*mockAnimationPtr, delete_())
.Times(1)
......@@ -713,7 +710,7 @@ TEST_F(AnimationCompositorAnimationsTest, createMultipleKeyframeOpacityAnimation
usesMockAnimation += EXPECT_CALL(*mockAnimationPtr, setIterations(5));
usesMockAnimation += EXPECT_CALL(*mockAnimationPtr, setTimeOffset(0.0));
usesMockAnimation += EXPECT_CALL(*mockAnimationPtr, setAlternatesDirection(true));
usesMockAnimation += EXPECT_CALL(*mockAnimationPtr, setDirection(blink::WebCompositorAnimation::DirectionAlternate));
EXPECT_CALL(*mockAnimationPtr, delete_())
.Times(1)
......@@ -762,7 +759,7 @@ TEST_F(AnimationCompositorAnimationsTest, createSimpleOpacityAnimationStartDelay
usesMockAnimation += EXPECT_CALL(*mockAnimationPtr, setIterations(5));
usesMockAnimation += EXPECT_CALL(*mockAnimationPtr, setTimeOffset(-3.25));
usesMockAnimation += EXPECT_CALL(*mockAnimationPtr, setAlternatesDirection(false));
usesMockAnimation += EXPECT_CALL(*mockAnimationPtr, setDirection(blink::WebCompositorAnimation::DirectionNormal));
EXPECT_CALL(*mockAnimationPtr, delete_())
.Times(1)
......@@ -821,7 +818,7 @@ TEST_F(AnimationCompositorAnimationsTest, createMultipleKeyframeOpacityAnimation
usesMockAnimation += EXPECT_CALL(*mockAnimationPtr, setIterations(10));
usesMockAnimation += EXPECT_CALL(*mockAnimationPtr, setTimeOffset(0.0));
usesMockAnimation += EXPECT_CALL(*mockAnimationPtr, setAlternatesDirection(true));
usesMockAnimation += EXPECT_CALL(*mockAnimationPtr, setDirection(blink::WebCompositorAnimation::DirectionAlternate));
EXPECT_CALL(*mockAnimationPtr, delete_())
.Times(1)
......@@ -867,10 +864,10 @@ TEST_F(AnimationCompositorAnimationsTest, createReversedOpacityAnimation)
EXPECT_CALL(mockCompositor, createFloatAnimationCurve())
.WillOnce(Return(mockCurvePtr));
usesMockCurve += EXPECT_CALL(*mockCurvePtr, add(WebFloatKeyframe(0.0, 5.0), 1.0, 0.0, 1.0, 1.0));
usesMockCurve += EXPECT_CALL(*mockCurvePtr, add(WebFloatKeyframe(0.5, 20.0), WebCompositorAnimationCurve::TimingFunctionTypeLinear));
usesMockCurve += EXPECT_CALL(*mockCurvePtr, add(WebFloatKeyframe(0.75, -1.0), WebCompositorAnimationCurve::TimingFunctionTypeEaseOut));
usesMockCurve += EXPECT_CALL(*mockCurvePtr, add(WebFloatKeyframe(1.0, 2.0)));
usesMockCurve += EXPECT_CALL(*mockCurvePtr, add(blink::WebFloatKeyframe(0.0, 2.0), blink::WebCompositorAnimationCurve::TimingFunctionTypeEaseIn));
usesMockCurve += EXPECT_CALL(*mockCurvePtr, add(blink::WebFloatKeyframe(0.25, -1.0), blink::WebCompositorAnimationCurve::TimingFunctionTypeLinear));
usesMockCurve += EXPECT_CALL(*mockCurvePtr, add(blink::WebFloatKeyframe(0.5, 20.0), 0.0, 0.0, 0.0, 1.0));
usesMockCurve += EXPECT_CALL(*mockCurvePtr, add(blink::WebFloatKeyframe(1.0, 5.0)));
// Create the animation
WebCompositorAnimationMock* mockAnimationPtr = new WebCompositorAnimationMock(WebCompositorAnimation::TargetPropertyOpacity);
......@@ -881,7 +878,7 @@ TEST_F(AnimationCompositorAnimationsTest, createReversedOpacityAnimation)
usesMockAnimation += EXPECT_CALL(*mockAnimationPtr, setIterations(10));
usesMockAnimation += EXPECT_CALL(*mockAnimationPtr, setTimeOffset(0.0));
usesMockAnimation += EXPECT_CALL(*mockAnimationPtr, setAlternatesDirection(true));
usesMockAnimation += EXPECT_CALL(*mockAnimationPtr, setDirection(blink::WebCompositorAnimation::DirectionAlternateReverse));
EXPECT_CALL(*mockAnimationPtr, delete_())
.Times(1)
......@@ -919,8 +916,8 @@ TEST_F(AnimationCompositorAnimationsTest, createReversedOpacityAnimationNegative
EXPECT_CALL(mockCompositor, createFloatAnimationCurve())
.WillOnce(Return(mockCurvePtr));
usesMockCurve += EXPECT_CALL(*mockCurvePtr, add(WebFloatKeyframe(0.0, 5.0), WebCompositorAnimationCurve::TimingFunctionTypeLinear));
usesMockCurve += EXPECT_CALL(*mockCurvePtr, add(WebFloatKeyframe(1.5, 2.0)));
usesMockCurve += EXPECT_CALL(*mockCurvePtr, add(blink::WebFloatKeyframe(0.0, 2.0), blink::WebCompositorAnimationCurve::TimingFunctionTypeLinear));
usesMockCurve += EXPECT_CALL(*mockCurvePtr, add(blink::WebFloatKeyframe(1.5, 5.0)));
// Create animation
WebCompositorAnimationMock* mockAnimationPtr = new WebCompositorAnimationMock(WebCompositorAnimation::TargetPropertyOpacity);
......@@ -931,7 +928,7 @@ TEST_F(AnimationCompositorAnimationsTest, createReversedOpacityAnimationNegative
usesMockAnimation += EXPECT_CALL(*mockAnimationPtr, setIterations(5));
usesMockAnimation += EXPECT_CALL(*mockAnimationPtr, setTimeOffset(3.0));
usesMockAnimation += EXPECT_CALL(*mockAnimationPtr, setAlternatesDirection(true));
usesMockAnimation += EXPECT_CALL(*mockAnimationPtr, setDirection(blink::WebCompositorAnimation::DirectionAlternateReverse));
EXPECT_CALL(*mockAnimationPtr, delete_())
.Times(1)
......
......@@ -85,8 +85,8 @@ public:
MOCK_CONST_METHOD0(timeOffset, double());
MOCK_METHOD1(setTimeOffset, void(double));
MOCK_CONST_METHOD0(alternatesDirection, bool());
MOCK_METHOD1(setAlternatesDirection, void(bool));
MOCK_CONST_METHOD0(direction, Direction());
MOCK_METHOD1(setDirection, void(Direction));
MOCK_METHOD0(delete_, void());
~WebCompositorAnimationMock() { delete_(); }
......
/*
* Copyright (c) 2013, Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
#include "core/animation/CompositorAnimations.h"
#include "wtf/PassRefPtr.h"
#include "wtf/RefPtr.h"
#include <gmock/gmock.h>
#include <gtest/gtest.h>
// FIXME: Remove once https://codereview.chromium.org/50603011/ lands.
#define EXPECT_REFV_EQ(a, b) EXPECT_EQ(*(a.get()), *(b.get()))
#define EXPECT_REFV_NE(a, b) EXPECT_NE(*(a.get()), *(b.get()))
namespace {
using namespace blink;
class AnimationCompositorAnimationsTimingFunctionReverserTest : public ::testing::Test {
protected:
public:
PassRefPtr<TimingFunction> reverse(const RefPtr<TimingFunction>& timefunc)
{
return CompositorAnimationsTimingFunctionReverser::reverse(*timefunc);
}
};
TEST_F(AnimationCompositorAnimationsTimingFunctionReverserTest, LinearReverse)
{
RefPtr<TimingFunction> linearTiming = LinearTimingFunction::shared();
EXPECT_REFV_EQ(linearTiming, reverse(linearTiming));
}
TEST_F(AnimationCompositorAnimationsTimingFunctionReverserTest, CubicReverse)
{
RefPtr<TimingFunction> cubicEaseInTiming = CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseIn);
RefPtr<TimingFunction> cubicEaseOutTiming = CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseOut);
RefPtr<TimingFunction> cubicEaseInOutTiming = CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseInOut);
EXPECT_REFV_EQ(cubicEaseOutTiming, reverse(cubicEaseInTiming));
EXPECT_REFV_EQ(cubicEaseInTiming, reverse(cubicEaseOutTiming));
EXPECT_REFV_EQ(cubicEaseInOutTiming, reverse(cubicEaseInOutTiming));
RefPtr<TimingFunction> cubicCustomTiming = CubicBezierTimingFunction::create(0.17, 0.67, 1, -1.73);
// Due to floating point, 1.0-(-1.73) != 2.73
RefPtr<TimingFunction> cubicCustomTimingReversed = CubicBezierTimingFunction::create(0, 1.0 - (-1.73), 1.0 - 0.17, 1.0 - 0.67);
EXPECT_REFV_EQ(cubicCustomTimingReversed, reverse(cubicCustomTiming));
RefPtr<TimingFunction> cubicEaseTiming = CubicBezierTimingFunction::preset(CubicBezierTimingFunction::Ease);
RefPtr<TimingFunction> cubicEaseTimingReversed = CubicBezierTimingFunction::create(1.0 - 0.25, 0.0, 1.0 - 0.25, 1.0 - 0.1);
EXPECT_REFV_EQ(cubicEaseTimingReversed, reverse(cubicEaseTiming));
}
} // namespace
......@@ -3446,7 +3446,6 @@
'animation/AnimationTranslationUtilTest.cpp',
'animation/CompositorAnimationsTest.cpp',
'animation/CompositorAnimationsTestHelper.h',
'animation/CompositorAnimationsTimingFunctionReverserTest.cpp',
'animation/EffectInputTest.cpp',
'animation/InterpolableValueTest.cpp',
'animation/InterpolationEffectTest.cpp',
......
......@@ -6,6 +6,7 @@
#define WebCompositorAnimation_h
#define WEB_ANIMATION_SUPPORTS_FRACTIONAL_ITERATIONS 1
#define WEB_ANIMATION_SUPPORTS_FULL_DIRECTION 1
namespace blink {
......@@ -19,6 +20,13 @@ public:
TargetPropertyScrollOffset
};
enum Direction {
DirectionNormal = 0,
DirectionReverse,
DirectionAlternate,
DirectionAlternateReverse
};
virtual ~WebCompositorAnimation() { }
// An id is effectively the animation's name, and it is not unique.
......@@ -38,9 +46,8 @@ public:
virtual double timeOffset() const = 0;
virtual void setTimeOffset(double monotonicTime) = 0;
// If alternatesDirection is true, on odd numbered iterations we reverse the curve.
virtual bool alternatesDirection() const = 0;
virtual void setAlternatesDirection(bool) = 0;
virtual Direction direction() const = 0;
virtual void setDirection(Direction) = 0;
};
} // namespace blink
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment