OLD | NEW |
1 // Copyright 2011 The Chromium Authors. All rights reserved. | 1 // Copyright 2011 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/trees/damage_tracker.h" | 5 #include "cc/trees/damage_tracker.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 | 8 |
9 #include "cc/base/filter_operation.h" | 9 #include "cc/base/filter_operation.h" |
10 #include "cc/base/filter_operations.h" | 10 #include "cc/base/filter_operations.h" |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
50 // This emulates only steps that are relevant to testing the damage tracker: | 50 // This emulates only steps that are relevant to testing the damage tracker: |
51 // 1. computing the render passes and layerlists | 51 // 1. computing the render passes and layerlists |
52 // 2. updating all damage trackers in the correct order | 52 // 2. updating all damage trackers in the correct order |
53 // 3. resetting all update_rects and property_changed flags for all layers | 53 // 3. resetting all update_rects and property_changed flags for all layers |
54 // and surfaces. | 54 // and surfaces. |
55 | 55 |
56 LayerImplList render_surface_layer_list; | 56 LayerImplList render_surface_layer_list; |
57 ExecuteCalculateDrawProperties(root, device_scale_factor, | 57 ExecuteCalculateDrawProperties(root, device_scale_factor, |
58 &render_surface_layer_list); | 58 &render_surface_layer_list); |
59 | 59 |
60 // Iterate back-to-front, so that damage correctly propagates from descendant | 60 DamageTracker::UpdateDamageTracking(root->layer_tree_impl(), |
61 // surfaces to ancestors. | 61 render_surface_layer_list); |
62 size_t render_surface_layer_list_size = render_surface_layer_list.size(); | |
63 for (size_t i = 0; i < render_surface_layer_list_size; ++i) { | |
64 size_t index = render_surface_layer_list_size - 1 - i; | |
65 RenderSurfaceImpl* target_surface = | |
66 render_surface_layer_list[index]->GetRenderSurface(); | |
67 target_surface->damage_tracker()->UpdateDamageTrackingState( | |
68 target_surface->layer_list(), target_surface, | |
69 target_surface->SurfacePropertyChangedOnlyFromDescendant(), | |
70 target_surface->content_rect(), target_surface->MaskLayer(), | |
71 target_surface->Filters()); | |
72 } | |
73 | 62 |
74 root->layer_tree_impl()->ResetAllChangeTracking(); | 63 root->layer_tree_impl()->ResetAllChangeTracking(); |
75 } | 64 } |
76 | 65 |
77 class DamageTrackerTest : public testing::Test { | 66 class DamageTrackerTest : public testing::Test { |
78 public: | 67 public: |
79 DamageTrackerTest() | 68 DamageTrackerTest() |
80 : host_impl_(&task_runner_provider_, &task_graph_runner_) {} | 69 : host_impl_(&task_runner_provider_, &task_graph_runner_) {} |
81 | 70 |
82 LayerImpl* CreateTestTreeWithOneSurface(int number_of_children) { | 71 LayerImpl* CreateTestTreeWithOneSurface(int number_of_children) { |
(...skipping 1254 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1337 ClearDamageForAllSurfaces(root); | 1326 ClearDamageForAllSurfaces(root); |
1338 root->GetRenderSurface()->damage_tracker()->AddDamageNextUpdate( | 1327 root->GetRenderSurface()->damage_tracker()->AddDamageNextUpdate( |
1339 gfx::Rect(30, 31, 14, 15)); | 1328 gfx::Rect(30, 31, 14, 15)); |
1340 root->layer_tree_impl()->property_trees()->needs_rebuild = true; | 1329 root->layer_tree_impl()->property_trees()->needs_rebuild = true; |
1341 EmulateDrawingOneFrame(root); | 1330 EmulateDrawingOneFrame(root); |
1342 EXPECT_TRUE(root->GetRenderSurface()->damage_tracker()->GetDamageRectIfValid( | 1331 EXPECT_TRUE(root->GetRenderSurface()->damage_tracker()->GetDamageRectIfValid( |
1343 &root_damage_rect)); | 1332 &root_damage_rect)); |
1344 EXPECT_EQ(gfx::Rect(30, 31, 14, 15).ToString(), root_damage_rect.ToString()); | 1333 EXPECT_EQ(gfx::Rect(30, 31, 14, 15).ToString(), root_damage_rect.ToString()); |
1345 } | 1334 } |
1346 | 1335 |
1347 TEST_F(DamageTrackerTest, VerifyDamageForEmptyLayerList) { | 1336 TEST_F(DamageTrackerTest, VerifyDamageWithNoContributingLayers) { |
1348 // Though it should never happen, its a good idea to verify that the damage | |
1349 // tracker does not crash when it receives an empty layer_list. | |
1350 | |
1351 std::unique_ptr<LayerImpl> root = | 1337 std::unique_ptr<LayerImpl> root = |
1352 LayerImpl::Create(host_impl_.active_tree(), 1); | 1338 LayerImpl::Create(host_impl_.active_tree(), 1); |
1353 root->test_properties()->force_render_surface = true; | 1339 root->test_properties()->force_render_surface = true; |
1354 host_impl_.active_tree()->SetRootLayerForTesting(std::move(root)); | 1340 host_impl_.active_tree()->SetRootLayerForTesting(std::move(root)); |
1355 LayerImpl* root_ptr = host_impl_.active_tree()->root_layer_for_testing(); | 1341 LayerImpl* root_ptr = host_impl_.active_tree()->root_layer_for_testing(); |
1356 root_ptr->layer_tree_impl()->property_trees()->needs_rebuild = true; | 1342 root_ptr->layer_tree_impl()->property_trees()->needs_rebuild = true; |
1357 EmulateDrawingOneFrame(root_ptr); | 1343 EmulateDrawingOneFrame(root_ptr); |
1358 | 1344 |
1359 DCHECK_EQ(root_ptr->GetRenderSurface(), root_ptr->render_target()); | 1345 DCHECK_EQ(root_ptr->GetRenderSurface(), root_ptr->render_target()); |
1360 RenderSurfaceImpl* target_surface = root_ptr->GetRenderSurface(); | 1346 RenderSurfaceImpl* target_surface = root_ptr->GetRenderSurface(); |
1361 | |
1362 LayerImplList empty_list; | |
1363 target_surface->damage_tracker()->UpdateDamageTrackingState( | |
1364 empty_list, target_surface, false, gfx::Rect(), NULL, FilterOperations()); | |
1365 | |
1366 gfx::Rect damage_rect; | 1347 gfx::Rect damage_rect; |
1367 EXPECT_TRUE( | 1348 EXPECT_TRUE( |
1368 target_surface->damage_tracker()->GetDamageRectIfValid(&damage_rect)); | 1349 target_surface->damage_tracker()->GetDamageRectIfValid(&damage_rect)); |
1369 EXPECT_TRUE(damage_rect.IsEmpty()); | 1350 EXPECT_TRUE(damage_rect.IsEmpty()); |
1370 } | 1351 } |
1371 | 1352 |
1372 TEST_F(DamageTrackerTest, VerifyDamageAccumulatesUntilReset) { | 1353 TEST_F(DamageTrackerTest, VerifyDamageAccumulatesUntilReset) { |
1373 // If damage is not cleared, it should accumulate. | 1354 // If damage is not cleared, it should accumulate. |
1374 | 1355 |
1375 LayerImpl* root = CreateAndSetUpTestTreeWithOneSurface(); | 1356 LayerImpl* root = CreateAndSetUpTestTreeWithOneSurface(); |
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1523 grandchild2->SetPosition( | 1504 grandchild2->SetPosition( |
1524 gfx::PointF(std::numeric_limits<int>::max() - 500, 0)); | 1505 gfx::PointF(std::numeric_limits<int>::max() - 500, 0)); |
1525 grandchild2->SetBounds(gfx::Size(1, 1)); | 1506 grandchild2->SetBounds(gfx::Size(1, 1)); |
1526 grandchild2->SetDrawsContent(true); | 1507 grandchild2->SetDrawsContent(true); |
1527 | 1508 |
1528 root->layer_tree_impl()->property_trees()->needs_rebuild = true; | 1509 root->layer_tree_impl()->property_trees()->needs_rebuild = true; |
1529 float device_scale_factor = 1.f; | 1510 float device_scale_factor = 1.f; |
1530 LayerImplList render_surface_layer_list; | 1511 LayerImplList render_surface_layer_list; |
1531 ExecuteCalculateDrawProperties(root, device_scale_factor, | 1512 ExecuteCalculateDrawProperties(root, device_scale_factor, |
1532 &render_surface_layer_list); | 1513 &render_surface_layer_list); |
1533 | 1514 // Avoid the descendant-only property change path that skips unioning damage |
1534 auto* surface = child1->GetRenderSurface(); | 1515 // from descendant layers. |
1535 surface->damage_tracker()->UpdateDamageTrackingState( | 1516 child1->GetRenderSurface()->NoteAncestorPropertyChanged(); |
1536 surface->layer_list(), surface, false, surface->content_rect(), | 1517 DamageTracker::UpdateDamageTracking(host_impl_.active_tree(), |
1537 surface->MaskLayer(), surface->Filters()); | 1518 render_surface_layer_list); |
1538 surface = root->GetRenderSurface(); | |
1539 surface->damage_tracker()->UpdateDamageTrackingState( | |
1540 surface->layer_list(), surface, false, surface->content_rect(), | |
1541 surface->MaskLayer(), surface->Filters()); | |
1542 | 1519 |
1543 // The expected damage would be too large to store in a gfx::Rect, so we | 1520 // The expected damage would be too large to store in a gfx::Rect, so we |
1544 // should damage everything on child1. | 1521 // should damage everything on child1. |
1545 gfx::Rect damage_rect; | 1522 gfx::Rect damage_rect; |
1546 EXPECT_FALSE( | 1523 EXPECT_FALSE( |
1547 child1->GetRenderSurface()->damage_tracker()->GetDamageRectIfValid( | 1524 child1->GetRenderSurface()->damage_tracker()->GetDamageRectIfValid( |
1548 &damage_rect)); | 1525 &damage_rect)); |
1549 EXPECT_EQ(child1->GetRenderSurface()->content_rect(), | 1526 EXPECT_EQ(child1->GetRenderSurface()->content_rect(), |
1550 child1->GetRenderSurface()->GetDamageRect()); | 1527 child1->GetRenderSurface()->GetDamageRect()); |
1551 | 1528 |
1552 // However, the root should just use the child1 render surface's content rect | 1529 // However, the root should just use the child1 render surface's content rect |
1553 // as damage. | 1530 // as damage. |
1554 ASSERT_TRUE(root->GetRenderSurface()->damage_tracker()->GetDamageRectIfValid( | 1531 ASSERT_TRUE(root->GetRenderSurface()->damage_tracker()->GetDamageRectIfValid( |
1555 &damage_rect)); | 1532 &damage_rect)); |
1556 EXPECT_TRUE(damage_rect.Contains(root->GetRenderSurface()->content_rect())); | 1533 EXPECT_TRUE(damage_rect.Contains(root->GetRenderSurface()->content_rect())); |
1557 EXPECT_TRUE(damage_rect.Contains( | 1534 EXPECT_TRUE(damage_rect.Contains( |
1558 gfx::ToEnclosingRect(child1->GetRenderSurface()->DrawableContentRect()))); | 1535 gfx::ToEnclosingRect(child1->GetRenderSurface()->DrawableContentRect()))); |
1559 EXPECT_EQ(damage_rect, root->GetRenderSurface()->GetDamageRect()); | 1536 EXPECT_EQ(damage_rect, root->GetRenderSurface()->GetDamageRect()); |
1560 | 1537 |
1561 // Add new damage, without changing properties, which goes down a different | 1538 // Add new damage, without changing properties, which goes down a different |
1562 // path in the damage tracker. | 1539 // path in the damage tracker. |
1563 root->layer_tree_impl()->ResetAllChangeTracking(); | 1540 root->layer_tree_impl()->ResetAllChangeTracking(); |
1564 grandchild1->AddDamageRect(gfx::Rect(grandchild1->bounds())); | 1541 grandchild1->AddDamageRect(gfx::Rect(grandchild1->bounds())); |
1565 grandchild2->AddDamageRect(gfx::Rect(grandchild1->bounds())); | 1542 grandchild2->AddDamageRect(gfx::Rect(grandchild1->bounds())); |
1566 | 1543 |
1567 // Recompute all damage / properties. | 1544 // Recompute all damage / properties. |
1568 render_surface_layer_list.clear(); | 1545 render_surface_layer_list.clear(); |
1569 ExecuteCalculateDrawProperties(root, device_scale_factor, | 1546 ExecuteCalculateDrawProperties(root, device_scale_factor, |
1570 &render_surface_layer_list); | 1547 &render_surface_layer_list); |
1571 surface = child1->GetRenderSurface(); | 1548 DamageTracker::UpdateDamageTracking(host_impl_.active_tree(), |
1572 surface->damage_tracker()->UpdateDamageTrackingState( | 1549 render_surface_layer_list); |
1573 surface->layer_list(), surface, false, surface->content_rect(), | |
1574 surface->MaskLayer(), surface->Filters()); | |
1575 surface = root->GetRenderSurface(); | |
1576 surface->damage_tracker()->UpdateDamageTrackingState( | |
1577 surface->layer_list(), surface, false, surface->content_rect(), | |
1578 surface->MaskLayer(), surface->Filters()); | |
1579 | 1550 |
1580 // Child1 should still not have a valid rect, since the union of the damage of | 1551 // Child1 should still not have a valid rect, since the union of the damage of |
1581 // its children is not representable by a single rect. | 1552 // its children is not representable by a single rect. |
1582 EXPECT_FALSE( | 1553 EXPECT_FALSE( |
1583 child1->GetRenderSurface()->damage_tracker()->GetDamageRectIfValid( | 1554 child1->GetRenderSurface()->damage_tracker()->GetDamageRectIfValid( |
1584 &damage_rect)); | 1555 &damage_rect)); |
1585 EXPECT_EQ(child1->GetRenderSurface()->content_rect(), | 1556 EXPECT_EQ(child1->GetRenderSurface()->content_rect(), |
1586 child1->GetRenderSurface()->GetDamageRect()); | 1557 child1->GetRenderSurface()->GetDamageRect()); |
1587 | 1558 |
1588 // Root should have valid damage and contain both its content rect and the | 1559 // Root should have valid damage and contain both its content rect and the |
(...skipping 28 matching lines...) Expand all Loading... |
1617 grandchild2->SetPosition( | 1588 grandchild2->SetPosition( |
1618 gfx::PointF(std::numeric_limits<int>::max() - 500, 0)); | 1589 gfx::PointF(std::numeric_limits<int>::max() - 500, 0)); |
1619 grandchild2->SetBounds(gfx::Size(1, 1)); | 1590 grandchild2->SetBounds(gfx::Size(1, 1)); |
1620 grandchild2->SetDrawsContent(true); | 1591 grandchild2->SetDrawsContent(true); |
1621 | 1592 |
1622 root->layer_tree_impl()->property_trees()->needs_rebuild = true; | 1593 root->layer_tree_impl()->property_trees()->needs_rebuild = true; |
1623 float device_scale_factor = 1.f; | 1594 float device_scale_factor = 1.f; |
1624 LayerImplList render_surface_layer_list; | 1595 LayerImplList render_surface_layer_list; |
1625 ExecuteCalculateDrawProperties(root, device_scale_factor, | 1596 ExecuteCalculateDrawProperties(root, device_scale_factor, |
1626 &render_surface_layer_list); | 1597 &render_surface_layer_list); |
1627 | 1598 // Avoid the descendant-only property change path that skips unioning damage |
1628 auto* surface = child1->GetRenderSurface(); | 1599 // from descendant layers. |
1629 surface->damage_tracker()->UpdateDamageTrackingState( | 1600 child1->GetRenderSurface()->NoteAncestorPropertyChanged(); |
1630 surface->layer_list(), surface, false, surface->content_rect(), | 1601 DamageTracker::UpdateDamageTracking(host_impl_.active_tree(), |
1631 surface->MaskLayer(), surface->Filters()); | 1602 render_surface_layer_list); |
1632 surface = root->GetRenderSurface(); | |
1633 surface->damage_tracker()->UpdateDamageTrackingState( | |
1634 surface->layer_list(), surface, false, surface->content_rect(), | |
1635 surface->MaskLayer(), surface->Filters()); | |
1636 | 1603 |
1637 // The expected damage would be too large to store in a gfx::Rect, so we | 1604 // The expected damage would be too large to store in a gfx::Rect, so we |
1638 // should damage everything on child1. | 1605 // should damage everything on child1. |
1639 gfx::Rect damage_rect; | 1606 gfx::Rect damage_rect; |
1640 EXPECT_FALSE( | 1607 EXPECT_FALSE( |
1641 child1->GetRenderSurface()->damage_tracker()->GetDamageRectIfValid( | 1608 child1->GetRenderSurface()->damage_tracker()->GetDamageRectIfValid( |
1642 &damage_rect)); | 1609 &damage_rect)); |
1643 EXPECT_EQ(child1->GetRenderSurface()->content_rect(), | 1610 EXPECT_EQ(child1->GetRenderSurface()->content_rect(), |
1644 child1->GetRenderSurface()->GetDamageRect()); | 1611 child1->GetRenderSurface()->GetDamageRect()); |
1645 | 1612 |
1646 // However, the root should just use the child1 render surface's content rect | 1613 // However, the root should just use the child1 render surface's content rect |
1647 // as damage. | 1614 // as damage. |
1648 ASSERT_TRUE(root->GetRenderSurface()->damage_tracker()->GetDamageRectIfValid( | 1615 ASSERT_TRUE(root->GetRenderSurface()->damage_tracker()->GetDamageRectIfValid( |
1649 &damage_rect)); | 1616 &damage_rect)); |
1650 EXPECT_TRUE(damage_rect.Contains(root->GetRenderSurface()->content_rect())); | 1617 EXPECT_TRUE(damage_rect.Contains(root->GetRenderSurface()->content_rect())); |
1651 EXPECT_TRUE(damage_rect.Contains( | 1618 EXPECT_TRUE(damage_rect.Contains( |
1652 gfx::ToEnclosingRect(child1->GetRenderSurface()->DrawableContentRect()))); | 1619 gfx::ToEnclosingRect(child1->GetRenderSurface()->DrawableContentRect()))); |
1653 EXPECT_EQ(damage_rect, root->GetRenderSurface()->GetDamageRect()); | 1620 EXPECT_EQ(damage_rect, root->GetRenderSurface()->GetDamageRect()); |
1654 | 1621 |
1655 // Add new damage, without changing properties, which goes down a different | 1622 // Add new damage, without changing properties, which goes down a different |
1656 // path in the damage tracker. | 1623 // path in the damage tracker. |
1657 root->layer_tree_impl()->ResetAllChangeTracking(); | 1624 root->layer_tree_impl()->ResetAllChangeTracking(); |
1658 grandchild1->AddDamageRect(gfx::Rect(grandchild1->bounds())); | 1625 grandchild1->AddDamageRect(gfx::Rect(grandchild1->bounds())); |
1659 grandchild2->AddDamageRect(gfx::Rect(grandchild1->bounds())); | 1626 grandchild2->AddDamageRect(gfx::Rect(grandchild1->bounds())); |
1660 | 1627 |
1661 // Recompute all damage / properties. | 1628 // Recompute all damage / properties. |
1662 render_surface_layer_list.clear(); | 1629 render_surface_layer_list.clear(); |
1663 ExecuteCalculateDrawProperties(root, device_scale_factor, | 1630 ExecuteCalculateDrawProperties(root, device_scale_factor, |
1664 &render_surface_layer_list); | 1631 &render_surface_layer_list); |
1665 surface = child1->GetRenderSurface(); | 1632 DamageTracker::UpdateDamageTracking(host_impl_.active_tree(), |
1666 surface->damage_tracker()->UpdateDamageTrackingState( | 1633 render_surface_layer_list); |
1667 surface->layer_list(), surface, false, surface->content_rect(), | |
1668 surface->MaskLayer(), surface->Filters()); | |
1669 surface = root->GetRenderSurface(); | |
1670 surface->damage_tracker()->UpdateDamageTrackingState( | |
1671 surface->layer_list(), surface, false, surface->content_rect(), | |
1672 surface->MaskLayer(), surface->Filters()); | |
1673 | 1634 |
1674 // Child1 should still not have a valid rect, since the union of the damage of | 1635 // Child1 should still not have a valid rect, since the union of the damage of |
1675 // its children is not representable by a single rect. | 1636 // its children is not representable by a single rect. |
1676 EXPECT_FALSE( | 1637 EXPECT_FALSE( |
1677 child1->GetRenderSurface()->damage_tracker()->GetDamageRectIfValid( | 1638 child1->GetRenderSurface()->damage_tracker()->GetDamageRectIfValid( |
1678 &damage_rect)); | 1639 &damage_rect)); |
1679 EXPECT_EQ(child1->GetRenderSurface()->content_rect(), | 1640 EXPECT_EQ(child1->GetRenderSurface()->content_rect(), |
1680 child1->GetRenderSurface()->GetDamageRect()); | 1641 child1->GetRenderSurface()->GetDamageRect()); |
1681 | 1642 |
1682 // Root should have valid damage and contain both its content rect and the | 1643 // Root should have valid damage and contain both its content rect and the |
1683 // drawable content rect of child1. | 1644 // drawable content rect of child1. |
1684 ASSERT_TRUE(root->GetRenderSurface()->damage_tracker()->GetDamageRectIfValid( | 1645 ASSERT_TRUE(root->GetRenderSurface()->damage_tracker()->GetDamageRectIfValid( |
1685 &damage_rect)); | 1646 &damage_rect)); |
1686 EXPECT_TRUE(damage_rect.Contains(root->GetRenderSurface()->content_rect())); | 1647 EXPECT_TRUE(damage_rect.Contains(root->GetRenderSurface()->content_rect())); |
1687 EXPECT_TRUE(damage_rect.Contains( | 1648 EXPECT_TRUE(damage_rect.Contains( |
1688 gfx::ToEnclosingRect(child1->GetRenderSurface()->DrawableContentRect()))); | 1649 gfx::ToEnclosingRect(child1->GetRenderSurface()->DrawableContentRect()))); |
1689 EXPECT_EQ(damage_rect, root->GetRenderSurface()->GetDamageRect()); | 1650 EXPECT_EQ(damage_rect, root->GetRenderSurface()->GetDamageRect()); |
1690 } | 1651 } |
1691 | 1652 |
1692 } // namespace | 1653 } // namespace |
1693 } // namespace cc | 1654 } // namespace cc |
OLD | NEW |