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