Adding Peter Thatcher to the owners file.
[chromium-blink-merge.git] / cc / surfaces / display_unittest.cc
blob7b012440907953afdb7a01d3ce5296c41671a0be
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 "cc/output/compositor_frame.h"
6 #include "cc/output/copy_output_result.h"
7 #include "cc/output/delegated_frame_data.h"
8 #include "cc/quads/render_pass.h"
9 #include "cc/resources/shared_bitmap_manager.h"
10 #include "cc/surfaces/display.h"
11 #include "cc/surfaces/display_client.h"
12 #include "cc/surfaces/surface.h"
13 #include "cc/surfaces/surface_factory.h"
14 #include "cc/surfaces/surface_factory_client.h"
15 #include "cc/surfaces/surface_id_allocator.h"
16 #include "cc/surfaces/surface_manager.h"
17 #include "cc/test/fake_output_surface.h"
18 #include "cc/test/test_shared_bitmap_manager.h"
19 #include "testing/gmock/include/gmock/gmock.h"
20 #include "testing/gtest/include/gtest/gtest.h"
22 namespace cc {
23 namespace {
25 class EmptySurfaceFactoryClient : public SurfaceFactoryClient {
26 public:
27 void ReturnResources(const ReturnedResourceArray& resources) override {}
30 class DisplayTest : public testing::Test {
31 public:
32 DisplayTest() : factory_(&manager_, &empty_client_) {}
34 void SetUp() override {
35 output_surface_ = FakeOutputSurface::CreateSoftware(
36 make_scoped_ptr(new SoftwareOutputDevice));
37 shared_bitmap_manager_.reset(new TestSharedBitmapManager);
38 output_surface_ptr_ = output_surface_.get();
41 protected:
42 void SubmitFrame(RenderPassList* pass_list, SurfaceId surface_id) {
43 scoped_ptr<DelegatedFrameData> frame_data(new DelegatedFrameData);
44 pass_list->swap(frame_data->render_pass_list);
46 scoped_ptr<CompositorFrame> frame(new CompositorFrame);
47 frame->delegated_frame_data = frame_data.Pass();
49 factory_.SubmitFrame(surface_id, frame.Pass(),
50 SurfaceFactory::DrawCallback());
53 SurfaceManager manager_;
54 EmptySurfaceFactoryClient empty_client_;
55 SurfaceFactory factory_;
56 scoped_ptr<FakeOutputSurface> output_surface_;
57 FakeOutputSurface* output_surface_ptr_;
58 scoped_ptr<SharedBitmapManager> shared_bitmap_manager_;
61 class TestDisplayClient : public DisplayClient {
62 public:
63 TestDisplayClient() : damaged(false), swapped(false) {}
64 ~TestDisplayClient() override {}
66 void DisplayDamaged() override { damaged = true; }
67 void DidSwapBuffers() override { swapped = true; }
68 void DidSwapBuffersComplete() override {}
69 void CommitVSyncParameters(base::TimeTicks timebase,
70 base::TimeDelta interval) override {}
71 void OutputSurfaceLost() override {}
72 void SetMemoryPolicy(const ManagedMemoryPolicy& policy) override {}
74 bool damaged;
75 bool swapped;
78 void CopyCallback(bool* called, scoped_ptr<CopyOutputResult> result) {
79 *called = true;
82 // Check that frame is damaged and swapped only under correct conditions.
83 TEST_F(DisplayTest, DisplayDamaged) {
84 TestDisplayClient client;
85 RendererSettings settings;
86 settings.partial_swap_enabled = true;
87 Display display(&client, &manager_, shared_bitmap_manager_.get(), nullptr,
88 settings);
90 display.Initialize(output_surface_.Pass());
92 SurfaceId surface_id(7u);
93 EXPECT_FALSE(client.damaged);
94 display.SetSurfaceId(surface_id, 1.f);
95 EXPECT_TRUE(client.damaged);
97 client.damaged = false;
98 display.Resize(gfx::Size(100, 100));
99 EXPECT_TRUE(client.damaged);
101 factory_.Create(surface_id);
103 // First draw from surface should have full damage.
104 RenderPassList pass_list;
105 scoped_ptr<RenderPass> pass = RenderPass::Create();
106 pass->output_rect = gfx::Rect(0, 0, 100, 100);
107 pass->damage_rect = gfx::Rect(10, 10, 1, 1);
108 pass->id = RenderPassId(1, 1);
109 pass_list.push_back(pass.Pass());
111 client.damaged = false;
112 SubmitFrame(&pass_list, surface_id);
113 EXPECT_TRUE(client.damaged);
115 EXPECT_FALSE(client.swapped);
116 EXPECT_EQ(0u, output_surface_ptr_->num_sent_frames());
117 display.Draw();
118 EXPECT_TRUE(client.swapped);
119 EXPECT_EQ(1u, output_surface_ptr_->num_sent_frames());
120 SoftwareFrameData* software_data =
121 output_surface_ptr_->last_sent_frame().software_frame_data.get();
122 ASSERT_NE(nullptr, software_data);
123 EXPECT_EQ(gfx::Size(100, 100).ToString(), software_data->size.ToString());
124 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
125 software_data->damage_rect.ToString());
128 // Only damaged portion should be swapped.
129 pass = RenderPass::Create();
130 pass->output_rect = gfx::Rect(0, 0, 100, 100);
131 pass->damage_rect = gfx::Rect(10, 10, 1, 1);
132 pass->id = RenderPassId(1, 1);
134 pass_list.push_back(pass.Pass());
135 client.damaged = false;
136 SubmitFrame(&pass_list, surface_id);
137 EXPECT_TRUE(client.damaged);
139 client.swapped = false;
140 display.Draw();
141 EXPECT_TRUE(client.swapped);
142 EXPECT_EQ(2u, output_surface_ptr_->num_sent_frames());
143 software_data =
144 output_surface_ptr_->last_sent_frame().software_frame_data.get();
145 ASSERT_NE(nullptr, software_data);
146 EXPECT_EQ(gfx::Size(100, 100).ToString(), software_data->size.ToString());
147 EXPECT_EQ(gfx::Rect(10, 10, 1, 1).ToString(),
148 software_data->damage_rect.ToString());
152 // Pass has no damage so shouldn't be swapped.
153 pass = RenderPass::Create();
154 pass->output_rect = gfx::Rect(0, 0, 100, 100);
155 pass->damage_rect = gfx::Rect(10, 10, 0, 0);
156 pass->id = RenderPassId(1, 1);
158 pass_list.push_back(pass.Pass());
159 client.damaged = false;
160 SubmitFrame(&pass_list, surface_id);
161 EXPECT_TRUE(client.damaged);
163 client.swapped = false;
164 display.Draw();
165 EXPECT_TRUE(client.swapped);
166 EXPECT_EQ(2u, output_surface_ptr_->num_sent_frames());
170 // Pass is wrong size so shouldn't be swapped.
171 pass = RenderPass::Create();
172 pass->output_rect = gfx::Rect(0, 0, 99, 99);
173 pass->damage_rect = gfx::Rect(10, 10, 10, 10);
174 pass->id = RenderPassId(1, 1);
176 pass_list.push_back(pass.Pass());
177 client.damaged = false;
178 SubmitFrame(&pass_list, surface_id);
179 EXPECT_TRUE(client.damaged);
181 client.swapped = false;
182 display.Draw();
183 EXPECT_TRUE(client.swapped);
184 EXPECT_EQ(2u, output_surface_ptr_->num_sent_frames());
188 // Pass has copy output request so should be swapped.
189 pass = RenderPass::Create();
190 pass->output_rect = gfx::Rect(0, 0, 100, 100);
191 pass->damage_rect = gfx::Rect(10, 10, 0, 0);
192 bool copy_called = false;
193 pass->copy_requests.push_back(CopyOutputRequest::CreateRequest(
194 base::Bind(&CopyCallback, &copy_called)));
195 pass->id = RenderPassId(1, 1);
197 pass_list.push_back(pass.Pass());
198 client.damaged = false;
199 SubmitFrame(&pass_list, surface_id);
200 EXPECT_TRUE(client.damaged);
202 client.swapped = false;
203 display.Draw();
204 EXPECT_TRUE(client.swapped);
205 EXPECT_EQ(3u, output_surface_ptr_->num_sent_frames());
206 EXPECT_TRUE(copy_called);
209 // Pass has latency info so should be swapped.
211 pass = RenderPass::Create();
212 pass->output_rect = gfx::Rect(0, 0, 100, 100);
213 pass->damage_rect = gfx::Rect(10, 10, 0, 0);
214 pass->id = RenderPassId(1, 1);
216 pass_list.push_back(pass.Pass());
217 client.damaged = false;
218 scoped_ptr<DelegatedFrameData> frame_data(new DelegatedFrameData);
219 pass_list.swap(frame_data->render_pass_list);
221 scoped_ptr<CompositorFrame> frame(new CompositorFrame);
222 frame->delegated_frame_data = frame_data.Pass();
223 frame->metadata.latency_info.push_back(ui::LatencyInfo());
225 factory_.SubmitFrame(surface_id, frame.Pass(),
226 SurfaceFactory::DrawCallback());
227 EXPECT_TRUE(client.damaged);
229 client.swapped = false;
230 display.Draw();
231 EXPECT_TRUE(client.swapped);
232 EXPECT_EQ(4u, output_surface_ptr_->num_sent_frames());
235 factory_.Destroy(surface_id);
238 } // namespace
239 } // namespace cc