layer_animation_controller.cc revision 0f1bc08d4cfcc34181b0b5cbf065c40f687bf740
1951a39d68df598db08dfced8b4707755864a0492Ying Wang// Copyright 2012 The Chromium Authors. All rights reserved. 2951a39d68df598db08dfced8b4707755864a0492Ying Wang// Use of this source code is governed by a BSD-style license that can be 3951a39d68df598db08dfced8b4707755864a0492Ying Wang// found in the LICENSE file. 4951a39d68df598db08dfced8b4707755864a0492Ying Wang 5951a39d68df598db08dfced8b4707755864a0492Ying Wang#include "cc/animation/layer_animation_controller.h" 6951a39d68df598db08dfced8b4707755864a0492Ying Wang 7951a39d68df598db08dfced8b4707755864a0492Ying Wang#include <algorithm> 8951a39d68df598db08dfced8b4707755864a0492Ying Wang 9951a39d68df598db08dfced8b4707755864a0492Ying Wang#include "cc/animation/animation.h" 10951a39d68df598db08dfced8b4707755864a0492Ying Wang#include "cc/animation/animation_delegate.h" 11951a39d68df598db08dfced8b4707755864a0492Ying Wang#include "cc/animation/animation_registrar.h" 12951a39d68df598db08dfced8b4707755864a0492Ying Wang#include "cc/animation/keyframed_animation_curve.h" 13951a39d68df598db08dfced8b4707755864a0492Ying Wang#include "cc/animation/layer_animation_value_observer.h" 14951a39d68df598db08dfced8b4707755864a0492Ying Wang#include "cc/base/scoped_ptr_algorithm.h" 15951a39d68df598db08dfced8b4707755864a0492Ying Wang#include "cc/output/filter_operations.h" 16951a39d68df598db08dfced8b4707755864a0492Ying Wang#include "ui/gfx/box_f.h" 17951a39d68df598db08dfced8b4707755864a0492Ying Wang#include "ui/gfx/transform.h" 18951a39d68df598db08dfced8b4707755864a0492Ying Wang 19951a39d68df598db08dfced8b4707755864a0492Ying Wangnamespace cc { 20951a39d68df598db08dfced8b4707755864a0492Ying Wang 21951a39d68df598db08dfced8b4707755864a0492Ying WangLayerAnimationController::LayerAnimationController(int id) 22951a39d68df598db08dfced8b4707755864a0492Ying Wang : force_sync_(false), 23951a39d68df598db08dfced8b4707755864a0492Ying Wang registrar_(0), 24951a39d68df598db08dfced8b4707755864a0492Ying Wang id_(id), 25951a39d68df598db08dfced8b4707755864a0492Ying Wang is_active_(false), 26951a39d68df598db08dfced8b4707755864a0492Ying Wang last_tick_time_(0), 27951a39d68df598db08dfced8b4707755864a0492Ying Wang layer_animation_delegate_(NULL) {} 28951a39d68df598db08dfced8b4707755864a0492Ying Wang 29951a39d68df598db08dfced8b4707755864a0492Ying WangLayerAnimationController::~LayerAnimationController() { 30951a39d68df598db08dfced8b4707755864a0492Ying Wang if (registrar_) 31951a39d68df598db08dfced8b4707755864a0492Ying Wang registrar_->UnregisterAnimationController(this); 32951a39d68df598db08dfced8b4707755864a0492Ying Wang} 33951a39d68df598db08dfced8b4707755864a0492Ying Wang 34951a39d68df598db08dfced8b4707755864a0492Ying Wangscoped_refptr<LayerAnimationController> LayerAnimationController::Create( 35951a39d68df598db08dfced8b4707755864a0492Ying Wang int id) { 36951a39d68df598db08dfced8b4707755864a0492Ying Wang return make_scoped_refptr(new LayerAnimationController(id)); 37951a39d68df598db08dfced8b4707755864a0492Ying Wang} 38951a39d68df598db08dfced8b4707755864a0492Ying Wang 39951a39d68df598db08dfced8b4707755864a0492Ying Wangvoid LayerAnimationController::PauseAnimation(int animation_id, 40951a39d68df598db08dfced8b4707755864a0492Ying Wang double time_offset) { 41951a39d68df598db08dfced8b4707755864a0492Ying Wang for (size_t i = 0; i < active_animations_.size(); ++i) { 42951a39d68df598db08dfced8b4707755864a0492Ying Wang if (active_animations_[i]->id() == animation_id) { 43951a39d68df598db08dfced8b4707755864a0492Ying Wang active_animations_[i]->SetRunState( 44951a39d68df598db08dfced8b4707755864a0492Ying Wang Animation::Paused, time_offset + active_animations_[i]->start_time()); 45951a39d68df598db08dfced8b4707755864a0492Ying Wang } 46951a39d68df598db08dfced8b4707755864a0492Ying Wang } 47951a39d68df598db08dfced8b4707755864a0492Ying Wang} 48951a39d68df598db08dfced8b4707755864a0492Ying Wang 49951a39d68df598db08dfced8b4707755864a0492Ying Wangstruct HasAnimationId { 50951a39d68df598db08dfced8b4707755864a0492Ying Wang explicit HasAnimationId(int id) : id_(id) {} 51951a39d68df598db08dfced8b4707755864a0492Ying Wang bool operator()(Animation* animation) const { 52951a39d68df598db08dfced8b4707755864a0492Ying Wang return animation->id() == id_; 53951a39d68df598db08dfced8b4707755864a0492Ying Wang } 54951a39d68df598db08dfced8b4707755864a0492Ying Wang 55951a39d68df598db08dfced8b4707755864a0492Ying Wang private: 56951a39d68df598db08dfced8b4707755864a0492Ying Wang int id_; 57951a39d68df598db08dfced8b4707755864a0492Ying Wang}; 58951a39d68df598db08dfced8b4707755864a0492Ying Wang 59951a39d68df598db08dfced8b4707755864a0492Ying Wangvoid LayerAnimationController::RemoveAnimation(int animation_id) { 60951a39d68df598db08dfced8b4707755864a0492Ying Wang ScopedPtrVector<Animation>& animations = active_animations_; 61951a39d68df598db08dfced8b4707755864a0492Ying Wang animations.erase(cc::remove_if(&animations, 62951a39d68df598db08dfced8b4707755864a0492Ying Wang animations.begin(), 63951a39d68df598db08dfced8b4707755864a0492Ying Wang animations.end(), 64951a39d68df598db08dfced8b4707755864a0492Ying Wang HasAnimationId(animation_id)), 65951a39d68df598db08dfced8b4707755864a0492Ying Wang animations.end()); 66951a39d68df598db08dfced8b4707755864a0492Ying Wang UpdateActivation(NormalActivation); 67951a39d68df598db08dfced8b4707755864a0492Ying Wang} 68951a39d68df598db08dfced8b4707755864a0492Ying Wang 69951a39d68df598db08dfced8b4707755864a0492Ying Wangstruct HasAnimationIdAndProperty { 70951a39d68df598db08dfced8b4707755864a0492Ying Wang HasAnimationIdAndProperty(int id, Animation::TargetProperty target_property) 71951a39d68df598db08dfced8b4707755864a0492Ying Wang : id_(id), target_property_(target_property) {} 72951a39d68df598db08dfced8b4707755864a0492Ying Wang bool operator()(Animation* animation) const { 73951a39d68df598db08dfced8b4707755864a0492Ying Wang return animation->id() == id_ && 74951a39d68df598db08dfced8b4707755864a0492Ying Wang animation->target_property() == target_property_; 75951a39d68df598db08dfced8b4707755864a0492Ying Wang } 76951a39d68df598db08dfced8b4707755864a0492Ying Wang 77951a39d68df598db08dfced8b4707755864a0492Ying Wang private: 78951a39d68df598db08dfced8b4707755864a0492Ying Wang int id_; 79951a39d68df598db08dfced8b4707755864a0492Ying Wang Animation::TargetProperty target_property_; 80951a39d68df598db08dfced8b4707755864a0492Ying Wang}; 81951a39d68df598db08dfced8b4707755864a0492Ying Wang 82951a39d68df598db08dfced8b4707755864a0492Ying Wangvoid LayerAnimationController::RemoveAnimation( 83951a39d68df598db08dfced8b4707755864a0492Ying Wang int animation_id, 84951a39d68df598db08dfced8b4707755864a0492Ying Wang Animation::TargetProperty target_property) { 85951a39d68df598db08dfced8b4707755864a0492Ying Wang ScopedPtrVector<Animation>& animations = active_animations_; 86951a39d68df598db08dfced8b4707755864a0492Ying Wang animations.erase(cc::remove_if(&animations, 87951a39d68df598db08dfced8b4707755864a0492Ying Wang animations.begin(), 88951a39d68df598db08dfced8b4707755864a0492Ying Wang animations.end(), 89951a39d68df598db08dfced8b4707755864a0492Ying Wang HasAnimationIdAndProperty(animation_id, 90951a39d68df598db08dfced8b4707755864a0492Ying Wang target_property)), 91951a39d68df598db08dfced8b4707755864a0492Ying Wang animations.end()); 92951a39d68df598db08dfced8b4707755864a0492Ying Wang UpdateActivation(NormalActivation); 93951a39d68df598db08dfced8b4707755864a0492Ying Wang} 94951a39d68df598db08dfced8b4707755864a0492Ying Wang 95951a39d68df598db08dfced8b4707755864a0492Ying Wang// Ensures that the list of active animations on the main thread and the impl 96951a39d68df598db08dfced8b4707755864a0492Ying Wang// thread are kept in sync. 97951a39d68df598db08dfced8b4707755864a0492Ying Wangvoid LayerAnimationController::PushAnimationUpdatesTo( 98951a39d68df598db08dfced8b4707755864a0492Ying Wang LayerAnimationController* controller_impl) { 99951a39d68df598db08dfced8b4707755864a0492Ying Wang DCHECK(this != controller_impl); 100951a39d68df598db08dfced8b4707755864a0492Ying Wang if (force_sync_) { 101951a39d68df598db08dfced8b4707755864a0492Ying Wang ReplaceImplThreadAnimations(controller_impl); 102951a39d68df598db08dfced8b4707755864a0492Ying Wang force_sync_ = false; 103951a39d68df598db08dfced8b4707755864a0492Ying Wang } else { 104951a39d68df598db08dfced8b4707755864a0492Ying Wang PurgeAnimationsMarkedForDeletion(); 105951a39d68df598db08dfced8b4707755864a0492Ying Wang PushNewAnimationsToImplThread(controller_impl); 106951a39d68df598db08dfced8b4707755864a0492Ying Wang 107951a39d68df598db08dfced8b4707755864a0492Ying Wang // Remove finished impl side animations only after pushing, 108951a39d68df598db08dfced8b4707755864a0492Ying Wang // and only after the animations are deleted on the main thread 109951a39d68df598db08dfced8b4707755864a0492Ying Wang // this insures we will never push an animation twice. 110951a39d68df598db08dfced8b4707755864a0492Ying Wang RemoveAnimationsCompletedOnMainThread(controller_impl); 111951a39d68df598db08dfced8b4707755864a0492Ying Wang 112951a39d68df598db08dfced8b4707755864a0492Ying Wang PushPropertiesToImplThread(controller_impl); 113951a39d68df598db08dfced8b4707755864a0492Ying Wang } 114951a39d68df598db08dfced8b4707755864a0492Ying Wang controller_impl->UpdateActivation(NormalActivation); 115951a39d68df598db08dfced8b4707755864a0492Ying Wang UpdateActivation(NormalActivation); 116951a39d68df598db08dfced8b4707755864a0492Ying Wang} 117951a39d68df598db08dfced8b4707755864a0492Ying Wang 118951a39d68df598db08dfced8b4707755864a0492Ying Wangvoid LayerAnimationController::Animate(double monotonic_time) { 119951a39d68df598db08dfced8b4707755864a0492Ying Wang if (!HasValueObserver()) 120951a39d68df598db08dfced8b4707755864a0492Ying Wang return; 121951a39d68df598db08dfced8b4707755864a0492Ying Wang 122951a39d68df598db08dfced8b4707755864a0492Ying Wang StartAnimationsWaitingForNextTick(monotonic_time); 123951a39d68df598db08dfced8b4707755864a0492Ying Wang StartAnimationsWaitingForStartTime(monotonic_time); 124951a39d68df598db08dfced8b4707755864a0492Ying Wang StartAnimationsWaitingForTargetAvailability(monotonic_time); 125951a39d68df598db08dfced8b4707755864a0492Ying Wang ResolveConflicts(monotonic_time); 126951a39d68df598db08dfced8b4707755864a0492Ying Wang TickAnimations(monotonic_time); 127951a39d68df598db08dfced8b4707755864a0492Ying Wang last_tick_time_ = monotonic_time; 128951a39d68df598db08dfced8b4707755864a0492Ying Wang} 129951a39d68df598db08dfced8b4707755864a0492Ying Wang 130951a39d68df598db08dfced8b4707755864a0492Ying Wangvoid LayerAnimationController::AccumulatePropertyUpdates( 131951a39d68df598db08dfced8b4707755864a0492Ying Wang double monotonic_time, 132951a39d68df598db08dfced8b4707755864a0492Ying Wang AnimationEventsVector* events) { 133951a39d68df598db08dfced8b4707755864a0492Ying Wang if (!events) 134951a39d68df598db08dfced8b4707755864a0492Ying Wang return; 135951a39d68df598db08dfced8b4707755864a0492Ying Wang 136951a39d68df598db08dfced8b4707755864a0492Ying Wang for (size_t i = 0; i < active_animations_.size(); ++i) { 137951a39d68df598db08dfced8b4707755864a0492Ying Wang Animation* animation = active_animations_[i]; 138951a39d68df598db08dfced8b4707755864a0492Ying Wang if (!animation->is_impl_only()) 139951a39d68df598db08dfced8b4707755864a0492Ying Wang continue; 140951a39d68df598db08dfced8b4707755864a0492Ying Wang 141951a39d68df598db08dfced8b4707755864a0492Ying Wang switch (animation->target_property()) { 142951a39d68df598db08dfced8b4707755864a0492Ying Wang case Animation::Opacity: { 143951a39d68df598db08dfced8b4707755864a0492Ying Wang AnimationEvent event(AnimationEvent::PropertyUpdate, 144951a39d68df598db08dfced8b4707755864a0492Ying Wang id_, 145951a39d68df598db08dfced8b4707755864a0492Ying Wang animation->group(), 146951a39d68df598db08dfced8b4707755864a0492Ying Wang Animation::Opacity, 147951a39d68df598db08dfced8b4707755864a0492Ying Wang monotonic_time); 148951a39d68df598db08dfced8b4707755864a0492Ying Wang event.opacity = animation->curve()->ToFloatAnimationCurve()->GetValue( 149951a39d68df598db08dfced8b4707755864a0492Ying Wang monotonic_time); 150951a39d68df598db08dfced8b4707755864a0492Ying Wang event.is_impl_only = true; 151951a39d68df598db08dfced8b4707755864a0492Ying Wang events->push_back(event); 152951a39d68df598db08dfced8b4707755864a0492Ying Wang break; 153951a39d68df598db08dfced8b4707755864a0492Ying Wang } 154951a39d68df598db08dfced8b4707755864a0492Ying Wang 155951a39d68df598db08dfced8b4707755864a0492Ying Wang case Animation::Transform: { 156951a39d68df598db08dfced8b4707755864a0492Ying Wang AnimationEvent event(AnimationEvent::PropertyUpdate, 157951a39d68df598db08dfced8b4707755864a0492Ying Wang id_, 158951a39d68df598db08dfced8b4707755864a0492Ying Wang animation->group(), 159951a39d68df598db08dfced8b4707755864a0492Ying Wang Animation::Transform, 160951a39d68df598db08dfced8b4707755864a0492Ying Wang monotonic_time); 161951a39d68df598db08dfced8b4707755864a0492Ying Wang event.transform = 162951a39d68df598db08dfced8b4707755864a0492Ying Wang animation->curve()->ToTransformAnimationCurve()->GetValue( 163951a39d68df598db08dfced8b4707755864a0492Ying Wang monotonic_time); 164951a39d68df598db08dfced8b4707755864a0492Ying Wang event.is_impl_only = true; 165951a39d68df598db08dfced8b4707755864a0492Ying Wang events->push_back(event); 166951a39d68df598db08dfced8b4707755864a0492Ying Wang break; 167951a39d68df598db08dfced8b4707755864a0492Ying Wang } 168951a39d68df598db08dfced8b4707755864a0492Ying Wang 169951a39d68df598db08dfced8b4707755864a0492Ying Wang case Animation::Filter: { 170951a39d68df598db08dfced8b4707755864a0492Ying Wang AnimationEvent event(AnimationEvent::PropertyUpdate, 171951a39d68df598db08dfced8b4707755864a0492Ying Wang id_, 172951a39d68df598db08dfced8b4707755864a0492Ying Wang animation->group(), 173 Animation::Filter, 174 monotonic_time); 175 event.filters = animation->curve()->ToFilterAnimationCurve()->GetValue( 176 monotonic_time); 177 event.is_impl_only = true; 178 events->push_back(event); 179 break; 180 } 181 182 case Animation::BackgroundColor: { break; } 183 184 case Animation::TargetPropertyEnumSize: 185 NOTREACHED(); 186 } 187 } 188} 189 190void LayerAnimationController::UpdateState(bool start_ready_animations, 191 AnimationEventsVector* events) { 192 if (!HasActiveValueObserver()) 193 return; 194 195 if (start_ready_animations) 196 PromoteStartedAnimations(last_tick_time_, events); 197 198 MarkFinishedAnimations(last_tick_time_); 199 MarkAnimationsForDeletion(last_tick_time_, events); 200 201 if (start_ready_animations) { 202 StartAnimationsWaitingForTargetAvailability(last_tick_time_); 203 PromoteStartedAnimations(last_tick_time_, events); 204 } 205 206 AccumulatePropertyUpdates(last_tick_time_, events); 207 208 UpdateActivation(NormalActivation); 209} 210 211void LayerAnimationController::AddAnimation(scoped_ptr<Animation> animation) { 212 active_animations_.push_back(animation.Pass()); 213 UpdateActivation(NormalActivation); 214} 215 216Animation* LayerAnimationController::GetAnimation( 217 int group_id, 218 Animation::TargetProperty target_property) const { 219 for (size_t i = 0; i < active_animations_.size(); ++i) 220 if (active_animations_[i]->group() == group_id && 221 active_animations_[i]->target_property() == target_property) 222 return active_animations_[i]; 223 return 0; 224} 225 226Animation* LayerAnimationController::GetAnimation( 227 Animation::TargetProperty target_property) const { 228 for (size_t i = 0; i < active_animations_.size(); ++i) { 229 size_t index = active_animations_.size() - i - 1; 230 if (active_animations_[index]->target_property() == target_property) 231 return active_animations_[index]; 232 } 233 return 0; 234} 235 236bool LayerAnimationController::HasActiveAnimation() const { 237 for (size_t i = 0; i < active_animations_.size(); ++i) { 238 if (!active_animations_[i]->is_finished()) 239 return true; 240 } 241 return false; 242} 243 244bool LayerAnimationController::IsAnimatingProperty( 245 Animation::TargetProperty target_property) const { 246 for (size_t i = 0; i < active_animations_.size(); ++i) { 247 if (!active_animations_[i]->is_finished() && 248 active_animations_[i]->target_property() == target_property) 249 return true; 250 } 251 return false; 252} 253 254void LayerAnimationController::SetAnimationRegistrar( 255 AnimationRegistrar* registrar) { 256 if (registrar_ == registrar) 257 return; 258 259 if (registrar_) 260 registrar_->UnregisterAnimationController(this); 261 262 registrar_ = registrar; 263 if (registrar_) 264 registrar_->RegisterAnimationController(this); 265 266 UpdateActivation(ForceActivation); 267} 268 269void LayerAnimationController::NotifyAnimationStarted( 270 const AnimationEvent& event, 271 double wall_clock_time) { 272 if (event.is_impl_only) { 273 FOR_EACH_OBSERVER(LayerAnimationEventObserver, event_observers_, 274 OnAnimationStarted(event)); 275 if (layer_animation_delegate_) 276 layer_animation_delegate_->NotifyAnimationStarted(wall_clock_time); 277 278 return; 279 } 280 281 for (size_t i = 0; i < active_animations_.size(); ++i) { 282 if (active_animations_[i]->group() == event.group_id && 283 active_animations_[i]->target_property() == event.target_property && 284 active_animations_[i]->needs_synchronized_start_time()) { 285 active_animations_[i]->set_needs_synchronized_start_time(false); 286 active_animations_[i]->set_start_time(event.monotonic_time); 287 288 FOR_EACH_OBSERVER(LayerAnimationEventObserver, event_observers_, 289 OnAnimationStarted(event)); 290 if (layer_animation_delegate_) 291 layer_animation_delegate_->NotifyAnimationStarted(wall_clock_time); 292 293 return; 294 } 295 } 296} 297 298void LayerAnimationController::NotifyAnimationFinished( 299 const AnimationEvent& event, 300 double wall_clock_time) { 301 if (event.is_impl_only) { 302 if (layer_animation_delegate_) 303 layer_animation_delegate_->NotifyAnimationFinished(wall_clock_time); 304 return; 305 } 306 307 for (size_t i = 0; i < active_animations_.size(); ++i) { 308 if (active_animations_[i]->group() == event.group_id && 309 active_animations_[i]->target_property() == event.target_property) { 310 active_animations_[i]->set_received_finished_event(true); 311 if (layer_animation_delegate_) 312 layer_animation_delegate_->NotifyAnimationFinished(wall_clock_time); 313 314 return; 315 } 316 } 317} 318 319void LayerAnimationController::NotifyAnimationPropertyUpdate( 320 const AnimationEvent& event) { 321 switch (event.target_property) { 322 case Animation::Opacity: 323 NotifyObserversOpacityAnimated(event.opacity); 324 break; 325 case Animation::Transform: 326 NotifyObserversTransformAnimated(event.transform); 327 break; 328 default: 329 NOTREACHED(); 330 } 331} 332 333void LayerAnimationController::AddValueObserver( 334 LayerAnimationValueObserver* observer) { 335 if (!value_observers_.HasObserver(observer)) 336 value_observers_.AddObserver(observer); 337} 338 339void LayerAnimationController::RemoveValueObserver( 340 LayerAnimationValueObserver* observer) { 341 value_observers_.RemoveObserver(observer); 342} 343 344void LayerAnimationController::AddEventObserver( 345 LayerAnimationEventObserver* observer) { 346 if (!event_observers_.HasObserver(observer)) 347 event_observers_.AddObserver(observer); 348} 349 350void LayerAnimationController::RemoveEventObserver( 351 LayerAnimationEventObserver* observer) { 352 event_observers_.RemoveObserver(observer); 353} 354 355bool LayerAnimationController::AnimatedBoundsForBox(const gfx::BoxF& box, 356 gfx::BoxF* bounds) { 357 // Compute bounds based on animations for which is_finished() is false. 358 // Do nothing if there are no such animations; in this case, it is assumed 359 // that callers will take care of computing bounds based on the owning layer's 360 // actual transform. 361 *bounds = gfx::BoxF(); 362 for (size_t i = 0; i < active_animations_.size(); ++i) { 363 if (active_animations_[i]->is_finished() || 364 active_animations_[i]->target_property() != Animation::Transform) 365 continue; 366 367 const TransformAnimationCurve* transform_animation_curve = 368 active_animations_[i]->curve()->ToTransformAnimationCurve(); 369 gfx::BoxF animation_bounds; 370 bool success = 371 transform_animation_curve->AnimatedBoundsForBox(box, &animation_bounds); 372 if (!success) 373 return false; 374 bounds->Union(animation_bounds); 375 } 376 377 return true; 378} 379 380void LayerAnimationController::PushNewAnimationsToImplThread( 381 LayerAnimationController* controller_impl) const { 382 // Any new animations owned by the main thread's controller are cloned and 383 // add to the impl thread's controller. 384 for (size_t i = 0; i < active_animations_.size(); ++i) { 385 // If the animation is already running on the impl thread, there is no 386 // need to copy it over. 387 if (controller_impl->GetAnimation(active_animations_[i]->group(), 388 active_animations_[i]->target_property())) 389 continue; 390 391 // If the animation is not running on the impl thread, it does not 392 // necessarily mean that it needs to be copied over and started; it may 393 // have already finished. In this case, the impl thread animation will 394 // have already notified that it has started and the main thread animation 395 // will no longer need 396 // a synchronized start time. 397 if (!active_animations_[i]->needs_synchronized_start_time()) 398 continue; 399 400 // The new animation should be set to run as soon as possible. 401 Animation::RunState initial_run_state = 402 Animation::WaitingForTargetAvailability; 403 double start_time = 0; 404 scoped_ptr<Animation> to_add(active_animations_[i]->CloneAndInitialize( 405 initial_run_state, start_time)); 406 DCHECK(!to_add->needs_synchronized_start_time()); 407 controller_impl->AddAnimation(to_add.Pass()); 408 } 409} 410 411struct IsCompleted { 412 explicit IsCompleted(const LayerAnimationController& main_thread_controller) 413 : main_thread_controller_(main_thread_controller) {} 414 bool operator()(Animation* animation) const { 415 if (animation->is_impl_only()) { 416 return (animation->run_state() == Animation::WaitingForDeletion); 417 } else { 418 return !main_thread_controller_.GetAnimation( 419 animation->group(), 420 animation->target_property()); 421 } 422 } 423 424 private: 425 const LayerAnimationController& main_thread_controller_; 426}; 427 428void LayerAnimationController::RemoveAnimationsCompletedOnMainThread( 429 LayerAnimationController* controller_impl) const { 430 // Delete all impl thread animations for which there is no corresponding 431 // main thread animation. Each iteration, 432 // controller->active_animations_.size() is decremented or i is incremented 433 // guaranteeing progress towards loop termination. 434 ScopedPtrVector<Animation>& animations = 435 controller_impl->active_animations_; 436 animations.erase(cc::remove_if(&animations, 437 animations.begin(), 438 animations.end(), 439 IsCompleted(*this)), 440 animations.end()); 441} 442 443void LayerAnimationController::PushPropertiesToImplThread( 444 LayerAnimationController* controller_impl) const { 445 for (size_t i = 0; i < active_animations_.size(); ++i) { 446 Animation* current_impl = 447 controller_impl->GetAnimation( 448 active_animations_[i]->group(), 449 active_animations_[i]->target_property()); 450 if (current_impl) 451 active_animations_[i]->PushPropertiesTo(current_impl); 452 } 453} 454 455void LayerAnimationController::StartAnimationsWaitingForNextTick( 456 double monotonic_time) { 457 for (size_t i = 0; i < active_animations_.size(); ++i) { 458 if (active_animations_[i]->run_state() == Animation::WaitingForNextTick) 459 active_animations_[i]->SetRunState(Animation::Starting, monotonic_time); 460 } 461} 462 463void LayerAnimationController::StartAnimationsWaitingForStartTime( 464 double monotonic_time) { 465 for (size_t i = 0; i < active_animations_.size(); ++i) { 466 if (active_animations_[i]->run_state() == Animation::WaitingForStartTime && 467 active_animations_[i]->start_time() <= monotonic_time) 468 active_animations_[i]->SetRunState(Animation::Starting, monotonic_time); 469 } 470} 471 472void LayerAnimationController::StartAnimationsWaitingForTargetAvailability( 473 double monotonic_time) { 474 // First collect running properties. 475 TargetProperties blocked_properties; 476 for (size_t i = 0; i < active_animations_.size(); ++i) { 477 if (active_animations_[i]->run_state() == Animation::Starting || 478 active_animations_[i]->run_state() == Animation::Running) 479 blocked_properties.insert(active_animations_[i]->target_property()); 480 } 481 482 for (size_t i = 0; i < active_animations_.size(); ++i) { 483 if (active_animations_[i]->run_state() == 484 Animation::WaitingForTargetAvailability) { 485 // Collect all properties for animations with the same group id (they 486 // should all also be in the list of animations). 487 TargetProperties enqueued_properties; 488 enqueued_properties.insert(active_animations_[i]->target_property()); 489 for (size_t j = i + 1; j < active_animations_.size(); ++j) { 490 if (active_animations_[i]->group() == active_animations_[j]->group()) 491 enqueued_properties.insert(active_animations_[j]->target_property()); 492 } 493 494 // Check to see if intersection of the list of properties affected by 495 // the group and the list of currently blocked properties is null. In 496 // any case, the group's target properties need to be added to the list 497 // of blocked properties. 498 bool null_intersection = true; 499 for (TargetProperties::iterator p_iter = enqueued_properties.begin(); 500 p_iter != enqueued_properties.end(); 501 ++p_iter) { 502 if (!blocked_properties.insert(*p_iter).second) 503 null_intersection = false; 504 } 505 506 // If the intersection is null, then we are free to start the animations 507 // in the group. 508 if (null_intersection) { 509 active_animations_[i]->SetRunState( 510 Animation::Starting, monotonic_time); 511 for (size_t j = i + 1; j < active_animations_.size(); ++j) { 512 if (active_animations_[i]->group() == 513 active_animations_[j]->group()) { 514 active_animations_[j]->SetRunState( 515 Animation::Starting, monotonic_time); 516 } 517 } 518 } 519 } 520 } 521} 522 523void LayerAnimationController::PromoteStartedAnimations( 524 double monotonic_time, 525 AnimationEventsVector* events) { 526 for (size_t i = 0; i < active_animations_.size(); ++i) { 527 if (active_animations_[i]->run_state() == Animation::Starting) { 528 active_animations_[i]->SetRunState(Animation::Running, monotonic_time); 529 if (!active_animations_[i]->has_set_start_time()) 530 active_animations_[i]->set_start_time(monotonic_time); 531 if (events) { 532 AnimationEvent started_event( 533 AnimationEvent::Started, 534 id_, 535 active_animations_[i]->group(), 536 active_animations_[i]->target_property(), 537 monotonic_time); 538 started_event.is_impl_only = active_animations_[i]->is_impl_only(); 539 events->push_back(started_event); 540 } 541 } 542 } 543} 544 545void LayerAnimationController::MarkFinishedAnimations(double monotonic_time) { 546 for (size_t i = 0; i < active_animations_.size(); ++i) { 547 if (active_animations_[i]->IsFinishedAt(monotonic_time) && 548 active_animations_[i]->run_state() != Animation::WaitingForDeletion) 549 active_animations_[i]->SetRunState(Animation::Finished, monotonic_time); 550 } 551} 552 553void LayerAnimationController::ResolveConflicts(double monotonic_time) { 554 // Find any animations that are animating the same property and resolve the 555 // confict. We could eventually blend, but for now we'll just abort the 556 // previous animation (where 'previous' means: (1) has a prior start time or 557 // (2) has an equal start time, but was added to the queue earlier, i.e., 558 // has a lower index in active_animations_). 559 for (size_t i = 0; i < active_animations_.size(); ++i) { 560 if (active_animations_[i]->run_state() == Animation::Starting || 561 active_animations_[i]->run_state() == Animation::Running) { 562 for (size_t j = i + 1; j < active_animations_.size(); ++j) { 563 if ((active_animations_[j]->run_state() == Animation::Starting || 564 active_animations_[j]->run_state() == Animation::Running) && 565 active_animations_[i]->target_property() == 566 active_animations_[j]->target_property()) { 567 if (active_animations_[i]->start_time() > 568 active_animations_[j]->start_time()) { 569 active_animations_[j]->SetRunState(Animation::Aborted, 570 monotonic_time); 571 } else { 572 active_animations_[i]->SetRunState(Animation::Aborted, 573 monotonic_time); 574 } 575 } 576 } 577 } 578 } 579} 580 581void LayerAnimationController::MarkAnimationsForDeletion( 582 double monotonic_time, AnimationEventsVector* events) { 583 // Non-aborted animations are marked for deletion after a corresponding 584 // AnimationEvent::Finished event is sent or received. This means that if 585 // we don't have an events vector, we must ensure that non-aborted animations 586 // have received a finished event before marking them for deletion. 587 for (size_t i = 0; i < active_animations_.size(); i++) { 588 int group_id = active_animations_[i]->group(); 589 bool all_anims_with_same_id_are_finished = false; 590 591 // Since deleting an animation on the main thread leads to its deletion 592 // on the impl thread, we only mark a Finished main thread animation for 593 // deletion once it has received a Finished event from the impl thread. 594 bool animation_i_will_send_or_has_received_finish_event = 595 events || active_animations_[i]->received_finished_event(); 596 // If an animation is finished, and not already marked for deletion, 597 // find out if all other animations in the same group are also finished. 598 if (active_animations_[i]->run_state() == Animation::Aborted || 599 (active_animations_[i]->run_state() == Animation::Finished && 600 animation_i_will_send_or_has_received_finish_event)) { 601 all_anims_with_same_id_are_finished = true; 602 for (size_t j = 0; j < active_animations_.size(); ++j) { 603 bool animation_j_will_send_or_has_received_finish_event = 604 events || active_animations_[j]->received_finished_event(); 605 if (group_id == active_animations_[j]->group() && 606 (!active_animations_[j]->is_finished() || 607 (active_animations_[j]->run_state() == Animation::Finished && 608 !animation_j_will_send_or_has_received_finish_event))) { 609 all_anims_with_same_id_are_finished = false; 610 break; 611 } 612 } 613 } 614 if (all_anims_with_same_id_are_finished) { 615 // We now need to remove all animations with the same group id as 616 // group_id (and send along animation finished notifications, if 617 // necessary). 618 for (size_t j = i; j < active_animations_.size(); j++) { 619 if (group_id == active_animations_[j]->group()) { 620 if (events) { 621 AnimationEvent finished_event( 622 AnimationEvent::Finished, 623 id_, 624 active_animations_[j]->group(), 625 active_animations_[j]->target_property(), 626 monotonic_time); 627 finished_event.is_impl_only = active_animations_[j]->is_impl_only(); 628 events->push_back(finished_event); 629 } 630 active_animations_[j]->SetRunState(Animation::WaitingForDeletion, 631 monotonic_time); 632 } 633 } 634 } 635 } 636} 637 638static bool IsWaitingForDeletion(Animation* animation) { 639 return animation->run_state() == Animation::WaitingForDeletion; 640} 641 642void LayerAnimationController::PurgeAnimationsMarkedForDeletion() { 643 ScopedPtrVector<Animation>& animations = active_animations_; 644 animations.erase(cc::remove_if(&animations, 645 animations.begin(), 646 animations.end(), 647 IsWaitingForDeletion), 648 animations.end()); 649} 650 651void LayerAnimationController::ReplaceImplThreadAnimations( 652 LayerAnimationController* controller_impl) const { 653 controller_impl->active_animations_.clear(); 654 for (size_t i = 0; i < active_animations_.size(); ++i) { 655 scoped_ptr<Animation> to_add; 656 if (active_animations_[i]->needs_synchronized_start_time()) { 657 // We haven't received an animation started notification yet, so it 658 // is important that we add it in a 'waiting' and not 'running' state. 659 Animation::RunState initial_run_state = 660 Animation::WaitingForTargetAvailability; 661 double start_time = 0; 662 to_add = active_animations_[i]->CloneAndInitialize( 663 initial_run_state, start_time).Pass(); 664 } else { 665 to_add = active_animations_[i]->Clone().Pass(); 666 } 667 668 controller_impl->AddAnimation(to_add.Pass()); 669 } 670} 671 672void LayerAnimationController::TickAnimations(double monotonic_time) { 673 for (size_t i = 0; i < active_animations_.size(); ++i) { 674 if (active_animations_[i]->run_state() == Animation::Starting || 675 active_animations_[i]->run_state() == Animation::Running || 676 active_animations_[i]->run_state() == Animation::Paused) { 677 double trimmed = 678 active_animations_[i]->TrimTimeToCurrentIteration(monotonic_time); 679 680 switch (active_animations_[i]->target_property()) { 681 case Animation::Transform: { 682 const TransformAnimationCurve* transform_animation_curve = 683 active_animations_[i]->curve()->ToTransformAnimationCurve(); 684 const gfx::Transform transform = 685 transform_animation_curve->GetValue(trimmed); 686 NotifyObserversTransformAnimated(transform); 687 break; 688 } 689 690 case Animation::Opacity: { 691 const FloatAnimationCurve* float_animation_curve = 692 active_animations_[i]->curve()->ToFloatAnimationCurve(); 693 const float opacity = float_animation_curve->GetValue(trimmed); 694 NotifyObserversOpacityAnimated(opacity); 695 break; 696 } 697 698 case Animation::Filter: { 699 const FilterAnimationCurve* filter_animation_curve = 700 active_animations_[i]->curve()->ToFilterAnimationCurve(); 701 const FilterOperations filter = 702 filter_animation_curve->GetValue(trimmed); 703 NotifyObserversFilterAnimated(filter); 704 break; 705 } 706 707 case Animation::BackgroundColor: { 708 // Not yet implemented. 709 break; 710 } 711 712 // Do nothing for sentinel value. 713 case Animation::TargetPropertyEnumSize: 714 NOTREACHED(); 715 } 716 } 717 } 718} 719 720void LayerAnimationController::UpdateActivation(UpdateActivationType type) { 721 bool force = type == ForceActivation; 722 if (registrar_) { 723 if (!active_animations_.empty() && (!is_active_ || force)) 724 registrar_->DidActivateAnimationController(this); 725 else if (active_animations_.empty() && (is_active_ || force)) 726 registrar_->DidDeactivateAnimationController(this); 727 is_active_ = !active_animations_.empty(); 728 } 729} 730 731void LayerAnimationController::NotifyObserversOpacityAnimated(float opacity) { 732 FOR_EACH_OBSERVER(LayerAnimationValueObserver, 733 value_observers_, 734 OnOpacityAnimated(opacity)); 735} 736 737void LayerAnimationController::NotifyObserversTransformAnimated( 738 const gfx::Transform& transform) { 739 FOR_EACH_OBSERVER(LayerAnimationValueObserver, 740 value_observers_, 741 OnTransformAnimated(transform)); 742} 743 744void LayerAnimationController::NotifyObserversFilterAnimated( 745 const FilterOperations& filters) { 746 FOR_EACH_OBSERVER(LayerAnimationValueObserver, 747 value_observers_, 748 OnFilterAnimated(filters)); 749} 750 751bool LayerAnimationController::HasValueObserver() { 752 if (value_observers_.might_have_observers()) { 753 ObserverListBase<LayerAnimationValueObserver>::Iterator it( 754 value_observers_); 755 return it.GetNext() != NULL; 756 } 757 return false; 758} 759 760bool LayerAnimationController::HasActiveValueObserver() { 761 if (value_observers_.might_have_observers()) { 762 ObserverListBase<LayerAnimationValueObserver>::Iterator it( 763 value_observers_); 764 LayerAnimationValueObserver* obs; 765 while ((obs = it.GetNext()) != NULL) 766 if (obs->IsActive()) 767 return true; 768 } 769 return false; 770} 771 772} // namespace cc 773