Update perf expectations since static linking ffmpeg.
[chromium-blink-merge.git] / cc / surfaces / display_unittest.cc
blobc0213905551f3e310e3a7616e50f7f851e69cc19
1 // Copyright 2015 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.
5 #include "base/test/null_task_runner.h"
6 #include "cc/output/compositor_frame.h"
7 #include "cc/output/copy_output_result.h"
8 #include "cc/output/delegated_frame_data.h"
9 #include "cc/quads/render_pass.h"
10 #include "cc/resources/shared_bitmap_manager.h"
11 #include "cc/surfaces/display.h"
12 #include "cc/surfaces/display_client.h"
13 #include "cc/surfaces/surface.h"
14 #include "cc/surfaces/surface_factory.h"
15 #include "cc/surfaces/surface_factory_client.h"
16 #include "cc/surfaces/surface_id_allocator.h"
17 #include "cc/surfaces/surface_manager.h"
18 #include "cc/test/fake_output_surface.h"
19 #include "cc/test/scheduler_test_common.h"
20 #include "cc/test/test_shared_bitmap_manager.h"
21 #include "testing/gmock/include/gmock/gmock.h"
22 #include "testing/gtest/include/gtest/gtest.h"
24 using testing::AnyNumber;
26 namespace cc {
27 namespace {
29 class EmptySurfaceFactoryClient : public SurfaceFactoryClient {
30 public:
31 void ReturnResources(const ReturnedResourceArray& resources) override {}
34 class DisplayTest : public testing::Test {
35 public:
36 DisplayTest() : factory_(&manager_, &empty_client_) {}
38 protected:
39 void SetUpContext(scoped_ptr<TestWebGraphicsContext3D> context) {
40 if (context) {
41 output_surface_ = FakeOutputSurface::Create3d(
42 TestContextProvider::Create(context.Pass()));
43 } else {
44 output_surface_ = FakeOutputSurface::CreateSoftware(
45 make_scoped_ptr(new SoftwareOutputDevice));
47 shared_bitmap_manager_.reset(new TestSharedBitmapManager);
48 output_surface_ptr_ = output_surface_.get();
51 void SubmitFrame(RenderPassList* pass_list, SurfaceId surface_id) {
52 scoped_ptr<DelegatedFrameData> frame_data(new DelegatedFrameData);
53 pass_list->swap(frame_data->render_pass_list);
55 scoped_ptr<CompositorFrame> frame(new CompositorFrame);
56 frame->delegated_frame_data = frame_data.Pass();
58 factory_.SubmitFrame(surface_id, frame.Pass(),
59 SurfaceFactory::DrawCallback());
62 SurfaceManager manager_;
63 EmptySurfaceFactoryClient empty_client_;
64 SurfaceFactory factory_;
65 scoped_ptr<FakeOutputSurface> output_surface_;
66 FakeOutputSurface* output_surface_ptr_;
67 FakeBeginFrameSource fake_begin_frame_source_;
68 scoped_ptr<SharedBitmapManager> shared_bitmap_manager_;
71 class TestDisplayClient : public DisplayClient {
72 public:
73 TestDisplayClient() {}
74 ~TestDisplayClient() override {}
76 void CommitVSyncParameters(base::TimeTicks timebase,
77 base::TimeDelta interval) override {}
78 void OutputSurfaceLost() override {}
79 void SetMemoryPolicy(const ManagedMemoryPolicy& policy) override {}
82 class TestDisplayScheduler : public DisplayScheduler {
83 public:
84 TestDisplayScheduler(DisplaySchedulerClient* client,
85 BeginFrameSource* begin_frame_source)
86 : DisplayScheduler(client,
87 begin_frame_source,
88 make_scoped_refptr(new base::NullTaskRunner),
89 1),
90 damaged(false),
91 entire_display_damaged(false),
92 swapped(false) {}
94 ~TestDisplayScheduler() override {}
96 void EntireDisplayDamaged(SurfaceId root_surface_id) override {
97 entire_display_damaged = true;
100 void SurfaceDamaged(SurfaceId surface_id) override {
101 damaged = true;
102 needs_draw_ = true;
105 void DidSwapBuffers() override { swapped = true; }
107 void ResetDamageForTest() {
108 damaged = false;
109 entire_display_damaged = false;
112 bool damaged;
113 bool entire_display_damaged;
114 bool swapped;
117 void CopyCallback(bool* called, scoped_ptr<CopyOutputResult> result) {
118 *called = true;
121 // Check that frame is damaged and swapped only under correct conditions.
122 TEST_F(DisplayTest, DisplayDamaged) {
123 SetUpContext(nullptr);
124 TestDisplayClient client;
125 RendererSettings settings;
126 settings.partial_swap_enabled = true;
127 settings.finish_rendering_on_resize = true;
128 Display display(&client, &manager_, shared_bitmap_manager_.get(), nullptr,
129 settings);
131 TestDisplayScheduler scheduler(&display, &fake_begin_frame_source_);
132 display.Initialize(output_surface_.Pass(), &scheduler);
134 SurfaceId surface_id(7u);
135 EXPECT_FALSE(scheduler.damaged);
136 EXPECT_FALSE(scheduler.entire_display_damaged);
137 display.SetSurfaceId(surface_id, 1.f);
138 EXPECT_FALSE(scheduler.damaged);
139 EXPECT_TRUE(scheduler.entire_display_damaged);
141 scheduler.ResetDamageForTest();
142 display.Resize(gfx::Size(100, 100));
143 EXPECT_FALSE(scheduler.damaged);
144 EXPECT_TRUE(scheduler.entire_display_damaged);
146 factory_.Create(surface_id);
148 // First draw from surface should have full damage.
149 RenderPassList pass_list;
150 scoped_ptr<RenderPass> pass = RenderPass::Create();
151 pass->output_rect = gfx::Rect(0, 0, 100, 100);
152 pass->damage_rect = gfx::Rect(10, 10, 1, 1);
153 pass->id = RenderPassId(1, 1);
154 pass_list.push_back(pass.Pass());
156 scheduler.ResetDamageForTest();
157 SubmitFrame(&pass_list, surface_id);
158 EXPECT_TRUE(scheduler.damaged);
159 EXPECT_FALSE(scheduler.entire_display_damaged);
161 EXPECT_FALSE(scheduler.swapped);
162 EXPECT_EQ(0u, output_surface_ptr_->num_sent_frames());
163 display.DrawAndSwap();
164 EXPECT_TRUE(scheduler.swapped);
165 EXPECT_EQ(1u, output_surface_ptr_->num_sent_frames());
166 SoftwareFrameData* software_data =
167 output_surface_ptr_->last_sent_frame().software_frame_data.get();
168 ASSERT_NE(nullptr, software_data);
169 EXPECT_EQ(gfx::Size(100, 100).ToString(), software_data->size.ToString());
170 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
171 software_data->damage_rect.ToString());
174 // Only damaged portion should be swapped.
175 pass = RenderPass::Create();
176 pass->output_rect = gfx::Rect(0, 0, 100, 100);
177 pass->damage_rect = gfx::Rect(10, 10, 1, 1);
178 pass->id = RenderPassId(1, 1);
180 pass_list.push_back(pass.Pass());
181 scheduler.ResetDamageForTest();
182 SubmitFrame(&pass_list, surface_id);
183 EXPECT_TRUE(scheduler.damaged);
184 EXPECT_FALSE(scheduler.entire_display_damaged);
186 scheduler.swapped = false;
187 display.DrawAndSwap();
188 EXPECT_TRUE(scheduler.swapped);
189 EXPECT_EQ(2u, output_surface_ptr_->num_sent_frames());
190 software_data =
191 output_surface_ptr_->last_sent_frame().software_frame_data.get();
192 ASSERT_NE(nullptr, software_data);
193 EXPECT_EQ(gfx::Size(100, 100).ToString(), software_data->size.ToString());
194 EXPECT_EQ(gfx::Rect(10, 10, 1, 1).ToString(),
195 software_data->damage_rect.ToString());
199 // Pass has no damage so shouldn't be swapped.
200 pass = RenderPass::Create();
201 pass->output_rect = gfx::Rect(0, 0, 100, 100);
202 pass->damage_rect = gfx::Rect(10, 10, 0, 0);
203 pass->id = RenderPassId(1, 1);
205 pass_list.push_back(pass.Pass());
206 scheduler.ResetDamageForTest();
207 SubmitFrame(&pass_list, surface_id);
208 EXPECT_TRUE(scheduler.damaged);
209 EXPECT_FALSE(scheduler.entire_display_damaged);
211 scheduler.swapped = false;
212 display.DrawAndSwap();
213 EXPECT_TRUE(scheduler.swapped);
214 EXPECT_EQ(2u, output_surface_ptr_->num_sent_frames());
218 // Pass is wrong size so shouldn't be swapped.
219 pass = RenderPass::Create();
220 pass->output_rect = gfx::Rect(0, 0, 99, 99);
221 pass->damage_rect = gfx::Rect(10, 10, 10, 10);
222 pass->id = RenderPassId(1, 1);
224 pass_list.push_back(pass.Pass());
225 scheduler.ResetDamageForTest();
226 SubmitFrame(&pass_list, surface_id);
227 EXPECT_TRUE(scheduler.damaged);
228 EXPECT_FALSE(scheduler.entire_display_damaged);
230 scheduler.swapped = false;
231 display.DrawAndSwap();
232 EXPECT_TRUE(scheduler.swapped);
233 EXPECT_EQ(2u, output_surface_ptr_->num_sent_frames());
237 // Pass has copy output request so should be swapped.
238 pass = RenderPass::Create();
239 pass->output_rect = gfx::Rect(0, 0, 100, 100);
240 pass->damage_rect = gfx::Rect(10, 10, 0, 0);
241 bool copy_called = false;
242 pass->copy_requests.push_back(CopyOutputRequest::CreateRequest(
243 base::Bind(&CopyCallback, &copy_called)));
244 pass->id = RenderPassId(1, 1);
246 pass_list.push_back(pass.Pass());
247 scheduler.ResetDamageForTest();
248 SubmitFrame(&pass_list, surface_id);
249 EXPECT_TRUE(scheduler.damaged);
250 EXPECT_FALSE(scheduler.entire_display_damaged);
252 scheduler.swapped = false;
253 display.DrawAndSwap();
254 EXPECT_TRUE(scheduler.swapped);
255 EXPECT_EQ(3u, output_surface_ptr_->num_sent_frames());
256 EXPECT_TRUE(copy_called);
259 // Pass has latency info so should be swapped.
261 pass = RenderPass::Create();
262 pass->output_rect = gfx::Rect(0, 0, 100, 100);
263 pass->damage_rect = gfx::Rect(10, 10, 0, 0);
264 pass->id = RenderPassId(1, 1);
266 pass_list.push_back(pass.Pass());
267 scheduler.ResetDamageForTest();
268 scoped_ptr<DelegatedFrameData> frame_data(new DelegatedFrameData);
269 pass_list.swap(frame_data->render_pass_list);
271 scoped_ptr<CompositorFrame> frame(new CompositorFrame);
272 frame->delegated_frame_data = frame_data.Pass();
273 frame->metadata.latency_info.push_back(ui::LatencyInfo());
275 factory_.SubmitFrame(surface_id, frame.Pass(),
276 SurfaceFactory::DrawCallback());
277 EXPECT_TRUE(scheduler.damaged);
278 EXPECT_FALSE(scheduler.entire_display_damaged);
280 scheduler.swapped = false;
281 display.DrawAndSwap();
282 EXPECT_TRUE(scheduler.swapped);
283 EXPECT_EQ(4u, output_surface_ptr_->num_sent_frames());
286 // Resize should cause a swap if no frame was swapped at the previous size.
288 scheduler.swapped = false;
289 display.Resize(gfx::Size(200, 200));
290 EXPECT_FALSE(scheduler.swapped);
291 EXPECT_EQ(4u, output_surface_ptr_->num_sent_frames());
293 pass = RenderPass::Create();
294 pass->output_rect = gfx::Rect(0, 0, 200, 200);
295 pass->damage_rect = gfx::Rect(10, 10, 10, 10);
296 pass->id = RenderPassId(1, 1);
298 pass_list.push_back(pass.Pass());
299 scheduler.ResetDamageForTest();
300 scoped_ptr<DelegatedFrameData> frame_data(new DelegatedFrameData);
301 pass_list.swap(frame_data->render_pass_list);
303 scoped_ptr<CompositorFrame> frame(new CompositorFrame);
304 frame->delegated_frame_data = frame_data.Pass();
306 factory_.SubmitFrame(surface_id, frame.Pass(),
307 SurfaceFactory::DrawCallback());
308 EXPECT_TRUE(scheduler.damaged);
309 EXPECT_FALSE(scheduler.entire_display_damaged);
311 scheduler.swapped = false;
312 display.Resize(gfx::Size(100, 100));
313 EXPECT_TRUE(scheduler.swapped);
314 EXPECT_EQ(5u, output_surface_ptr_->num_sent_frames());
317 factory_.Destroy(surface_id);
320 class MockedContext : public TestWebGraphicsContext3D {
321 public:
322 MOCK_METHOD0(shallowFinishCHROMIUM, void());
325 TEST_F(DisplayTest, Finish) {
326 scoped_ptr<MockedContext> context(new MockedContext());
327 MockedContext* context_ptr = context.get();
328 SetUpContext(context.Pass());
330 EXPECT_CALL(*context_ptr, shallowFinishCHROMIUM()).Times(0);
331 TestDisplayClient client;
332 RendererSettings settings;
333 settings.partial_swap_enabled = true;
334 settings.finish_rendering_on_resize = true;
335 Display display(&client, &manager_, shared_bitmap_manager_.get(), nullptr,
336 settings);
338 TestDisplayScheduler scheduler(&display, &fake_begin_frame_source_);
339 display.Initialize(output_surface_.Pass(), &scheduler);
341 SurfaceId surface_id(7u);
342 display.SetSurfaceId(surface_id, 1.f);
344 display.Resize(gfx::Size(100, 100));
345 factory_.Create(surface_id);
348 RenderPassList pass_list;
349 scoped_ptr<RenderPass> pass = RenderPass::Create();
350 pass->output_rect = gfx::Rect(0, 0, 100, 100);
351 pass->damage_rect = gfx::Rect(10, 10, 1, 1);
352 pass->id = RenderPassId(1, 1);
353 pass_list.push_back(pass.Pass());
355 SubmitFrame(&pass_list, surface_id);
358 display.DrawAndSwap();
360 // First resize and draw shouldn't finish.
361 testing::Mock::VerifyAndClearExpectations(context_ptr);
363 EXPECT_CALL(*context_ptr, shallowFinishCHROMIUM());
364 display.Resize(gfx::Size(150, 150));
365 testing::Mock::VerifyAndClearExpectations(context_ptr);
367 // Another resize without a swap doesn't need to finish.
368 EXPECT_CALL(*context_ptr, shallowFinishCHROMIUM()).Times(0);
369 display.Resize(gfx::Size(200, 200));
370 testing::Mock::VerifyAndClearExpectations(context_ptr);
372 EXPECT_CALL(*context_ptr, shallowFinishCHROMIUM()).Times(0);
374 RenderPassList pass_list;
375 scoped_ptr<RenderPass> pass = RenderPass::Create();
376 pass->output_rect = gfx::Rect(0, 0, 200, 200);
377 pass->damage_rect = gfx::Rect(10, 10, 1, 1);
378 pass->id = RenderPassId(1, 1);
379 pass_list.push_back(pass.Pass());
381 SubmitFrame(&pass_list, surface_id);
384 display.DrawAndSwap();
386 testing::Mock::VerifyAndClearExpectations(context_ptr);
388 EXPECT_CALL(*context_ptr, shallowFinishCHROMIUM());
389 display.Resize(gfx::Size(250, 250));
390 testing::Mock::VerifyAndClearExpectations(context_ptr);
392 factory_.Destroy(surface_id);
395 } // namespace
396 } // namespace cc