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 1538 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1549 DCHECK(*this); | 1549 DCHECK(*this); |
1550 | 1550 |
1551 IteratorType index = stages_[current_stage_].iterator_type; | 1551 IteratorType index = stages_[current_stage_].iterator_type; |
1552 DCHECK(iterators_[index]); | 1552 DCHECK(iterators_[index]); |
1553 DCHECK(iterators_[index].get_type() == stages_[current_stage_].tile_type); | 1553 DCHECK(iterators_[index].get_type() == stages_[current_stage_].tile_type); |
1554 | 1554 |
1555 return *iterators_[index]; | 1555 return *iterators_[index]; |
1556 } | 1556 } |
1557 | 1557 |
1558 PictureLayerImpl::LayerEvictionTileIterator::LayerEvictionTileIterator() | 1558 PictureLayerImpl::LayerEvictionTileIterator::LayerEvictionTileIterator() |
1559 : iterator_index_(0), | 1559 : tiling_index_(0), |
1560 tiling_direction_(HIGHER_THAN_HIGH_RES), | |
1560 iteration_stage_(TilePriority::EVENTUALLY), | 1561 iteration_stage_(TilePriority::EVENTUALLY), |
1561 required_for_activation_(false), | 1562 required_for_activation_(false), |
1562 layer_(NULL) {} | 1563 high_res_tiling_index_(0), |
1564 low_res_tiling_index_(0), | |
1565 tree_priority_(SAME_PRIORITY_FOR_BOTH_TREES), | |
1566 layer_(NULL) { | |
1567 } | |
1563 | 1568 |
1564 PictureLayerImpl::LayerEvictionTileIterator::LayerEvictionTileIterator( | 1569 PictureLayerImpl::LayerEvictionTileIterator::LayerEvictionTileIterator( |
1565 PictureLayerImpl* layer, | 1570 PictureLayerImpl* layer, |
1566 TreePriority tree_priority) | 1571 TreePriority tree_priority) |
1567 : iterator_index_(0), | 1572 : tiling_index_(0), |
1573 tiling_direction_(HIGHER_THAN_HIGH_RES), | |
1568 iteration_stage_(TilePriority::EVENTUALLY), | 1574 iteration_stage_(TilePriority::EVENTUALLY), |
1569 required_for_activation_(false), | 1575 required_for_activation_(false), |
1576 high_res_tiling_index_(0), | |
1577 low_res_tiling_index_(0), | |
1578 tree_priority_(tree_priority), | |
1570 layer_(layer) { | 1579 layer_(layer) { |
1571 // Early out if the layer has no tilings. | 1580 // Early out if the layer has no tilings. |
1572 // TODO(vmpstr): Once tile priorities are determined by the iterators, ensure | 1581 // TODO(vmpstr): Once tile priorities are determined by the iterators, ensure |
1573 // that layers that don't have valid tile priorities have lowest priorities so | 1582 // that layers that don't have valid tile priorities have lowest priorities so |
1574 // they evict their tiles first (crbug.com/381704) | 1583 // they evict their tiles first (crbug.com/381704) |
1575 if (!layer_->tilings_ || !layer_->tilings_->num_tilings()) | 1584 if (!layer_->tilings_ || !layer_->tilings_->num_tilings()) |
1576 return; | 1585 return; |
1577 | 1586 |
1578 size_t high_res_tiling_index = layer_->tilings_->num_tilings(); | 1587 high_res_tiling_index_ = layer_->tilings_->num_tilings(); |
1579 size_t low_res_tiling_index = layer_->tilings_->num_tilings(); | 1588 low_res_tiling_index_ = layer_->tilings_->num_tilings(); |
1580 for (size_t i = 0; i < layer_->tilings_->num_tilings(); ++i) { | 1589 for (size_t i = 0; i < layer_->tilings_->num_tilings(); ++i) { |
1581 PictureLayerTiling* tiling = layer_->tilings_->tiling_at(i); | 1590 PictureLayerTiling* tiling = layer_->tilings_->tiling_at(i); |
1582 if (tiling->resolution() == HIGH_RESOLUTION) | 1591 if (tiling->resolution() == HIGH_RESOLUTION) |
1583 high_res_tiling_index = i; | 1592 high_res_tiling_index_ = i; |
1584 else if (tiling->resolution() == LOW_RESOLUTION) | 1593 else if (tiling->resolution() == LOW_RESOLUTION) |
1585 low_res_tiling_index = i; | 1594 low_res_tiling_index_ = i; |
1586 } | 1595 } |
1587 | 1596 |
1588 iterators_.reserve(layer_->tilings_->num_tilings()); | 1597 if (tiling_index_ == high_res_tiling_index_ || |
1589 | 1598 tiling_index_ == low_res_tiling_index_) { |
1590 // Higher resolution non-ideal goes first. | 1599 AdvanceNextTilingIndex(); |
1591 for (size_t i = 0; i < high_res_tiling_index; ++i) { | |
1592 iterators_.push_back(PictureLayerTiling::TilingEvictionTileIterator( | |
1593 layer_->tilings_->tiling_at(i), tree_priority)); | |
1594 } | 1600 } |
1595 | 1601 |
1596 // Lower resolution non-ideal goes next. | 1602 iterator_ = PictureLayerTiling::TilingEvictionTileIterator( |
1597 for (size_t i = layer_->tilings_->num_tilings() - 1; | 1603 layer_->tilings_->tiling_at(tiling_index_), |
1598 i > high_res_tiling_index; | 1604 tree_priority, |
1599 --i) { | 1605 iteration_stage_, |
1600 PictureLayerTiling* tiling = layer_->tilings_->tiling_at(i); | 1606 required_for_activation_); |
1601 if (tiling->resolution() == LOW_RESOLUTION) | 1607 if (!iterator_) |
1602 continue; | |
1603 | |
1604 iterators_.push_back( | |
1605 PictureLayerTiling::TilingEvictionTileIterator(tiling, tree_priority)); | |
1606 } | |
1607 | |
1608 // Now, put the low res tiling if we have one. | |
1609 if (low_res_tiling_index < layer_->tilings_->num_tilings()) { | |
1610 iterators_.push_back(PictureLayerTiling::TilingEvictionTileIterator( | |
1611 layer_->tilings_->tiling_at(low_res_tiling_index), tree_priority)); | |
1612 } | |
1613 | |
1614 // Finally, put the high res tiling if we have one. | |
1615 if (high_res_tiling_index < layer_->tilings_->num_tilings()) { | |
1616 iterators_.push_back(PictureLayerTiling::TilingEvictionTileIterator( | |
1617 layer_->tilings_->tiling_at(high_res_tiling_index), tree_priority)); | |
1618 } | |
1619 | |
1620 DCHECK_GT(iterators_.size(), 0u); | |
1621 | |
1622 if (!iterators_[iterator_index_] || | |
1623 !IsCorrectType(&iterators_[iterator_index_])) { | |
1624 AdvanceToNextIterator(); | 1608 AdvanceToNextIterator(); |
1625 } | |
1626 } | 1609 } |
1627 | 1610 |
1628 PictureLayerImpl::LayerEvictionTileIterator::~LayerEvictionTileIterator() {} | 1611 PictureLayerImpl::LayerEvictionTileIterator::~LayerEvictionTileIterator() {} |
1629 | 1612 |
1630 Tile* PictureLayerImpl::LayerEvictionTileIterator::operator*() { | 1613 Tile* PictureLayerImpl::LayerEvictionTileIterator::operator*() { |
1631 DCHECK(*this); | 1614 DCHECK(*this); |
1632 return *iterators_[iterator_index_]; | 1615 return *iterator_; |
1633 } | 1616 } |
1634 | 1617 |
1635 const Tile* PictureLayerImpl::LayerEvictionTileIterator::operator*() const { | 1618 const Tile* PictureLayerImpl::LayerEvictionTileIterator::operator*() const { |
1636 DCHECK(*this); | 1619 DCHECK(*this); |
1637 return *iterators_[iterator_index_]; | 1620 return *iterator_; |
1638 } | 1621 } |
1639 | 1622 |
1640 PictureLayerImpl::LayerEvictionTileIterator& | 1623 PictureLayerImpl::LayerEvictionTileIterator& |
1641 PictureLayerImpl::LayerEvictionTileIterator:: | 1624 PictureLayerImpl::LayerEvictionTileIterator:: |
1642 operator++() { | 1625 operator++() { |
1643 DCHECK(*this); | 1626 DCHECK(*this); |
1644 ++iterators_[iterator_index_]; | 1627 ++iterator_; |
1645 if (!iterators_[iterator_index_] || | 1628 if (!iterator_) |
1646 !IsCorrectType(&iterators_[iterator_index_])) { | |
1647 AdvanceToNextIterator(); | 1629 AdvanceToNextIterator(); |
1648 } | |
1649 return *this; | 1630 return *this; |
1650 } | 1631 } |
1651 | 1632 |
1652 void PictureLayerImpl::LayerEvictionTileIterator::AdvanceToNextIterator() { | 1633 void PictureLayerImpl::LayerEvictionTileIterator::AdvanceToNextIterator() { |
1653 ++iterator_index_; | 1634 bool cycled = AdvanceNextTilingIndex(); |
1654 | |
1655 while (true) { | 1635 while (true) { |
1656 while (iterator_index_ < iterators_.size()) { | 1636 // If we cycle the tiling iteration directions, then we need to update the |
1657 if (iterators_[iterator_index_] && | 1637 // iteration stage before proceeding. |
1658 IsCorrectType(&iterators_[iterator_index_])) { | 1638 while (!cycled) { |
1639 iterator_ = PictureLayerTiling::TilingEvictionTileIterator( | |
1640 layer_->tilings_->tiling_at(tiling_index_), | |
1641 tree_priority_, | |
1642 iteration_stage_, | |
1643 required_for_activation_); | |
1644 if (iterator_) | |
1659 return; | 1645 return; |
1660 } | 1646 cycled = AdvanceNextTilingIndex(); |
1661 ++iterator_index_; | |
1662 } | 1647 } |
1663 | 1648 |
1664 // If we're NOW and required_for_activation, then this was the last pass | 1649 // If we're NOW and required_for_activation, then this was the last pass |
1665 // through the iterators. | 1650 // through the iterators. |
1666 if (iteration_stage_ == TilePriority::NOW && required_for_activation_) | 1651 if (iteration_stage_ == TilePriority::NOW && required_for_activation_) |
1667 break; | 1652 break; |
1668 | 1653 |
1669 if (!required_for_activation_) { | 1654 if (!required_for_activation_) { |
1670 required_for_activation_ = true; | 1655 required_for_activation_ = true; |
1671 } else { | 1656 } else { |
1672 required_for_activation_ = false; | 1657 required_for_activation_ = false; |
1673 iteration_stage_ = | 1658 iteration_stage_ = |
1674 static_cast<TilePriority::PriorityBin>(iteration_stage_ - 1); | 1659 static_cast<TilePriority::PriorityBin>(iteration_stage_ - 1); |
1675 } | 1660 } |
1676 iterator_index_ = 0; | 1661 cycled = false; |
1677 } | 1662 } |
1678 } | 1663 } |
1679 | 1664 |
1680 PictureLayerImpl::LayerEvictionTileIterator::operator bool() const { | 1665 PictureLayerImpl::LayerEvictionTileIterator::operator bool() const { |
1681 return iterator_index_ < iterators_.size(); | 1666 return iterator_; |
1682 } | 1667 } |
1683 | 1668 |
1684 bool PictureLayerImpl::LayerEvictionTileIterator::IsCorrectType( | 1669 bool PictureLayerImpl::LayerEvictionTileIterator::AdvanceNextTilingIndex() { |
vmpstr
2014/07/28 23:32:07
This function is what I'm uncomfortable about.
| |
1685 PictureLayerTiling::TilingEvictionTileIterator* it) const { | 1670 bool initial_run = true; |
1686 return it->get_type() == iteration_stage_ && | 1671 while (true) { |
1687 (**it)->required_for_activation() == required_for_activation_; | 1672 bool is_valid = true; |
1673 switch (tiling_direction_) { | |
1674 case HIGHER_THAN_HIGH_RES: | |
1675 ++tiling_index_; | |
1676 // This tiling is valid if it's not high res and refers to a valid | |
1677 // tiling. | |
1678 is_valid = tiling_index_ != high_res_tiling_index_ && | |
1679 tiling_index_ < layer_->tilings_->num_tilings(); | |
1680 break; | |
1681 case LOWER_THAN_HIGH_RES: | |
1682 // This tiling is invalid if it's already at 0. | |
1683 if (tiling_index_ == 0) { | |
1684 is_valid = false; | |
1685 break; | |
1686 } | |
1687 --tiling_index_; | |
1688 if (tiling_index_ == low_res_tiling_index_) { | |
1689 // This tiling is invalid if it's already at 0. | |
1690 if (tiling_index_ == 0) { | |
1691 is_valid = false; | |
1692 break; | |
1693 } | |
1694 --tiling_index_; | |
1695 } | |
1696 // This tiling is valid if it's not high res. | |
1697 is_valid = tiling_index_ != high_res_tiling_index_; | |
1698 break; | |
1699 case LOW_RES: | |
1700 tiling_index_ = low_res_tiling_index_; | |
1701 // This tiling is valid if it refers to a valid tiling. Note, if we | |
1702 // already had this mode set (ie initial run is true), then this tiling | |
1703 // is invalid, since we don't want to process the same tiling multiple | |
1704 // times. | |
1705 is_valid = | |
1706 !initial_run && tiling_index_ != layer_->tilings_->num_tilings(); | |
1707 break; | |
1708 case HIGH_RES: | |
1709 tiling_index_ = high_res_tiling_index_; | |
1710 // This tiling is valid if it refers to a valid tiling. Note, if we | |
1711 // already had this mode set (ie initial run is true), then this tiling | |
1712 // is invalid, since we don't want to process the same tiling multiple | |
1713 // times. | |
1714 is_valid = | |
1715 !initial_run && tiling_index_ != layer_->tilings_->num_tilings(); | |
1716 break; | |
1717 default: | |
1718 break; | |
1719 } | |
1720 if (is_valid) | |
1721 return false; | |
1722 | |
1723 initial_run = false; | |
1724 tiling_direction_ = static_cast<TilingIterationDirection>( | |
1725 (tiling_direction_ + 1) % NUM_ITERATION_DIRECTIONS); | |
1726 if (tiling_direction_ == HIGHER_THAN_HIGH_RES) { | |
1727 tiling_index_ = 0; | |
1728 return true; | |
1729 } else if (tiling_direction_ == LOWER_THAN_HIGH_RES) { | |
1730 tiling_index_ = layer_->tilings_->num_tilings(); | |
1731 } | |
1732 } | |
1733 return true; | |
1688 } | 1734 } |
1689 | 1735 |
1690 } // namespace cc | 1736 } // namespace cc |
OLD | NEW |