OLD | NEW |
(Empty) | |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "cc/resources/tiling_set_eviction_queue.h" |
| 6 |
| 7 namespace cc { |
| 8 |
| 9 TilingSetEvictionQueue::TilingSetEvictionQueue() |
| 10 : tiling_set_(nullptr), |
| 11 tree_priority_(SAME_PRIORITY_FOR_BOTH_TREES), |
| 12 current_category_(PictureLayerTiling::EVENTUALLY), |
| 13 current_tiling_index_(0u), |
| 14 current_tiling_range_type_(PictureLayerTilingSet::HIGHER_THAN_HIGH_RES), |
| 15 current_eviction_tile_(nullptr), |
| 16 eviction_tiles_(nullptr), |
| 17 next_eviction_tile_index_(0u) { |
| 18 } |
| 19 |
| 20 TilingSetEvictionQueue::TilingSetEvictionQueue( |
| 21 PictureLayerTilingSet* tiling_set, |
| 22 TreePriority tree_priority) |
| 23 : tiling_set_(tiling_set), |
| 24 tree_priority_(tree_priority), |
| 25 current_category_(PictureLayerTiling::EVENTUALLY), |
| 26 current_tiling_index_(0u), |
| 27 current_tiling_range_type_(PictureLayerTilingSet::HIGHER_THAN_HIGH_RES), |
| 28 current_eviction_tile_(nullptr), |
| 29 eviction_tiles_(nullptr), |
| 30 next_eviction_tile_index_(0u) { |
| 31 DCHECK(tiling_set_); |
| 32 |
| 33 // Early out if the layer has no tilings. |
| 34 if (!tiling_set_->num_tilings()) |
| 35 return; |
| 36 |
| 37 current_tiling_index_ = CurrentTilingRange().start - 1u; |
| 38 AdvanceToNextValidTiling(); |
| 39 } |
| 40 |
| 41 TilingSetEvictionQueue::~TilingSetEvictionQueue() { |
| 42 } |
| 43 |
| 44 bool TilingSetEvictionQueue::IsEmpty() const { |
| 45 return !current_eviction_tile_; |
| 46 } |
| 47 |
| 48 void TilingSetEvictionQueue::Pop() { |
| 49 DCHECK(!IsEmpty()); |
| 50 |
| 51 if (!AdvanceToNextEvictionTile()) |
| 52 AdvanceToNextValidTiling(); |
| 53 } |
| 54 |
| 55 Tile* TilingSetEvictionQueue::Top() { |
| 56 DCHECK(!IsEmpty()); |
| 57 return current_eviction_tile_; |
| 58 } |
| 59 |
| 60 const Tile* TilingSetEvictionQueue::Top() const { |
| 61 DCHECK(!IsEmpty()); |
| 62 return current_eviction_tile_; |
| 63 } |
| 64 |
| 65 bool TilingSetEvictionQueue::AdvanceToNextCategory() { |
| 66 // Advance to the next category. This is done only after all tiling range |
| 67 // types within the previous category have been gone through. |
| 68 DCHECK_EQ(current_tiling_range_type_, PictureLayerTilingSet::HIGH_RES); |
| 69 |
| 70 switch (current_category_) { |
| 71 case PictureLayerTiling::EVENTUALLY: |
| 72 current_category_ = |
| 73 PictureLayerTiling::EVENTUALLY_AND_REQUIRED_FOR_ACTIVATION; |
| 74 return true; |
| 75 case PictureLayerTiling::EVENTUALLY_AND_REQUIRED_FOR_ACTIVATION: |
| 76 current_category_ = PictureLayerTiling::SOON; |
| 77 return true; |
| 78 case PictureLayerTiling::SOON: |
| 79 current_category_ = PictureLayerTiling::SOON_AND_REQUIRED_FOR_ACTIVATION; |
| 80 return true; |
| 81 case PictureLayerTiling::SOON_AND_REQUIRED_FOR_ACTIVATION: |
| 82 current_category_ = PictureLayerTiling::NOW; |
| 83 return true; |
| 84 case PictureLayerTiling::NOW: |
| 85 current_category_ = PictureLayerTiling::NOW_AND_REQUIRED_FOR_ACTIVATION; |
| 86 return true; |
| 87 case PictureLayerTiling::NOW_AND_REQUIRED_FOR_ACTIVATION: |
| 88 return false; |
| 89 } |
| 90 NOTREACHED(); |
| 91 return false; |
| 92 } |
| 93 |
| 94 bool TilingSetEvictionQueue::AdvanceToNextEvictionTile() { |
| 95 // Advance to the next eviction tile within the current category and tiling. |
| 96 // This is done while advancing to a new tiling (in which case the next |
| 97 // eviction tile index is 0) and while popping the current tile (in which |
| 98 // case the next eviction tile index is greater than 0). |
| 99 DCHECK_EQ(next_eviction_tile_index_ > 0, current_eviction_tile_ != nullptr); |
| 100 |
| 101 while (next_eviction_tile_index_ < eviction_tiles_->size()) { |
| 102 Tile* tile = (*eviction_tiles_)[next_eviction_tile_index_]; |
| 103 ++next_eviction_tile_index_; |
| 104 if (tile->HasResources()) { |
| 105 current_eviction_tile_ = tile; |
| 106 return true; |
| 107 } |
| 108 } |
| 109 |
| 110 current_eviction_tile_ = nullptr; |
| 111 return false; |
| 112 } |
| 113 |
| 114 bool TilingSetEvictionQueue::AdvanceToNextTilingRangeType() { |
| 115 // Advance to the next tiling range type within the current category or to |
| 116 // the first tiling range type within the next category. This is done only |
| 117 // after all tilings within the previous tiling range type have been gone |
| 118 // through. |
| 119 DCHECK_EQ(current_tiling_index_, CurrentTilingRange().end); |
| 120 |
| 121 switch (current_tiling_range_type_) { |
| 122 case PictureLayerTilingSet::HIGHER_THAN_HIGH_RES: |
| 123 current_tiling_range_type_ = PictureLayerTilingSet::LOWER_THAN_LOW_RES; |
| 124 return true; |
| 125 case PictureLayerTilingSet::LOWER_THAN_LOW_RES: |
| 126 current_tiling_range_type_ = |
| 127 PictureLayerTilingSet::BETWEEN_HIGH_AND_LOW_RES; |
| 128 return true; |
| 129 case PictureLayerTilingSet::BETWEEN_HIGH_AND_LOW_RES: |
| 130 current_tiling_range_type_ = PictureLayerTilingSet::LOW_RES; |
| 131 return true; |
| 132 case PictureLayerTilingSet::LOW_RES: |
| 133 current_tiling_range_type_ = PictureLayerTilingSet::HIGH_RES; |
| 134 return true; |
| 135 case PictureLayerTilingSet::HIGH_RES: |
| 136 if (!AdvanceToNextCategory()) |
| 137 return false; |
| 138 |
| 139 current_tiling_range_type_ = PictureLayerTilingSet::HIGHER_THAN_HIGH_RES; |
| 140 return true; |
| 141 } |
| 142 NOTREACHED(); |
| 143 return false; |
| 144 } |
| 145 |
| 146 bool TilingSetEvictionQueue::AdvanceToNextValidTiling() { |
| 147 // Advance to the next tiling within current tiling range type or to |
| 148 // the first tiling within the next tiling range type or category until |
| 149 // the next eviction tile is found. This is done only after all eviction |
| 150 // tiles within the previous tiling within the current category and tiling |
| 151 // range type have been gone through. |
| 152 DCHECK(!current_eviction_tile_); |
| 153 DCHECK_NE(current_tiling_index_, CurrentTilingRange().end); |
| 154 |
| 155 for (;;) { |
| 156 ++current_tiling_index_; |
| 157 while (current_tiling_index_ == CurrentTilingRange().end) { |
| 158 if (!AdvanceToNextTilingRangeType()) |
| 159 return false; |
| 160 current_tiling_index_ = CurrentTilingRange().start; |
| 161 } |
| 162 |
| 163 PictureLayerTiling* tiling = tiling_set_->tiling_at(CurrentTilingIndex()); |
| 164 eviction_tiles_ = |
| 165 tiling->GetEvictionTiles(tree_priority_, current_category_); |
| 166 next_eviction_tile_index_ = 0u; |
| 167 if (AdvanceToNextEvictionTile()) |
| 168 return true; |
| 169 } |
| 170 } |
| 171 |
| 172 PictureLayerTilingSet::TilingRange |
| 173 TilingSetEvictionQueue::CurrentTilingRange() const { |
| 174 return tiling_set_->GetTilingRange(current_tiling_range_type_); |
| 175 } |
| 176 |
| 177 size_t TilingSetEvictionQueue::CurrentTilingIndex() const { |
| 178 DCHECK_NE(current_tiling_index_, CurrentTilingRange().end); |
| 179 switch (current_tiling_range_type_) { |
| 180 case PictureLayerTilingSet::HIGHER_THAN_HIGH_RES: |
| 181 case PictureLayerTilingSet::LOW_RES: |
| 182 case PictureLayerTilingSet::HIGH_RES: |
| 183 return current_tiling_index_; |
| 184 // Tilings in the following ranges are accessed in reverse order. |
| 185 case PictureLayerTilingSet::BETWEEN_HIGH_AND_LOW_RES: |
| 186 case PictureLayerTilingSet::LOWER_THAN_LOW_RES: { |
| 187 PictureLayerTilingSet::TilingRange tiling_range = CurrentTilingRange(); |
| 188 size_t current_tiling_range_offset = |
| 189 current_tiling_index_ - tiling_range.start; |
| 190 return tiling_range.end - 1 - current_tiling_range_offset; |
| 191 } |
| 192 } |
| 193 NOTREACHED(); |
| 194 return 0; |
| 195 } |
| 196 |
| 197 } |
OLD | NEW |