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

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

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