| OLD | NEW |
| 1 // Copyright 2012 The Chromium Authors. All rights reserved. | 1 // Copyright 2012 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/occlusion_tracker.h" | 5 #include "cc/trees/occlusion_tracker.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 | 8 |
| 9 #include "cc/base/math_util.h" | 9 #include "cc/base/math_util.h" |
| 10 #include "cc/layers/layer.h" | 10 #include "cc/layers/layer.h" |
| (...skipping 1451 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1462 LayerImpl* filtered_surface = this->CreateDrawingLayer( | 1462 LayerImpl* filtered_surface = this->CreateDrawingLayer( |
| 1463 parent, scale_by_half, gfx::PointF(50.f, 50.f), gfx::Size(100, 100), | 1463 parent, scale_by_half, gfx::PointF(50.f, 50.f), gfx::Size(100, 100), |
| 1464 false); | 1464 false); |
| 1465 filtered_surface->test_properties()->background_filters = filters; | 1465 filtered_surface->test_properties()->background_filters = filters; |
| 1466 gfx::Rect occlusion_rect; | 1466 gfx::Rect occlusion_rect; |
| 1467 switch (i) { | 1467 switch (i) { |
| 1468 case LEFT: | 1468 case LEFT: |
| 1469 occlusion_rect = gfx::Rect(0, 0, 50, 200); | 1469 occlusion_rect = gfx::Rect(0, 0, 50, 200); |
| 1470 break; | 1470 break; |
| 1471 case RIGHT: | 1471 case RIGHT: |
| 1472 // This is the right edge; filtered_surface is scaled by half. |
| 1472 occlusion_rect = gfx::Rect(100, 0, 50, 200); | 1473 occlusion_rect = gfx::Rect(100, 0, 50, 200); |
| 1473 break; | 1474 break; |
| 1474 case TOP: | 1475 case TOP: |
| 1475 occlusion_rect = gfx::Rect(0, 0, 200, 50); | 1476 occlusion_rect = gfx::Rect(0, 0, 200, 50); |
| 1476 break; | 1477 break; |
| 1477 case BOTTOM: | 1478 case BOTTOM: |
| 1479 // This is the bottom edge; filtered_surface is scaled by half. |
| 1478 occlusion_rect = gfx::Rect(0, 100, 200, 50); | 1480 occlusion_rect = gfx::Rect(0, 100, 200, 50); |
| 1479 break; | 1481 break; |
| 1480 } | 1482 } |
| 1481 | 1483 |
| 1482 LayerImpl* occluding_layer = this->CreateDrawingLayer( | 1484 LayerImpl* occluding_layer = this->CreateDrawingLayer( |
| 1483 parent, this->identity_matrix, gfx::PointF(occlusion_rect.origin()), | 1485 parent, this->identity_matrix, gfx::PointF(occlusion_rect.origin()), |
| 1484 occlusion_rect.size(), true); | 1486 occlusion_rect.size(), true); |
| 1485 occluding_layer->test_properties()->force_render_surface = false; | 1487 occluding_layer->test_properties()->force_render_surface = false; |
| 1486 this->CalcDrawEtc(parent); | 1488 this->CalcDrawEtc(parent); |
| 1487 | 1489 |
| (...skipping 11 matching lines...) Expand all Loading... |
| 1499 this->VisitLayer(filtered_surface, &occlusion); | 1501 this->VisitLayer(filtered_surface, &occlusion); |
| 1500 | 1502 |
| 1501 // The occlusion is used fully inside the surface. | 1503 // The occlusion is used fully inside the surface. |
| 1502 gfx::Rect occlusion_inside_surface = | 1504 gfx::Rect occlusion_inside_surface = |
| 1503 occlusion_rect - gfx::Vector2d(50, 50); | 1505 occlusion_rect - gfx::Vector2d(50, 50); |
| 1504 EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty()); | 1506 EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty()); |
| 1505 EXPECT_EQ(occlusion_inside_surface.ToString(), | 1507 EXPECT_EQ(occlusion_inside_surface.ToString(), |
| 1506 occlusion.occlusion_from_outside_target().ToString()); | 1508 occlusion.occlusion_from_outside_target().ToString()); |
| 1507 | 1509 |
| 1508 // The surface has a background blur, so it needs pixels that are | 1510 // The surface has a background blur, so it needs pixels that are |
| 1509 // currently considered occluded in order to be drawn. So the pixels it | 1511 // currently considered occluded in order to be drawn. The pixels it |
| 1510 // needs should be removed some the occluded area so that when we get to | 1512 // needs should be removed from the occluded area, so that they are drawn |
| 1511 // the parent they are drawn. | 1513 // when we get to the parent. |
| 1512 this->VisitContributingSurface(filtered_surface, &occlusion); | 1514 this->VisitContributingSurface(filtered_surface, &occlusion); |
| 1513 this->EnterLayer(parent, &occlusion); | 1515 this->EnterLayer(parent, &occlusion); |
| 1514 | 1516 |
| 1515 gfx::Rect expected_occlusion = occlusion_rect; | 1517 gfx::Rect expected_occlusion = occlusion_rect; |
| 1516 switch (i) { | 1518 switch (i) { |
| 1517 case LEFT: | 1519 case LEFT: |
| 1518 expected_occlusion.Inset(0, 0, outset_right, 0); | 1520 expected_occlusion.Inset(0, 0, outset_right, 0); |
| 1519 break; | 1521 break; |
| 1520 case RIGHT: | 1522 case RIGHT: |
| 1521 expected_occlusion.Inset(outset_right, 0, 0, 0); | 1523 expected_occlusion.Inset(outset_right, 0, 0, 0); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 1533 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty()); | 1535 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty()); |
| 1534 | 1536 |
| 1535 this->DestroyLayers(); | 1537 this->DestroyLayers(); |
| 1536 } | 1538 } |
| 1537 } | 1539 } |
| 1538 }; | 1540 }; |
| 1539 | 1541 |
| 1540 ALL_OCCLUSIONTRACKER_TEST( | 1542 ALL_OCCLUSIONTRACKER_TEST( |
| 1541 OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilter); | 1543 OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilter); |
| 1542 | 1544 |
| 1545 class OcclusionTrackerTestDontOccludePixelsNeededForDropShadowBackgroundFilter |
| 1546 : public OcclusionTrackerTest { |
| 1547 protected: |
| 1548 explicit OcclusionTrackerTestDontOccludePixelsNeededForDropShadowBackgroundFil
ter( |
| 1549 bool opaque_layers) |
| 1550 : OcclusionTrackerTest(opaque_layers) {} |
| 1551 void RunMyTest() override { |
| 1552 gfx::Transform scale_by_half; |
| 1553 scale_by_half.Scale(0.5, 0.5); |
| 1554 |
| 1555 FilterOperations filters; |
| 1556 filters.Append(FilterOperation::CreateDropShadowFilter(gfx::Point(10, 10), |
| 1557 5, SK_ColorBLACK)); |
| 1558 |
| 1559 enum Direction { |
| 1560 LEFT, |
| 1561 RIGHT, |
| 1562 TOP, |
| 1563 BOTTOM, |
| 1564 LAST_DIRECTION = BOTTOM, |
| 1565 }; |
| 1566 |
| 1567 for (int i = 0; i <= LAST_DIRECTION; ++i) { |
| 1568 SCOPED_TRACE(i); |
| 1569 |
| 1570 // Make a 50x50 filtered surface that is adjacent to occluding layers |
| 1571 // which are above it in the z-order in various configurations. The |
| 1572 // surface is scaled to test that the pixel moving is done in the target |
| 1573 // space, where the background filter is applied. |
| 1574 TestContentLayerImpl* parent = this->CreateRoot( |
| 1575 this->identity_matrix, gfx::PointF(), gfx::Size(200, 200)); |
| 1576 LayerImpl* filtered_surface = this->CreateDrawingLayer( |
| 1577 parent, scale_by_half, gfx::PointF(50.f, 50.f), gfx::Size(100, 100), |
| 1578 false); |
| 1579 filtered_surface->test_properties()->background_filters = filters; |
| 1580 gfx::Rect occlusion_rect; |
| 1581 switch (i) { |
| 1582 case LEFT: |
| 1583 occlusion_rect = gfx::Rect(0, 0, 50, 200); |
| 1584 break; |
| 1585 case RIGHT: |
| 1586 // This is the right edge; filtered_surface is scaled by half. |
| 1587 occlusion_rect = gfx::Rect(100, 0, 50, 200); |
| 1588 break; |
| 1589 case TOP: |
| 1590 occlusion_rect = gfx::Rect(0, 0, 200, 50); |
| 1591 break; |
| 1592 case BOTTOM: |
| 1593 // This is the bottom edge; filtered_surface is scaled by half. |
| 1594 occlusion_rect = gfx::Rect(0, 100, 200, 50); |
| 1595 break; |
| 1596 } |
| 1597 |
| 1598 LayerImpl* occluding_layer = this->CreateDrawingLayer( |
| 1599 parent, this->identity_matrix, gfx::PointF(occlusion_rect.origin()), |
| 1600 occlusion_rect.size(), true); |
| 1601 occluding_layer->test_properties()->force_render_surface = false; |
| 1602 this->CalcDrawEtc(parent); |
| 1603 |
| 1604 TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 200, 200)); |
| 1605 |
| 1606 // This layer occludes pixels directly beside the filtered_surface. |
| 1607 // Because filtered surface blends pixels in a radius, it will need to see |
| 1608 // some of the pixels (up to radius far) underneath the occluding layers. |
| 1609 this->VisitLayer(occluding_layer, &occlusion); |
| 1610 |
| 1611 EXPECT_EQ(occlusion_rect.ToString(), |
| 1612 occlusion.occlusion_from_inside_target().ToString()); |
| 1613 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty()); |
| 1614 |
| 1615 this->VisitLayer(filtered_surface, &occlusion); |
| 1616 |
| 1617 // The occlusion is used fully inside the surface. |
| 1618 gfx::Rect occlusion_inside_surface = |
| 1619 occlusion_rect - gfx::Vector2d(50, 50); |
| 1620 EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty()); |
| 1621 EXPECT_EQ(occlusion_inside_surface.ToString(), |
| 1622 occlusion.occlusion_from_outside_target().ToString()); |
| 1623 |
| 1624 // The surface has a background filter, so it needs pixels that are |
| 1625 // currently considered occluded in order to be drawn. The pixels it |
| 1626 // needs should be removed from the occluded area, so that they are drawn |
| 1627 // when we get to the parent. |
| 1628 this->VisitContributingSurface(filtered_surface, &occlusion); |
| 1629 this->EnterLayer(parent, &occlusion); |
| 1630 |
| 1631 gfx::Rect expected_occlusion; |
| 1632 switch (i) { |
| 1633 case LEFT: |
| 1634 // The right half of the occlusion is close enough to cast a shadow |
| 1635 // that would be visible in the background filter. The shadow reaches |
| 1636 // 3*5 + 10 = 25 pixels to the right. |
| 1637 expected_occlusion = gfx::Rect(0, 0, 25, 200); |
| 1638 break; |
| 1639 case RIGHT: |
| 1640 // The shadow spreads 3*5 - 10 = 5 pixels to the left, so the |
| 1641 // occlusion must recede by 5 to account for that. |
| 1642 expected_occlusion = gfx::Rect(105, 0, 45, 200); |
| 1643 break; |
| 1644 case TOP: |
| 1645 // Similar to LEFT. |
| 1646 expected_occlusion = gfx::Rect(0, 0, 200, 25); |
| 1647 break; |
| 1648 case BOTTOM: |
| 1649 // Similar to RIGHT. |
| 1650 expected_occlusion = gfx::Rect(0, 105, 200, 45); |
| 1651 break; |
| 1652 } |
| 1653 |
| 1654 EXPECT_EQ(expected_occlusion.ToString(), |
| 1655 occlusion.occlusion_from_inside_target().ToString()); |
| 1656 EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty()); |
| 1657 |
| 1658 this->DestroyLayers(); |
| 1659 } |
| 1660 } |
| 1661 }; |
| 1662 |
| 1663 ALL_OCCLUSIONTRACKER_TEST( |
| 1664 OcclusionTrackerTestDontOccludePixelsNeededForDropShadowBackgroundFilter); |
| 1665 |
| 1543 class OcclusionTrackerTestTwoBackgroundFiltersReduceOcclusionTwice | 1666 class OcclusionTrackerTestTwoBackgroundFiltersReduceOcclusionTwice |
| 1544 : public OcclusionTrackerTest { | 1667 : public OcclusionTrackerTest { |
| 1545 protected: | 1668 protected: |
| 1546 explicit OcclusionTrackerTestTwoBackgroundFiltersReduceOcclusionTwice( | 1669 explicit OcclusionTrackerTestTwoBackgroundFiltersReduceOcclusionTwice( |
| 1547 bool opaque_layers) | 1670 bool opaque_layers) |
| 1548 : OcclusionTrackerTest(opaque_layers) {} | 1671 : OcclusionTrackerTest(opaque_layers) {} |
| 1549 void RunMyTest() override { | 1672 void RunMyTest() override { |
| 1550 gfx::Transform scale_by_half; | 1673 gfx::Transform scale_by_half; |
| 1551 scale_by_half.Scale(0.5, 0.5); | 1674 scale_by_half.Scale(0.5, 0.5); |
| 1552 | 1675 |
| (...skipping 962 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2515 EXPECT_EQ(gfx::Rect(), | 2638 EXPECT_EQ(gfx::Rect(), |
| 2516 occlusion.UnoccludedSurfaceContentRect( | 2639 occlusion.UnoccludedSurfaceContentRect( |
| 2517 surface, gfx::Rect(80, 70, 50, 50))); | 2640 surface, gfx::Rect(80, 70, 50, 50))); |
| 2518 } | 2641 } |
| 2519 }; | 2642 }; |
| 2520 | 2643 |
| 2521 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestUnoccludedSurfaceQuery) | 2644 ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestUnoccludedSurfaceQuery) |
| 2522 | 2645 |
| 2523 } // namespace | 2646 } // namespace |
| 2524 } // namespace cc | 2647 } // namespace cc |
| OLD | NEW |