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

Side by Side Diff: cc/surfaces/surface_aggregator_unittest.cc

Issue 139763003: Initial surface aggregator implementation (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: use less advanced struct initialization syntax Created 6 years, 10 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 | Annotate | Revision Log
« no previous file with comments | « cc/surfaces/surface_aggregator_test_helpers.cc ('k') | cc/surfaces/surface_unittest.cc » ('j') | 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 2014 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/delegated_frame_data.h"
7 #include "cc/quads/render_pass.h"
8 #include "cc/quads/render_pass_draw_quad.h"
9 #include "cc/quads/solid_color_draw_quad.h"
10 #include "cc/quads/surface_draw_quad.h"
11 #include "cc/surfaces/surface.h"
12 #include "cc/surfaces/surface_aggregator.h"
13 #include "cc/surfaces/surface_aggregator_test_helpers.h"
14 #include "cc/surfaces/surface_manager.h"
15 #include "cc/test/render_pass_test_common.h"
16 #include "cc/test/render_pass_test_utils.h"
17 #include "testing/gtest/include/gtest/gtest.h"
18 #include "third_party/skia/include/core/SkColor.h"
19
20 namespace cc {
21 namespace {
22 const int kInvalidSurfaceId = -1;
23
24 class SurfaceAggregatorTest : public testing::Test {
25 public:
26 SurfaceAggregatorTest() : aggregator_(&manager_) {}
27
28 protected:
29 SurfaceManager manager_;
30 SurfaceAggregator aggregator_;
31 };
32
33 TEST_F(SurfaceAggregatorTest, InvalidSurfaceId) {
34 scoped_ptr<CompositorFrame> frame = aggregator_.Aggregate(kInvalidSurfaceId);
35 EXPECT_FALSE(frame);
36 }
37
38 TEST_F(SurfaceAggregatorTest, ValidSurfaceNoFrame) {
39 Surface one(&manager_, NULL, gfx::Size(5, 5));
40 scoped_ptr<CompositorFrame> frame = aggregator_.Aggregate(one.surface_id());
41 EXPECT_FALSE(frame);
42 }
43
44 class SurfaceAggregatorValidSurfaceTest : public SurfaceAggregatorTest {
45 public:
46 SurfaceAggregatorValidSurfaceTest()
47 : root_surface_(&manager_, NULL, gfx::Size(5, 5)) {}
48
49 void AggregateAndVerify(test::Pass* expected_passes,
50 size_t expected_pass_count) {
51 scoped_ptr<CompositorFrame> aggregated_frame =
52 aggregator_.Aggregate(root_surface_.surface_id());
53
54 ASSERT_TRUE(aggregated_frame);
55 ASSERT_TRUE(aggregated_frame->delegated_frame_data);
56
57 DelegatedFrameData* frame_data =
58 aggregated_frame->delegated_frame_data.get();
59
60 TestPassesMatchExpectations(
61 expected_passes, expected_pass_count, &frame_data->render_pass_list);
62 }
63
64 protected:
65 Surface root_surface_;
66 };
67
68 // Tests that a very simple frame containing only two solid color quads makes it
69 // through the aggregator correctly.
70 TEST_F(SurfaceAggregatorValidSurfaceTest, SimpleFrame) {
71 test::Quad quads[] = {test::Quad::SolidColorQuad(SK_ColorRED),
72 test::Quad::SolidColorQuad(SK_ColorBLUE)};
73 test::Pass passes[] = {test::Pass(quads, arraysize(quads))};
74
75 SubmitFrame(passes, arraysize(passes), &root_surface_);
76
77 AggregateAndVerify(passes, arraysize(passes));
78 }
79
80 TEST_F(SurfaceAggregatorValidSurfaceTest, MultiPassSimpleFrame) {
81 test::Quad quads[][2] = {{test::Quad::SolidColorQuad(SK_ColorWHITE),
82 test::Quad::SolidColorQuad(SK_ColorLTGRAY)},
83 {test::Quad::SolidColorQuad(SK_ColorGRAY),
84 test::Quad::SolidColorQuad(SK_ColorDKGRAY)}};
85 test::Pass passes[] = {test::Pass(quads[0], arraysize(quads[0])),
86 test::Pass(quads[1], arraysize(quads[1]))};
87
88 SubmitFrame(passes, arraysize(passes), &root_surface_);
89
90 AggregateAndVerify(passes, arraysize(passes));
91 }
92
93 // This tests very simple embedding. root_surface has a frame containing a few
94 // solid color quads and a surface quad referencing embedded_surface.
95 // embedded_surface has a frame containing only a solid color quad. The solid
96 // color quad should be aggregated into the final frame.
97 TEST_F(SurfaceAggregatorValidSurfaceTest, SimpleSurfaceReference) {
98 gfx::Size surface_size(5, 5);
99
100 Surface embedded_surface(&manager_, NULL, surface_size);
101
102 test::Quad embedded_quads[] = {test::Quad::SolidColorQuad(SK_ColorGREEN)};
103 test::Pass embedded_passes[] = {
104 test::Pass(embedded_quads, arraysize(embedded_quads))};
105
106 SubmitFrame(embedded_passes, arraysize(embedded_passes), &embedded_surface);
107
108 test::Quad root_quads[] = {
109 test::Quad::SolidColorQuad(SK_ColorWHITE),
110 test::Quad::SurfaceQuad(embedded_surface.surface_id()),
111 test::Quad::SolidColorQuad(SK_ColorBLACK)};
112 test::Pass root_passes[] = {test::Pass(root_quads, arraysize(root_quads))};
113
114 SubmitFrame(root_passes, arraysize(root_passes), &root_surface_);
115
116 test::Quad expected_quads[] = {test::Quad::SolidColorQuad(SK_ColorWHITE),
117 test::Quad::SolidColorQuad(SK_ColorGREEN),
118 test::Quad::SolidColorQuad(SK_ColorBLACK)};
119 test::Pass expected_passes[] = {
120 test::Pass(expected_quads, arraysize(expected_quads))};
121 AggregateAndVerify(expected_passes, arraysize(expected_passes));
122 }
123
124 // This tests referencing a surface that has multiple render passes.
125 TEST_F(SurfaceAggregatorValidSurfaceTest, MultiPassSurfaceReference) {
126 gfx::Size surface_size(5, 5);
127
128 Surface embedded_surface(&manager_, NULL, surface_size);
129
130 RenderPass::Id pass_ids[] = {RenderPass::Id(1, 1), RenderPass::Id(1, 2),
131 RenderPass::Id(1, 3)};
132
133 test::Quad embedded_quads[][2] = {
134 {test::Quad::SolidColorQuad(1), test::Quad::SolidColorQuad(2)},
135 {test::Quad::SolidColorQuad(3), test::Quad::RenderPassQuad(pass_ids[0])},
136 {test::Quad::SolidColorQuad(4), test::Quad::RenderPassQuad(pass_ids[1])}};
137 test::Pass embedded_passes[] = {
138 test::Pass(embedded_quads[0], arraysize(embedded_quads[0]), pass_ids[0]),
139 test::Pass(embedded_quads[1], arraysize(embedded_quads[1]), pass_ids[1]),
140 test::Pass(embedded_quads[2], arraysize(embedded_quads[2]), pass_ids[2])};
141
142 SubmitFrame(embedded_passes, arraysize(embedded_passes), &embedded_surface);
143
144 test::Quad root_quads[][2] = {
145 {test::Quad::SolidColorQuad(5), test::Quad::SolidColorQuad(6)},
146 {test::Quad::SurfaceQuad(embedded_surface.surface_id()),
147 test::Quad::RenderPassQuad(pass_ids[0])},
148 {test::Quad::SolidColorQuad(7), test::Quad::RenderPassQuad(pass_ids[1])}};
149 test::Pass root_passes[] = {
150 test::Pass(root_quads[0], arraysize(root_quads[0]), pass_ids[0]),
151 test::Pass(root_quads[1], arraysize(root_quads[1]), pass_ids[1]),
152 test::Pass(root_quads[2], arraysize(root_quads[2]), pass_ids[2])};
153
154 SubmitFrame(root_passes, arraysize(root_passes), &root_surface_);
155
156 scoped_ptr<CompositorFrame> aggregated_frame =
157 aggregator_.Aggregate(root_surface_.surface_id());
158
159 ASSERT_TRUE(aggregated_frame);
160 ASSERT_TRUE(aggregated_frame->delegated_frame_data);
161
162 DelegatedFrameData* frame_data = aggregated_frame->delegated_frame_data.get();
163
164 const RenderPassList& aggregated_pass_list = frame_data->render_pass_list;
165
166 ASSERT_EQ(5u, aggregated_pass_list.size());
167 RenderPass::Id actual_pass_ids[] = {
168 aggregated_pass_list[0]->id, aggregated_pass_list[1]->id,
169 aggregated_pass_list[2]->id, aggregated_pass_list[3]->id,
170 aggregated_pass_list[4]->id};
171 for (size_t i = 0; i < 5; ++i) {
172 for (size_t j = 0; j < i; ++j) {
173 EXPECT_NE(actual_pass_ids[i], actual_pass_ids[j]);
174 }
175 }
176
177 {
178 SCOPED_TRACE("First pass");
179 // The first pass will just be the first pass from the root surfaces quad
180 // with no render pass quads to remap.
181 TestPassMatchesExpectations(root_passes[0], aggregated_pass_list[0]);
182 }
183
184 {
185 SCOPED_TRACE("Second pass");
186 // The next two passes will be from the embedded surface since we have to
187 // draw those passes before they are referenced from the render pass draw
188 // quad embedded into the root surface's second pass.
189 // First, there's the first embedded pass which doesn't reference anything
190 // else.
191 TestPassMatchesExpectations(embedded_passes[0], aggregated_pass_list[1]);
192 }
193
194 {
195 SCOPED_TRACE("Third pass");
196 const QuadList& third_pass_quad_list = aggregated_pass_list[2]->quad_list;
197 ASSERT_EQ(2u, third_pass_quad_list.size());
198 TestQuadMatchesExpectations(embedded_quads[1][0],
199 third_pass_quad_list.at(0u));
200
201 // This render pass pass quad will reference the first pass from the
202 // embedded surface, which is the second pass in the aggregated frame.
203 ASSERT_EQ(DrawQuad::RENDER_PASS, third_pass_quad_list.at(1u)->material);
204 const RenderPassDrawQuad* third_pass_render_pass_draw_quad =
205 RenderPassDrawQuad::MaterialCast(third_pass_quad_list.at(1u));
206 EXPECT_EQ(actual_pass_ids[1],
207 third_pass_render_pass_draw_quad->render_pass_id);
208 }
209
210 {
211 SCOPED_TRACE("Fourth pass");
212 // The fourth pass will have aggregated quads from the root surface's second
213 // pass and the embedded surface's first pass.
214 const QuadList& fourth_pass_quad_list = aggregated_pass_list[3]->quad_list;
215 ASSERT_EQ(3u, fourth_pass_quad_list.size());
216
217 // The first quad will be the yellow quad from the embedded surface's last
218 // pass.
219 TestQuadMatchesExpectations(embedded_quads[2][0],
220 fourth_pass_quad_list.at(0u));
221
222 // The next quad will be a render pass quad referencing the second pass from
223 // the embedded surface, which is the third pass in the aggregated frame.
224 ASSERT_EQ(DrawQuad::RENDER_PASS, fourth_pass_quad_list.at(1u)->material);
225 const RenderPassDrawQuad* fourth_pass_first_render_pass_draw_quad =
226 RenderPassDrawQuad::MaterialCast(fourth_pass_quad_list.at(1u));
227 EXPECT_EQ(actual_pass_ids[2],
228 fourth_pass_first_render_pass_draw_quad->render_pass_id);
229
230 // The last quad will be a render pass quad referencing the first pass from
231 // the root surface, which is the first pass overall.
232 ASSERT_EQ(DrawQuad::RENDER_PASS, fourth_pass_quad_list.at(2u)->material);
233 const RenderPassDrawQuad* fourth_pass_second_render_pass_draw_quad =
234 RenderPassDrawQuad::MaterialCast(fourth_pass_quad_list.at(2u));
235 EXPECT_EQ(actual_pass_ids[0],
236 fourth_pass_second_render_pass_draw_quad->render_pass_id);
237 }
238
239 {
240 SCOPED_TRACE("Fifth pass");
241 const QuadList& fifth_pass_quad_list = aggregated_pass_list[4]->quad_list;
242 ASSERT_EQ(2u, fifth_pass_quad_list.size());
243
244 TestQuadMatchesExpectations(root_quads[2][0], fifth_pass_quad_list.at(0));
245
246 // The last quad in the last pass will reference the second pass from the
247 // root surface, which after aggregating is the fourth pass in the overall
248 // list.
249 ASSERT_EQ(DrawQuad::RENDER_PASS, fifth_pass_quad_list.at(1u)->material);
250 const RenderPassDrawQuad* fifth_pass_render_pass_draw_quad =
251 RenderPassDrawQuad::MaterialCast(fifth_pass_quad_list.at(1u));
252 EXPECT_EQ(actual_pass_ids[3],
253 fifth_pass_render_pass_draw_quad->render_pass_id);
254 }
255 }
256
257 // Tests an invalid surface reference in a frame. The surface quad should just
258 // be dropped.
259 TEST_F(SurfaceAggregatorValidSurfaceTest, InvalidSurfaceReference) {
260 test::Quad quads[] = {test::Quad::SolidColorQuad(SK_ColorGREEN),
261 test::Quad::SurfaceQuad(kInvalidSurfaceId),
262 test::Quad::SolidColorQuad(SK_ColorBLUE)};
263 test::Pass passes[] = {test::Pass(quads, arraysize(quads))};
264
265 SubmitFrame(passes, arraysize(passes), &root_surface_);
266
267 test::Quad expected_quads[] = {test::Quad::SolidColorQuad(SK_ColorGREEN),
268 test::Quad::SolidColorQuad(SK_ColorBLUE)};
269 test::Pass expected_passes[] = {
270 test::Pass(expected_quads, arraysize(expected_quads))};
271 AggregateAndVerify(expected_passes, arraysize(expected_passes));
272 }
273
274 // Tests a reference to a valid surface with no submitted frame. This quad
275 // should also just be dropped.
276 TEST_F(SurfaceAggregatorValidSurfaceTest, ValidSurfaceReferenceWithNoFrame) {
277 Surface surface_with_no_frame(&manager_, NULL, gfx::Size(5, 5));
278 test::Quad quads[] = {
279 test::Quad::SolidColorQuad(SK_ColorGREEN),
280 test::Quad::SurfaceQuad(surface_with_no_frame.surface_id()),
281 test::Quad::SolidColorQuad(SK_ColorBLUE)};
282 test::Pass passes[] = {test::Pass(quads, arraysize(quads))};
283
284 SubmitFrame(passes, arraysize(passes), &root_surface_);
285
286 test::Quad expected_quads[] = {test::Quad::SolidColorQuad(SK_ColorGREEN),
287 test::Quad::SolidColorQuad(SK_ColorBLUE)};
288 test::Pass expected_passes[] = {
289 test::Pass(expected_quads, arraysize(expected_quads))};
290 AggregateAndVerify(expected_passes, arraysize(expected_passes));
291 }
292
293 // Tests a surface quad referencing itself, generating a trivial cycle.
294 // The quad creating the cycle should be dropped from the final frame.
295 TEST_F(SurfaceAggregatorValidSurfaceTest, SimpleCyclicalReference) {
296 test::Quad quads[] = {test::Quad::SurfaceQuad(root_surface_.surface_id()),
297 test::Quad::SolidColorQuad(SK_ColorYELLOW)};
298 test::Pass passes[] = {test::Pass(quads, arraysize(quads))};
299
300 SubmitFrame(passes, arraysize(passes), &root_surface_);
301
302 test::Quad expected_quads[] = {test::Quad::SolidColorQuad(SK_ColorYELLOW)};
303 test::Pass expected_passes[] = {
304 test::Pass(expected_quads, arraysize(expected_quads))};
305 AggregateAndVerify(expected_passes, arraysize(expected_passes));
306 }
307
308 // Tests a more complex cycle with one intermediate surface.
309 TEST_F(SurfaceAggregatorValidSurfaceTest, TwoSurfaceCyclicalReference) {
310 gfx::Size surface_size(5, 5);
311
312 Surface child_surface(&manager_, NULL, surface_size);
313
314 test::Quad parent_quads[] = {
315 test::Quad::SolidColorQuad(SK_ColorBLUE),
316 test::Quad::SurfaceQuad(child_surface.surface_id()),
317 test::Quad::SolidColorQuad(SK_ColorCYAN)};
318 test::Pass parent_passes[] = {
319 test::Pass(parent_quads, arraysize(parent_quads))};
320
321 SubmitFrame(parent_passes, arraysize(parent_passes), &root_surface_);
322
323 test::Quad child_quads[] = {
324 test::Quad::SolidColorQuad(SK_ColorGREEN),
325 test::Quad::SurfaceQuad(root_surface_.surface_id()),
326 test::Quad::SolidColorQuad(SK_ColorMAGENTA)};
327 test::Pass child_passes[] = {test::Pass(child_quads, arraysize(child_quads))};
328
329 SubmitFrame(child_passes, arraysize(child_passes), &child_surface);
330
331 // The child surface's reference to the root_surface_ will be dropped, so
332 // we'll end up with:
333 // SK_ColorBLUE from the parent
334 // SK_ColorGREEN from the child
335 // SK_ColorMAGENTA from the child
336 // SK_ColorCYAN from the parent
337 test::Quad expected_quads[] = {test::Quad::SolidColorQuad(SK_ColorBLUE),
338 test::Quad::SolidColorQuad(SK_ColorGREEN),
339 test::Quad::SolidColorQuad(SK_ColorMAGENTA),
340 test::Quad::SolidColorQuad(SK_ColorCYAN)};
341 test::Pass expected_passes[] = {
342 test::Pass(expected_quads, arraysize(expected_quads))};
343 AggregateAndVerify(expected_passes, arraysize(expected_passes));
344 }
345
346 // Tests that we map render pass IDs from different surfaces into a unified
347 // namespace and update RenderPassDrawQuad's id references to match.
348 TEST_F(SurfaceAggregatorValidSurfaceTest, RenderPassIdMapping) {
349 gfx::Size surface_size(5, 5);
350
351 Surface child_surface(&manager_, NULL, surface_size);
352
353 RenderPass::Id child_pass_id[] = {RenderPass::Id(1, 1), RenderPass::Id(1, 2)};
354 test::Quad child_quad[][1] = {{test::Quad::SolidColorQuad(SK_ColorGREEN)},
355 {test::Quad::RenderPassQuad(child_pass_id[0])}};
356 test::Pass surface_passes[] = {
357 test::Pass(child_quad[0], arraysize(child_quad[0]), child_pass_id[0]),
358 test::Pass(child_quad[1], arraysize(child_quad[1]), child_pass_id[1])};
359
360 SubmitFrame(surface_passes, arraysize(surface_passes), &child_surface);
361
362 // Pass IDs from the parent surface may collide with ones from the child.
363 RenderPass::Id parent_pass_id[] = {RenderPass::Id(2, 1),
364 RenderPass::Id(1, 2)};
365 test::Quad parent_quad[][1] = {
366 {test::Quad::SurfaceQuad(child_surface.surface_id())},
367 {test::Quad::RenderPassQuad(parent_pass_id[0])}};
368 test::Pass parent_passes[] = {
369 test::Pass(parent_quad[0], arraysize(parent_quad[0]), parent_pass_id[0]),
370 test::Pass(parent_quad[1], arraysize(parent_quad[1]), parent_pass_id[1])};
371
372 SubmitFrame(parent_passes, arraysize(parent_passes), &root_surface_);
373 scoped_ptr<CompositorFrame> aggregated_frame =
374 aggregator_.Aggregate(root_surface_.surface_id());
375
376 ASSERT_TRUE(aggregated_frame);
377 ASSERT_TRUE(aggregated_frame->delegated_frame_data);
378
379 DelegatedFrameData* frame_data = aggregated_frame->delegated_frame_data.get();
380
381 const RenderPassList& aggregated_pass_list = frame_data->render_pass_list;
382
383 ASSERT_EQ(3u, aggregated_pass_list.size());
384 RenderPass::Id actual_pass_ids[] = {aggregated_pass_list[0]->id,
385 aggregated_pass_list[1]->id,
386 aggregated_pass_list[2]->id};
387 // Make sure the aggregated frame's pass IDs are all unique.
388 for (size_t i = 0; i < 3; ++i) {
389 for (size_t j = 0; j < i; ++j) {
390 EXPECT_NE(actual_pass_ids[j], actual_pass_ids[i]) << "pass ids " << i
391 << " and " << j;
392 }
393 }
394
395 // Make sure the render pass quads reference the remapped pass IDs.
396 DrawQuad* render_pass_quads[] = {aggregated_pass_list[1]->quad_list[0],
397 aggregated_pass_list[2]->quad_list[0]};
398 ASSERT_EQ(render_pass_quads[0]->material, DrawQuad::RENDER_PASS);
399 EXPECT_EQ(
400 actual_pass_ids[0],
401 RenderPassDrawQuad::MaterialCast(render_pass_quads[0])->render_pass_id);
402
403 ASSERT_EQ(render_pass_quads[1]->material, DrawQuad::RENDER_PASS);
404 EXPECT_EQ(
405 actual_pass_ids[1],
406 RenderPassDrawQuad::MaterialCast(render_pass_quads[1])->render_pass_id);
407 }
408
409 } // namespace
410 } // namespace cc
OLDNEW
« no previous file with comments | « cc/surfaces/surface_aggregator_test_helpers.cc ('k') | cc/surfaces/surface_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698