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/layers/picture_layer_impl.h" | 5 #include "cc/layers/picture_layer_impl.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <limits> | 8 #include <limits> |
9 | 9 |
10 #include "base/time/time.h" | 10 #include "base/time/time.h" |
(...skipping 1523 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1534 DCHECK(*this); | 1534 DCHECK(*this); |
1535 | 1535 |
1536 IteratorType index = stages_[current_stage_].iterator_type; | 1536 IteratorType index = stages_[current_stage_].iterator_type; |
1537 DCHECK(iterators_[index]); | 1537 DCHECK(iterators_[index]); |
1538 DCHECK(iterators_[index].get_type() == stages_[current_stage_].tile_type); | 1538 DCHECK(iterators_[index].get_type() == stages_[current_stage_].tile_type); |
1539 | 1539 |
1540 return *iterators_[index]; | 1540 return *iterators_[index]; |
1541 } | 1541 } |
1542 | 1542 |
1543 PictureLayerImpl::LayerEvictionTileIterator::LayerEvictionTileIterator() | 1543 PictureLayerImpl::LayerEvictionTileIterator::LayerEvictionTileIterator() |
1544 : iterator_index_(0), | 1544 : current_tiling_index_(0), |
1545 iteration_stage_(TilePriority::EVENTUALLY), | 1545 current_range_type_(HIGHER_THAN_HIGH_RES), |
1546 required_for_activation_(false), | 1546 current_stage_(TilePriority::EVENTUALLY, false), |
1547 layer_(NULL) {} | 1547 tree_priority_(SAME_PRIORITY_FOR_BOTH_TREES), |
| 1548 layer_(NULL) { |
| 1549 } |
1548 | 1550 |
1549 PictureLayerImpl::LayerEvictionTileIterator::LayerEvictionTileIterator( | 1551 PictureLayerImpl::LayerEvictionTileIterator::LayerEvictionTileIterator( |
1550 PictureLayerImpl* layer, | 1552 PictureLayerImpl* layer, |
1551 TreePriority tree_priority) | 1553 TreePriority tree_priority) |
1552 : iterator_index_(0), | 1554 : current_tiling_index_(0), |
1553 iteration_stage_(TilePriority::EVENTUALLY), | 1555 current_range_type_(HIGHER_THAN_HIGH_RES), |
1554 required_for_activation_(false), | 1556 current_stage_(TilePriority::EVENTUALLY, false), |
| 1557 tree_priority_(tree_priority), |
1555 layer_(layer) { | 1558 layer_(layer) { |
1556 // Early out if the layer has no tilings. | 1559 // Early out if the layer has no tilings. |
1557 // TODO(vmpstr): Once tile priorities are determined by the iterators, ensure | 1560 // TODO(vmpstr): Once tile priorities are determined by the iterators, ensure |
1558 // that layers that don't have valid tile priorities have lowest priorities so | 1561 // that layers that don't have valid tile priorities have lowest priorities so |
1559 // they evict their tiles first (crbug.com/381704) | 1562 // they evict their tiles first (crbug.com/381704) |
1560 if (!layer_->tilings_ || !layer_->tilings_->num_tilings()) | 1563 if (!layer_->tilings_ || !layer_->tilings_->num_tilings()) |
1561 return; | 1564 return; |
1562 | 1565 |
| 1566 ConstructRanges(); |
| 1567 if (!CurrentTilingIndexInRange()) |
| 1568 AdvanceRange(); |
| 1569 |
| 1570 // There must be at least one valid range. |
| 1571 DCHECK(CurrentTilingIndexInRange()); |
| 1572 |
| 1573 iterator_ = PictureLayerTiling::TilingEvictionTileIterator( |
| 1574 layer_->tilings_->tiling_at(current_tiling_index_), |
| 1575 tree_priority, |
| 1576 current_stage_.tile_type, |
| 1577 current_stage_.required_for_activation); |
| 1578 |
| 1579 if (!iterator_) |
| 1580 AdvanceToNextIterator(); |
| 1581 } |
| 1582 |
| 1583 PictureLayerImpl::LayerEvictionTileIterator::~LayerEvictionTileIterator() { |
| 1584 } |
| 1585 |
| 1586 Tile* PictureLayerImpl::LayerEvictionTileIterator::operator*() { |
| 1587 DCHECK(*this); |
| 1588 return *iterator_; |
| 1589 } |
| 1590 |
| 1591 const Tile* PictureLayerImpl::LayerEvictionTileIterator::operator*() const { |
| 1592 DCHECK(*this); |
| 1593 return *iterator_; |
| 1594 } |
| 1595 |
| 1596 PictureLayerImpl::LayerEvictionTileIterator& |
| 1597 PictureLayerImpl::LayerEvictionTileIterator:: |
| 1598 operator++() { |
| 1599 DCHECK(*this); |
| 1600 ++iterator_; |
| 1601 |
| 1602 if (!iterator_) |
| 1603 AdvanceToNextIterator(); |
| 1604 return *this; |
| 1605 } |
| 1606 |
| 1607 void PictureLayerImpl::LayerEvictionTileIterator::ConstructRanges() { |
| 1608 // TODO(vmpstr): See if these can be looked up from the tiling set. |
1563 size_t high_res_tiling_index = layer_->tilings_->num_tilings(); | 1609 size_t high_res_tiling_index = layer_->tilings_->num_tilings(); |
1564 size_t low_res_tiling_index = layer_->tilings_->num_tilings(); | 1610 size_t low_res_tiling_index = layer_->tilings_->num_tilings(); |
1565 for (size_t i = 0; i < layer_->tilings_->num_tilings(); ++i) { | 1611 for (size_t i = 0; i < layer_->tilings_->num_tilings(); ++i) { |
1566 PictureLayerTiling* tiling = layer_->tilings_->tiling_at(i); | 1612 PictureLayerTiling* tiling = layer_->tilings_->tiling_at(i); |
1567 if (tiling->resolution() == HIGH_RESOLUTION) | 1613 if (tiling->resolution() == HIGH_RESOLUTION) |
1568 high_res_tiling_index = i; | 1614 high_res_tiling_index = i; |
1569 else if (tiling->resolution() == LOW_RESOLUTION) | 1615 else if (tiling->resolution() == LOW_RESOLUTION) |
1570 low_res_tiling_index = i; | 1616 low_res_tiling_index = i; |
1571 } | 1617 } |
1572 | 1618 |
1573 iterators_.reserve(layer_->tilings_->num_tilings()); | 1619 DCHECK_LT(high_res_tiling_index, layer_->tilings_->num_tilings()); |
1574 | 1620 |
1575 // Higher resolution non-ideal goes first. | 1621 // First iterate from highest resolution to the HIGH_RES tiling. |
1576 for (size_t i = 0; i < high_res_tiling_index; ++i) { | 1622 ranges_[HIGHER_THAN_HIGH_RES].start_index = 0; |
1577 iterators_.push_back(PictureLayerTiling::TilingEvictionTileIterator( | 1623 ranges_[HIGHER_THAN_HIGH_RES].one_past_end_index = high_res_tiling_index; |
1578 layer_->tilings_->tiling_at(i), tree_priority)); | 1624 |
| 1625 // Next, iterate from the lowest resolution to the LOW_RES tiling. Note that |
| 1626 // if we don't have a low res tiling, then the start index will be the same as |
| 1627 // one past the end, which means it is an empty range. |
| 1628 ranges_[LOWER_THAN_LOW_RES].start_index = layer_->tilings_->num_tilings() - 1; |
| 1629 ranges_[LOWER_THAN_LOW_RES].one_past_end_index = low_res_tiling_index; |
| 1630 |
| 1631 // Next, iterate from just after the LOW_RES tiling to the HIGH_RES tiling. |
| 1632 // Note that if there is no low res tiling, then start index will be the last |
| 1633 // tiling. |
| 1634 ranges_[BETWEEN_HIGH_AND_LOW_RES].start_index = low_res_tiling_index - 1; |
| 1635 ranges_[BETWEEN_HIGH_AND_LOW_RES].one_past_end_index = high_res_tiling_index; |
| 1636 |
| 1637 if (low_res_tiling_index < layer_->tilings_->num_tilings()) { |
| 1638 // Next, iterate a range of one element: LOW_RES tiling. |
| 1639 ranges_[LOW_RES].start_index = low_res_tiling_index; |
| 1640 ranges_[LOW_RES].one_past_end_index = low_res_tiling_index + 1; |
| 1641 } else { |
| 1642 // If there is no LOW_RES tiling, then set an empty range. |
| 1643 ranges_[LOW_RES].start_index = 0; |
| 1644 ranges_[LOW_RES].one_past_end_index = 0; |
1579 } | 1645 } |
1580 | 1646 |
1581 // Lower resolution non-ideal goes next. | 1647 // Finally, iterate a range of one element: HIGH_RES tiling. |
1582 for (size_t i = layer_->tilings_->num_tilings() - 1; | 1648 ranges_[HIGH_RES].start_index = high_res_tiling_index; |
1583 i > high_res_tiling_index; | 1649 ranges_[HIGH_RES].one_past_end_index = high_res_tiling_index + 1; |
1584 --i) { | |
1585 PictureLayerTiling* tiling = layer_->tilings_->tiling_at(i); | |
1586 if (tiling->resolution() == LOW_RESOLUTION) | |
1587 continue; | |
1588 | 1650 |
1589 iterators_.push_back( | 1651 current_range_type_ = HIGHER_THAN_HIGH_RES; |
1590 PictureLayerTiling::TilingEvictionTileIterator(tiling, tree_priority)); | 1652 current_tiling_index_ = ranges_[current_range_type_].start_index; |
| 1653 } |
| 1654 |
| 1655 bool PictureLayerImpl::LayerEvictionTileIterator::CurrentTilingIndexInRange() { |
| 1656 TilingIterationRange& range = ranges_[current_range_type_]; |
| 1657 if (range.start_index < range.one_past_end_index) { |
| 1658 return current_tiling_index_ >= range.start_index && |
| 1659 current_tiling_index_ < range.one_past_end_index; |
| 1660 } else if (range.start_index > range.one_past_end_index) { |
| 1661 return current_tiling_index_ <= range.start_index && |
| 1662 current_tiling_index_ > range.one_past_end_index; |
1591 } | 1663 } |
| 1664 // Empty range means we're not in range. |
| 1665 return false; |
| 1666 } |
1592 | 1667 |
1593 // Now, put the low res tiling if we have one. | 1668 void PictureLayerImpl::LayerEvictionTileIterator::AdvanceToNextIterator() { |
1594 if (low_res_tiling_index < layer_->tilings_->num_tilings()) { | 1669 DCHECK(!iterator_); |
1595 iterators_.push_back(PictureLayerTiling::TilingEvictionTileIterator( | 1670 while (!iterator_) { |
1596 layer_->tilings_->tiling_at(low_res_tiling_index), tree_priority)); | 1671 bool success = AdvanceTiling(); |
1597 } | 1672 if (!success) |
| 1673 success = AdvanceRange(); |
| 1674 if (!success) |
| 1675 success = AdvanceStage(); |
| 1676 if (!success) |
| 1677 break; |
1598 | 1678 |
1599 // Finally, put the high res tiling if we have one. | 1679 iterator_ = PictureLayerTiling::TilingEvictionTileIterator( |
1600 if (high_res_tiling_index < layer_->tilings_->num_tilings()) { | 1680 layer_->tilings_->tiling_at(current_tiling_index_), |
1601 iterators_.push_back(PictureLayerTiling::TilingEvictionTileIterator( | 1681 tree_priority_, |
1602 layer_->tilings_->tiling_at(high_res_tiling_index), tree_priority)); | 1682 current_stage_.tile_type, |
1603 } | 1683 current_stage_.required_for_activation); |
1604 | |
1605 DCHECK_GT(iterators_.size(), 0u); | |
1606 | |
1607 if (!iterators_[iterator_index_] || | |
1608 !IsCorrectType(&iterators_[iterator_index_])) { | |
1609 AdvanceToNextIterator(); | |
1610 } | 1684 } |
1611 } | 1685 } |
1612 | 1686 |
1613 PictureLayerImpl::LayerEvictionTileIterator::~LayerEvictionTileIterator() {} | 1687 bool PictureLayerImpl::LayerEvictionTileIterator::AdvanceTiling() { |
| 1688 DCHECK(CurrentTilingIndexInRange()); |
1614 | 1689 |
1615 Tile* PictureLayerImpl::LayerEvictionTileIterator::operator*() { | 1690 int direction = ranges_[current_range_type_].start_index < |
1616 DCHECK(*this); | 1691 ranges_[current_range_type_].one_past_end_index |
1617 return *iterators_[iterator_index_]; | 1692 ? 1 |
| 1693 : -1; |
| 1694 current_tiling_index_ += direction; |
| 1695 |
| 1696 return CurrentTilingIndexInRange(); |
1618 } | 1697 } |
1619 | 1698 |
1620 const Tile* PictureLayerImpl::LayerEvictionTileIterator::operator*() const { | 1699 bool PictureLayerImpl::LayerEvictionTileIterator::AdvanceRange() { |
1621 DCHECK(*this); | 1700 DCHECK(!CurrentTilingIndexInRange()); |
1622 return *iterators_[iterator_index_]; | 1701 bool wrapped_around = false; |
| 1702 while (!CurrentTilingIndexInRange()) { |
| 1703 switch (current_range_type_) { |
| 1704 case HIGHER_THAN_HIGH_RES: |
| 1705 current_range_type_ = LOWER_THAN_LOW_RES; |
| 1706 break; |
| 1707 case LOWER_THAN_LOW_RES: |
| 1708 current_range_type_ = BETWEEN_HIGH_AND_LOW_RES; |
| 1709 break; |
| 1710 case BETWEEN_HIGH_AND_LOW_RES: |
| 1711 current_range_type_ = LOW_RES; |
| 1712 break; |
| 1713 case LOW_RES: |
| 1714 current_range_type_ = HIGH_RES; |
| 1715 break; |
| 1716 case HIGH_RES: |
| 1717 current_range_type_ = HIGHER_THAN_HIGH_RES; |
| 1718 wrapped_around = true; |
| 1719 break; |
| 1720 case NUM_RANGE_TYPES: |
| 1721 NOTREACHED(); |
| 1722 break; |
| 1723 } |
| 1724 current_tiling_index_ = ranges_[current_range_type_].start_index; |
| 1725 } |
| 1726 // If we wrapped around the ranges, we need to indicate that we should advance |
| 1727 // the stage. |
| 1728 return !wrapped_around; |
1623 } | 1729 } |
1624 | 1730 |
1625 PictureLayerImpl::LayerEvictionTileIterator& | 1731 bool PictureLayerImpl::LayerEvictionTileIterator::AdvanceStage() { |
1626 PictureLayerImpl::LayerEvictionTileIterator:: | 1732 // If we're NOW and required_for_activation, then this was the last pass |
1627 operator++() { | 1733 // through the iterators. |
1628 DCHECK(*this); | 1734 if (current_stage_.tile_type == TilePriority::NOW && |
1629 ++iterators_[iterator_index_]; | 1735 current_stage_.required_for_activation) |
1630 if (!iterators_[iterator_index_] || | 1736 return false; |
1631 !IsCorrectType(&iterators_[iterator_index_])) { | 1737 |
1632 AdvanceToNextIterator(); | 1738 if (!current_stage_.required_for_activation) { |
| 1739 current_stage_.required_for_activation = true; |
| 1740 } else { |
| 1741 current_stage_.required_for_activation = false; |
| 1742 current_stage_.tile_type = |
| 1743 static_cast<TilePriority::PriorityBin>(current_stage_.tile_type - 1); |
1633 } | 1744 } |
1634 return *this; | 1745 return true; |
1635 } | |
1636 | |
1637 void PictureLayerImpl::LayerEvictionTileIterator::AdvanceToNextIterator() { | |
1638 ++iterator_index_; | |
1639 | |
1640 while (true) { | |
1641 while (iterator_index_ < iterators_.size()) { | |
1642 if (iterators_[iterator_index_] && | |
1643 IsCorrectType(&iterators_[iterator_index_])) { | |
1644 return; | |
1645 } | |
1646 ++iterator_index_; | |
1647 } | |
1648 | |
1649 // If we're NOW and required_for_activation, then this was the last pass | |
1650 // through the iterators. | |
1651 if (iteration_stage_ == TilePriority::NOW && required_for_activation_) | |
1652 break; | |
1653 | |
1654 if (!required_for_activation_) { | |
1655 required_for_activation_ = true; | |
1656 } else { | |
1657 required_for_activation_ = false; | |
1658 iteration_stage_ = | |
1659 static_cast<TilePriority::PriorityBin>(iteration_stage_ - 1); | |
1660 } | |
1661 iterator_index_ = 0; | |
1662 } | |
1663 } | 1746 } |
1664 | 1747 |
1665 PictureLayerImpl::LayerEvictionTileIterator::operator bool() const { | 1748 PictureLayerImpl::LayerEvictionTileIterator::operator bool() const { |
1666 return iterator_index_ < iterators_.size(); | 1749 return !!iterator_; |
1667 } | |
1668 | |
1669 bool PictureLayerImpl::LayerEvictionTileIterator::IsCorrectType( | |
1670 PictureLayerTiling::TilingEvictionTileIterator* it) const { | |
1671 return it->get_type() == iteration_stage_ && | |
1672 (**it)->required_for_activation() == required_for_activation_; | |
1673 } | 1750 } |
1674 | 1751 |
1675 } // namespace cc | 1752 } // namespace cc |
OLD | NEW |