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

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

Issue 2755573002: Add FrameGenerator Unit Tests (Closed)
Patch Set: ReferencedSurfaces() 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
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/gtest/include/gtest/gtest.h"
16
17 namespace ui {
18 namespace ws {
19 namespace test {
20
21 class TestFrameGeneratorDelegate : public FrameGeneratorDelegate {
22 public:
23 TestFrameGeneratorDelegate() {}
24 ~TestFrameGeneratorDelegate() override {}
25
26 // FrameGeneratorDelegate implementation:
27 bool IsInHighContrastMode() override { return false; }
28 };
29
30 class TestServerWindowDelegate : public ServerWindowDelegate {
31 public:
32 TestServerWindowDelegate() {}
33 ~TestServerWindowDelegate() override {}
34
35 // ServerWindowDelegate implementation:
36 cc::mojom::DisplayCompositor* GetDisplayCompositor() override {
37 return nullptr;
38 }
39
40 ServerWindow* GetRootWindow(const ServerWindow* window) override {
41 return nullptr;
42 }
43 };
44
45 // FakeCompositorFrameSink observes a FakeExternalBeginFrameSource and receives
46 // CompositorFrame from a FrameGenerator.
47 class FakeCompositorFrameSink : public cc::CompositorFrameSink,
48 public cc::BeginFrameObserver,
49 public cc::ExternalBeginFrameSourceClient {
50 public:
51 FakeCompositorFrameSink()
52 : cc::CompositorFrameSink(nullptr, nullptr, nullptr, nullptr) {}
53
54 // cc::CompositorFrameSink implementation:
55 bool BindToClient(cc::CompositorFrameSinkClient* client) override {
56 if (!cc::CompositorFrameSink::BindToClient(client))
57 return false;
58
59 external_begin_frame_source_ =
60 base::MakeUnique<cc::ExternalBeginFrameSource>(this);
61 client_->SetBeginFrameSource(external_begin_frame_source_.get());
62 return true;
63 }
64
65 void DetachFromClient() override {
66 cc::CompositorFrameSink::DetachFromClient();
67 }
68
69 void SubmitCompositorFrame(cc::CompositorFrame frame) override {
70 ++number_frames_received_;
71 last_frame_ = std::move(frame);
72 last_referenced_surfaces_ = &last_frame_.metadata.referenced_surfaces;
73 }
74
75 // cc::BeginFrameObserver implementation.
76 void OnBeginFrame(const cc::BeginFrameArgs& args) override {
77 external_begin_frame_source_->OnBeginFrame(args);
78 last_begin_frame_args_ = args;
79 }
80
81 const cc::BeginFrameArgs& LastUsedBeginFrameArgs() const override {
82 return last_begin_frame_args_;
83 }
84
85 void OnBeginFrameSourcePausedChanged(bool paused) override {}
86
87 // cc::ExternalBeginFrameSourceClient implementation:
88 void OnNeedsBeginFrames(bool needs_begin_frames) override {
89 needs_begin_frames_ = needs_begin_frames;
90 UpdateNeedsBeginFramesInternal();
91 }
92
93 void OnDidFinishFrame(const cc::BeginFrameAck& ack) override {
94 external_begin_frame_source_->DidFinishFrame(this, ack);
95 }
96
97 void SetBeginFrameSource(cc::BeginFrameSource* source) {
98 if (begin_frame_source_ && observing_begin_frames_) {
99 begin_frame_source_->RemoveObserver(this);
100 observing_begin_frames_ = false;
101 }
102 begin_frame_source_ = source;
103 UpdateNeedsBeginFramesInternal();
104 }
105
106 const std::vector<cc::SurfaceId>* last_referenced_surfaces() {
107 return last_referenced_surfaces_;
108 }
109
110 int number_frames_received() { return number_frames_received_; }
111
112 private:
113 void UpdateNeedsBeginFramesInternal() {
114 if (!begin_frame_source_)
115 return;
116
117 if (needs_begin_frames_ == observing_begin_frames_)
118 return;
119
120 observing_begin_frames_ = needs_begin_frames_;
121 if (needs_begin_frames_) {
122 begin_frame_source_->AddObserver(this);
123 } else {
124 begin_frame_source_->RemoveObserver(this);
125 }
126 }
127
128 int number_frames_received_ = 0;
129 std::unique_ptr<cc::ExternalBeginFrameSource> external_begin_frame_source_;
130 cc::BeginFrameSource* begin_frame_source_ = nullptr;
131 cc::BeginFrameArgs last_begin_frame_args_;
132 bool observing_begin_frames_ = false;
133 bool needs_begin_frames_ = false;
134 cc::CompositorFrame last_frame_;
135 const std::vector<cc::SurfaceId>* last_referenced_surfaces_ = nullptr;
136 };
137
138 class FrameGeneratorTest : public testing::Test {
139 public:
140 FrameGeneratorTest() {}
141 ~FrameGeneratorTest() override {}
142
143 // testing::Test overrides:
144 void SetUp() override {
145 testing::Test::SetUp();
146
147 std::unique_ptr<FakeCompositorFrameSink> compositor_frame_sink =
148 base::MakeUnique<FakeCompositorFrameSink>();
149 compositor_frame_sink_ = compositor_frame_sink.get();
150
151 constexpr float kRefreshRate = 0.f;
152 constexpr bool kTickAutomatically = false;
153 begin_frame_source_ = base::MakeUnique<cc::FakeExternalBeginFrameSource>(
154 kRefreshRate, kTickAutomatically);
155 compositor_frame_sink_->SetBeginFrameSource(begin_frame_source_.get());
156 delegate_ = base::MakeUnique<TestFrameGeneratorDelegate>();
157 server_window_delegate_ = base::MakeUnique<TestServerWindowDelegate>();
158 root_window_ = base::MakeUnique<ServerWindow>(server_window_delegate_.get(),
159 WindowId());
160 root_window_->SetVisible(true);
161 frame_generator_ = base::MakeUnique<FrameGenerator>(
162 delegate_.get(), root_window_.get(), std::move(compositor_frame_sink));
163 };
164
165 int NumberOfFramesReceived() {
166 return compositor_frame_sink_->number_frames_received();
167 }
168
169 void IssueBeginFrame() {
170 begin_frame_source_->TestOnBeginFrame(cc::CreateBeginFrameArgsForTesting(
171 BEGINFRAME_FROM_HERE, 0, next_sequence_number_));
172 ++next_sequence_number_;
173 }
174
175 FrameGenerator* frame_generator() { return frame_generator_.get(); }
176
177 const std::vector<cc::SurfaceId>* ReferencedSurfaces() {
178 return compositor_frame_sink_->last_referenced_surfaces();
179 }
180
181 private:
182 FakeCompositorFrameSink* compositor_frame_sink_ = nullptr;
183 std::unique_ptr<cc::FakeExternalBeginFrameSource> begin_frame_source_;
184 std::unique_ptr<TestFrameGeneratorDelegate> delegate_;
185 std::unique_ptr<TestServerWindowDelegate> server_window_delegate_;
186 std::unique_ptr<ServerWindow> root_window_;
187 std::unique_ptr<FrameGenerator> frame_generator_;
188 int next_sequence_number_ = 1;
189
190 DISALLOW_COPY_AND_ASSIGN(FrameGeneratorTest);
191 };
192
193 TEST_F(FrameGeneratorTest, OnSurfaceCreated) {
194 DCHECK_EQ(0, NumberOfFramesReceived());
195 DCHECK_EQ(nullptr, ReferencedSurfaces());
196
197 // FrameGenerator does not request BeginFrames upon creation.
198 IssueBeginFrame();
199 EXPECT_EQ(0, NumberOfFramesReceived());
200
201 const cc::SurfaceId kArbitrarySurfaceId(
202 cc::FrameSinkId(1, 1),
203 cc::LocalSurfaceId(1, base::UnguessableToken::Create()));
204 const cc::SurfaceInfo kArbitrarySurfaceInfo(kArbitrarySurfaceId, 1.0f,
205 gfx::Size(100, 100));
206 frame_generator()->OnSurfaceCreated(kArbitrarySurfaceInfo);
207 // FrameGenerator gets the missed BeginFrame when AddObserver() is called.
Fady Samuel 2017/03/17 14:06:40 This comment is weird here. I would just remove it
Alex Z. 2017/03/17 14:43:00 Done. I took this note while debugging and missed
208 EXPECT_EQ(0, NumberOfFramesReceived());
209
210 IssueBeginFrame();
211 EXPECT_EQ(1, NumberOfFramesReceived());
212
213 // Verify that the CompositorFrame refers to the window manager's surface via
214 // referenced_surfaces.
215 const std::vector<cc::SurfaceId>* referenced_surfaces = ReferencedSurfaces();
216 EXPECT_TRUE(referenced_surfaces);
217 EXPECT_EQ(kArbitrarySurfaceId, referenced_surfaces->front());
Fady Samuel 2017/03/17 14:06:40 Use EXPECT_THAT? https://cs.chromium.org/chromium/
Alex Z. 2017/03/17 14:43:00 Done.
218
219 // FrameGenerator stops requesting BeginFrames after submitting a
220 // CompositorFrame.
221 IssueBeginFrame();
222 EXPECT_EQ(1, NumberOfFramesReceived());
223 }
224
225 TEST_F(FrameGeneratorTest, SetDeviceScaleFactor) {
226 DCHECK_EQ(0, NumberOfFramesReceived());
227 const cc::SurfaceId kArbitrarySurfaceId(
228 cc::FrameSinkId(1, 1),
229 cc::LocalSurfaceId(1, base::UnguessableToken::Create()));
230 const cc::SurfaceInfo kArbitrarySurfaceInfo(kArbitrarySurfaceId, 1.0f,
231 gfx::Size(100, 100));
232 constexpr float kDefaultScaleFactor = 1.0f;
233 constexpr float kArbitraryScaleFactor = 0.5f;
234
235 // A valid SurfaceInfo is required before setting device scale factor.
236 frame_generator()->OnSurfaceCreated(kArbitrarySurfaceInfo);
237 IssueBeginFrame();
238 DCHECK_EQ(1, NumberOfFramesReceived());
Fady Samuel 2017/03/17 14:06:40 Verify that the device scale factor in the Composi
Alex Z. 2017/03/17 14:43:00 Done.
239
240 IssueBeginFrame();
241 DCHECK_EQ(1, NumberOfFramesReceived());
Fady Samuel 2017/03/17 14:06:40 Either remove this or comment about what it does?
Alex Z. 2017/03/17 14:43:00 Done.
242
243 // FrameGenerator does not request BeginFrames if its device scale factor
244 // remains unchanged.
245 frame_generator()->SetDeviceScaleFactor(kDefaultScaleFactor);
246 IssueBeginFrame();
247 EXPECT_EQ(1, NumberOfFramesReceived());
248
249 frame_generator()->SetDeviceScaleFactor(kArbitraryScaleFactor);
250 IssueBeginFrame();
251 EXPECT_EQ(2, NumberOfFramesReceived());
Fady Samuel 2017/03/17 14:06:40 Verify that the new compositorframe gets the new d
Alex Z. 2017/03/17 14:43:00 Done.
252 }
253
254 } // namespace test
255 } // namespace ws
256 } // namespace ui
OLDNEW
« services/ui/ws/frame_generator.cc ('K') | « services/ui/ws/frame_generator.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698