Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(903)

Side by Side Diff: services/ui/ws/frame_generator_unittest.cc

Issue 2755573002: Add FrameGenerator Unit Tests (Closed)
Patch Set: Addressed comments Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « services/ui/ws/frame_generator.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2017 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
5 #include "services/ui/ws/frame_generator.h"
6
7 #include "base/macros.h"
8 #include "cc/output/compositor_frame_sink.h"
9 #include "cc/scheduler/begin_frame_source.h"
10 #include "cc/test/begin_frame_args_test.cc"
11 #include "cc/test/fake_external_begin_frame_source.h"
12 #include "services/ui/ws/frame_generator_delegate.h"
13 #include "services/ui/ws/server_window.h"
14 #include "services/ui/ws/server_window_delegate.h"
15 #include "testing/gmock/include/gmock/gmock.h"
msw 2017/03/17 16:35:38 Is this used? (if just for EXPECT_THAT... Unordere
Fady Samuel 2017/03/17 16:55:31 Ahh I suggested using gmock as other cc uses it. I
Alex Z. 2017/03/17 19:15:07 Done.
16 #include "testing/gtest/include/gtest/gtest.h"
17
18 using testing::UnorderedElementsAre;
19
20 namespace ui {
21 namespace ws {
22 namespace test {
23
24 class TestFrameGeneratorDelegate : public FrameGeneratorDelegate {
msw 2017/03/17 16:35:38 nit: class comment?
Alex Z. 2017/03/17 19:15:07 Done.
25 public:
26 TestFrameGeneratorDelegate() {}
27 ~TestFrameGeneratorDelegate() override {}
28
29 // FrameGeneratorDelegate implementation:
30 bool IsInHighContrastMode() override { return false; }
msw 2017/03/17 16:35:38 aside: It's unfortunate if we need a delegate subc
Fady Samuel 2017/03/17 16:55:31 This will go away in a future CL.
31 };
msw 2017/03/17 16:35:38 nit: DISALLOW_COPY_AND_ASSIGN?
Alex Z. 2017/03/17 19:15:07 Done.
32
33 class TestServerWindowDelegate : public ServerWindowDelegate {
msw 2017/03/17 16:35:38 nit: class comment?
Alex Z. 2017/03/17 19:15:07 Done.
34 public:
35 TestServerWindowDelegate() {}
36 ~TestServerWindowDelegate() override {}
37
38 // ServerWindowDelegate implementation:
39 cc::mojom::DisplayCompositor* GetDisplayCompositor() override {
msw 2017/03/17 16:35:38 ditto: It's unfortunate if we need a delegate subc
40 return nullptr;
41 }
42
43 ServerWindow* GetRootWindow(const ServerWindow* window) override {
44 return nullptr;
45 }
46 };
msw 2017/03/17 16:35:38 nit: DISALLOW_COPY_AND_ASSIGN?
Alex Z. 2017/03/17 19:15:07 Done.
47
48 // FakeCompositorFrameSink observes a FakeExternalBeginFrameSource and receives
49 // CompositorFrame from a FrameGenerator.
msw 2017/03/17 16:35:38 nit: 'a CompositorFrame', 'CompositorFrames' or 'C
Alex Z. 2017/03/17 19:15:07 Done.
50 class FakeCompositorFrameSink : public cc::CompositorFrameSink,
51 public cc::BeginFrameObserver,
52 public cc::ExternalBeginFrameSourceClient {
53 public:
54 FakeCompositorFrameSink()
55 : cc::CompositorFrameSink(nullptr, nullptr, nullptr, nullptr) {}
56
57 // cc::CompositorFrameSink implementation:
58 bool BindToClient(cc::CompositorFrameSinkClient* client) override {
59 if (!cc::CompositorFrameSink::BindToClient(client))
60 return false;
61
62 external_begin_frame_source_ =
63 base::MakeUnique<cc::ExternalBeginFrameSource>(this);
64 client_->SetBeginFrameSource(external_begin_frame_source_.get());
65 return true;
66 }
67
68 void DetachFromClient() override {
69 cc::CompositorFrameSink::DetachFromClient();
70 }
71
72 void SubmitCompositorFrame(cc::CompositorFrame frame) override {
73 ++number_frames_received_;
74 last_frame_ = std::move(frame);
75 last_referenced_surfaces_ = &last_frame_.metadata.referenced_surfaces;
76 last_metadata_ = &last_frame_.metadata;
77 }
78
79 // cc::BeginFrameObserver implementation.
80 void OnBeginFrame(const cc::BeginFrameArgs& args) override {
81 external_begin_frame_source_->OnBeginFrame(args);
82 last_begin_frame_args_ = args;
83 }
84
85 const cc::BeginFrameArgs& LastUsedBeginFrameArgs() const override {
86 return last_begin_frame_args_;
87 }
88
89 void OnBeginFrameSourcePausedChanged(bool paused) override {}
90
91 // cc::ExternalBeginFrameSourceClient implementation:
92 void OnNeedsBeginFrames(bool needs_begin_frames) override {
93 needs_begin_frames_ = needs_begin_frames;
94 UpdateNeedsBeginFramesInternal();
95 }
96
97 void OnDidFinishFrame(const cc::BeginFrameAck& ack) override {
98 external_begin_frame_source_->DidFinishFrame(this, ack);
99 }
100
101 void SetBeginFrameSource(cc::BeginFrameSource* source) {
102 if (begin_frame_source_ && observing_begin_frames_) {
103 begin_frame_source_->RemoveObserver(this);
104 observing_begin_frames_ = false;
105 }
106 begin_frame_source_ = source;
107 UpdateNeedsBeginFramesInternal();
108 }
109
110 const std::vector<cc::SurfaceId>* last_referenced_surfaces() {
111 return last_referenced_surfaces_;
112 }
113
114 const cc::CompositorFrameMetadata* last_metadata() { return last_metadata_; }
115
116 int number_frames_received() { return number_frames_received_; }
117
118 private:
119 void UpdateNeedsBeginFramesInternal() {
120 if (!begin_frame_source_)
121 return;
122
123 if (needs_begin_frames_ == observing_begin_frames_)
124 return;
125
126 observing_begin_frames_ = needs_begin_frames_;
127 if (needs_begin_frames_) {
128 begin_frame_source_->AddObserver(this);
129 } else {
130 begin_frame_source_->RemoveObserver(this);
131 }
132 }
133
134 int number_frames_received_ = 0;
135 std::unique_ptr<cc::ExternalBeginFrameSource> external_begin_frame_source_;
136 cc::BeginFrameSource* begin_frame_source_ = nullptr;
137 cc::BeginFrameArgs last_begin_frame_args_;
138 bool observing_begin_frames_ = false;
139 bool needs_begin_frames_ = false;
140 cc::CompositorFrame last_frame_;
141 const std::vector<cc::SurfaceId>* last_referenced_surfaces_ = nullptr;
142 const cc::CompositorFrameMetadata* last_metadata_ = nullptr;
143 };
msw 2017/03/17 16:35:38 nit: DISALLOW_COPY_AND_ASSIGN?
Alex Z. 2017/03/17 19:15:07 Done.
144
145 class FrameGeneratorTest : public testing::Test {
146 public:
147 FrameGeneratorTest() {}
148 ~FrameGeneratorTest() override {}
149
150 // testing::Test overrides:
151 void SetUp() override {
152 testing::Test::SetUp();
153
154 std::unique_ptr<FakeCompositorFrameSink> compositor_frame_sink =
155 base::MakeUnique<FakeCompositorFrameSink>();
156 compositor_frame_sink_ = compositor_frame_sink.get();
157
158 constexpr float kRefreshRate = 0.f;
159 constexpr bool kTickAutomatically = false;
160 begin_frame_source_ = base::MakeUnique<cc::FakeExternalBeginFrameSource>(
161 kRefreshRate, kTickAutomatically);
162 compositor_frame_sink_->SetBeginFrameSource(begin_frame_source_.get());
163 delegate_ = base::MakeUnique<TestFrameGeneratorDelegate>();
164 server_window_delegate_ = base::MakeUnique<TestServerWindowDelegate>();
165 root_window_ = base::MakeUnique<ServerWindow>(server_window_delegate_.get(),
166 WindowId());
167 root_window_->SetVisible(true);
168 frame_generator_ = base::MakeUnique<FrameGenerator>(
169 delegate_.get(), root_window_.get(), std::move(compositor_frame_sink));
170 };
171
172 int NumberOfFramesReceived() {
173 return compositor_frame_sink_->number_frames_received();
174 }
175
176 void IssueBeginFrame() {
177 begin_frame_source_->TestOnBeginFrame(cc::CreateBeginFrameArgsForTesting(
178 BEGINFRAME_FROM_HERE, 0, next_sequence_number_));
179 ++next_sequence_number_;
180 }
181
182 FrameGenerator* frame_generator() { return frame_generator_.get(); }
183
184 const std::vector<cc::SurfaceId>* ReferencedSurfaces() {
185 return compositor_frame_sink_->last_referenced_surfaces();
186 }
187
188 const cc::CompositorFrameMetadata* LastMetadata() {
189 return compositor_frame_sink_->last_metadata();
190 }
191
192 private:
193 FakeCompositorFrameSink* compositor_frame_sink_ = nullptr;
194 std::unique_ptr<cc::FakeExternalBeginFrameSource> begin_frame_source_;
195 std::unique_ptr<TestFrameGeneratorDelegate> delegate_;
196 std::unique_ptr<TestServerWindowDelegate> server_window_delegate_;
197 std::unique_ptr<ServerWindow> root_window_;
198 std::unique_ptr<FrameGenerator> frame_generator_;
199 int next_sequence_number_ = 1;
200
201 DISALLOW_COPY_AND_ASSIGN(FrameGeneratorTest);
202 };
203
204 TEST_F(FrameGeneratorTest, OnSurfaceCreated) {
205 EXPECT_EQ(0, NumberOfFramesReceived());
206 EXPECT_EQ(nullptr, ReferencedSurfaces());
207
208 // FrameGenerator does not request BeginFrames upon creation.
209 IssueBeginFrame();
210 EXPECT_EQ(0, NumberOfFramesReceived());
211
212 const cc::SurfaceId kArbitrarySurfaceId(
213 cc::FrameSinkId(1, 1),
214 cc::LocalSurfaceId(1, base::UnguessableToken::Create()));
215 const cc::SurfaceInfo kArbitrarySurfaceInfo(kArbitrarySurfaceId, 1.0f,
216 gfx::Size(100, 100));
217 frame_generator()->OnSurfaceCreated(kArbitrarySurfaceInfo);
218 EXPECT_EQ(0, NumberOfFramesReceived());
219
220 IssueBeginFrame();
221 EXPECT_EQ(1, NumberOfFramesReceived());
222
223 // Verify that the CompositorFrame refers to the window manager's surface via
224 // referenced_surfaces.
225 const std::vector<cc::SurfaceId>* referenced_surfaces = ReferencedSurfaces();
226 EXPECT_TRUE(referenced_surfaces);
227 EXPECT_THAT(*referenced_surfaces, UnorderedElementsAre(kArbitrarySurfaceId));
228
229 // FrameGenerator stops requesting BeginFrames after submitting a
230 // CompositorFrame.
231 IssueBeginFrame();
232 EXPECT_EQ(1, NumberOfFramesReceived());
233 }
234
235 TEST_F(FrameGeneratorTest, SetDeviceScaleFactor) {
236 EXPECT_EQ(0, NumberOfFramesReceived());
237 const cc::SurfaceId kArbitrarySurfaceId(
238 cc::FrameSinkId(1, 1),
239 cc::LocalSurfaceId(1, base::UnguessableToken::Create()));
240 const cc::SurfaceInfo kArbitrarySurfaceInfo(kArbitrarySurfaceId, 1.0f,
241 gfx::Size(100, 100));
242 constexpr float kDefaultScaleFactor = 1.0f;
243 constexpr float kArbitraryScaleFactor = 0.5f;
244
245 // A valid SurfaceInfo is required before setting device scale factor.
246 frame_generator()->OnSurfaceCreated(kArbitrarySurfaceInfo);
247 IssueBeginFrame();
248 EXPECT_EQ(1, NumberOfFramesReceived());
249
250 // FrameGenerator stops requesting BeginFrames after receiving one.
msw 2017/03/17 16:35:38 nit: s/requesting/accepting/?
Fady Samuel 2017/03/17 16:55:31 I think requesting is appropriate here.
251 IssueBeginFrame();
252 EXPECT_EQ(1, NumberOfFramesReceived());
253
254 // FrameGenerator does not request BeginFrames if its device scale factor
msw 2017/03/17 16:35:38 nit: s/request/accept/?
Fady Samuel 2017/03/17 16:55:31 I think requesting is appropriate here.
255 // remains unchanged.
256 frame_generator()->SetDeviceScaleFactor(kDefaultScaleFactor);
257 IssueBeginFrame();
258 EXPECT_EQ(1, NumberOfFramesReceived());
259 const cc::CompositorFrameMetadata* last_metadata = LastMetadata();
260 EXPECT_TRUE(last_metadata);
261 EXPECT_EQ(kDefaultScaleFactor, last_metadata->device_scale_factor);
262
263 frame_generator()->SetDeviceScaleFactor(kArbitraryScaleFactor);
264 IssueBeginFrame();
265 EXPECT_EQ(2, NumberOfFramesReceived());
266 last_metadata = LastMetadata();
267 EXPECT_EQ(kArbitraryScaleFactor, last_metadata->device_scale_factor);
268 }
269
270 } // namespace test
271 } // namespace ws
272 } // namespace ui
OLDNEW
« no previous file with comments | « services/ui/ws/frame_generator.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698