Index: cc/layers/picture_layer_impl.cc |
diff --git a/cc/layers/picture_layer_impl.cc b/cc/layers/picture_layer_impl.cc |
index dcbcc7474a0d1ed0a0fb9aac6a1377e24d6c49b2..54875bcdfc8268f46d4614db9010f6ca3917e49a 100644 |
--- a/cc/layers/picture_layer_impl.cc |
+++ b/cc/layers/picture_layer_impl.cc |
@@ -1550,135 +1550,200 @@ const Tile* PictureLayerImpl::LayerRasterTileIterator::operator*() const { |
} |
PictureLayerImpl::LayerEvictionTileIterator::LayerEvictionTileIterator() |
- : iterator_index_(0), |
- iteration_stage_(TilePriority::EVENTUALLY), |
- required_for_activation_(false), |
- layer_(NULL) {} |
+ : current_range_offset_(0), |
+ current_tiling_range_type_(PictureLayerTilingSet::HIGHER_THAN_HIGH_RES), |
+ current_stage_(EVENTUALLY), |
+ tree_priority_(SAME_PRIORITY_FOR_BOTH_TREES), |
+ layer_(NULL) { |
+} |
PictureLayerImpl::LayerEvictionTileIterator::LayerEvictionTileIterator( |
PictureLayerImpl* layer, |
TreePriority tree_priority) |
- : iterator_index_(0), |
- iteration_stage_(TilePriority::EVENTUALLY), |
- required_for_activation_(false), |
+ : current_range_offset_(0), |
+ current_tiling_range_type_(PictureLayerTilingSet::HIGHER_THAN_HIGH_RES), |
+ current_stage_(EVENTUALLY), |
+ tree_priority_(tree_priority), |
layer_(layer) { |
- // Early out if the layer has no tilings. |
+ // Early out if the tilings_ object doesn't exist. |
// TODO(vmpstr): Once tile priorities are determined by the iterators, ensure |
// that layers that don't have valid tile priorities have lowest priorities so |
// they evict their tiles first (crbug.com/381704) |
- if (!layer_->tilings_ || !layer_->tilings_->num_tilings()) |
+ if (!layer_->tilings_) |
return; |
- size_t high_res_tiling_index = layer_->tilings_->num_tilings(); |
- size_t low_res_tiling_index = layer_->tilings_->num_tilings(); |
- for (size_t i = 0; i < layer_->tilings_->num_tilings(); ++i) { |
- PictureLayerTiling* tiling = layer_->tilings_->tiling_at(i); |
- if (tiling->resolution() == HIGH_RESOLUTION) |
- high_res_tiling_index = i; |
- else if (tiling->resolution() == LOW_RESOLUTION) |
- low_res_tiling_index = i; |
- } |
- |
- iterators_.reserve(layer_->tilings_->num_tilings()); |
+ if (!CurrentRange().IsIndexWithinRange(CurrentTilingIndex())) |
+ AdvanceRange(); |
- // Higher resolution non-ideal goes first. |
- for (size_t i = 0; i < high_res_tiling_index; ++i) { |
- iterators_.push_back(PictureLayerTiling::TilingEvictionTileIterator( |
- layer_->tilings_->tiling_at(i), tree_priority)); |
- } |
- |
- // Lower resolution non-ideal goes next. |
- for (size_t i = layer_->tilings_->num_tilings() - 1; |
- i > high_res_tiling_index; |
- --i) { |
- PictureLayerTiling* tiling = layer_->tilings_->tiling_at(i); |
- if (tiling->resolution() == LOW_RESOLUTION) |
- continue; |
+ iterator_ = PictureLayerTiling::TilingEvictionTileIterator( |
+ layer_->tilings_->tiling_at(CurrentTilingIndex()), |
+ tree_priority, |
+ PriorityBinFromIterationStage(current_stage_), |
+ RequiredForActivationFromIterationStage(current_stage_)); |
- iterators_.push_back( |
- PictureLayerTiling::TilingEvictionTileIterator(tiling, tree_priority)); |
- } |
- |
- // Now, put the low res tiling if we have one. |
- if (low_res_tiling_index < layer_->tilings_->num_tilings()) { |
- iterators_.push_back(PictureLayerTiling::TilingEvictionTileIterator( |
- layer_->tilings_->tiling_at(low_res_tiling_index), tree_priority)); |
- } |
- |
- // Finally, put the high res tiling if we have one. |
- if (high_res_tiling_index < layer_->tilings_->num_tilings()) { |
- iterators_.push_back(PictureLayerTiling::TilingEvictionTileIterator( |
- layer_->tilings_->tiling_at(high_res_tiling_index), tree_priority)); |
- } |
- |
- DCHECK_GT(iterators_.size(), 0u); |
- |
- if (!iterators_[iterator_index_] || |
- !IsCorrectType(&iterators_[iterator_index_])) { |
+ if (!iterator_) |
AdvanceToNextIterator(); |
- } |
} |
-PictureLayerImpl::LayerEvictionTileIterator::~LayerEvictionTileIterator() {} |
+PictureLayerImpl::LayerEvictionTileIterator::~LayerEvictionTileIterator() { |
+} |
Tile* PictureLayerImpl::LayerEvictionTileIterator::operator*() { |
DCHECK(*this); |
- return *iterators_[iterator_index_]; |
+ return *iterator_; |
} |
const Tile* PictureLayerImpl::LayerEvictionTileIterator::operator*() const { |
DCHECK(*this); |
- return *iterators_[iterator_index_]; |
+ return *iterator_; |
} |
PictureLayerImpl::LayerEvictionTileIterator& |
PictureLayerImpl::LayerEvictionTileIterator:: |
operator++() { |
DCHECK(*this); |
- ++iterators_[iterator_index_]; |
- if (!iterators_[iterator_index_] || |
- !IsCorrectType(&iterators_[iterator_index_])) { |
+ ++iterator_; |
+ |
+ if (!iterator_) |
AdvanceToNextIterator(); |
- } |
return *this; |
} |
void PictureLayerImpl::LayerEvictionTileIterator::AdvanceToNextIterator() { |
- ++iterator_index_; |
+ DCHECK(!iterator_); |
+ while (!iterator_) { |
+ bool success = AdvanceTiling(); |
+ if (!success) |
+ success = AdvanceRange(); |
+ if (!success) |
+ success = AdvanceStage(); |
+ if (!success) |
+ break; |
- while (true) { |
- while (iterator_index_ < iterators_.size()) { |
- if (iterators_[iterator_index_] && |
- IsCorrectType(&iterators_[iterator_index_])) { |
- return; |
- } |
- ++iterator_index_; |
+ iterator_ = PictureLayerTiling::TilingEvictionTileIterator( |
+ layer_->tilings_->tiling_at(CurrentTilingIndex()), |
+ tree_priority_, |
+ PriorityBinFromIterationStage(current_stage_), |
+ RequiredForActivationFromIterationStage(current_stage_)); |
+ } |
+} |
+ |
+bool PictureLayerImpl::LayerEvictionTileIterator::AdvanceTiling() { |
+ DCHECK(CurrentRange().IsIndexWithinRange(CurrentTilingIndex())); |
+ ++current_range_offset_; |
+ return CurrentRange().IsIndexWithinRange(CurrentTilingIndex()); |
+} |
+ |
+bool PictureLayerImpl::LayerEvictionTileIterator::AdvanceRange() { |
+ DCHECK(!CurrentRange().IsIndexWithinRange(CurrentTilingIndex())); |
+ bool wrapped_around = false; |
+ while (!CurrentRange().IsIndexWithinRange(CurrentTilingIndex())) { |
+ switch (current_tiling_range_type_) { |
+ case PictureLayerTilingSet::HIGHER_THAN_HIGH_RES: |
+ current_tiling_range_type_ = PictureLayerTilingSet::LOWER_THAN_LOW_RES; |
+ break; |
+ case PictureLayerTilingSet::LOWER_THAN_LOW_RES: |
+ current_tiling_range_type_ = |
+ PictureLayerTilingSet::BETWEEN_HIGH_AND_LOW_RES; |
+ break; |
+ case PictureLayerTilingSet::BETWEEN_HIGH_AND_LOW_RES: |
+ current_tiling_range_type_ = PictureLayerTilingSet::LOW_RES; |
+ break; |
+ case PictureLayerTilingSet::LOW_RES: |
+ current_tiling_range_type_ = PictureLayerTilingSet::HIGH_RES; |
+ break; |
+ case PictureLayerTilingSet::HIGH_RES: |
+ current_tiling_range_type_ = |
+ PictureLayerTilingSet::HIGHER_THAN_HIGH_RES; |
+ wrapped_around = true; |
+ break; |
} |
+ current_range_offset_ = 0; |
+ } |
+ // If we wrapped around the ranges, we need to indicate that we should advance |
+ // the stage. |
+ return !wrapped_around; |
+} |
+ |
+TilePriority::PriorityBin |
+PictureLayerImpl::LayerEvictionTileIterator::PriorityBinFromIterationStage( |
+ IterationStage stage) { |
+ switch (stage) { |
+ case EVENTUALLY: |
+ case EVENTUALLY_AND_REQUIRED_FOR_ACTIVATION: |
+ return TilePriority::EVENTUALLY; |
+ case SOON: |
+ case SOON_AND_REQUIRED_FOR_ACTIVATION: |
+ return TilePriority::SOON; |
+ case NOW: |
+ case NOW_AND_REQUIRED_FOR_ACTIVATION: |
+ return TilePriority::NOW; |
+ } |
+ NOTREACHED(); |
+ return TilePriority::EVENTUALLY; |
+} |
+ |
+bool PictureLayerImpl::LayerEvictionTileIterator:: |
+ RequiredForActivationFromIterationStage(IterationStage stage) { |
+ switch (stage) { |
+ case EVENTUALLY: |
+ case SOON: |
+ case NOW: |
+ return false; |
+ case EVENTUALLY_AND_REQUIRED_FOR_ACTIVATION: |
+ case SOON_AND_REQUIRED_FOR_ACTIVATION: |
+ case NOW_AND_REQUIRED_FOR_ACTIVATION: |
+ return true; |
+ } |
+ NOTREACHED(); |
+ return false; |
+} |
- // If we're NOW and required_for_activation, then this was the last pass |
- // through the iterators. |
- if (iteration_stage_ == TilePriority::NOW && required_for_activation_) |
- break; |
+PictureLayerTilingSet::TilingRange |
+PictureLayerImpl::LayerEvictionTileIterator::CurrentRange() { |
+ return layer_->tilings_->GetTilingRange(current_tiling_range_type_); |
+} |
- if (!required_for_activation_) { |
- required_for_activation_ = true; |
- } else { |
- required_for_activation_ = false; |
- iteration_stage_ = |
- static_cast<TilePriority::PriorityBin>(iteration_stage_ - 1); |
- } |
- iterator_index_ = 0; |
+int PictureLayerImpl::LayerEvictionTileIterator::CurrentTilingIndex() { |
+ const PictureLayerTilingSet::TilingRange& range = CurrentRange(); |
+ switch (current_tiling_range_type_) { |
+ case PictureLayerTilingSet::HIGHER_THAN_HIGH_RES: |
+ case PictureLayerTilingSet::LOW_RES: |
+ case PictureLayerTilingSet::HIGH_RES: |
+ return range.start + current_range_offset_; |
+ case PictureLayerTilingSet::BETWEEN_HIGH_AND_LOW_RES: |
+ case PictureLayerTilingSet::LOWER_THAN_LOW_RES: |
+ return static_cast<int>(range.end) - 1 - current_range_offset_; |
} |
+ NOTREACHED(); |
+ return 0; |
} |
-PictureLayerImpl::LayerEvictionTileIterator::operator bool() const { |
- return iterator_index_ < iterators_.size(); |
+bool PictureLayerImpl::LayerEvictionTileIterator::AdvanceStage() { |
+ switch (current_stage_) { |
+ case EVENTUALLY: |
+ current_stage_ = EVENTUALLY_AND_REQUIRED_FOR_ACTIVATION; |
+ break; |
+ case EVENTUALLY_AND_REQUIRED_FOR_ACTIVATION: |
+ current_stage_ = SOON; |
+ break; |
+ case SOON: |
+ current_stage_ = SOON_AND_REQUIRED_FOR_ACTIVATION; |
+ break; |
+ case SOON_AND_REQUIRED_FOR_ACTIVATION: |
+ current_stage_ = NOW; |
+ break; |
+ case NOW: |
+ current_stage_ = NOW_AND_REQUIRED_FOR_ACTIVATION; |
+ break; |
+ case NOW_AND_REQUIRED_FOR_ACTIVATION: |
+ return false; |
+ } |
+ return true; |
} |
-bool PictureLayerImpl::LayerEvictionTileIterator::IsCorrectType( |
- PictureLayerTiling::TilingEvictionTileIterator* it) const { |
- return it->get_type() == iteration_stage_ && |
- (**it)->required_for_activation() == required_for_activation_; |
+PictureLayerImpl::LayerEvictionTileIterator::operator bool() const { |
+ return !!iterator_; |
} |
} // namespace cc |