| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "cc/output/compositor_frame.h" | 5 #include "cc/output/compositor_frame.h" |
| 6 #include "cc/output/delegated_frame_data.h" | 6 #include "cc/output/delegated_frame_data.h" |
| 7 #include "cc/quads/render_pass.h" | 7 #include "cc/quads/render_pass.h" |
| 8 #include "cc/quads/render_pass_draw_quad.h" | 8 #include "cc/quads/render_pass_draw_quad.h" |
| 9 #include "cc/quads/solid_color_draw_quad.h" | 9 #include "cc/quads/solid_color_draw_quad.h" |
| 10 #include "cc/quads/surface_draw_quad.h" | 10 #include "cc/quads/surface_draw_quad.h" |
| (...skipping 30 matching lines...) Expand all Loading... |
| 41 return size; | 41 return size; |
| 42 } | 42 } |
| 43 | 43 |
| 44 class EmptySurfaceFactoryClient : public SurfaceFactoryClient { | 44 class EmptySurfaceFactoryClient : public SurfaceFactoryClient { |
| 45 public: | 45 public: |
| 46 void ReturnResources(const ReturnedResourceArray& resources) override {} | 46 void ReturnResources(const ReturnedResourceArray& resources) override {} |
| 47 }; | 47 }; |
| 48 | 48 |
| 49 class SurfaceAggregatorTest : public testing::Test { | 49 class SurfaceAggregatorTest : public testing::Test { |
| 50 public: | 50 public: |
| 51 SurfaceAggregatorTest() | 51 explicit SurfaceAggregatorTest(bool use_damage_rect) |
| 52 : factory_(&manager_, &empty_client_), aggregator_(&manager_, NULL) {} | 52 : factory_(&manager_, &empty_client_), |
| 53 aggregator_(&manager_, NULL, use_damage_rect) {} |
| 54 |
| 55 SurfaceAggregatorTest() : SurfaceAggregatorTest(false) {} |
| 53 | 56 |
| 54 protected: | 57 protected: |
| 55 SurfaceManager manager_; | 58 SurfaceManager manager_; |
| 56 EmptySurfaceFactoryClient empty_client_; | 59 EmptySurfaceFactoryClient empty_client_; |
| 57 SurfaceFactory factory_; | 60 SurfaceFactory factory_; |
| 58 SurfaceAggregator aggregator_; | 61 SurfaceAggregator aggregator_; |
| 59 }; | 62 }; |
| 60 | 63 |
| 61 TEST_F(SurfaceAggregatorTest, ValidSurfaceNoFrame) { | 64 TEST_F(SurfaceAggregatorTest, ValidSurfaceNoFrame) { |
| 62 SurfaceId one_id(7); | 65 SurfaceId one_id(7); |
| 63 factory_.Create(one_id); | 66 factory_.Create(one_id); |
| 64 scoped_ptr<CompositorFrame> frame = aggregator_.Aggregate(one_id); | 67 scoped_ptr<CompositorFrame> frame = aggregator_.Aggregate(one_id); |
| 65 EXPECT_FALSE(frame); | 68 EXPECT_FALSE(frame); |
| 66 factory_.Destroy(one_id); | 69 factory_.Destroy(one_id); |
| 67 } | 70 } |
| 68 | 71 |
| 69 class SurfaceAggregatorValidSurfaceTest : public SurfaceAggregatorTest { | 72 class SurfaceAggregatorValidSurfaceTest : public SurfaceAggregatorTest { |
| 70 public: | 73 public: |
| 71 SurfaceAggregatorValidSurfaceTest() : allocator_(1u), child_allocator_(2u) {} | 74 explicit SurfaceAggregatorValidSurfaceTest(bool use_damage_rect) |
| 75 : SurfaceAggregatorTest(use_damage_rect), |
| 76 allocator_(1u), |
| 77 child_allocator_(2u) {} |
| 78 SurfaceAggregatorValidSurfaceTest() |
| 79 : SurfaceAggregatorValidSurfaceTest(false) {} |
| 72 | 80 |
| 73 void SetUp() override { | 81 void SetUp() override { |
| 74 SurfaceAggregatorTest::SetUp(); | 82 SurfaceAggregatorTest::SetUp(); |
| 75 root_surface_id_ = allocator_.GenerateId(); | 83 root_surface_id_ = allocator_.GenerateId(); |
| 76 factory_.Create(root_surface_id_); | 84 factory_.Create(root_surface_id_); |
| 77 } | 85 } |
| 78 | 86 |
| 79 void TearDown() override { | 87 void TearDown() override { |
| 80 factory_.Destroy(root_surface_id_); | 88 factory_.Destroy(root_surface_id_); |
| 81 SurfaceAggregatorTest::TearDown(); | 89 SurfaceAggregatorTest::TearDown(); |
| (...skipping 23 matching lines...) Expand all Loading... |
| 105 | 113 |
| 106 EXPECT_EQ(expected_surface_count, | 114 EXPECT_EQ(expected_surface_count, |
| 107 aggregator_.previous_contained_surfaces().size()); | 115 aggregator_.previous_contained_surfaces().size()); |
| 108 for (size_t i = 0; i < expected_surface_count; i++) { | 116 for (size_t i = 0; i < expected_surface_count; i++) { |
| 109 EXPECT_TRUE( | 117 EXPECT_TRUE( |
| 110 aggregator_.previous_contained_surfaces().find(surface_ids[i]) != | 118 aggregator_.previous_contained_surfaces().find(surface_ids[i]) != |
| 111 aggregator_.previous_contained_surfaces().end()); | 119 aggregator_.previous_contained_surfaces().end()); |
| 112 } | 120 } |
| 113 } | 121 } |
| 114 | 122 |
| 115 void SubmitFrame(test::Pass* passes, | 123 void SubmitPassListAsFrame(SurfaceId surface_id, RenderPassList* pass_list) { |
| 116 size_t pass_count, | |
| 117 SurfaceId surface_id) { | |
| 118 RenderPassList pass_list; | |
| 119 AddPasses(&pass_list, gfx::Rect(SurfaceSize()), passes, pass_count); | |
| 120 | |
| 121 scoped_ptr<DelegatedFrameData> frame_data(new DelegatedFrameData); | 124 scoped_ptr<DelegatedFrameData> frame_data(new DelegatedFrameData); |
| 122 pass_list.swap(frame_data->render_pass_list); | 125 pass_list->swap(frame_data->render_pass_list); |
| 123 | 126 |
| 124 scoped_ptr<CompositorFrame> frame(new CompositorFrame); | 127 scoped_ptr<CompositorFrame> frame(new CompositorFrame); |
| 125 frame->delegated_frame_data = frame_data.Pass(); | 128 frame->delegated_frame_data = frame_data.Pass(); |
| 126 | 129 |
| 127 factory_.SubmitFrame(surface_id, frame.Pass(), | 130 factory_.SubmitFrame(surface_id, frame.Pass(), |
| 128 SurfaceFactory::DrawCallback()); | 131 SurfaceFactory::DrawCallback()); |
| 129 } | 132 } |
| 130 | 133 |
| 134 void SubmitFrame(test::Pass* passes, |
| 135 size_t pass_count, |
| 136 SurfaceId surface_id) { |
| 137 RenderPassList pass_list; |
| 138 AddPasses(&pass_list, gfx::Rect(SurfaceSize()), passes, pass_count); |
| 139 SubmitPassListAsFrame(surface_id, &pass_list); |
| 140 } |
| 141 |
| 131 void QueuePassAsFrame(scoped_ptr<RenderPass> pass, SurfaceId surface_id) { | 142 void QueuePassAsFrame(scoped_ptr<RenderPass> pass, SurfaceId surface_id) { |
| 132 scoped_ptr<DelegatedFrameData> delegated_frame_data(new DelegatedFrameData); | 143 scoped_ptr<DelegatedFrameData> delegated_frame_data(new DelegatedFrameData); |
| 133 delegated_frame_data->render_pass_list.push_back(pass.Pass()); | 144 delegated_frame_data->render_pass_list.push_back(pass.Pass()); |
| 134 | 145 |
| 135 scoped_ptr<CompositorFrame> child_frame(new CompositorFrame); | 146 scoped_ptr<CompositorFrame> child_frame(new CompositorFrame); |
| 136 child_frame->delegated_frame_data = delegated_frame_data.Pass(); | 147 child_frame->delegated_frame_data = delegated_frame_data.Pass(); |
| 137 | 148 |
| 138 factory_.SubmitFrame(surface_id, child_frame.Pass(), | 149 factory_.SubmitFrame(surface_id, child_frame.Pass(), |
| 139 SurfaceFactory::DrawCallback()); | 150 SurfaceFactory::DrawCallback()); |
| 140 } | 151 } |
| (...skipping 1145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1286 | 1297 |
| 1287 ASSERT_EQ(2u, aggregated_pass_list.size()); | 1298 ASSERT_EQ(2u, aggregated_pass_list.size()); |
| 1288 | 1299 |
| 1289 EXPECT_TRUE(aggregated_pass_list[1]->damage_rect.Contains( | 1300 EXPECT_TRUE(aggregated_pass_list[1]->damage_rect.Contains( |
| 1290 gfx::Rect(SurfaceSize()))); | 1301 gfx::Rect(SurfaceSize()))); |
| 1291 } | 1302 } |
| 1292 | 1303 |
| 1293 factory_.Destroy(child_surface_id); | 1304 factory_.Destroy(child_surface_id); |
| 1294 } | 1305 } |
| 1295 | 1306 |
| 1307 class SurfaceAggregatorPartialSwapTest |
| 1308 : public SurfaceAggregatorValidSurfaceTest { |
| 1309 public: |
| 1310 SurfaceAggregatorPartialSwapTest() |
| 1311 : SurfaceAggregatorValidSurfaceTest(true) {} |
| 1312 }; |
| 1313 |
| 1314 // Tests that quads outside the damage rect are ignored. |
| 1315 TEST_F(SurfaceAggregatorPartialSwapTest, IgnoreOutside) { |
| 1316 SurfaceId child_surface_id = allocator_.GenerateId(); |
| 1317 factory_.Create(child_surface_id); |
| 1318 // The child surface has two quads, one with a visible rect of 10,10 2x2 and |
| 1319 // the other other with a visible rect of 12,12 2x2 (relative to root target |
| 1320 // space). |
| 1321 { |
| 1322 RenderPassId child_pass_id = RenderPassId(1, 1); |
| 1323 test::Quad child_quads[] = {test::Quad::RenderPassQuad(child_pass_id), |
| 1324 test::Quad::RenderPassQuad(child_pass_id)}; |
| 1325 test::Pass child_passes[] = { |
| 1326 test::Pass(child_quads, arraysize(child_quads), child_pass_id)}; |
| 1327 |
| 1328 RenderPassList child_pass_list; |
| 1329 AddPasses(&child_pass_list, gfx::Rect(SurfaceSize()), child_passes, |
| 1330 arraysize(child_passes)); |
| 1331 |
| 1332 RenderPass* child_root_pass = child_pass_list.at(0u); |
| 1333 child_root_pass->quad_list.ElementAt(0)->visible_rect = |
| 1334 gfx::Rect(0, 0, 2, 2); |
| 1335 child_root_pass->quad_list.ElementAt(1)->visible_rect = |
| 1336 gfx::Rect(1, 1, 2, 2); |
| 1337 SharedQuadState* child_sqs = |
| 1338 child_root_pass->shared_quad_state_list.ElementAt(1u); |
| 1339 child_sqs->quad_to_target_transform.Translate(1, 1); |
| 1340 |
| 1341 SubmitPassListAsFrame(child_surface_id, &child_pass_list); |
| 1342 } |
| 1343 |
| 1344 { |
| 1345 test::Quad root_quads[] = {test::Quad::SurfaceQuad(child_surface_id, 1.f)}; |
| 1346 |
| 1347 test::Pass root_passes[] = {test::Pass(root_quads, arraysize(root_quads))}; |
| 1348 |
| 1349 RenderPassList root_pass_list; |
| 1350 AddPasses(&root_pass_list, gfx::Rect(SurfaceSize()), root_passes, |
| 1351 arraysize(root_passes)); |
| 1352 |
| 1353 RenderPass* root_pass = root_pass_list.at(0u); |
| 1354 root_pass->shared_quad_state_list.front() |
| 1355 ->quad_to_target_transform.Translate(10, 10); |
| 1356 root_pass->damage_rect = gfx::Rect(0, 0, 1, 1); |
| 1357 |
| 1358 SubmitPassListAsFrame(root_surface_id_, &root_pass_list); |
| 1359 } |
| 1360 |
| 1361 scoped_ptr<CompositorFrame> aggregated_frame = |
| 1362 aggregator_.Aggregate(root_surface_id_); |
| 1363 |
| 1364 ASSERT_TRUE(aggregated_frame); |
| 1365 ASSERT_TRUE(aggregated_frame->delegated_frame_data); |
| 1366 |
| 1367 DelegatedFrameData* frame_data = aggregated_frame->delegated_frame_data.get(); |
| 1368 |
| 1369 const RenderPassList& aggregated_pass_list = frame_data->render_pass_list; |
| 1370 |
| 1371 ASSERT_EQ(1u, aggregated_pass_list.size()); |
| 1372 |
| 1373 // Damage rect for first aggregation should contain entire root surface. |
| 1374 EXPECT_EQ(gfx::Rect(0, 0, 15, 15), aggregated_pass_list[0]->damage_rect); |
| 1375 EXPECT_EQ(2u, aggregated_pass_list[0]->quad_list.size()); |
| 1376 |
| 1377 // Create a root surface with a smaller damage rect. |
| 1378 { |
| 1379 test::Quad root_quads[] = {test::Quad::SurfaceQuad(child_surface_id, 1.f)}; |
| 1380 |
| 1381 test::Pass root_passes[] = {test::Pass(root_quads, arraysize(root_quads))}; |
| 1382 |
| 1383 RenderPassList root_pass_list; |
| 1384 AddPasses(&root_pass_list, gfx::Rect(SurfaceSize()), root_passes, |
| 1385 arraysize(root_passes)); |
| 1386 |
| 1387 RenderPass* root_pass = root_pass_list.at(0u); |
| 1388 root_pass->shared_quad_state_list.front() |
| 1389 ->quad_to_target_transform.Translate(10, 10); |
| 1390 root_pass->damage_rect = gfx::Rect(10, 10, 2, 2); |
| 1391 SubmitPassListAsFrame(root_surface_id_, &root_pass_list); |
| 1392 } |
| 1393 |
| 1394 { |
| 1395 scoped_ptr<CompositorFrame> aggregated_frame = |
| 1396 aggregator_.Aggregate(root_surface_id_); |
| 1397 |
| 1398 ASSERT_TRUE(aggregated_frame); |
| 1399 ASSERT_TRUE(aggregated_frame->delegated_frame_data); |
| 1400 |
| 1401 DelegatedFrameData* frame_data = |
| 1402 aggregated_frame->delegated_frame_data.get(); |
| 1403 |
| 1404 const RenderPassList& aggregated_pass_list = frame_data->render_pass_list; |
| 1405 |
| 1406 ASSERT_EQ(1u, aggregated_pass_list.size()); |
| 1407 |
| 1408 // Only first quad from surface is inside damage rect and should be |
| 1409 // included. |
| 1410 EXPECT_EQ(gfx::Rect(10, 10, 2, 2), aggregated_pass_list[0]->damage_rect); |
| 1411 EXPECT_EQ(1u, aggregated_pass_list[0]->quad_list.size()); |
| 1412 EXPECT_EQ(gfx::Rect(0, 0, 2, 2), |
| 1413 aggregated_pass_list[0]->quad_list.back()->visible_rect); |
| 1414 } |
| 1415 |
| 1416 // New child frame has same content and no damage, but has a |
| 1417 // CopyOutputRequest. |
| 1418 { |
| 1419 RenderPassId child_pass_id = RenderPassId(1, 1); |
| 1420 test::Quad child_quads[] = {test::Quad::RenderPassQuad(child_pass_id), |
| 1421 test::Quad::RenderPassQuad(child_pass_id)}; |
| 1422 test::Pass child_passes[] = { |
| 1423 test::Pass(child_quads, arraysize(child_quads), child_pass_id)}; |
| 1424 |
| 1425 RenderPassList child_pass_list; |
| 1426 AddPasses(&child_pass_list, gfx::Rect(SurfaceSize()), child_passes, |
| 1427 arraysize(child_passes)); |
| 1428 |
| 1429 RenderPass* child_root_pass = child_pass_list.at(0u); |
| 1430 child_root_pass->quad_list.ElementAt(0)->visible_rect = |
| 1431 gfx::Rect(0, 0, 2, 2); |
| 1432 child_root_pass->quad_list.ElementAt(1)->visible_rect = |
| 1433 gfx::Rect(1, 1, 2, 2); |
| 1434 SharedQuadState* child_sqs = |
| 1435 child_root_pass->shared_quad_state_list.ElementAt(1u); |
| 1436 child_sqs->quad_to_target_transform.Translate(1, 1); |
| 1437 child_root_pass->copy_requests.push_back( |
| 1438 CopyOutputRequest::CreateEmptyRequest()); |
| 1439 child_root_pass->damage_rect = gfx::Rect(); |
| 1440 SubmitPassListAsFrame(child_surface_id, &child_pass_list); |
| 1441 } |
| 1442 |
| 1443 { |
| 1444 scoped_ptr<CompositorFrame> aggregated_frame = |
| 1445 aggregator_.Aggregate(root_surface_id_); |
| 1446 |
| 1447 ASSERT_TRUE(aggregated_frame); |
| 1448 ASSERT_TRUE(aggregated_frame->delegated_frame_data); |
| 1449 |
| 1450 DelegatedFrameData* frame_data = |
| 1451 aggregated_frame->delegated_frame_data.get(); |
| 1452 |
| 1453 const RenderPassList& aggregated_pass_list = frame_data->render_pass_list; |
| 1454 |
| 1455 // Output frame should have no damage, but all quads included. |
| 1456 ASSERT_EQ(2u, aggregated_pass_list.size()); |
| 1457 |
| 1458 EXPECT_TRUE(aggregated_pass_list[1]->damage_rect.IsEmpty()); |
| 1459 ASSERT_EQ(2u, aggregated_pass_list[0]->quad_list.size()); |
| 1460 const QuadList& child_quad_list = aggregated_pass_list[0]->quad_list; |
| 1461 EXPECT_EQ(gfx::Rect(0, 0, 2, 2), |
| 1462 child_quad_list.ElementAt(0)->visible_rect); |
| 1463 EXPECT_EQ(gfx::Rect(1, 1, 2, 2), |
| 1464 child_quad_list.ElementAt(1)->visible_rect); |
| 1465 } |
| 1466 |
| 1467 { |
| 1468 scoped_ptr<CompositorFrame> aggregated_frame = |
| 1469 aggregator_.Aggregate(root_surface_id_); |
| 1470 |
| 1471 ASSERT_TRUE(aggregated_frame); |
| 1472 ASSERT_TRUE(aggregated_frame->delegated_frame_data); |
| 1473 |
| 1474 DelegatedFrameData* frame_data = |
| 1475 aggregated_frame->delegated_frame_data.get(); |
| 1476 |
| 1477 const RenderPassList& aggregated_pass_list = frame_data->render_pass_list; |
| 1478 // There were no changes since last aggregation, so output should be empty |
| 1479 // and have no damage. |
| 1480 ASSERT_EQ(1u, aggregated_pass_list.size()); |
| 1481 EXPECT_TRUE(aggregated_pass_list[0]->damage_rect.IsEmpty()); |
| 1482 ASSERT_EQ(0u, aggregated_pass_list[0]->quad_list.size()); |
| 1483 } |
| 1484 |
| 1485 factory_.Destroy(child_surface_id); |
| 1486 } |
| 1487 |
| 1296 class SurfaceAggregatorWithResourcesTest : public testing::Test { | 1488 class SurfaceAggregatorWithResourcesTest : public testing::Test { |
| 1297 public: | 1489 public: |
| 1298 void SetUp() override { | 1490 void SetUp() override { |
| 1299 output_surface_ = FakeOutputSurface::CreateSoftware( | 1491 output_surface_ = FakeOutputSurface::CreateSoftware( |
| 1300 make_scoped_ptr(new SoftwareOutputDevice)); | 1492 make_scoped_ptr(new SoftwareOutputDevice)); |
| 1301 output_surface_->BindToClient(&output_surface_client_); | 1493 output_surface_->BindToClient(&output_surface_client_); |
| 1302 shared_bitmap_manager_.reset(new TestSharedBitmapManager); | 1494 shared_bitmap_manager_.reset(new TestSharedBitmapManager); |
| 1303 | 1495 |
| 1304 resource_provider_ = FakeResourceProvider::Create( | 1496 resource_provider_ = FakeResourceProvider::Create( |
| 1305 output_surface_.get(), shared_bitmap_manager_.get()); | 1497 output_surface_.get(), shared_bitmap_manager_.get()); |
| 1306 | 1498 |
| 1307 aggregator_.reset( | 1499 aggregator_.reset( |
| 1308 new SurfaceAggregator(&manager_, resource_provider_.get())); | 1500 new SurfaceAggregator(&manager_, resource_provider_.get(), false)); |
| 1309 } | 1501 } |
| 1310 | 1502 |
| 1311 protected: | 1503 protected: |
| 1312 SurfaceManager manager_; | 1504 SurfaceManager manager_; |
| 1313 FakeOutputSurfaceClient output_surface_client_; | 1505 FakeOutputSurfaceClient output_surface_client_; |
| 1314 scoped_ptr<OutputSurface> output_surface_; | 1506 scoped_ptr<OutputSurface> output_surface_; |
| 1315 scoped_ptr<SharedBitmapManager> shared_bitmap_manager_; | 1507 scoped_ptr<SharedBitmapManager> shared_bitmap_manager_; |
| 1316 scoped_ptr<ResourceProvider> resource_provider_; | 1508 scoped_ptr<ResourceProvider> resource_provider_; |
| 1317 scoped_ptr<SurfaceAggregator> aggregator_; | 1509 scoped_ptr<SurfaceAggregator> aggregator_; |
| 1318 }; | 1510 }; |
| (...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1526 EXPECT_EQ(9u, pass_list->back()->quad_list.size()); | 1718 EXPECT_EQ(9u, pass_list->back()->quad_list.size()); |
| 1527 | 1719 |
| 1528 factory.Destroy(root_surface_id); | 1720 factory.Destroy(root_surface_id); |
| 1529 factory.Destroy(child_surface_id); | 1721 factory.Destroy(child_surface_id); |
| 1530 factory.Destroy(middle_surface_id); | 1722 factory.Destroy(middle_surface_id); |
| 1531 } | 1723 } |
| 1532 | 1724 |
| 1533 } // namespace | 1725 } // namespace |
| 1534 } // namespace cc | 1726 } // namespace cc |
| 1535 | 1727 |
| OLD | NEW |