OLD | NEW |
| (Empty) |
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. | |
4 | |
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" | |
21 | |
22 namespace cc { | |
23 namespace { | |
24 | |
25 class EmptySurfaceFactoryClient : public SurfaceFactoryClient { | |
26 public: | |
27 void ReturnResources(const ReturnedResourceArray& resources) override {} | |
28 }; | |
29 | |
30 class DisplayTest : public testing::Test { | |
31 public: | |
32 DisplayTest() : factory_(&manager_, &empty_client_) {} | |
33 | |
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(); | |
39 } | |
40 | |
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); | |
45 | |
46 scoped_ptr<CompositorFrame> frame(new CompositorFrame); | |
47 frame->delegated_frame_data = frame_data.Pass(); | |
48 | |
49 factory_.SubmitFrame(surface_id, frame.Pass(), | |
50 SurfaceFactory::DrawCallback()); | |
51 } | |
52 | |
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_; | |
59 }; | |
60 | |
61 class TestDisplayClient : public DisplayClient { | |
62 public: | |
63 TestDisplayClient() : damaged(false), swapped(false) {} | |
64 ~TestDisplayClient() override {} | |
65 | |
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 {} | |
73 | |
74 bool damaged; | |
75 bool swapped; | |
76 }; | |
77 | |
78 void CopyCallback(bool* called, scoped_ptr<CopyOutputResult> result) { | |
79 *called = true; | |
80 } | |
81 | |
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); | |
89 | |
90 display.Initialize(output_surface_.Pass()); | |
91 | |
92 SurfaceId surface_id(7u); | |
93 EXPECT_FALSE(client.damaged); | |
94 display.SetSurfaceId(surface_id, 1.f); | |
95 EXPECT_TRUE(client.damaged); | |
96 | |
97 client.damaged = false; | |
98 display.Resize(gfx::Size(100, 100)); | |
99 EXPECT_TRUE(client.damaged); | |
100 | |
101 factory_.Create(surface_id); | |
102 | |
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()); | |
110 | |
111 client.damaged = false; | |
112 SubmitFrame(&pass_list, surface_id); | |
113 EXPECT_TRUE(client.damaged); | |
114 | |
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()); | |
126 | |
127 { | |
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); | |
133 | |
134 pass_list.push_back(pass.Pass()); | |
135 client.damaged = false; | |
136 SubmitFrame(&pass_list, surface_id); | |
137 EXPECT_TRUE(client.damaged); | |
138 | |
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()); | |
149 } | |
150 | |
151 { | |
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); | |
157 | |
158 pass_list.push_back(pass.Pass()); | |
159 client.damaged = false; | |
160 SubmitFrame(&pass_list, surface_id); | |
161 EXPECT_TRUE(client.damaged); | |
162 | |
163 client.swapped = false; | |
164 display.Draw(); | |
165 EXPECT_TRUE(client.swapped); | |
166 EXPECT_EQ(2u, output_surface_ptr_->num_sent_frames()); | |
167 } | |
168 | |
169 { | |
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); | |
175 | |
176 pass_list.push_back(pass.Pass()); | |
177 client.damaged = false; | |
178 SubmitFrame(&pass_list, surface_id); | |
179 EXPECT_TRUE(client.damaged); | |
180 | |
181 client.swapped = false; | |
182 display.Draw(); | |
183 EXPECT_TRUE(client.swapped); | |
184 EXPECT_EQ(2u, output_surface_ptr_->num_sent_frames()); | |
185 } | |
186 | |
187 { | |
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, ©_called))); | |
195 pass->id = RenderPassId(1, 1); | |
196 | |
197 pass_list.push_back(pass.Pass()); | |
198 client.damaged = false; | |
199 SubmitFrame(&pass_list, surface_id); | |
200 EXPECT_TRUE(client.damaged); | |
201 | |
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); | |
207 } | |
208 | |
209 // Pass has latency info so should be swapped. | |
210 { | |
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); | |
215 | |
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); | |
220 | |
221 scoped_ptr<CompositorFrame> frame(new CompositorFrame); | |
222 frame->delegated_frame_data = frame_data.Pass(); | |
223 frame->metadata.latency_info.push_back(ui::LatencyInfo()); | |
224 | |
225 factory_.SubmitFrame(surface_id, frame.Pass(), | |
226 SurfaceFactory::DrawCallback()); | |
227 EXPECT_TRUE(client.damaged); | |
228 | |
229 client.swapped = false; | |
230 display.Draw(); | |
231 EXPECT_TRUE(client.swapped); | |
232 EXPECT_EQ(4u, output_surface_ptr_->num_sent_frames()); | |
233 } | |
234 | |
235 factory_.Destroy(surface_id); | |
236 } | |
237 | |
238 } // namespace | |
239 } // namespace cc | |
OLD | NEW |