1797e4f1087e408060f2812c79bddcd2b73a3830dNicolas Roard/*
2797e4f1087e408060f2812c79bddcd2b73a3830dNicolas Roard * Copyright (C) 2009 The Android Open Source Project
3797e4f1087e408060f2812c79bddcd2b73a3830dNicolas Roard *
4797e4f1087e408060f2812c79bddcd2b73a3830dNicolas Roard * Licensed under the Apache License, Version 2.0 (the "License");
5797e4f1087e408060f2812c79bddcd2b73a3830dNicolas Roard * you may not use this file except in compliance with the License.
6797e4f1087e408060f2812c79bddcd2b73a3830dNicolas Roard * You may obtain a copy of the License at
7797e4f1087e408060f2812c79bddcd2b73a3830dNicolas Roard *
8797e4f1087e408060f2812c79bddcd2b73a3830dNicolas Roard *      http://www.apache.org/licenses/LICENSE-2.0
9797e4f1087e408060f2812c79bddcd2b73a3830dNicolas Roard *
10797e4f1087e408060f2812c79bddcd2b73a3830dNicolas Roard * Unless required by applicable law or agreed to in writing, software
11797e4f1087e408060f2812c79bddcd2b73a3830dNicolas Roard * distributed under the License is distributed on an "AS IS" BASIS,
12797e4f1087e408060f2812c79bddcd2b73a3830dNicolas Roard * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13797e4f1087e408060f2812c79bddcd2b73a3830dNicolas Roard * See the License for the specific language governing permissions and
14797e4f1087e408060f2812c79bddcd2b73a3830dNicolas Roard * limitations under the License.
15797e4f1087e408060f2812c79bddcd2b73a3830dNicolas Roard */
16797e4f1087e408060f2812c79bddcd2b73a3830dNicolas Roard
17797e4f1087e408060f2812c79bddcd2b73a3830dNicolas Roard#include "config.h"
18797e4f1087e408060f2812c79bddcd2b73a3830dNicolas Roard#include "AndroidAnimation.h"
19797e4f1087e408060f2812c79bddcd2b73a3830dNicolas Roard
20797e4f1087e408060f2812c79bddcd2b73a3830dNicolas Roard#if USE(ACCELERATED_COMPOSITING)
21797e4f1087e408060f2812c79bddcd2b73a3830dNicolas Roard
22797e4f1087e408060f2812c79bddcd2b73a3830dNicolas Roard#include "Animation.h"
23797e4f1087e408060f2812c79bddcd2b73a3830dNicolas Roard#include "GraphicsLayerAndroid.h"
24797e4f1087e408060f2812c79bddcd2b73a3830dNicolas Roard
25797e4f1087e408060f2812c79bddcd2b73a3830dNicolas Roard#include "Timer.h"
26797e4f1087e408060f2812c79bddcd2b73a3830dNicolas Roard#include "TimingFunction.h"
27ff8665d820cc087df2b169dc727396c2a57e65aeNicolas Roard#include "TranslateTransformOperation.h"
28797e4f1087e408060f2812c79bddcd2b73a3830dNicolas Roard#include "UnitBezier.h"
29797e4f1087e408060f2812c79bddcd2b73a3830dNicolas Roard
30797e4f1087e408060f2812c79bddcd2b73a3830dNicolas Roard#include <wtf/CurrentTime.h>
31ff8665d820cc087df2b169dc727396c2a57e65aeNicolas Roard#include <cutils/log.h>
32ff8665d820cc087df2b169dc727396c2a57e65aeNicolas Roard#include <wtf/text/CString.h>
33ff8665d820cc087df2b169dc727396c2a57e65aeNicolas Roard
348cc0fa17a42ae1dec75fe8ab00d5baa75e46499eNicolas Roard#undef XLOGC
358cc0fa17a42ae1dec75fe8ab00d5baa75e46499eNicolas Roard#define XLOGC(...) android_printLog(ANDROID_LOG_DEBUG, "AndroidAnimation", __VA_ARGS__)
368cc0fa17a42ae1dec75fe8ab00d5baa75e46499eNicolas Roard
378cc0fa17a42ae1dec75fe8ab00d5baa75e46499eNicolas Roard#ifdef DEBUG
388cc0fa17a42ae1dec75fe8ab00d5baa75e46499eNicolas Roard
39ff8665d820cc087df2b169dc727396c2a57e65aeNicolas Roard#undef XLOG
40ff8665d820cc087df2b169dc727396c2a57e65aeNicolas Roard#define XLOG(...) android_printLog(ANDROID_LOG_DEBUG, "AndroidAnimation", __VA_ARGS__)
41ff8665d820cc087df2b169dc727396c2a57e65aeNicolas Roard
42ff8665d820cc087df2b169dc727396c2a57e65aeNicolas Roard#else
43ff8665d820cc087df2b169dc727396c2a57e65aeNicolas Roard
44ff8665d820cc087df2b169dc727396c2a57e65aeNicolas Roard#undef XLOG
45ff8665d820cc087df2b169dc727396c2a57e65aeNicolas Roard#define XLOG(...)
46ff8665d820cc087df2b169dc727396c2a57e65aeNicolas Roard
47ff8665d820cc087df2b169dc727396c2a57e65aeNicolas Roard#endif // DEBUG
48ff8665d820cc087df2b169dc727396c2a57e65aeNicolas Roard
49ff8665d820cc087df2b169dc727396c2a57e65aeNicolas Roard
50797e4f1087e408060f2812c79bddcd2b73a3830dNicolas Roardnamespace WebCore {
51797e4f1087e408060f2812c79bddcd2b73a3830dNicolas Roard
52aeca53d3fee2e94ce013c1dc12648f0335284fbbChris Craikstatic int gUniqueId;
53aeca53d3fee2e94ce013c1dc12648f0335284fbbChris Craik
54797e4f1087e408060f2812c79bddcd2b73a3830dNicolas Roardstatic long gDebugAndroidAnimationInstances;
55797e4f1087e408060f2812c79bddcd2b73a3830dNicolas Roard
56797e4f1087e408060f2812c79bddcd2b73a3830dNicolas Roardlong AndroidAnimation::instancesCount()
57797e4f1087e408060f2812c79bddcd2b73a3830dNicolas Roard{
58797e4f1087e408060f2812c79bddcd2b73a3830dNicolas Roard    return gDebugAndroidAnimationInstances;
59797e4f1087e408060f2812c79bddcd2b73a3830dNicolas Roard}
60797e4f1087e408060f2812c79bddcd2b73a3830dNicolas Roard
61ac8d9f13717dd67de94dc7ab18690d6da10b0c99Nicolas RoardAndroidAnimation::AndroidAnimation(AnimatedPropertyID type,
6291672cbe203b55ec355d118636d333e9e7d7f3d7Nicolas Roard                                   const Animation* animation,
63ac8d9f13717dd67de94dc7ab18690d6da10b0c99Nicolas Roard                                   KeyframeValueList* operations,
64ff8665d820cc087df2b169dc727396c2a57e65aeNicolas Roard                                   double beginTime)
65ff8665d820cc087df2b169dc727396c2a57e65aeNicolas Roard    : m_beginTime(beginTime)
66ff8665d820cc087df2b169dc727396c2a57e65aeNicolas Roard    , m_duration(animation->duration())
678cc0fa17a42ae1dec75fe8ab00d5baa75e46499eNicolas Roard    , m_fillsBackwards(animation->fillsBackwards())
688cc0fa17a42ae1dec75fe8ab00d5baa75e46499eNicolas Roard    , m_fillsForwards(animation->fillsForwards())
69ff8665d820cc087df2b169dc727396c2a57e65aeNicolas Roard    , m_iterationCount(animation->iterationCount())
70ff8665d820cc087df2b169dc727396c2a57e65aeNicolas Roard    , m_direction(animation->direction())
71ff8665d820cc087df2b169dc727396c2a57e65aeNicolas Roard    , m_timingFunction(animation->timingFunction())
7291672cbe203b55ec355d118636d333e9e7d7f3d7Nicolas Roard    , m_type(type)
73ac8d9f13717dd67de94dc7ab18690d6da10b0c99Nicolas Roard    , m_operations(operations)
74aeca53d3fee2e94ce013c1dc12648f0335284fbbChris Craik    , m_uniqueId(++gUniqueId)
75aeca53d3fee2e94ce013c1dc12648f0335284fbbChris Craik    , m_hasFinished(false)
76797e4f1087e408060f2812c79bddcd2b73a3830dNicolas Roard{
77f7a8a768a4485e7de59f3707eae666e989a76356Iain Merrick    ASSERT(m_timingFunction);
78f7a8a768a4485e7de59f3707eae666e989a76356Iain Merrick
79797e4f1087e408060f2812c79bddcd2b73a3830dNicolas Roard    gDebugAndroidAnimationInstances++;
80797e4f1087e408060f2812c79bddcd2b73a3830dNicolas Roard}
81797e4f1087e408060f2812c79bddcd2b73a3830dNicolas Roard
82797e4f1087e408060f2812c79bddcd2b73a3830dNicolas RoardAndroidAnimation::~AndroidAnimation()
83797e4f1087e408060f2812c79bddcd2b73a3830dNicolas Roard{
84797e4f1087e408060f2812c79bddcd2b73a3830dNicolas Roard    gDebugAndroidAnimationInstances--;
85797e4f1087e408060f2812c79bddcd2b73a3830dNicolas Roard}
86797e4f1087e408060f2812c79bddcd2b73a3830dNicolas Roard
87aeca53d3fee2e94ce013c1dc12648f0335284fbbChris Craikvoid AndroidAnimation::suggestBeginTime(double time)
88797e4f1087e408060f2812c79bddcd2b73a3830dNicolas Roard{
89aeca53d3fee2e94ce013c1dc12648f0335284fbbChris Craik    if (m_beginTime <= 0.000001) // overflow or not yet set
90797e4f1087e408060f2812c79bddcd2b73a3830dNicolas Roard        m_beginTime = time;
91aeca53d3fee2e94ce013c1dc12648f0335284fbbChris Craik}
92797e4f1087e408060f2812c79bddcd2b73a3830dNicolas Roard
93aeca53d3fee2e94ce013c1dc12648f0335284fbbChris Craikdouble AndroidAnimation::elapsedTime(double time)
94aeca53d3fee2e94ce013c1dc12648f0335284fbbChris Craik{
95c6151a04881a67d08d91237891fbc7cb82927219John Reck    double elapsedTime = (m_beginTime < 0.000001) ? 0 : time - m_beginTime;
96797e4f1087e408060f2812c79bddcd2b73a3830dNicolas Roard
97797e4f1087e408060f2812c79bddcd2b73a3830dNicolas Roard    if (m_duration <= 0)
98797e4f1087e408060f2812c79bddcd2b73a3830dNicolas Roard      m_duration = 0.000001;
99797e4f1087e408060f2812c79bddcd2b73a3830dNicolas Roard
100aeca53d3fee2e94ce013c1dc12648f0335284fbbChris Craik    if (elapsedTime < 0) // animation not yet started.
101797e4f1087e408060f2812c79bddcd2b73a3830dNicolas Roard        return 0;
102797e4f1087e408060f2812c79bddcd2b73a3830dNicolas Roard
103aeca53d3fee2e94ce013c1dc12648f0335284fbbChris Craik    return elapsedTime;
104797e4f1087e408060f2812c79bddcd2b73a3830dNicolas Roard}
105797e4f1087e408060f2812c79bddcd2b73a3830dNicolas Roard
106797e4f1087e408060f2812c79bddcd2b73a3830dNicolas Roardbool AndroidAnimation::checkIterationsAndProgress(double time, float* finalProgress)
107797e4f1087e408060f2812c79bddcd2b73a3830dNicolas Roard{
108ac8d9f13717dd67de94dc7ab18690d6da10b0c99Nicolas Roard    double progress = elapsedTime(time);
109ac8d9f13717dd67de94dc7ab18690d6da10b0c99Nicolas Roard    double dur = m_duration;
110ac8d9f13717dd67de94dc7ab18690d6da10b0c99Nicolas Roard    if (m_iterationCount > 0)
111ac8d9f13717dd67de94dc7ab18690d6da10b0c99Nicolas Roard        dur *= m_iterationCount;
112797e4f1087e408060f2812c79bddcd2b73a3830dNicolas Roard
113ac8d9f13717dd67de94dc7ab18690d6da10b0c99Nicolas Roard    if (m_duration <= 0)
114ac8d9f13717dd67de94dc7ab18690d6da10b0c99Nicolas Roard        return false;
115797e4f1087e408060f2812c79bddcd2b73a3830dNicolas Roard
116ac8d9f13717dd67de94dc7ab18690d6da10b0c99Nicolas Roard    // If not infinite, return false if we are done
117ce22862b0c41a8fedaf28166e857034f1484ea5cNicolas Roard    if (m_iterationCount > 0 && progress > dur) {
118ce22862b0c41a8fedaf28166e857034f1484ea5cNicolas Roard        *finalProgress = 1.0;
119aeca53d3fee2e94ce013c1dc12648f0335284fbbChris Craik        if (!m_hasFinished) {
120aeca53d3fee2e94ce013c1dc12648f0335284fbbChris Craik            // first time past duration, continue with progress 1.0 so the
121aeca53d3fee2e94ce013c1dc12648f0335284fbbChris Craik            // element's final position lines up with it's last keyframe
122aeca53d3fee2e94ce013c1dc12648f0335284fbbChris Craik            m_hasFinished = true;
123aeca53d3fee2e94ce013c1dc12648f0335284fbbChris Craik            return true;
124aeca53d3fee2e94ce013c1dc12648f0335284fbbChris Craik        }
125aeca53d3fee2e94ce013c1dc12648f0335284fbbChris Craik
126797e4f1087e408060f2812c79bddcd2b73a3830dNicolas Roard        return false;
127ce22862b0c41a8fedaf28166e857034f1484ea5cNicolas Roard    }
128797e4f1087e408060f2812c79bddcd2b73a3830dNicolas Roard
129ac8d9f13717dd67de94dc7ab18690d6da10b0c99Nicolas Roard    double fractionalTime = progress / m_duration;
130ac8d9f13717dd67de94dc7ab18690d6da10b0c99Nicolas Roard    int integralTime = static_cast<int>(fractionalTime);
131ac8d9f13717dd67de94dc7ab18690d6da10b0c99Nicolas Roard
132ac8d9f13717dd67de94dc7ab18690d6da10b0c99Nicolas Roard    fractionalTime -= integralTime;
133ac8d9f13717dd67de94dc7ab18690d6da10b0c99Nicolas Roard
134ac8d9f13717dd67de94dc7ab18690d6da10b0c99Nicolas Roard    if ((m_direction == Animation::AnimationDirectionAlternate) && (integralTime & 1))
135ac8d9f13717dd67de94dc7ab18690d6da10b0c99Nicolas Roard        fractionalTime = 1 - fractionalTime;
136ac8d9f13717dd67de94dc7ab18690d6da10b0c99Nicolas Roard
137ac8d9f13717dd67de94dc7ab18690d6da10b0c99Nicolas Roard    *finalProgress = fractionalTime;
138ac8d9f13717dd67de94dc7ab18690d6da10b0c99Nicolas Roard    return true;
139ac8d9f13717dd67de94dc7ab18690d6da10b0c99Nicolas Roard}
140ac8d9f13717dd67de94dc7ab18690d6da10b0c99Nicolas Roard
141ac8d9f13717dd67de94dc7ab18690d6da10b0c99Nicolas Roarddouble AndroidAnimation::applyTimingFunction(float from, float to, double progress,
142ac8d9f13717dd67de94dc7ab18690d6da10b0c99Nicolas Roard                                             const TimingFunction* tf)
143ac8d9f13717dd67de94dc7ab18690d6da10b0c99Nicolas Roard{
144ac8d9f13717dd67de94dc7ab18690d6da10b0c99Nicolas Roard    double fractionalTime = progress;
145ac8d9f13717dd67de94dc7ab18690d6da10b0c99Nicolas Roard    double offset = from;
146ac8d9f13717dd67de94dc7ab18690d6da10b0c99Nicolas Roard    double scale = 1.0 / (to - from);
147ac8d9f13717dd67de94dc7ab18690d6da10b0c99Nicolas Roard
148ac8d9f13717dd67de94dc7ab18690d6da10b0c99Nicolas Roard    if (scale != 1 || offset)
149ac8d9f13717dd67de94dc7ab18690d6da10b0c99Nicolas Roard        fractionalTime = (fractionalTime - offset) * scale;
150ac8d9f13717dd67de94dc7ab18690d6da10b0c99Nicolas Roard
151ac8d9f13717dd67de94dc7ab18690d6da10b0c99Nicolas Roard    const TimingFunction* timingFunction = tf;
152ac8d9f13717dd67de94dc7ab18690d6da10b0c99Nicolas Roard
153ac8d9f13717dd67de94dc7ab18690d6da10b0c99Nicolas Roard    if (!timingFunction)
154ac8d9f13717dd67de94dc7ab18690d6da10b0c99Nicolas Roard        timingFunction = m_timingFunction.get();
155ac8d9f13717dd67de94dc7ab18690d6da10b0c99Nicolas Roard
156ac8d9f13717dd67de94dc7ab18690d6da10b0c99Nicolas Roard    if (timingFunction && timingFunction->isCubicBezierTimingFunction()) {
157ac8d9f13717dd67de94dc7ab18690d6da10b0c99Nicolas Roard        const CubicBezierTimingFunction* bezierFunction = static_cast<const CubicBezierTimingFunction*>(timingFunction);
158f7a8a768a4485e7de59f3707eae666e989a76356Iain Merrick        UnitBezier bezier(bezierFunction->x1(),
159f7a8a768a4485e7de59f3707eae666e989a76356Iain Merrick                          bezierFunction->y1(),
160f7a8a768a4485e7de59f3707eae666e989a76356Iain Merrick                          bezierFunction->x2(),
161f7a8a768a4485e7de59f3707eae666e989a76356Iain Merrick                          bezierFunction->y2());
162797e4f1087e408060f2812c79bddcd2b73a3830dNicolas Roard        if (m_duration > 0)
163ac8d9f13717dd67de94dc7ab18690d6da10b0c99Nicolas Roard            fractionalTime = bezier.solve(fractionalTime, 1.0f / (200.0f * m_duration));
164ac8d9f13717dd67de94dc7ab18690d6da10b0c99Nicolas Roard    } else if (timingFunction && timingFunction->isStepsTimingFunction()) {
165ac8d9f13717dd67de94dc7ab18690d6da10b0c99Nicolas Roard        const StepsTimingFunction* stepFunction = static_cast<const StepsTimingFunction*>(timingFunction);
166ac8d9f13717dd67de94dc7ab18690d6da10b0c99Nicolas Roard        if (stepFunction->stepAtStart()) {
167ac8d9f13717dd67de94dc7ab18690d6da10b0c99Nicolas Roard            fractionalTime = (floor(stepFunction->numberOfSteps() * fractionalTime) + 1) / stepFunction->numberOfSteps();
168ac8d9f13717dd67de94dc7ab18690d6da10b0c99Nicolas Roard            if (fractionalTime > 1.0)
169ac8d9f13717dd67de94dc7ab18690d6da10b0c99Nicolas Roard                fractionalTime = 1.0;
170ac8d9f13717dd67de94dc7ab18690d6da10b0c99Nicolas Roard        } else {
171ac8d9f13717dd67de94dc7ab18690d6da10b0c99Nicolas Roard            fractionalTime = floor(stepFunction->numberOfSteps() * fractionalTime) / stepFunction->numberOfSteps();
172ac8d9f13717dd67de94dc7ab18690d6da10b0c99Nicolas Roard        }
173797e4f1087e408060f2812c79bddcd2b73a3830dNicolas Roard    }
174ac8d9f13717dd67de94dc7ab18690d6da10b0c99Nicolas Roard    return fractionalTime;
175797e4f1087e408060f2812c79bddcd2b73a3830dNicolas Roard}
176797e4f1087e408060f2812c79bddcd2b73a3830dNicolas Roard
1778cc0fa17a42ae1dec75fe8ab00d5baa75e46499eNicolas Roardbool AndroidAnimation::evaluate(LayerAndroid* layer, double time)
1788cc0fa17a42ae1dec75fe8ab00d5baa75e46499eNicolas Roard{
1798cc0fa17a42ae1dec75fe8ab00d5baa75e46499eNicolas Roard    float progress;
1808cc0fa17a42ae1dec75fe8ab00d5baa75e46499eNicolas Roard    if (!checkIterationsAndProgress(time, &progress)
1818cc0fa17a42ae1dec75fe8ab00d5baa75e46499eNicolas Roard        && !(m_fillsBackwards || m_fillsForwards))
1828cc0fa17a42ae1dec75fe8ab00d5baa75e46499eNicolas Roard        return false;
1838cc0fa17a42ae1dec75fe8ab00d5baa75e46499eNicolas Roard
1848cc0fa17a42ae1dec75fe8ab00d5baa75e46499eNicolas Roard    if (progress < 0) {
1858cc0fa17a42ae1dec75fe8ab00d5baa75e46499eNicolas Roard        // The animation hasn't started yet
186c6151a04881a67d08d91237891fbc7cb82927219John Reck        if (m_fillsBackwards || m_beginTime <= 0.000001) {
1878cc0fa17a42ae1dec75fe8ab00d5baa75e46499eNicolas Roard            // in this case we want to apply the initial keyframe to the layer
1888cc0fa17a42ae1dec75fe8ab00d5baa75e46499eNicolas Roard            applyForProgress(layer, 0);
1898cc0fa17a42ae1dec75fe8ab00d5baa75e46499eNicolas Roard        }
1908cc0fa17a42ae1dec75fe8ab00d5baa75e46499eNicolas Roard        // we still want to be evaluated until we get progress > 0
1918cc0fa17a42ae1dec75fe8ab00d5baa75e46499eNicolas Roard        return true;
1928cc0fa17a42ae1dec75fe8ab00d5baa75e46499eNicolas Roard    }
1938cc0fa17a42ae1dec75fe8ab00d5baa75e46499eNicolas Roard
194aeca53d3fee2e94ce013c1dc12648f0335284fbbChris Craik    if (progress > 1) {
1958cc0fa17a42ae1dec75fe8ab00d5baa75e46499eNicolas Roard        if (!m_fillsForwards)
1968cc0fa17a42ae1dec75fe8ab00d5baa75e46499eNicolas Roard            return false;
1978cc0fa17a42ae1dec75fe8ab00d5baa75e46499eNicolas Roard        progress = 1;
1988cc0fa17a42ae1dec75fe8ab00d5baa75e46499eNicolas Roard    }
1998cc0fa17a42ae1dec75fe8ab00d5baa75e46499eNicolas Roard
2008cc0fa17a42ae1dec75fe8ab00d5baa75e46499eNicolas Roard    if (!m_operations->size())
2018cc0fa17a42ae1dec75fe8ab00d5baa75e46499eNicolas Roard        return false;
2028cc0fa17a42ae1dec75fe8ab00d5baa75e46499eNicolas Roard
2038cc0fa17a42ae1dec75fe8ab00d5baa75e46499eNicolas Roard    applyForProgress(layer, progress);
2048cc0fa17a42ae1dec75fe8ab00d5baa75e46499eNicolas Roard
2058cc0fa17a42ae1dec75fe8ab00d5baa75e46499eNicolas Roard    return true;
2068cc0fa17a42ae1dec75fe8ab00d5baa75e46499eNicolas Roard}
2078cc0fa17a42ae1dec75fe8ab00d5baa75e46499eNicolas Roard
20830e39dd1918530408d55dbead3bf1567661b606eNicolas RoardPassRefPtr<AndroidOpacityAnimation> AndroidOpacityAnimation::create(
20930e39dd1918530408d55dbead3bf1567661b606eNicolas Roard                                                const Animation* animation,
2108d060c05a073fedcf8cd4142926ff5a5e1991de9Russell Brenner                                                KeyframeValueList* operations,
21130e39dd1918530408d55dbead3bf1567661b606eNicolas Roard                                                double beginTime)
21230e39dd1918530408d55dbead3bf1567661b606eNicolas Roard{
2138d060c05a073fedcf8cd4142926ff5a5e1991de9Russell Brenner    return adoptRef(new AndroidOpacityAnimation(animation, operations,
2148d060c05a073fedcf8cd4142926ff5a5e1991de9Russell Brenner                                                beginTime));
215797e4f1087e408060f2812c79bddcd2b73a3830dNicolas Roard}
216797e4f1087e408060f2812c79bddcd2b73a3830dNicolas Roard
2178d060c05a073fedcf8cd4142926ff5a5e1991de9Russell BrennerAndroidOpacityAnimation::AndroidOpacityAnimation(const Animation* animation,
2188d060c05a073fedcf8cd4142926ff5a5e1991de9Russell Brenner                                                 KeyframeValueList* operations,
21930e39dd1918530408d55dbead3bf1567661b606eNicolas Roard                                                 double beginTime)
220ac8d9f13717dd67de94dc7ab18690d6da10b0c99Nicolas Roard    : AndroidAnimation(AnimatedPropertyOpacity, animation, operations, beginTime)
221797e4f1087e408060f2812c79bddcd2b73a3830dNicolas Roard{
222797e4f1087e408060f2812c79bddcd2b73a3830dNicolas Roard}
223797e4f1087e408060f2812c79bddcd2b73a3830dNicolas Roard
224ac8d9f13717dd67de94dc7ab18690d6da10b0c99Nicolas Roardvoid AndroidAnimation::pickValues(double progress, int* start, int* end)
225797e4f1087e408060f2812c79bddcd2b73a3830dNicolas Roard{
226ac8d9f13717dd67de94dc7ab18690d6da10b0c99Nicolas Roard    float distance = -1;
2278d060c05a073fedcf8cd4142926ff5a5e1991de9Russell Brenner    unsigned int foundAt = 0;
2288d060c05a073fedcf8cd4142926ff5a5e1991de9Russell Brenner    for (unsigned int i = 0; i < m_operations->size(); i++) {
229ac8d9f13717dd67de94dc7ab18690d6da10b0c99Nicolas Roard        const AnimationValue* value = m_operations->at(i);
2308d060c05a073fedcf8cd4142926ff5a5e1991de9Russell Brenner        float key = value->keyTime();
2318d060c05a073fedcf8cd4142926ff5a5e1991de9Russell Brenner        float d = progress - key;
232ac8d9f13717dd67de94dc7ab18690d6da10b0c99Nicolas Roard        if (distance == -1 || (d >= 0 && d < distance && i + 1 < m_operations->size())) {
2338d060c05a073fedcf8cd4142926ff5a5e1991de9Russell Brenner            distance = d;
2348d060c05a073fedcf8cd4142926ff5a5e1991de9Russell Brenner            foundAt = i;
2358d060c05a073fedcf8cd4142926ff5a5e1991de9Russell Brenner        }
2368d060c05a073fedcf8cd4142926ff5a5e1991de9Russell Brenner    }
2378d060c05a073fedcf8cd4142926ff5a5e1991de9Russell Brenner
238ac8d9f13717dd67de94dc7ab18690d6da10b0c99Nicolas Roard    *start = foundAt;
239ac8d9f13717dd67de94dc7ab18690d6da10b0c99Nicolas Roard
2408d060c05a073fedcf8cd4142926ff5a5e1991de9Russell Brenner    if (foundAt + 1 < m_operations->size())
241ac8d9f13717dd67de94dc7ab18690d6da10b0c99Nicolas Roard        *end = foundAt + 1;
2428d060c05a073fedcf8cd4142926ff5a5e1991de9Russell Brenner    else
243ac8d9f13717dd67de94dc7ab18690d6da10b0c99Nicolas Roard        *end = foundAt;
244ac8d9f13717dd67de94dc7ab18690d6da10b0c99Nicolas Roard}
2458d060c05a073fedcf8cd4142926ff5a5e1991de9Russell Brenner
2468cc0fa17a42ae1dec75fe8ab00d5baa75e46499eNicolas Roardvoid AndroidOpacityAnimation::applyForProgress(LayerAndroid* layer, float progress)
247ac8d9f13717dd67de94dc7ab18690d6da10b0c99Nicolas Roard{
248ac8d9f13717dd67de94dc7ab18690d6da10b0c99Nicolas Roard    // First, we need to get the from and to values
249ac8d9f13717dd67de94dc7ab18690d6da10b0c99Nicolas Roard    int from, to;
250ac8d9f13717dd67de94dc7ab18690d6da10b0c99Nicolas Roard    pickValues(progress, &from, &to);
251ac8d9f13717dd67de94dc7ab18690d6da10b0c99Nicolas Roard    FloatAnimationValue* fromValue = (FloatAnimationValue*) m_operations->at(from);
252ac8d9f13717dd67de94dc7ab18690d6da10b0c99Nicolas Roard    FloatAnimationValue* toValue = (FloatAnimationValue*) m_operations->at(to);
253ac8d9f13717dd67de94dc7ab18690d6da10b0c99Nicolas Roard
254ac8d9f13717dd67de94dc7ab18690d6da10b0c99Nicolas Roard    XLOG("[layer %d] opacity fromValue %x, key %.2f, toValue %x, key %.2f for progress %.2f",
2558d060c05a073fedcf8cd4142926ff5a5e1991de9Russell Brenner         layer->uniqueId(),
2568d060c05a073fedcf8cd4142926ff5a5e1991de9Russell Brenner         fromValue, fromValue->keyTime(),
2578d060c05a073fedcf8cd4142926ff5a5e1991de9Russell Brenner         toValue, toValue->keyTime(), progress);
2588d060c05a073fedcf8cd4142926ff5a5e1991de9Russell Brenner
2598d060c05a073fedcf8cd4142926ff5a5e1991de9Russell Brenner    // We now have the correct two values to work with, let's compute the
2608d060c05a073fedcf8cd4142926ff5a5e1991de9Russell Brenner    // progress value
2618d060c05a073fedcf8cd4142926ff5a5e1991de9Russell Brenner
262ac8d9f13717dd67de94dc7ab18690d6da10b0c99Nicolas Roard    const TimingFunction* timingFunction = fromValue->timingFunction();
263ac8d9f13717dd67de94dc7ab18690d6da10b0c99Nicolas Roard    progress = applyTimingFunction(fromValue->keyTime(), toValue->keyTime(),
264ac8d9f13717dd67de94dc7ab18690d6da10b0c99Nicolas Roard                                   progress, timingFunction);
2658d060c05a073fedcf8cd4142926ff5a5e1991de9Russell Brenner
266ac8d9f13717dd67de94dc7ab18690d6da10b0c99Nicolas Roard
2678cc0fa17a42ae1dec75fe8ab00d5baa75e46499eNicolas Roard    float value = fromValue->value() + ((toValue->value() - fromValue->value()) * progress);
268db110d3dd9014246922c7d44d485928cc2ea2692Nicolas Roard
2698cc0fa17a42ae1dec75fe8ab00d5baa75e46499eNicolas Roard    layer->setOpacity(value);
270797e4f1087e408060f2812c79bddcd2b73a3830dNicolas Roard}
271797e4f1087e408060f2812c79bddcd2b73a3830dNicolas Roard
27230e39dd1918530408d55dbead3bf1567661b606eNicolas RoardPassRefPtr<AndroidTransformAnimation> AndroidTransformAnimation::create(
27330e39dd1918530408d55dbead3bf1567661b606eNicolas Roard                                                     const Animation* animation,
274ff8665d820cc087df2b169dc727396c2a57e65aeNicolas Roard                                                     KeyframeValueList* operations,
27530e39dd1918530408d55dbead3bf1567661b606eNicolas Roard                                                     double beginTime)
276797e4f1087e408060f2812c79bddcd2b73a3830dNicolas Roard{
277ff8665d820cc087df2b169dc727396c2a57e65aeNicolas Roard    return adoptRef(new AndroidTransformAnimation(animation, operations, beginTime));
278797e4f1087e408060f2812c79bddcd2b73a3830dNicolas Roard}
279797e4f1087e408060f2812c79bddcd2b73a3830dNicolas Roard
28030e39dd1918530408d55dbead3bf1567661b606eNicolas RoardAndroidTransformAnimation::AndroidTransformAnimation(const Animation* animation,
281ff8665d820cc087df2b169dc727396c2a57e65aeNicolas Roard                                                     KeyframeValueList* operations,
28230e39dd1918530408d55dbead3bf1567661b606eNicolas Roard                                                     double beginTime)
283ac8d9f13717dd67de94dc7ab18690d6da10b0c99Nicolas Roard    : AndroidAnimation(AnimatedPropertyWebkitTransform, animation, operations, beginTime)
284797e4f1087e408060f2812c79bddcd2b73a3830dNicolas Roard{
285797e4f1087e408060f2812c79bddcd2b73a3830dNicolas Roard}
286797e4f1087e408060f2812c79bddcd2b73a3830dNicolas Roard
2878cc0fa17a42ae1dec75fe8ab00d5baa75e46499eNicolas Roardvoid AndroidTransformAnimation::applyForProgress(LayerAndroid* layer, float progress)
288797e4f1087e408060f2812c79bddcd2b73a3830dNicolas Roard{
289ff8665d820cc087df2b169dc727396c2a57e65aeNicolas Roard    // First, we need to get the from and to values
290ac8d9f13717dd67de94dc7ab18690d6da10b0c99Nicolas Roard    int from, to;
291ac8d9f13717dd67de94dc7ab18690d6da10b0c99Nicolas Roard    pickValues(progress, &from, &to);
2928cc0fa17a42ae1dec75fe8ab00d5baa75e46499eNicolas Roard
293ac8d9f13717dd67de94dc7ab18690d6da10b0c99Nicolas Roard    TransformAnimationValue* fromValue = (TransformAnimationValue*) m_operations->at(from);
294ac8d9f13717dd67de94dc7ab18690d6da10b0c99Nicolas Roard    TransformAnimationValue* toValue = (TransformAnimationValue*) m_operations->at(to);
295ff8665d820cc087df2b169dc727396c2a57e65aeNicolas Roard
296ff8665d820cc087df2b169dc727396c2a57e65aeNicolas Roard    XLOG("[layer %d] fromValue %x, key %.2f, toValue %x, key %.2f for progress %.2f",
297ff8665d820cc087df2b169dc727396c2a57e65aeNicolas Roard         layer->uniqueId(),
298ff8665d820cc087df2b169dc727396c2a57e65aeNicolas Roard         fromValue, fromValue->keyTime(),
299ff8665d820cc087df2b169dc727396c2a57e65aeNicolas Roard         toValue, toValue->keyTime(), progress);
300ff8665d820cc087df2b169dc727396c2a57e65aeNicolas Roard
301ff8665d820cc087df2b169dc727396c2a57e65aeNicolas Roard    // We now have the correct two values to work with, let's compute the
302ff8665d820cc087df2b169dc727396c2a57e65aeNicolas Roard    // progress value
303ff8665d820cc087df2b169dc727396c2a57e65aeNicolas Roard
304ac8d9f13717dd67de94dc7ab18690d6da10b0c99Nicolas Roard    const TimingFunction* timingFunction = fromValue->timingFunction();
305ac8d9f13717dd67de94dc7ab18690d6da10b0c99Nicolas Roard    float p = applyTimingFunction(fromValue->keyTime(), toValue->keyTime(),
306ac8d9f13717dd67de94dc7ab18690d6da10b0c99Nicolas Roard                                  progress, timingFunction);
307ac8d9f13717dd67de94dc7ab18690d6da10b0c99Nicolas Roard    XLOG("progress %.2f => %.2f from: %.2f to: %.2f", progress, p, fromValue->keyTime(),
308ac8d9f13717dd67de94dc7ab18690d6da10b0c99Nicolas Roard         toValue->keyTime());
309ac8d9f13717dd67de94dc7ab18690d6da10b0c99Nicolas Roard    progress = p;
310ff8665d820cc087df2b169dc727396c2a57e65aeNicolas Roard
311ff8665d820cc087df2b169dc727396c2a57e65aeNicolas Roard    // With both values and the progress, we also need to check out that
312ff8665d820cc087df2b169dc727396c2a57e65aeNicolas Roard    // the operations are compatible (i.e. we are animating the same number
313ff8665d820cc087df2b169dc727396c2a57e65aeNicolas Roard    // of values; if not we do a matrix blend)
314ff8665d820cc087df2b169dc727396c2a57e65aeNicolas Roard
315ff8665d820cc087df2b169dc727396c2a57e65aeNicolas Roard    TransformationMatrix transformMatrix;
316ff8665d820cc087df2b169dc727396c2a57e65aeNicolas Roard    bool valid = true;
317ff8665d820cc087df2b169dc727396c2a57e65aeNicolas Roard    unsigned int fromSize = fromValue->value()->size();
318ff8665d820cc087df2b169dc727396c2a57e65aeNicolas Roard    if (fromSize) {
319ff8665d820cc087df2b169dc727396c2a57e65aeNicolas Roard        if (toValue->value()->size() != fromSize)
320ff8665d820cc087df2b169dc727396c2a57e65aeNicolas Roard            valid = false;
321ff8665d820cc087df2b169dc727396c2a57e65aeNicolas Roard        else {
322ff8665d820cc087df2b169dc727396c2a57e65aeNicolas Roard            for (unsigned int j = 0; j < fromSize && valid; j++) {
323ff8665d820cc087df2b169dc727396c2a57e65aeNicolas Roard                if (!fromValue->value()->operations()[j]->isSameType(
324ff8665d820cc087df2b169dc727396c2a57e65aeNicolas Roard                    *toValue->value()->operations()[j]))
325ff8665d820cc087df2b169dc727396c2a57e65aeNicolas Roard                    valid = false;
326ff8665d820cc087df2b169dc727396c2a57e65aeNicolas Roard            }
327ff8665d820cc087df2b169dc727396c2a57e65aeNicolas Roard        }
328ff8665d820cc087df2b169dc727396c2a57e65aeNicolas Roard    }
329ff8665d820cc087df2b169dc727396c2a57e65aeNicolas Roard
3308cc0fa17a42ae1dec75fe8ab00d5baa75e46499eNicolas Roard    IntSize size(layer->getSize().width(), layer->getSize().height());
331ff8665d820cc087df2b169dc727396c2a57e65aeNicolas Roard    if (valid) {
332ff8665d820cc087df2b169dc727396c2a57e65aeNicolas Roard        for (size_t i = 0; i < toValue->value()->size(); ++i)
333ff8665d820cc087df2b169dc727396c2a57e65aeNicolas Roard            toValue->value()->operations()[i]->blend(fromValue->value()->at(i),
334ff8665d820cc087df2b169dc727396c2a57e65aeNicolas Roard                                                     progress)->apply(transformMatrix, size);
335ff8665d820cc087df2b169dc727396c2a57e65aeNicolas Roard    } else {
336ff8665d820cc087df2b169dc727396c2a57e65aeNicolas Roard        TransformationMatrix source;
337fe41360961a5f02a9f54dbe4922d301ef4bc4a20Nicolas Roard
338ff8665d820cc087df2b169dc727396c2a57e65aeNicolas Roard        fromValue->value()->apply(size, source);
339ff8665d820cc087df2b169dc727396c2a57e65aeNicolas Roard        toValue->value()->apply(size, transformMatrix);
340ff8665d820cc087df2b169dc727396c2a57e65aeNicolas Roard
341ff8665d820cc087df2b169dc727396c2a57e65aeNicolas Roard        transformMatrix.blend(source, progress);
342ff8665d820cc087df2b169dc727396c2a57e65aeNicolas Roard    }
343fe41360961a5f02a9f54dbe4922d301ef4bc4a20Nicolas Roard
344ff8665d820cc087df2b169dc727396c2a57e65aeNicolas Roard    // Set the final transform on the layer
345ff8665d820cc087df2b169dc727396c2a57e65aeNicolas Roard    layer->setTransform(transformMatrix);
346797e4f1087e408060f2812c79bddcd2b73a3830dNicolas Roard}
347797e4f1087e408060f2812c79bddcd2b73a3830dNicolas Roard
348797e4f1087e408060f2812c79bddcd2b73a3830dNicolas Roard} // namespace WebCore
349797e4f1087e408060f2812c79bddcd2b73a3830dNicolas Roard
350797e4f1087e408060f2812c79bddcd2b73a3830dNicolas Roard#endif // USE(ACCELERATED_COMPOSITING)
351