1 /* 2 * Copyright (C) 2009 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include "config.h" 18 #include "AndroidAnimation.h" 19 20 #if USE(ACCELERATED_COMPOSITING) 21 22 #include "Animation.h" 23 #include "GraphicsLayerAndroid.h" 24 25 #include "Timer.h" 26 #include "TimingFunction.h" 27 #include "UnitBezier.h" 28 29 #include <wtf/CurrentTime.h> 30 31 namespace WebCore { 32 33 static long gDebugAndroidAnimationInstances; 34 35 long AndroidAnimation::instancesCount() 36 { 37 return gDebugAndroidAnimationInstances; 38 } 39 40 AndroidAnimation::AndroidAnimation(const Animation* animation, 41 double beginTime) : 42 m_beginTime(beginTime), 43 m_duration(animation->duration()), 44 m_iterationCount(animation->iterationCount()), 45 m_currentIteration(0), 46 m_direction(animation->direction()), 47 m_timingFunction(animation->timingFunction()) 48 { 49 if (!static_cast<int>(beginTime)) // time not set 50 m_beginTime = WTF::currentTime(); 51 52 gDebugAndroidAnimationInstances++; 53 } 54 55 AndroidAnimation::AndroidAnimation(AndroidAnimation* anim) : 56 m_beginTime(anim->m_beginTime), 57 m_duration(anim->m_duration), 58 m_iterationCount(anim->m_iterationCount), 59 m_currentIteration(0), 60 m_direction(anim->m_direction), 61 m_timingFunction(anim->m_timingFunction) 62 { 63 gDebugAndroidAnimationInstances++; 64 } 65 66 AndroidAnimation::~AndroidAnimation() 67 { 68 gDebugAndroidAnimationInstances--; 69 } 70 71 float AndroidAnimation::currentProgress(double time) 72 { 73 if (m_beginTime <= 0.000001) // overflow or not correctly set 74 m_beginTime = time; 75 76 m_elapsedTime = time - m_beginTime; 77 78 if (m_duration <= 0) 79 m_duration = 0.000001; 80 81 if (m_elapsedTime < 0) // animation not yet started. 82 return 0; 83 84 return m_elapsedTime / m_duration; 85 } 86 87 bool AndroidAnimation::checkIterationsAndProgress(double time, float* finalProgress) 88 { 89 float progress = currentProgress(time); 90 91 int currentIteration = static_cast<int>(progress); 92 if (currentIteration != m_currentIteration) 93 if (m_direction == Animation::AnimationDirectionAlternate) 94 swapDirection(); 95 96 m_currentIteration = currentIteration; 97 progress -= m_currentIteration; 98 99 if ((m_currentIteration >= m_iterationCount) 100 && (m_iterationCount != Animation::IterationCountInfinite)) 101 return false; 102 103 if (m_timingFunction.type() != LinearTimingFunction) { 104 UnitBezier bezier(m_timingFunction.x1(), 105 m_timingFunction.y1(), 106 m_timingFunction.x2(), 107 m_timingFunction.y2()); 108 if (m_duration > 0) 109 progress = bezier.solve(progress, 1.0f / (200.0f * m_duration)); 110 } 111 112 *finalProgress = progress; 113 return true; 114 } 115 116 PassRefPtr<AndroidOpacityAnimation> AndroidOpacityAnimation::create( 117 float fromValue, 118 float toValue, 119 const Animation* animation, 120 double beginTime) 121 { 122 return adoptRef(new AndroidOpacityAnimation(fromValue, toValue, 123 animation, beginTime)); 124 } 125 126 AndroidOpacityAnimation::AndroidOpacityAnimation(float fromValue, float toValue, 127 const Animation* animation, 128 double beginTime) 129 : AndroidAnimation(animation, beginTime), 130 m_fromValue(fromValue), m_toValue(toValue) 131 { 132 } 133 134 AndroidOpacityAnimation::AndroidOpacityAnimation(AndroidOpacityAnimation* anim) 135 : AndroidAnimation(anim), 136 m_fromValue(anim->m_fromValue), 137 m_toValue(anim->m_toValue) 138 { 139 } 140 141 PassRefPtr<AndroidAnimation> AndroidOpacityAnimation::copy() 142 { 143 return adoptRef(new AndroidOpacityAnimation(this)); 144 } 145 146 void AndroidOpacityAnimation::swapDirection() 147 { 148 float v = m_toValue; 149 m_toValue = m_fromValue; 150 m_fromValue = m_toValue; 151 } 152 153 bool AndroidOpacityAnimation::evaluate(LayerAndroid* layer, double time) 154 { 155 float progress; 156 if (!checkIterationsAndProgress(time, &progress)) 157 return false; 158 159 if (progress < 0) // we still want to be evaluated until we get progress > 0 160 return true; 161 162 float value = m_fromValue + ((m_toValue - m_fromValue) * progress); 163 layer->setOpacity(value); 164 return true; 165 } 166 167 PassRefPtr<AndroidTransformAnimation> AndroidTransformAnimation::create( 168 const Animation* animation, 169 double beginTime) 170 { 171 return adoptRef(new AndroidTransformAnimation(animation, beginTime)); 172 } 173 174 AndroidTransformAnimation::AndroidTransformAnimation(const Animation* animation, 175 double beginTime) 176 : AndroidAnimation(animation, beginTime), 177 m_doTranslation(false), 178 m_doScaling(false), 179 m_doRotation(false) 180 { 181 } 182 183 AndroidTransformAnimation::AndroidTransformAnimation(AndroidTransformAnimation* anim) 184 : AndroidAnimation(anim), 185 m_doTranslation(anim->m_doTranslation), 186 m_doScaling(anim->m_doScaling), 187 m_doRotation(anim->m_doRotation), 188 m_position(anim->m_position), 189 m_fromX(anim->m_fromX), m_fromY(anim->m_fromY), m_fromZ(anim->m_fromZ), 190 m_toX(anim->m_toX), m_toY(anim->m_toY), m_toZ(anim->m_toZ), 191 m_fromAngle(anim->m_fromAngle), m_toAngle(anim->m_toAngle), 192 m_fromScaleX(anim->m_fromScaleX), m_fromScaleY(anim->m_fromScaleY), m_fromScaleZ(anim->m_fromScaleZ), 193 m_toScaleX(anim->m_toScaleX), m_toScaleY(anim->m_toScaleY), m_toScaleZ(anim->m_toScaleZ) 194 { 195 } 196 197 PassRefPtr<AndroidAnimation> AndroidTransformAnimation::copy() 198 { 199 return adoptRef(new AndroidTransformAnimation(this)); 200 } 201 202 void AndroidTransformAnimation::setRotation(float fA, float tA) 203 { 204 m_fromAngle = fA; 205 m_toAngle = tA; 206 m_doRotation = true; 207 } 208 209 void AndroidTransformAnimation::setTranslation(float fX, float fY, float fZ, 210 float tX, float tY, float tZ) 211 { 212 m_fromX = fX; 213 m_fromY = fY; 214 m_fromZ = fZ; 215 m_toX = tX; 216 m_toY = tY; 217 m_toZ = tZ; 218 m_doTranslation = true; 219 } 220 221 void AndroidTransformAnimation::setScale(float fX, float fY, float fZ, 222 float tX, float tY, float tZ) 223 { 224 m_fromScaleX = fX; 225 m_fromScaleY = fY; 226 m_fromScaleZ = fZ; 227 m_toScaleX = tX; 228 m_toScaleY = tY; 229 m_toScaleZ = tZ; 230 m_doScaling = true; 231 } 232 233 void AndroidTransformAnimation::swapDirection() 234 { 235 if (m_doTranslation) { 236 float tx = m_toX; 237 m_toX = m_fromX; 238 m_fromX = tx; 239 float ty = m_toY; 240 m_toY = m_fromY; 241 m_fromY = ty; 242 float tz = m_toZ; 243 m_toZ = m_fromZ; 244 m_fromZ = tz; 245 } 246 if (m_doScaling) { 247 float sx = m_toScaleX; 248 m_toScaleX = m_fromScaleX; 249 m_fromScaleX = sx; 250 float sy = m_toScaleY; 251 m_toScaleY = m_fromScaleY; 252 m_fromScaleY = sy; 253 } 254 if (m_doRotation) { 255 float a = m_toAngle; 256 m_toAngle = m_fromAngle; 257 m_fromAngle = a; 258 } 259 } 260 261 bool AndroidTransformAnimation::evaluate(LayerAndroid* layer, double time) 262 { 263 float progress; 264 if (!checkIterationsAndProgress(time, &progress)) 265 return false; 266 267 if (progress < 0) // we still want to be evaluated until we get progress > 0 268 return true; 269 270 float x = m_fromX + (m_toX - m_fromX) * progress; 271 float y = m_fromY + (m_toY - m_fromY) * progress; 272 float z = m_fromZ + (m_toZ - m_fromZ) * progress; 273 float sx = m_fromScaleX + (m_toScaleX - m_fromScaleX) * progress; 274 float sy = m_fromScaleY + (m_toScaleY - m_fromScaleY) * progress; 275 float sz = m_fromScaleZ + (m_toScaleZ - m_fromScaleZ) * progress; 276 float a = m_fromAngle + (m_toAngle - m_fromAngle) * progress; 277 278 if (m_doTranslation) 279 layer->setTranslation(x, y); 280 281 if (m_doScaling) 282 layer->setScale(sx, sy); 283 284 if (m_doRotation) 285 layer->setRotation(a); 286 287 return true; 288 } 289 290 } // namespace WebCore 291 292 #endif // USE(ACCELERATED_COMPOSITING) 293