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_range_offset_(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_range_offset_(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 (current_range_offset_ >= ranges_[current_range_type_].count) | |
1568 AdvanceRange(); | |
1569 | |
1570 // There must be at least one valid range. | |
1571 DCHECK(current_range_offset_ < ranges_[current_range_type_].count); | |
1572 | |
1573 iterator_ = PictureLayerTiling::TilingEvictionTileIterator( | |
1574 layer_->tilings_->tiling_at(GetCurrentTilingIndex()), | |
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::SetEmptyRange( | |
1608 RangeType type) { | |
1609 ranges_[type].tiling_offset = 0; | |
1610 ranges_[type].count = 0; | |
1611 } | |
1612 | |
1613 void PictureLayerImpl::LayerEvictionTileIterator::SetRange(RangeType type, | |
1614 int start_index, | |
1615 int end_index) { | |
1616 if (start_index > end_index) { | |
1617 SetEmptyRange(type); | |
1618 return; | |
1619 } | |
1620 ranges_[type].tiling_offset = start_index; | |
1621 ranges_[type].count = end_index - start_index + 1; | |
1622 } | |
1623 | |
1624 void PictureLayerImpl::LayerEvictionTileIterator::ConstructRanges() { | |
1625 // TODO(vmpstr): See if these can be looked up from the tiling set. | |
1563 size_t high_res_tiling_index = layer_->tilings_->num_tilings(); | 1626 size_t high_res_tiling_index = layer_->tilings_->num_tilings(); |
1564 size_t low_res_tiling_index = layer_->tilings_->num_tilings(); | 1627 size_t low_res_tiling_index = layer_->tilings_->num_tilings(); |
1565 for (size_t i = 0; i < layer_->tilings_->num_tilings(); ++i) { | 1628 for (size_t i = 0; i < layer_->tilings_->num_tilings(); ++i) { |
1566 PictureLayerTiling* tiling = layer_->tilings_->tiling_at(i); | 1629 PictureLayerTiling* tiling = layer_->tilings_->tiling_at(i); |
1567 if (tiling->resolution() == HIGH_RESOLUTION) | 1630 if (tiling->resolution() == HIGH_RESOLUTION) |
1568 high_res_tiling_index = i; | 1631 high_res_tiling_index = i; |
1569 else if (tiling->resolution() == LOW_RESOLUTION) | 1632 else if (tiling->resolution() == LOW_RESOLUTION) |
1570 low_res_tiling_index = i; | 1633 low_res_tiling_index = i; |
1571 } | 1634 } |
1572 | 1635 |
1573 iterators_.reserve(layer_->tilings_->num_tilings()); | 1636 DCHECK_LT(high_res_tiling_index, layer_->tilings_->num_tilings()); |
1574 | 1637 |
1575 // Higher resolution non-ideal goes first. | 1638 // First iterate from highest resolution to the HIGH_RES tiling. |
1576 for (size_t i = 0; i < high_res_tiling_index; ++i) { | 1639 int start_index = 0; |
1577 iterators_.push_back(PictureLayerTiling::TilingEvictionTileIterator( | 1640 int end_index = high_res_tiling_index - 1; |
1578 layer_->tilings_->tiling_at(i), tree_priority)); | 1641 SetRange(HIGHER_THAN_HIGH_RES, start_index, end_index); |
1579 } | 1642 |
1580 | 1643 // Next, iterate from the lowest resolution to the LOW_RES tiling. Note that |
1581 // Lower resolution non-ideal goes next. | 1644 // if we don't have a low res tiling, then the start index will be the same as |
1582 for (size_t i = layer_->tilings_->num_tilings() - 1; | 1645 // one past the end, which means it is an empty range. |
1583 i > high_res_tiling_index; | 1646 start_index = low_res_tiling_index + 1; |
1584 --i) { | 1647 end_index = layer_->tilings_->num_tilings() - 1; |
1585 PictureLayerTiling* tiling = layer_->tilings_->tiling_at(i); | 1648 SetRange(LOWER_THAN_LOW_RES, start_index, end_index); |
1586 if (tiling->resolution() == LOW_RESOLUTION) | 1649 |
1587 continue; | 1650 // Next, iterate from just after the LOW_RES tiling to the HIGH_RES tiling. |
1588 | 1651 // Note that if there is no low res tiling, then start index will be the last |
1589 iterators_.push_back( | 1652 // tiling. |
1590 PictureLayerTiling::TilingEvictionTileIterator(tiling, tree_priority)); | 1653 start_index = high_res_tiling_index + 1; |
1591 } | 1654 end_index = low_res_tiling_index - 1; |
1592 | 1655 SetRange(BETWEEN_HIGH_AND_LOW_RES, start_index, end_index); |
1593 // Now, put the low res tiling if we have one. | 1656 |
1594 if (low_res_tiling_index < layer_->tilings_->num_tilings()) { | 1657 if (low_res_tiling_index < layer_->tilings_->num_tilings()) { |
1595 iterators_.push_back(PictureLayerTiling::TilingEvictionTileIterator( | 1658 // Next, iterate a range of one element: LOW_RES tiling. |
1596 layer_->tilings_->tiling_at(low_res_tiling_index), tree_priority)); | 1659 SetRange(LOW_RES, low_res_tiling_index, low_res_tiling_index); |
1597 } | 1660 } else { |
1598 | 1661 SetEmptyRange(LOW_RES); |
1599 // Finally, put the high res tiling if we have one. | 1662 } |
1600 if (high_res_tiling_index < layer_->tilings_->num_tilings()) { | 1663 |
1601 iterators_.push_back(PictureLayerTiling::TilingEvictionTileIterator( | 1664 // Finally, iterate a range of one element: HIGH_RES tiling. |
1602 layer_->tilings_->tiling_at(high_res_tiling_index), tree_priority)); | 1665 SetRange(HIGH_RES, high_res_tiling_index, high_res_tiling_index); |
1603 } | 1666 |
1604 | 1667 current_range_type_ = HIGHER_THAN_HIGH_RES; |
1605 DCHECK_GT(iterators_.size(), 0u); | 1668 current_range_offset_ = 0; |
1606 | |
1607 if (!iterators_[iterator_index_] || | |
1608 !IsCorrectType(&iterators_[iterator_index_])) { | |
1609 AdvanceToNextIterator(); | |
1610 } | |
1611 } | |
1612 | |
1613 PictureLayerImpl::LayerEvictionTileIterator::~LayerEvictionTileIterator() {} | |
1614 | |
1615 Tile* PictureLayerImpl::LayerEvictionTileIterator::operator*() { | |
1616 DCHECK(*this); | |
1617 return *iterators_[iterator_index_]; | |
1618 } | |
1619 | |
1620 const Tile* PictureLayerImpl::LayerEvictionTileIterator::operator*() const { | |
1621 DCHECK(*this); | |
1622 return *iterators_[iterator_index_]; | |
1623 } | |
1624 | |
1625 PictureLayerImpl::LayerEvictionTileIterator& | |
1626 PictureLayerImpl::LayerEvictionTileIterator:: | |
1627 operator++() { | |
1628 DCHECK(*this); | |
1629 ++iterators_[iterator_index_]; | |
1630 if (!iterators_[iterator_index_] || | |
1631 !IsCorrectType(&iterators_[iterator_index_])) { | |
1632 AdvanceToNextIterator(); | |
1633 } | |
1634 return *this; | |
1635 } | 1669 } |
1636 | 1670 |
1637 void PictureLayerImpl::LayerEvictionTileIterator::AdvanceToNextIterator() { | 1671 void PictureLayerImpl::LayerEvictionTileIterator::AdvanceToNextIterator() { |
1638 ++iterator_index_; | 1672 DCHECK(!iterator_); |
1639 | 1673 while (!iterator_) { |
1640 while (true) { | 1674 bool success = AdvanceTiling(); |
1641 while (iterator_index_ < iterators_.size()) { | 1675 if (!success) |
1642 if (iterators_[iterator_index_] && | 1676 success = AdvanceRange(); |
1643 IsCorrectType(&iterators_[iterator_index_])) { | 1677 if (!success) |
1644 return; | 1678 success = AdvanceStage(); |
1645 } | 1679 if (!success) |
1646 ++iterator_index_; | 1680 break; |
1681 | |
1682 iterator_ = PictureLayerTiling::TilingEvictionTileIterator( | |
1683 layer_->tilings_->tiling_at(GetCurrentTilingIndex()), | |
1684 tree_priority_, | |
1685 current_stage_.tile_type, | |
1686 current_stage_.required_for_activation); | |
1687 } | |
1688 } | |
1689 | |
1690 bool PictureLayerImpl::LayerEvictionTileIterator::AdvanceTiling() { | |
1691 DCHECK(current_range_offset_ < ranges_[current_range_type_].count); | |
1692 ++current_range_offset_; | |
1693 return current_range_offset_ < ranges_[current_range_type_].count; | |
1694 } | |
1695 | |
1696 bool PictureLayerImpl::LayerEvictionTileIterator::AdvanceRange() { | |
1697 DCHECK(current_range_offset_ >= ranges_[current_range_type_].count); | |
1698 bool wrapped_around = false; | |
1699 while (current_range_offset_ >= ranges_[current_range_type_].count) { | |
1700 switch (current_range_type_) { | |
1701 case HIGHER_THAN_HIGH_RES: | |
1702 current_range_type_ = LOWER_THAN_LOW_RES; | |
1703 break; | |
1704 case LOWER_THAN_LOW_RES: | |
1705 current_range_type_ = BETWEEN_HIGH_AND_LOW_RES; | |
1706 break; | |
1707 case BETWEEN_HIGH_AND_LOW_RES: | |
1708 current_range_type_ = LOW_RES; | |
1709 break; | |
1710 case LOW_RES: | |
1711 current_range_type_ = HIGH_RES; | |
1712 break; | |
1713 case HIGH_RES: | |
1714 current_range_type_ = HIGHER_THAN_HIGH_RES; | |
1715 wrapped_around = true; | |
1716 break; | |
1717 case NUM_RANGE_TYPES: | |
1718 NOTREACHED(); | |
1719 break; | |
1647 } | 1720 } |
1648 | 1721 current_range_offset_ = 0; |
1649 // If we're NOW and required_for_activation, then this was the last pass | 1722 } |
1650 // through the iterators. | 1723 // If we wrapped around the ranges, we need to indicate that we should advance |
1651 if (iteration_stage_ == TilePriority::NOW && required_for_activation_) | 1724 // the stage. |
1725 return !wrapped_around; | |
1726 } | |
1727 | |
1728 int PictureLayerImpl::LayerEvictionTileIterator::GetCurrentTilingIndex() { | |
reveman
2014/07/31 15:32:48
can you move this function to anonymous namespace?
vmpstr
2014/08/01 06:04:48
It's using member variables. I like the fact that
reveman
2014/08/01 17:54:46
Acknowledged.
| |
1729 DCHECK(current_range_offset_ < ranges_[current_range_type_].count); | |
1730 const TilingIterationRange& range = ranges_[current_range_type_]; | |
1731 switch (current_range_type_) { | |
1732 case HIGHER_THAN_HIGH_RES: | |
1733 case LOW_RES: | |
1734 case HIGH_RES: | |
1735 return range.tiling_offset + current_range_offset_; | |
1736 case BETWEEN_HIGH_AND_LOW_RES: | |
1737 case LOWER_THAN_LOW_RES: | |
1738 return range.tiling_offset + (range.count - current_range_offset_ - 1); | |
1739 case NUM_RANGE_TYPES: | |
1652 break; | 1740 break; |
1653 | 1741 } |
1654 if (!required_for_activation_) { | 1742 NOTREACHED(); |
1655 required_for_activation_ = true; | 1743 return 0; |
1656 } else { | 1744 } |
1657 required_for_activation_ = false; | 1745 |
1658 iteration_stage_ = | 1746 bool PictureLayerImpl::LayerEvictionTileIterator::AdvanceStage() { |
1659 static_cast<TilePriority::PriorityBin>(iteration_stage_ - 1); | 1747 // This function advances the stage to the next stage. The order of stages |
1748 // is as follows: | |
1749 // | |
1750 // EVENTUALLY bin and not required for activation, | |
1751 // EVENTUALLY bin and required for activation | |
1752 // SOON bin and not required for activation, | |
1753 // SOON bin and required for activation, | |
1754 // NOW bin and not required for activation, | |
1755 // NOW bin and required for activation. | |
1756 | |
1757 // If we're NOW and required_for_activation, then this was the last pass | |
1758 // through the iterators. | |
1759 if (current_stage_.tile_type == TilePriority::NOW && | |
1760 current_stage_.required_for_activation) | |
1761 return false; | |
1762 | |
1763 if (!current_stage_.required_for_activation) { | |
1764 current_stage_.required_for_activation = true; | |
1765 } else { | |
1766 current_stage_.required_for_activation = false; | |
1767 switch (current_stage_.tile_type) { | |
1768 case TilePriority::EVENTUALLY: | |
1769 current_stage_.tile_type = TilePriority::SOON; | |
1770 break; | |
1771 case TilePriority::SOON: | |
1772 current_stage_.tile_type = TilePriority::NOW; | |
1773 break; | |
1774 case TilePriority::NOW: | |
1775 NOTREACHED(); | |
1776 break; | |
1660 } | 1777 } |
1661 iterator_index_ = 0; | 1778 } |
1662 } | 1779 return true; |
1663 } | 1780 } |
1664 | 1781 |
1665 PictureLayerImpl::LayerEvictionTileIterator::operator bool() const { | 1782 PictureLayerImpl::LayerEvictionTileIterator::operator bool() const { |
1666 return iterator_index_ < iterators_.size(); | 1783 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 } | 1784 } |
1674 | 1785 |
1675 } // namespace cc | 1786 } // namespace cc |
OLD | NEW |