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 1520 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1531 DCHECK(*this); | 1531 DCHECK(*this); |
1532 | 1532 |
1533 IteratorType index = stages_[current_stage_].iterator_type; | 1533 IteratorType index = stages_[current_stage_].iterator_type; |
1534 DCHECK(iterators_[index]); | 1534 DCHECK(iterators_[index]); |
1535 DCHECK(iterators_[index].get_type() == stages_[current_stage_].tile_type); | 1535 DCHECK(iterators_[index].get_type() == stages_[current_stage_].tile_type); |
1536 | 1536 |
1537 return *iterators_[index]; | 1537 return *iterators_[index]; |
1538 } | 1538 } |
1539 | 1539 |
1540 PictureLayerImpl::LayerEvictionTileIterator::LayerEvictionTileIterator() | 1540 PictureLayerImpl::LayerEvictionTileIterator::LayerEvictionTileIterator() |
1541 : iterator_index_(0), | 1541 : current_range_offset_(0), |
1542 iteration_stage_(TilePriority::EVENTUALLY), | 1542 current_tiling_range_type_(PictureLayerTilingSet::HIGHER_THAN_HIGH_RES), |
1543 required_for_activation_(false), | 1543 current_stage_(EVENTUALLY), |
1544 layer_(NULL) {} | 1544 tree_priority_(SAME_PRIORITY_FOR_BOTH_TREES), |
1545 layer_(NULL) { | |
1546 } | |
1545 | 1547 |
1546 PictureLayerImpl::LayerEvictionTileIterator::LayerEvictionTileIterator( | 1548 PictureLayerImpl::LayerEvictionTileIterator::LayerEvictionTileIterator( |
1547 PictureLayerImpl* layer, | 1549 PictureLayerImpl* layer, |
1548 TreePriority tree_priority) | 1550 TreePriority tree_priority) |
1549 : iterator_index_(0), | 1551 : current_range_offset_(0), |
1550 iteration_stage_(TilePriority::EVENTUALLY), | 1552 current_tiling_range_type_(PictureLayerTilingSet::HIGHER_THAN_HIGH_RES), |
1551 required_for_activation_(false), | 1553 current_stage_(EVENTUALLY), |
1554 tree_priority_(tree_priority), | |
1552 layer_(layer) { | 1555 layer_(layer) { |
1553 // Early out if the layer has no tilings. | 1556 // Early out if the layer has no tilings. |
1554 // TODO(vmpstr): Once tile priorities are determined by the iterators, ensure | 1557 // TODO(vmpstr): Once tile priorities are determined by the iterators, ensure |
1555 // that layers that don't have valid tile priorities have lowest priorities so | 1558 // that layers that don't have valid tile priorities have lowest priorities so |
1556 // they evict their tiles first (crbug.com/381704) | 1559 // they evict their tiles first (crbug.com/381704) |
1557 if (!layer_->tilings_ || !layer_->tilings_->num_tilings()) | 1560 if (!layer_->tilings_ || !layer_->tilings_->num_tilings()) |
reveman
2014/08/01 17:54:47
I don't think you should need to check num_tilings
vmpstr
2014/08/01 19:39:50
It's an easy constructor early out. I mean even if
reveman
2014/08/04 14:56:17
I don't recommend doing it unless it's a cleanup.
| |
1558 return; | 1561 return; |
1559 | 1562 |
1560 size_t high_res_tiling_index = layer_->tilings_->num_tilings(); | 1563 if (!CurrentRange().IsIndexWithinRange(CurrentTilingIndex())) |
1561 size_t low_res_tiling_index = layer_->tilings_->num_tilings(); | 1564 AdvanceRange(); |
1562 for (size_t i = 0; i < layer_->tilings_->num_tilings(); ++i) { | |
1563 PictureLayerTiling* tiling = layer_->tilings_->tiling_at(i); | |
1564 if (tiling->resolution() == HIGH_RESOLUTION) | |
1565 high_res_tiling_index = i; | |
1566 else if (tiling->resolution() == LOW_RESOLUTION) | |
1567 low_res_tiling_index = i; | |
1568 } | |
1569 | 1565 |
1570 iterators_.reserve(layer_->tilings_->num_tilings()); | 1566 iterator_ = PictureLayerTiling::TilingEvictionTileIterator( |
1567 layer_->tilings_->tiling_at(CurrentTilingIndex()), | |
1568 tree_priority, | |
1569 PriorityBinFromIterationStage(current_stage_), | |
1570 RequiredForActivationFromIterationStage(current_stage_)); | |
1571 | 1571 |
1572 // Higher resolution non-ideal goes first. | 1572 if (!iterator_) |
1573 for (size_t i = 0; i < high_res_tiling_index; ++i) { | |
1574 iterators_.push_back(PictureLayerTiling::TilingEvictionTileIterator( | |
1575 layer_->tilings_->tiling_at(i), tree_priority)); | |
1576 } | |
1577 | |
1578 // Lower resolution non-ideal goes next. | |
1579 for (size_t i = layer_->tilings_->num_tilings() - 1; | |
1580 i > high_res_tiling_index; | |
1581 --i) { | |
1582 PictureLayerTiling* tiling = layer_->tilings_->tiling_at(i); | |
1583 if (tiling->resolution() == LOW_RESOLUTION) | |
1584 continue; | |
1585 | |
1586 iterators_.push_back( | |
1587 PictureLayerTiling::TilingEvictionTileIterator(tiling, tree_priority)); | |
1588 } | |
1589 | |
1590 // Now, put the low res tiling if we have one. | |
1591 if (low_res_tiling_index < layer_->tilings_->num_tilings()) { | |
1592 iterators_.push_back(PictureLayerTiling::TilingEvictionTileIterator( | |
1593 layer_->tilings_->tiling_at(low_res_tiling_index), tree_priority)); | |
1594 } | |
1595 | |
1596 // Finally, put the high res tiling if we have one. | |
1597 if (high_res_tiling_index < layer_->tilings_->num_tilings()) { | |
1598 iterators_.push_back(PictureLayerTiling::TilingEvictionTileIterator( | |
1599 layer_->tilings_->tiling_at(high_res_tiling_index), tree_priority)); | |
1600 } | |
1601 | |
1602 DCHECK_GT(iterators_.size(), 0u); | |
1603 | |
1604 if (!iterators_[iterator_index_] || | |
1605 !IsCorrectType(&iterators_[iterator_index_])) { | |
1606 AdvanceToNextIterator(); | 1573 AdvanceToNextIterator(); |
1607 } | |
1608 } | 1574 } |
1609 | 1575 |
1610 PictureLayerImpl::LayerEvictionTileIterator::~LayerEvictionTileIterator() {} | 1576 PictureLayerImpl::LayerEvictionTileIterator::~LayerEvictionTileIterator() { |
1577 } | |
1611 | 1578 |
1612 Tile* PictureLayerImpl::LayerEvictionTileIterator::operator*() { | 1579 Tile* PictureLayerImpl::LayerEvictionTileIterator::operator*() { |
1613 DCHECK(*this); | 1580 DCHECK(*this); |
1614 return *iterators_[iterator_index_]; | 1581 return *iterator_; |
1615 } | 1582 } |
1616 | 1583 |
1617 const Tile* PictureLayerImpl::LayerEvictionTileIterator::operator*() const { | 1584 const Tile* PictureLayerImpl::LayerEvictionTileIterator::operator*() const { |
1618 DCHECK(*this); | 1585 DCHECK(*this); |
1619 return *iterators_[iterator_index_]; | 1586 return *iterator_; |
1620 } | 1587 } |
1621 | 1588 |
1622 PictureLayerImpl::LayerEvictionTileIterator& | 1589 PictureLayerImpl::LayerEvictionTileIterator& |
1623 PictureLayerImpl::LayerEvictionTileIterator:: | 1590 PictureLayerImpl::LayerEvictionTileIterator:: |
1624 operator++() { | 1591 operator++() { |
1625 DCHECK(*this); | 1592 DCHECK(*this); |
1626 ++iterators_[iterator_index_]; | 1593 ++iterator_; |
1627 if (!iterators_[iterator_index_] || | 1594 |
1628 !IsCorrectType(&iterators_[iterator_index_])) { | 1595 if (!iterator_) |
1629 AdvanceToNextIterator(); | 1596 AdvanceToNextIterator(); |
1630 } | |
1631 return *this; | 1597 return *this; |
1632 } | 1598 } |
1633 | 1599 |
1634 void PictureLayerImpl::LayerEvictionTileIterator::AdvanceToNextIterator() { | 1600 void PictureLayerImpl::LayerEvictionTileIterator::AdvanceToNextIterator() { |
1635 ++iterator_index_; | 1601 DCHECK(!iterator_); |
1636 | 1602 while (!iterator_) { |
1637 while (true) { | 1603 bool success = AdvanceTiling(); |
1638 while (iterator_index_ < iterators_.size()) { | 1604 if (!success) |
1639 if (iterators_[iterator_index_] && | 1605 success = AdvanceRange(); |
1640 IsCorrectType(&iterators_[iterator_index_])) { | 1606 if (!success) |
1641 return; | 1607 success = AdvanceStage(); |
1642 } | 1608 if (!success) |
1643 ++iterator_index_; | |
1644 } | |
1645 | |
1646 // If we're NOW and required_for_activation, then this was the last pass | |
1647 // through the iterators. | |
1648 if (iteration_stage_ == TilePriority::NOW && required_for_activation_) | |
1649 break; | 1609 break; |
1650 | 1610 |
1651 if (!required_for_activation_) { | 1611 iterator_ = PictureLayerTiling::TilingEvictionTileIterator( |
1652 required_for_activation_ = true; | 1612 layer_->tilings_->tiling_at(CurrentTilingIndex()), |
1653 } else { | 1613 tree_priority_, |
1654 required_for_activation_ = false; | 1614 PriorityBinFromIterationStage(current_stage_), |
1655 iteration_stage_ = | 1615 RequiredForActivationFromIterationStage(current_stage_)); |
1656 static_cast<TilePriority::PriorityBin>(iteration_stage_ - 1); | |
1657 } | |
1658 iterator_index_ = 0; | |
1659 } | 1616 } |
1660 } | 1617 } |
1661 | 1618 |
1662 PictureLayerImpl::LayerEvictionTileIterator::operator bool() const { | 1619 bool PictureLayerImpl::LayerEvictionTileIterator::AdvanceTiling() { |
1663 return iterator_index_ < iterators_.size(); | 1620 DCHECK(CurrentRange().IsIndexWithinRange(CurrentTilingIndex())); |
1621 ++current_range_offset_; | |
1622 return CurrentRange().IsIndexWithinRange(CurrentTilingIndex()); | |
1664 } | 1623 } |
1665 | 1624 |
1666 bool PictureLayerImpl::LayerEvictionTileIterator::IsCorrectType( | 1625 bool PictureLayerImpl::LayerEvictionTileIterator::AdvanceRange() { |
1667 PictureLayerTiling::TilingEvictionTileIterator* it) const { | 1626 DCHECK(!CurrentRange().IsIndexWithinRange(CurrentTilingIndex())); |
1668 return it->get_type() == iteration_stage_ && | 1627 bool wrapped_around = false; |
1669 (**it)->required_for_activation() == required_for_activation_; | 1628 while (!CurrentRange().IsIndexWithinRange(CurrentTilingIndex())) { |
1629 switch (current_tiling_range_type_) { | |
1630 case PictureLayerTilingSet::HIGHER_THAN_HIGH_RES: | |
1631 current_tiling_range_type_ = PictureLayerTilingSet::LOWER_THAN_LOW_RES; | |
1632 break; | |
1633 case PictureLayerTilingSet::LOWER_THAN_LOW_RES: | |
1634 current_tiling_range_type_ = | |
1635 PictureLayerTilingSet::BETWEEN_HIGH_AND_LOW_RES; | |
1636 break; | |
1637 case PictureLayerTilingSet::BETWEEN_HIGH_AND_LOW_RES: | |
1638 current_tiling_range_type_ = PictureLayerTilingSet::LOW_RES; | |
1639 break; | |
1640 case PictureLayerTilingSet::LOW_RES: | |
1641 current_tiling_range_type_ = PictureLayerTilingSet::HIGH_RES; | |
1642 break; | |
1643 case PictureLayerTilingSet::HIGH_RES: | |
1644 current_tiling_range_type_ = | |
1645 PictureLayerTilingSet::HIGHER_THAN_HIGH_RES; | |
1646 wrapped_around = true; | |
1647 break; | |
1648 } | |
1649 current_range_offset_ = 0; | |
1650 } | |
1651 // If we wrapped around the ranges, we need to indicate that we should advance | |
1652 // the stage. | |
1653 return !wrapped_around; | |
1654 } | |
1655 | |
1656 TilePriority::PriorityBin | |
1657 PictureLayerImpl::LayerEvictionTileIterator::PriorityBinFromIterationStage( | |
1658 IterationStage stage) { | |
1659 switch (stage) { | |
1660 case EVENTUALLY: | |
1661 case EVENTUALLY_AND_REQUIRED_FOR_ACTIVATION: | |
1662 return TilePriority::EVENTUALLY; | |
1663 case SOON: | |
1664 case SOON_AND_REQUIRED_FOR_ACTIVATION: | |
1665 return TilePriority::SOON; | |
1666 case NOW: | |
1667 case NOW_AND_REQUIRED_FOR_ACTIVATION: | |
1668 return TilePriority::NOW; | |
1669 } | |
1670 } | |
1671 | |
1672 bool PictureLayerImpl::LayerEvictionTileIterator:: | |
1673 RequiredForActivationFromIterationStage(IterationStage stage) { | |
1674 switch (stage) { | |
1675 case EVENTUALLY: | |
1676 case SOON: | |
1677 case NOW: | |
1678 return false; | |
1679 case EVENTUALLY_AND_REQUIRED_FOR_ACTIVATION: | |
1680 case SOON_AND_REQUIRED_FOR_ACTIVATION: | |
1681 case NOW_AND_REQUIRED_FOR_ACTIVATION: | |
1682 return true; | |
1683 } | |
1684 } | |
1685 | |
1686 PictureLayerTilingSet::TilingRange | |
1687 PictureLayerImpl::LayerEvictionTileIterator::CurrentRange() { | |
1688 return layer_->tilings_->GetTilingRange(current_tiling_range_type_); | |
1689 } | |
1690 | |
1691 int PictureLayerImpl::LayerEvictionTileIterator::CurrentTilingIndex() { | |
1692 const PictureLayerTilingSet::TilingRange& range = CurrentRange(); | |
1693 switch (current_tiling_range_type_) { | |
1694 case PictureLayerTilingSet::HIGHER_THAN_HIGH_RES: | |
1695 case PictureLayerTilingSet::LOW_RES: | |
1696 case PictureLayerTilingSet::HIGH_RES: | |
1697 return range.start + current_range_offset_; | |
1698 case PictureLayerTilingSet::BETWEEN_HIGH_AND_LOW_RES: | |
1699 case PictureLayerTilingSet::LOWER_THAN_LOW_RES: | |
1700 return static_cast<int>(range.end) - 1 - current_range_offset_; | |
1701 } | |
1702 NOTREACHED(); | |
1703 return 0; | |
1704 } | |
1705 | |
1706 bool PictureLayerImpl::LayerEvictionTileIterator::AdvanceStage() { | |
1707 switch (current_stage_) { | |
1708 case EVENTUALLY: | |
1709 current_stage_ = EVENTUALLY_AND_REQUIRED_FOR_ACTIVATION; | |
1710 break; | |
1711 case EVENTUALLY_AND_REQUIRED_FOR_ACTIVATION: | |
1712 current_stage_ = SOON; | |
1713 break; | |
1714 case SOON: | |
1715 current_stage_ = SOON_AND_REQUIRED_FOR_ACTIVATION; | |
1716 break; | |
1717 case SOON_AND_REQUIRED_FOR_ACTIVATION: | |
1718 current_stage_ = NOW; | |
1719 break; | |
1720 case NOW: | |
1721 current_stage_ = NOW_AND_REQUIRED_FOR_ACTIVATION; | |
1722 break; | |
1723 case NOW_AND_REQUIRED_FOR_ACTIVATION: | |
1724 return false; | |
1725 } | |
1726 return true; | |
1727 } | |
1728 | |
1729 PictureLayerImpl::LayerEvictionTileIterator::operator bool() const { | |
1730 return !!iterator_; | |
1670 } | 1731 } |
1671 | 1732 |
1672 } // namespace cc | 1733 } // namespace cc |
OLD | NEW |