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