animation_throughput_reporter_unittest.cc 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275
  1. // Copyright 2020 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/compositor/animation_throughput_reporter.h"
  5. #include <memory>
  6. #include "base/test/bind.h"
  7. #include "base/time/time.h"
  8. #include "build/build_config.h"
  9. #include "cc/metrics/frame_sequence_metrics.h"
  10. #include "ui/compositor/layer.h"
  11. #include "ui/compositor/layer_animation_sequence.h"
  12. #include "ui/compositor/layer_animator.h"
  13. #include "ui/compositor/scoped_layer_animation_settings.h"
  14. #include "ui/compositor/test/animation_throughput_reporter_test_base.h"
  15. #include "ui/compositor/test/throughput_report_checker.h"
  16. #include "ui/gfx/geometry/rect.h"
  17. namespace ui {
  18. using AnimationThroughputReporterTest = AnimationThroughputReporterTestBase;
  19. // Tests animation throughput collection with implicit animation scenario.
  20. TEST_F(AnimationThroughputReporterTest, ImplicitAnimation) {
  21. Layer layer;
  22. layer.SetOpacity(0.5f);
  23. root_layer()->Add(&layer);
  24. ThroughputReportChecker checker(this);
  25. {
  26. LayerAnimator* animator = layer.GetAnimator();
  27. AnimationThroughputReporter reporter(animator,
  28. checker.repeating_callback());
  29. ScopedLayerAnimationSettings settings(animator);
  30. settings.SetTransitionDuration(base::Milliseconds(48));
  31. layer.SetOpacity(1.0f);
  32. }
  33. // The animation starts in next frame (16ms) and ends 48 ms later.
  34. EXPECT_TRUE(checker.WaitUntilReported());
  35. }
  36. // Tests animation throughput collection with implicit animation setup before
  37. // Layer is attached to a compositor.
  38. TEST_F(AnimationThroughputReporterTest, ImplicitAnimationLateAttach) {
  39. Layer layer;
  40. layer.SetOpacity(0.5f);
  41. ThroughputReportChecker checker(this);
  42. {
  43. LayerAnimator* animator = layer.GetAnimator();
  44. AnimationThroughputReporter reporter(animator,
  45. checker.repeating_callback());
  46. ScopedLayerAnimationSettings settings(animator);
  47. settings.SetTransitionDuration(base::Milliseconds(48));
  48. layer.SetOpacity(1.0f);
  49. }
  50. // Attach to root after animation setup.
  51. root_layer()->Add(&layer);
  52. EXPECT_TRUE(checker.WaitUntilReported());
  53. }
  54. // Tests animation throughput collection with explicitly created animation
  55. // sequence scenario.
  56. TEST_F(AnimationThroughputReporterTest, ExplicitAnimation) {
  57. Layer layer;
  58. layer.SetOpacity(0.5f);
  59. root_layer()->Add(&layer);
  60. ThroughputReportChecker checker(this);
  61. LayerAnimator* animator = layer.GetAnimator();
  62. AnimationThroughputReporter reporter(animator, checker.repeating_callback());
  63. animator->ScheduleAnimation(
  64. new LayerAnimationSequence(LayerAnimationElement::CreateOpacityElement(
  65. 1.0f, base::Milliseconds(48))));
  66. EXPECT_TRUE(checker.WaitUntilReported());
  67. }
  68. // Tests animation throughput collection for a persisted animator of a Layer.
  69. TEST_F(AnimationThroughputReporterTest, PersistedAnimation) {
  70. auto layer = std::make_unique<Layer>();
  71. layer->SetOpacity(0.5f);
  72. root_layer()->Add(layer.get());
  73. // Set a persisted animator to |layer|.
  74. LayerAnimator* animator = new LayerAnimator(base::Milliseconds(48));
  75. layer->SetAnimator(animator);
  76. // |reporter| keeps reporting as long as it is alive.
  77. ThroughputReportChecker checker(this);
  78. AnimationThroughputReporter reporter(animator, checker.repeating_callback());
  79. // Report data for animation of opacity goes to 1.
  80. layer->SetOpacity(1.0f);
  81. EXPECT_TRUE(checker.WaitUntilReported());
  82. // Report data for animation of opacity goes to 0.5.
  83. checker.reset();
  84. layer->SetOpacity(0.5f);
  85. EXPECT_TRUE(checker.WaitUntilReported());
  86. }
  87. // Tests animation throughput not reported when animation is aborted.
  88. TEST_F(AnimationThroughputReporterTest, AbortedAnimation) {
  89. auto layer = std::make_unique<Layer>();
  90. layer->SetOpacity(0.5f);
  91. root_layer()->Add(layer.get());
  92. ThroughputReportChecker checker(this, /*fail_if_reported=*/true);
  93. // Reporter started monitoring animation, then deleted, which should be
  94. // reported when the animation ends.
  95. {
  96. LayerAnimator* animator = layer->GetAnimator();
  97. AnimationThroughputReporter reporter(animator,
  98. checker.repeating_callback());
  99. ScopedLayerAnimationSettings settings(animator);
  100. settings.SetTransitionDuration(base::Milliseconds(48));
  101. layer->SetOpacity(1.0f);
  102. }
  103. // Delete |layer| to abort on-going animations.
  104. layer.reset();
  105. // Wait a bit to ensure that report does not happen.
  106. Advance(base::Milliseconds(100));
  107. // TODO(crbug.com/1158510): Test the scenario where the report exists when the
  108. // layer is removed.
  109. }
  110. // Tests no report and no leak when underlying layer is gone before reporter.
  111. TEST_F(AnimationThroughputReporterTest, LayerDestroyedBeforeReporter) {
  112. auto layer = std::make_unique<Layer>();
  113. layer->SetOpacity(0.5f);
  114. root_layer()->Add(layer.get());
  115. ThroughputReportChecker checker(this, /*fail_if_reported=*/true);
  116. LayerAnimator* animator = layer->GetAnimator();
  117. AnimationThroughputReporter reporter(animator, checker.repeating_callback());
  118. {
  119. ScopedLayerAnimationSettings settings(animator);
  120. settings.SetTransitionDuration(base::Milliseconds(48));
  121. layer->SetOpacity(1.0f);
  122. }
  123. // Delete |layer| to before the reporter.
  124. layer.reset();
  125. // Wait a bit to ensure that report does not happen.
  126. Advance(base::Milliseconds(100));
  127. }
  128. // Tests animation throughput not reported when detached from timeline.
  129. TEST_F(AnimationThroughputReporterTest, NoReportOnDetach) {
  130. auto layer = std::make_unique<Layer>();
  131. layer->SetOpacity(0.5f);
  132. root_layer()->Add(layer.get());
  133. ThroughputReportChecker checker(this, /*fail_if_reported=*/true);
  134. {
  135. LayerAnimator* animator = layer->GetAnimator();
  136. AnimationThroughputReporter reporter(animator,
  137. checker.repeating_callback());
  138. ScopedLayerAnimationSettings settings(animator);
  139. settings.SetTransitionDuration(base::Milliseconds(48));
  140. layer->SetOpacity(1.0f);
  141. }
  142. // Detach from the root and attach to a root.
  143. root_layer()->Remove(layer.get());
  144. root_layer()->Add(layer.get());
  145. // Wait a bit to ensure that report does not happen.
  146. Advance(base::Milliseconds(100));
  147. }
  148. // Tests animation throughput not reported and no leak when animation is stopped
  149. // without being attached to a root.
  150. TEST_F(AnimationThroughputReporterTest, EndDetachedNoReportNoLeak) {
  151. auto layer = std::make_unique<Layer>();
  152. layer->SetOpacity(0.5f);
  153. ThroughputReportChecker checker(this, /*fail_if_reported=*/true);
  154. LayerAnimator* animator = layer->GetAnimator();
  155. // Schedule an animation without being attached to a root.
  156. {
  157. AnimationThroughputReporter reporter(animator,
  158. checker.repeating_callback());
  159. ScopedLayerAnimationSettings settings(animator);
  160. settings.SetTransitionDuration(base::Milliseconds(50));
  161. layer->SetOpacity(1.0f);
  162. }
  163. // End the animation without being attached to a root.
  164. animator->StopAnimating();
  165. // Wait a bit to ensure that report does not happen.
  166. Advance(base::Milliseconds(100));
  167. // AnimationTracker in |reporter| should not leak in asan.
  168. }
  169. // Tests animation throughput are reported if there was a previous animation
  170. // preempted under IMMEDIATELY_ANIMATE_TO_NEW_TARGET strategy.
  171. TEST_F(AnimationThroughputReporterTest, ReportForAnimateToNewTarget) {
  172. auto layer = std::make_unique<Layer>();
  173. layer->SetOpacity(0.f);
  174. layer->SetBounds(gfx::Rect(0, 0, 1, 2));
  175. root_layer()->Add(layer.get());
  176. ThroughputReportChecker checker(this, /*fail_if_reported=*/true);
  177. LayerAnimator* animator = layer->GetAnimator();
  178. // Schedule an animation that will be preempted. No report should happen.
  179. {
  180. AnimationThroughputReporter reporter(animator,
  181. checker.repeating_callback());
  182. ScopedLayerAnimationSettings settings(animator);
  183. settings.SetTransitionDuration(base::Milliseconds(50));
  184. layer->SetOpacity(0.5f);
  185. layer->SetBounds(gfx::Rect(0, 0, 3, 4));
  186. }
  187. // Animate to new target. Report should happen.
  188. ThroughputReportChecker checker2(this);
  189. {
  190. AnimationThroughputReporter reporter(animator,
  191. checker2.repeating_callback());
  192. ScopedLayerAnimationSettings settings(animator);
  193. settings.SetPreemptionStrategy(
  194. LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
  195. settings.SetTransitionDuration(base::Milliseconds(48));
  196. layer->SetOpacity(1.0f);
  197. layer->SetBounds(gfx::Rect(0, 0, 5, 6));
  198. }
  199. EXPECT_TRUE(checker2.WaitUntilReported());
  200. }
  201. // Tests AnimationThroughputReporter does not leak its AnimationTracker when
  202. // there are existing animations but no new animation sequence starts after it
  203. // is created.
  204. TEST_F(AnimationThroughputReporterTest, NoLeakWithNoAnimationStart) {
  205. auto layer = std::make_unique<Layer>();
  206. layer->SetOpacity(0.5f);
  207. root_layer()->Add(layer.get());
  208. LayerAnimator* animator = layer->GetAnimator();
  209. // Create an existing animation.
  210. {
  211. ScopedLayerAnimationSettings settings(animator);
  212. settings.SetTransitionDuration(base::Milliseconds(50));
  213. layer->SetOpacity(0.0f);
  214. }
  215. // Create the reporter with the existing animation.
  216. ThroughputReportChecker checker(this, /*fail_if_reported=*/true);
  217. {
  218. AnimationThroughputReporter reporter(animator,
  219. checker.repeating_callback());
  220. }
  221. // Wait a bit to ensure to let the existing animation finish.
  222. // There should be no report and no leak.
  223. Advance(base::Milliseconds(100));
  224. }
  225. } // namespace ui