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