animation_builder.cc 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360
  1. // Copyright 2021 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "ui/views/animation/animation_builder.h"
  5. #include <algorithm>
  6. #include <tuple>
  7. #include <utility>
  8. #include <vector>
  9. #include "base/callback.h"
  10. #include "base/check_op.h"
  11. #include "base/memory/ptr_util.h"
  12. #include "base/no_destructor.h"
  13. #include "base/ranges/algorithm.h"
  14. #include "base/time/time.h"
  15. #include "ui/compositor/layer.h"
  16. #include "ui/compositor/layer_animation_element.h"
  17. #include "ui/compositor/layer_animation_observer.h"
  18. #include "ui/compositor/layer_animation_sequence.h"
  19. #include "ui/compositor/layer_animator.h"
  20. #include "ui/compositor/layer_owner.h"
  21. #include "ui/compositor/scoped_layer_animation_settings.h"
  22. #include "ui/views/animation/animation_abort_handle.h"
  23. #include "ui/views/animation/animation_key.h"
  24. #include "ui/views/animation/animation_sequence_block.h"
  25. namespace views {
  26. AnimationBuilder::Observer::Observer() = default;
  27. AnimationBuilder::Observer::~Observer() {
  28. DCHECK(attached_to_sequence_)
  29. << "You must register callbacks and get abort handle before "
  30. << "creating a sequence block.";
  31. if (abort_handle_)
  32. abort_handle_->OnObserverDeleted();
  33. base::RepeatingClosure& on_observer_deleted =
  34. AnimationBuilder::GetObserverDeletedCallback();
  35. if (on_observer_deleted)
  36. on_observer_deleted.Run();
  37. }
  38. void AnimationBuilder::Observer::SetOnStarted(base::OnceClosure callback) {
  39. DCHECK(!on_started_);
  40. on_started_ = std::move(callback);
  41. }
  42. void AnimationBuilder::Observer::SetOnEnded(base::OnceClosure callback) {
  43. DCHECK(!on_ended_);
  44. on_ended_ = std::move(callback);
  45. }
  46. void AnimationBuilder::Observer::SetOnWillRepeat(
  47. base::RepeatingClosure callback) {
  48. DCHECK(!on_will_repeat_);
  49. on_will_repeat_ = std::move(callback);
  50. }
  51. void AnimationBuilder::Observer::SetOnAborted(base::OnceClosure callback) {
  52. DCHECK(!on_aborted_);
  53. on_aborted_ = std::move(callback);
  54. }
  55. void AnimationBuilder::Observer::SetOnScheduled(base::OnceClosure callback) {
  56. DCHECK(!on_scheduled_);
  57. on_scheduled_ = std::move(callback);
  58. }
  59. void AnimationBuilder::Observer::OnLayerAnimationStarted(
  60. ui::LayerAnimationSequence* sequence) {
  61. if (abort_handle_ && abort_handle_->animation_state() ==
  62. AnimationAbortHandle::AnimationState::kNotStarted) {
  63. abort_handle_->OnAnimationStarted();
  64. }
  65. if (on_started_)
  66. std::move(on_started_).Run();
  67. }
  68. void AnimationBuilder::Observer::SetAbortHandle(
  69. AnimationAbortHandle* abort_handle) {
  70. abort_handle_ = abort_handle;
  71. }
  72. void AnimationBuilder::Observer::OnLayerAnimationEnded(
  73. ui::LayerAnimationSequence* sequence) {
  74. if (--sequences_to_run_ == 0) {
  75. if (on_ended_)
  76. std::move(on_ended_).Run();
  77. if (abort_handle_ && abort_handle_->animation_state() ==
  78. AnimationAbortHandle::AnimationState::kRunning)
  79. abort_handle_->OnAnimationEnded();
  80. }
  81. }
  82. void AnimationBuilder::Observer::OnLayerAnimationWillRepeat(
  83. ui::LayerAnimationSequence* sequence) {
  84. if (!on_will_repeat_)
  85. return;
  86. // First time through, initialize the repeat_map_ with the sequences.
  87. if (repeat_map_.empty()) {
  88. for (auto* seq : attached_sequences())
  89. repeat_map_[seq] = 0;
  90. }
  91. // Only trigger the repeat callback on the last LayerAnimationSequence on
  92. // which this observer is attached.
  93. const int next_cycle = ++repeat_map_[sequence];
  94. if (base::ranges::none_of(
  95. repeat_map_, [next_cycle](int count) { return count < next_cycle; },
  96. &RepeatMap::value_type::second)) {
  97. on_will_repeat_.Run();
  98. }
  99. }
  100. void AnimationBuilder::Observer::OnLayerAnimationAborted(
  101. ui::LayerAnimationSequence* sequence) {
  102. if (on_aborted_)
  103. std::move(on_aborted_).Run();
  104. if (abort_handle_ && abort_handle_->animation_state() ==
  105. AnimationAbortHandle::AnimationState::kRunning)
  106. abort_handle_->OnAnimationEnded();
  107. }
  108. void AnimationBuilder::Observer::OnLayerAnimationScheduled(
  109. ui::LayerAnimationSequence* sequence) {
  110. if (on_scheduled_)
  111. std::move(on_scheduled_).Run();
  112. }
  113. void AnimationBuilder::Observer::OnAttachedToSequence(
  114. ui::LayerAnimationSequence* sequence) {
  115. ui::LayerAnimationObserver::OnAttachedToSequence(sequence);
  116. attached_to_sequence_ = true;
  117. sequences_to_run_++;
  118. }
  119. void AnimationBuilder::Observer::OnDetachedFromSequence(
  120. ui::LayerAnimationSequence* sequence) {
  121. if (attached_sequences().empty())
  122. delete this;
  123. }
  124. bool AnimationBuilder::Observer::RequiresNotificationWhenAnimatorDestroyed()
  125. const {
  126. return true;
  127. }
  128. struct AnimationBuilder::Value {
  129. base::TimeDelta start;
  130. // Save the original duration because the duration on the element can be a
  131. // scaled version. The scale can potentially be zero.
  132. base::TimeDelta original_duration;
  133. std::unique_ptr<ui::LayerAnimationElement> element;
  134. bool operator<(const Value& key) const {
  135. // Animations with zero duration need to be ordered before animations with
  136. // nonzero of the same start time to prevent the DCHECK from happening in
  137. // TerminateSequence(). These animations don't count as overlapping
  138. // properties.
  139. auto element_properties = element->properties();
  140. auto key_element_properties = key.element->properties();
  141. return std::tie(start, original_duration, element_properties) <
  142. std::tie(key.start, key.original_duration, key_element_properties);
  143. }
  144. };
  145. AnimationBuilder::AnimationBuilder() = default;
  146. AnimationBuilder::AnimationBuilder(AnimationBuilder&& rhs) = default;
  147. AnimationBuilder& AnimationBuilder::operator=(AnimationBuilder&& rhs) = default;
  148. AnimationBuilder::~AnimationBuilder() {
  149. // Terminate `current_sequence_` to complete layer animation configuration.
  150. current_sequence_.reset();
  151. DCHECK(!next_animation_observer_)
  152. << "Callbacks were scheduled without creating a sequence block "
  153. "afterwards. There are no animations to run these callbacks on.";
  154. // The observer needs to outlive the AnimationBuilder and will manage its own
  155. // lifetime. GetAttachedToSequence should not return false here. This is
  156. // DCHECKed in the observer’s destructor.
  157. if (animation_observer_ && animation_observer_->GetAttachedToSequence())
  158. animation_observer_.release();
  159. for (auto it = layer_animation_sequences_.begin();
  160. it != layer_animation_sequences_.end();) {
  161. auto* const target = it->first;
  162. auto end_it = layer_animation_sequences_.upper_bound(target);
  163. if (abort_handle_)
  164. abort_handle_->AddLayer(target);
  165. ui::ScopedLayerAnimationSettings settings(target->GetAnimator());
  166. if (preemption_strategy_)
  167. settings.SetPreemptionStrategy(preemption_strategy_.value());
  168. std::vector<ui::LayerAnimationSequence*> sequences;
  169. std::transform(it, end_it, std::back_inserter(sequences),
  170. [](auto& it) { return it.second.release(); });
  171. target->GetAnimator()->StartTogether(std::move(sequences));
  172. it = end_it;
  173. }
  174. }
  175. AnimationBuilder& AnimationBuilder::SetPreemptionStrategy(
  176. ui::LayerAnimator::PreemptionStrategy preemption_strategy) {
  177. preemption_strategy_ = preemption_strategy;
  178. return *this;
  179. }
  180. AnimationBuilder& AnimationBuilder::OnStarted(base::OnceClosure callback) {
  181. GetObserver()->SetOnStarted(std::move(callback));
  182. return *this;
  183. }
  184. AnimationBuilder& AnimationBuilder::OnEnded(base::OnceClosure callback) {
  185. GetObserver()->SetOnEnded(std::move(callback));
  186. return *this;
  187. }
  188. AnimationBuilder& AnimationBuilder::OnWillRepeat(
  189. base::RepeatingClosure callback) {
  190. GetObserver()->SetOnWillRepeat(std::move(callback));
  191. return *this;
  192. }
  193. AnimationBuilder& AnimationBuilder::OnAborted(base::OnceClosure callback) {
  194. GetObserver()->SetOnAborted(std::move(callback));
  195. return *this;
  196. }
  197. AnimationBuilder& AnimationBuilder::OnScheduled(base::OnceClosure callback) {
  198. GetObserver()->SetOnScheduled(std::move(callback));
  199. return *this;
  200. }
  201. AnimationSequenceBlock& AnimationBuilder::Once() {
  202. return NewSequence(false);
  203. }
  204. AnimationSequenceBlock& AnimationBuilder::Repeatedly() {
  205. return NewSequence(true);
  206. }
  207. void AnimationBuilder::AddLayerAnimationElement(
  208. base::PassKey<AnimationSequenceBlock>,
  209. AnimationKey key,
  210. base::TimeDelta start,
  211. base::TimeDelta original_duration,
  212. std::unique_ptr<ui::LayerAnimationElement> element) {
  213. auto& values = values_[key];
  214. Value value = {start, original_duration, std::move(element)};
  215. auto it = base::ranges::upper_bound(values, value);
  216. values.insert(it, std::move(value));
  217. }
  218. std::unique_ptr<AnimationSequenceBlock> AnimationBuilder::SwapCurrentSequence(
  219. base::PassKey<AnimationSequenceBlock>,
  220. std::unique_ptr<AnimationSequenceBlock> new_sequence) {
  221. auto old_sequence = std::move(current_sequence_);
  222. current_sequence_ = std::move(new_sequence);
  223. return old_sequence;
  224. }
  225. void AnimationBuilder::BlockEndedAt(base::PassKey<AnimationSequenceBlock>,
  226. base::TimeDelta end) {
  227. end_ = std::max(end_, end);
  228. }
  229. void AnimationBuilder::TerminateSequence(base::PassKey<AnimationSequenceBlock>,
  230. bool repeating) {
  231. for (auto& pair : values_) {
  232. auto sequence = std::make_unique<ui::LayerAnimationSequence>();
  233. sequence->set_is_repeating(repeating);
  234. if (animation_observer_)
  235. sequence->AddObserver(animation_observer_.get());
  236. base::TimeDelta start;
  237. ui::LayerAnimationElement::AnimatableProperties properties =
  238. ui::LayerAnimationElement::UNKNOWN;
  239. for (auto& value : pair.second) {
  240. DCHECK_GE(value.start, start)
  241. << "Do not overlap animations of the same property on the same view.";
  242. properties = value.element->properties();
  243. if (value.start > start) {
  244. sequence->AddElement(ui::LayerAnimationElement::CreatePauseElement(
  245. properties, value.start - start));
  246. start = value.start;
  247. }
  248. start += value.original_duration;
  249. sequence->AddElement(std::move(value.element));
  250. }
  251. if (start < end_) {
  252. sequence->AddElement(ui::LayerAnimationElement::CreatePauseElement(
  253. properties, end_ - start));
  254. }
  255. layer_animation_sequences_.insert({pair.first.target, std::move(sequence)});
  256. }
  257. values_.clear();
  258. }
  259. AnimationSequenceBlock& AnimationBuilder::GetCurrentSequence() {
  260. DCHECK(current_sequence_);
  261. return *current_sequence_;
  262. }
  263. std::unique_ptr<AnimationAbortHandle> AnimationBuilder::GetAbortHandle() {
  264. DCHECK(!abort_handle_) << "An abort handle is already created.";
  265. abort_handle_ = new AnimationAbortHandle(GetObserver());
  266. return base::WrapUnique(abort_handle_.get());
  267. }
  268. AnimationBuilder::Observer* AnimationBuilder::GetObserver() {
  269. if (!next_animation_observer_)
  270. next_animation_observer_ = std::make_unique<Observer>();
  271. return next_animation_observer_.get();
  272. }
  273. // static
  274. void AnimationBuilder::SetObserverDeletedCallbackForTesting(
  275. base::RepeatingClosure deleted_closure) {
  276. GetObserverDeletedCallback() = std::move(deleted_closure);
  277. }
  278. AnimationSequenceBlock& AnimationBuilder::NewSequence(bool repeating) {
  279. // Each sequence should have its own observer.
  280. // Ensure to terminate the current sequence block before touching the
  281. // animation sequence observer so that the sequence observer is attached to
  282. // the layer animation sequence.
  283. if (current_sequence_)
  284. current_sequence_.reset();
  285. // The observer needs to outlive the AnimationBuilder and will manage its own
  286. // lifetime. GetAttachedToSequence should not return false here. This is
  287. // DCHECKed in the observer’s destructor.
  288. if (animation_observer_ && animation_observer_->GetAttachedToSequence())
  289. animation_observer_.release();
  290. if (next_animation_observer_) {
  291. animation_observer_ = std::move(next_animation_observer_);
  292. next_animation_observer_.reset();
  293. }
  294. end_ = base::TimeDelta();
  295. current_sequence_ = std::make_unique<AnimationSequenceBlock>(
  296. base::PassKey<AnimationBuilder>(), this, base::TimeDelta(), repeating);
  297. return *current_sequence_;
  298. }
  299. // static
  300. base::RepeatingClosure& AnimationBuilder::GetObserverDeletedCallback() {
  301. static base::NoDestructor<base::RepeatingClosure> on_observer_deleted;
  302. return *on_observer_deleted;
  303. }
  304. } // namespace views