| 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 |