Chromium Code Reviews| 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 |