12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright 2012 The Chromium Authors. All rights reserved. 22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file. 42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/animation/animation.h" 62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <cmath> 82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/debug/trace_event.h" 10868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_util.h" 112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/animation/animation_curve.h" 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace { 142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// This should match the RunState enum. 162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static const char* const s_runStateNames[] = { 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "WaitingForTargetAvailability", 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "WaitingForDeletion", 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "Starting", 202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "Running", 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "Paused", 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "Finished", 232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "Aborted" 242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)COMPILE_ASSERT(static_cast<int>(cc::Animation::RunStateEnumSize) == 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) arraysize(s_runStateNames), 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RunState_names_match_enum); 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// This should match the TargetProperty enum. 312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static const char* const s_targetPropertyNames[] = { 322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "Transform", 334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) "Opacity", 341e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) "Filter", 355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) "ScrollOffset", 365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) "BackgroundColor" 372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)COMPILE_ASSERT(static_cast<int>(cc::Animation::TargetPropertyEnumSize) == 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) arraysize(s_targetPropertyNames), 412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TargetProperty_names_match_enum); 422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace cc { 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)scoped_ptr<Animation> Animation::Create( 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<AnimationCurve> curve, 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int animation_id, 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int group_id, 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TargetProperty target_property) { 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return make_scoped_ptr(new Animation(curve.Pass(), 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) animation_id, 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) group_id, 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) target_property)); } 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Animation::Animation(scoped_ptr<AnimationCurve> curve, 582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int animation_id, 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int group_id, 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TargetProperty target_property) 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : curve_(curve.Pass()), 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) id_(animation_id), 632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) group_(group_id), 642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) target_property_(target_property), 652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) run_state_(WaitingForTargetAvailability), 662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) iterations_(1), 671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci iteration_start_(0), 68010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) direction_(Normal), 6903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) playback_rate_(1), 701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci fill_mode_(FillModeBoth), 712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) needs_synchronized_start_time_(false), 72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) received_finished_event_(false), 732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) suspended_(false), 742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) is_controlling_instance_(false), 755c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu is_impl_only_(false), 765c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu affects_active_observers_(true), 775c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu affects_pending_observers_(true) { 785c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu} 792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Animation::~Animation() { 812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (run_state_ == Running || run_state_ == Paused) 82cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) SetRunState(Aborted, base::TimeTicks()); 832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 85cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void Animation::SetRunState(RunState run_state, 86cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::TimeTicks monotonic_time) { 872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (suspended_) 882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) char name_buffer[256]; 912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::snprintf(name_buffer, 922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) sizeof(name_buffer), 932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "%s-%d%s", 942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) s_targetPropertyNames[target_property_], 952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) group_, 962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) is_controlling_instance_ ? "(impl)" : ""); 972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 98f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) bool is_waiting_to_start = run_state_ == WaitingForTargetAvailability || 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) run_state_ == Starting; 1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (is_waiting_to_start && run_state == Running) { 1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_EVENT_ASYNC_BEGIN1( 1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "cc", "Animation", this, "Name", TRACE_STR_COPY(name_buffer)); 1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool was_finished = is_finished(); 1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const char* old_run_state_name = s_runStateNames[run_state_]; 1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (run_state == Running && run_state_ == Paused) 111cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) total_paused_time_ += (monotonic_time - pause_time_); 1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) else if (run_state == Paused) 1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) pause_time_ = monotonic_time; 1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) run_state_ = run_state; 1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const char* new_run_state_name = s_runStateNames[run_state]; 1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!was_finished && is_finished()) 1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_EVENT_ASYNC_END0("cc", "Animation", this); 1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) char state_buffer[256]; 1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::snprintf(state_buffer, 1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) sizeof(state_buffer), 1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "%s->%s", 1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) old_run_state_name, 1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) new_run_state_name); 1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_EVENT_INSTANT2("cc", 1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "LayerAnimationController::SetRunState", 130c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) TRACE_EVENT_SCOPE_THREAD, 1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "Name", 1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_STR_COPY(name_buffer), 1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "State", 1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_STR_COPY(state_buffer)); 1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 137cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void Animation::Suspend(base::TimeTicks monotonic_time) { 1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SetRunState(Paused, monotonic_time); 1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) suspended_ = true; 1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 142cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void Animation::Resume(base::TimeTicks monotonic_time) { 1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) suspended_ = false; 1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SetRunState(Running, monotonic_time); 1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 147cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)bool Animation::IsFinishedAt(base::TimeTicks monotonic_time) const { 1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (is_finished()) 1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (needs_synchronized_start_time_) 1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 15403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (playback_rate_ == 0) 15503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) return false; 15603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 157cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return run_state_ == Running && iterations_ >= 0 && 15803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) iterations_ * curve_->Duration() / std::abs(playback_rate_) <= 159cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) (monotonic_time + time_offset_ - start_time_ - total_paused_time_) 160cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) .InSecondsF(); 1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibool Animation::InEffect(base::TimeTicks monotonic_time) const { 1641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return ConvertToActiveTime(monotonic_time) >= 0 || 1651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci (fill_mode_ == FillModeBoth || fill_mode_ == FillModeBackwards); 1661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccidouble Animation::ConvertToActiveTime(base::TimeTicks monotonic_time) const { 1691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::TimeTicks trimmed = monotonic_time + time_offset_; 17003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If we're paused, time is 'stuck' at the pause time. 1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (run_state_ == Paused) 1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) trimmed = pause_time_; 1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Returned time should always be relative to the start time and should 1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // subtract all time spent paused. 177cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) trimmed -= (start_time_ - base::TimeTicks()) + total_paused_time_; 1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 17958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // If we're just starting or we're waiting on receiving a start time, 18058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // time is 'stuck' at the initial state. 18158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if ((run_state_ == Starting && !has_set_start_time()) || 18258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) needs_synchronized_start_time()) 183cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) trimmed = base::TimeTicks() + time_offset_; 184cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 1851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return (trimmed - base::TimeTicks()).InSecondsF(); 1861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 1871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccidouble Animation::TrimTimeToCurrentIteration( 1891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::TimeTicks monotonic_time) const { 1901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Check for valid parameters 1911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(playback_rate_); 1921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK_GE(iteration_start_, 0); 1931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci double active_time = ConvertToActiveTime(monotonic_time); 195ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch double start_offset = iteration_start_ * curve_->Duration(); 19658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 197ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch // Return start offset if we are before the start of the animation 1981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (active_time < 0) 199ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch return start_offset; 2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Always return zero if we have no iterations. 2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!iterations_) 2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return 0; 2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Don't attempt to trim if we have no duration. 2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (curve_->Duration() <= 0) 2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return 0; 2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci double repeated_duration = iterations_ * curve_->Duration(); 2101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci double active_duration = repeated_duration / std::abs(playback_rate_); 2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Check if we are past active duration 2131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (iterations_ > 0 && active_time >= active_duration) 2141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci active_time = active_duration; 215010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 2161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Calculate the scaled active time 2171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci double scaled_active_time; 2181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (playback_rate_ < 0) 2191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scaled_active_time = 2201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci (active_time - active_duration) * playback_rate_ + start_offset; 2211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci else 2221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scaled_active_time = active_time * playback_rate_ + start_offset; 2231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Calculate the iteration time 2251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci double iteration_time; 2261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (scaled_active_time - start_offset == repeated_duration && 2271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci fmod(iterations_ + iteration_start_, 1) == 0) 2281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci iteration_time = curve_->Duration(); 2291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci else 2301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci iteration_time = fmod(scaled_active_time, curve_->Duration()); 2311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Calculate the current iteration 2331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci int iteration; 2341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (scaled_active_time <= 0) 2351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci iteration = 0; 2361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci else if (iteration_time == curve_->Duration()) 2371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci iteration = ceil(iteration_start_ + iterations_ - 1); 2381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci else 2391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci iteration = static_cast<int>(scaled_active_time / curve_->Duration()); 2401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Check if we are running the animation in reverse direction for the current 242010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // iteration 243010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) bool reverse = (direction_ == Reverse) || 244010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) (direction_ == Alternate && iteration % 2 == 1) || 245010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) (direction_ == AlternateReverse && iteration % 2 == 0); 2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // If we are running the animation in reverse direction, reverse the result 248010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (reverse) 2491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci iteration_time = curve_->Duration() - iteration_time; 2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return iteration_time; 2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 254c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochscoped_ptr<Animation> Animation::CloneAndInitialize( 255c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch RunState initial_run_state) const { 2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<Animation> to_return( 2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) new Animation(curve_->Clone(), id_, group_, target_property_)); 2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) to_return->run_state_ = initial_run_state; 2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) to_return->iterations_ = iterations_; 2601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci to_return->iteration_start_ = iteration_start_; 261c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch to_return->start_time_ = start_time_; 2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) to_return->pause_time_ = pause_time_; 2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) to_return->total_paused_time_ = total_paused_time_; 2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) to_return->time_offset_ = time_offset_; 265010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) to_return->direction_ = direction_; 26603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) to_return->playback_rate_ = playback_rate_; 2671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci to_return->fill_mode_ = fill_mode_; 2688bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) DCHECK(!to_return->is_controlling_instance_); 2698bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) to_return->is_controlling_instance_ = true; 2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return to_return.Pass(); 2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void Animation::PushPropertiesTo(Animation* other) const { 2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Currently, we only push changes due to pausing and resuming animations on 2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // the main thread. 2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (run_state_ == Animation::Paused || 2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) other->run_state_ == Animation::Paused) { 2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) other->run_state_ = run_state_; 2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) other->pause_time_ = pause_time_; 2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) other->total_paused_time_ = total_paused_time_; 2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace cc 285