OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 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 <utility> | 5 #include <utility> |
6 | 6 |
7 #include "cc/resources/tiling_set_eviction_queue.h" | 7 #include "cc/resources/tiling_set_eviction_queue.h" |
8 | 8 |
9 namespace cc { | 9 namespace cc { |
10 namespace { | 10 namespace { |
(...skipping 20 matching lines...) Expand all Loading... |
31 // If priorities are the same, it does not matter which tree returns | 31 // If priorities are the same, it does not matter which tree returns |
32 // the tile. Let's pick the pending tree. | 32 // the tile. Let's pick the pending tree. |
33 return tree != PENDING_TREE; | 33 return tree != PENDING_TREE; |
34 } | 34 } |
35 | 35 |
36 } // namespace | 36 } // namespace |
37 | 37 |
38 TilingSetEvictionQueue::TilingSetEvictionQueue( | 38 TilingSetEvictionQueue::TilingSetEvictionQueue( |
39 PictureLayerTilingSet* tiling_set, | 39 PictureLayerTilingSet* tiling_set, |
40 bool skip_shared_out_of_order_tiles) | 40 bool skip_shared_out_of_order_tiles) |
41 : tiling_set_(tiling_set), | 41 : tree_(tiling_set->client()->GetTree()), |
42 tree_(tiling_set->client()->GetTree()), | |
43 skip_shared_out_of_order_tiles_(skip_shared_out_of_order_tiles), | 42 skip_shared_out_of_order_tiles_(skip_shared_out_of_order_tiles), |
44 processing_soon_border_rect_(false), | 43 phase_(EVENTUALLY_RECT), |
45 processing_required_for_activation_tiles_(false), | 44 current_tile_(nullptr) { |
46 current_priority_bin_(TilePriority::EVENTUALLY), | |
47 current_tiling_index_(0u), | |
48 current_tiling_range_type_(PictureLayerTilingSet::HIGHER_THAN_HIGH_RES), | |
49 current_eviction_tile_(nullptr) { | |
50 // Early out if the layer has no tilings. | 45 // Early out if the layer has no tilings. |
51 if (!tiling_set_->num_tilings()) | 46 if (!tiling_set->num_tilings()) |
52 return; | 47 return; |
53 | 48 GenerateTilingOrder(tiling_set); |
54 current_tiling_index_ = CurrentTilingRange().start - 1u; | 49 eventually_iterator_ = EventuallyTilingIterator( |
55 AdvanceToNextValidTiling(); | 50 &tilings_, tree_, skip_shared_out_of_order_tiles_); |
| 51 if (eventually_iterator_.done()) { |
| 52 AdvancePhase(); |
| 53 return; |
| 54 } |
| 55 current_tile_ = *eventually_iterator_; |
56 } | 56 } |
57 | 57 |
58 TilingSetEvictionQueue::~TilingSetEvictionQueue() { | 58 TilingSetEvictionQueue::~TilingSetEvictionQueue() { |
59 } | 59 } |
60 | 60 |
| 61 void TilingSetEvictionQueue::GenerateTilingOrder( |
| 62 PictureLayerTilingSet* tiling_set) { |
| 63 tilings_.reserve(tiling_set->num_tilings()); |
| 64 // Generate all of the tilings in the order described in the header comment |
| 65 // for this class. |
| 66 auto range = |
| 67 tiling_set->GetTilingRange(PictureLayerTilingSet::HIGHER_THAN_HIGH_RES); |
| 68 for (int i = range.start; i < range.end; ++i) |
| 69 tilings_.push_back(tiling_set->tiling_at(i)); |
| 70 |
| 71 range = tiling_set->GetTilingRange(PictureLayerTilingSet::LOWER_THAN_LOW_RES); |
| 72 for (int i = range.end - 1; i >= range.start; --i) |
| 73 tilings_.push_back(tiling_set->tiling_at(i)); |
| 74 |
| 75 range = tiling_set->GetTilingRange( |
| 76 PictureLayerTilingSet::BETWEEN_HIGH_AND_LOW_RES); |
| 77 for (int i = range.end - 1; i >= range.start; --i) |
| 78 tilings_.push_back(tiling_set->tiling_at(i)); |
| 79 |
| 80 range = tiling_set->GetTilingRange(PictureLayerTilingSet::LOW_RES); |
| 81 for (int i = range.start; i < range.end; ++i) |
| 82 tilings_.push_back(tiling_set->tiling_at(i)); |
| 83 |
| 84 range = tiling_set->GetTilingRange(PictureLayerTilingSet::HIGH_RES); |
| 85 for (int i = range.start; i < range.end; ++i) |
| 86 tilings_.push_back(tiling_set->tiling_at(i)); |
| 87 DCHECK_EQ(tiling_set->num_tilings(), tilings_.size()); |
| 88 } |
| 89 |
| 90 void TilingSetEvictionQueue::AdvancePhase() { |
| 91 current_tile_ = nullptr; |
| 92 while (!current_tile_ && |
| 93 phase_ != VISIBLE_RECT_REQUIRED_FOR_ACTIVATION_UNOCCLUDED) { |
| 94 phase_ = static_cast<Phase>(phase_ + 1); |
| 95 switch (phase_) { |
| 96 case EVENTUALLY_RECT: |
| 97 NOTREACHED(); |
| 98 break; |
| 99 case SOON_BORDER_RECT: |
| 100 soon_iterator_ = SoonBorderTilingIterator( |
| 101 &tilings_, tree_, skip_shared_out_of_order_tiles_); |
| 102 if (!soon_iterator_.done()) |
| 103 current_tile_ = *soon_iterator_; |
| 104 break; |
| 105 case SKEWPORT_RECT: |
| 106 skewport_iterator_ = SkewportTilingIterator( |
| 107 &tilings_, tree_, skip_shared_out_of_order_tiles_); |
| 108 if (!skewport_iterator_.done()) |
| 109 current_tile_ = *skewport_iterator_; |
| 110 break; |
| 111 case VISIBLE_RECT_OCCLUDED: |
| 112 visible_iterator_ = VisibleTilingIterator( |
| 113 &tilings_, tree_, skip_shared_out_of_order_tiles_, |
| 114 true /* return occluded tiles */, |
| 115 false /* return required for activation tiles */); |
| 116 if (!visible_iterator_.done()) |
| 117 current_tile_ = *visible_iterator_; |
| 118 break; |
| 119 case VISIBLE_RECT_UNOCCLUDED: |
| 120 visible_iterator_ = VisibleTilingIterator( |
| 121 &tilings_, tree_, skip_shared_out_of_order_tiles_, |
| 122 false /* return occluded tiles */, |
| 123 false /* return required for activation tiles */); |
| 124 if (!visible_iterator_.done()) |
| 125 current_tile_ = *visible_iterator_; |
| 126 break; |
| 127 case VISIBLE_RECT_REQUIRED_FOR_ACTIVATION_OCCLUDED: |
| 128 visible_iterator_ = VisibleTilingIterator( |
| 129 &tilings_, tree_, skip_shared_out_of_order_tiles_, |
| 130 true /* return occluded tiles */, |
| 131 true /* return required for activation tiles */); |
| 132 if (!visible_iterator_.done()) |
| 133 current_tile_ = *visible_iterator_; |
| 134 break; |
| 135 case VISIBLE_RECT_REQUIRED_FOR_ACTIVATION_UNOCCLUDED: |
| 136 visible_iterator_ = VisibleTilingIterator( |
| 137 &tilings_, tree_, skip_shared_out_of_order_tiles_, |
| 138 false /* return occluded tiles */, |
| 139 true /* return required for activation tiles */); |
| 140 if (!visible_iterator_.done()) |
| 141 current_tile_ = *visible_iterator_; |
| 142 break; |
| 143 } |
| 144 } |
| 145 } |
| 146 |
61 bool TilingSetEvictionQueue::IsEmpty() const { | 147 bool TilingSetEvictionQueue::IsEmpty() const { |
62 return !current_eviction_tile_; | 148 return !current_tile_; |
| 149 } |
| 150 |
| 151 Tile* TilingSetEvictionQueue::Top() { |
| 152 DCHECK(!IsEmpty()); |
| 153 return current_tile_; |
| 154 } |
| 155 |
| 156 const Tile* TilingSetEvictionQueue::Top() const { |
| 157 DCHECK(!IsEmpty()); |
| 158 return current_tile_; |
63 } | 159 } |
64 | 160 |
65 void TilingSetEvictionQueue::Pop() { | 161 void TilingSetEvictionQueue::Pop() { |
66 DCHECK(!IsEmpty()); | 162 DCHECK(!IsEmpty()); |
67 | 163 current_tile_ = nullptr; |
68 if (!AdvanceToNextEvictionTile()) | 164 switch (phase_) { |
69 AdvanceToNextValidTiling(); | 165 case EVENTUALLY_RECT: |
70 } | 166 ++eventually_iterator_; |
71 | 167 if (!eventually_iterator_.done()) |
72 Tile* TilingSetEvictionQueue::Top() { | 168 current_tile_ = *eventually_iterator_; |
73 DCHECK(!IsEmpty()); | 169 break; |
74 return current_eviction_tile_; | 170 case SOON_BORDER_RECT: |
75 } | 171 ++soon_iterator_; |
76 | 172 if (!soon_iterator_.done()) |
77 const Tile* TilingSetEvictionQueue::Top() const { | 173 current_tile_ = *soon_iterator_; |
78 DCHECK(!IsEmpty()); | 174 break; |
79 return current_eviction_tile_; | 175 case SKEWPORT_RECT: |
80 } | 176 ++skewport_iterator_; |
81 | 177 if (!skewport_iterator_.done()) |
82 bool TilingSetEvictionQueue::AdvanceToNextEvictionTile() { | 178 current_tile_ = *skewport_iterator_; |
83 // Advance to the next eviction tile within the current priority bin and | 179 break; |
84 // tiling. This is done while advancing to a new tiling and while popping | 180 case VISIBLE_RECT_OCCLUDED: |
85 // the current tile. | 181 case VISIBLE_RECT_UNOCCLUDED: |
86 | 182 case VISIBLE_RECT_REQUIRED_FOR_ACTIVATION_OCCLUDED: |
87 bool required_for_activation = processing_required_for_activation_tiles_; | 183 case VISIBLE_RECT_REQUIRED_FOR_ACTIVATION_UNOCCLUDED: |
88 | 184 ++visible_iterator_; |
89 for (;;) { | 185 if (!visible_iterator_.done()) |
90 while (spiral_iterator_) { | 186 current_tile_ = *visible_iterator_; |
91 std::pair<int, int> next_index = spiral_iterator_.index(); | 187 break; |
92 Tile* tile = current_tiling_->TileAt(next_index.first, next_index.second); | 188 } |
93 ++spiral_iterator_; | 189 if (!current_tile_) |
94 if (!tile || !tile->HasResource()) | 190 AdvancePhase(); |
95 continue; | 191 } |
96 current_tiling_->UpdateTileAndTwinPriority(tile); | 192 |
97 if (skip_shared_out_of_order_tiles_ && | 193 // EvictionRectIterator |
98 IsSharedOutOfOrderTile(tree_, tile)) | 194 TilingSetEvictionQueue::EvictionRectIterator::EvictionRectIterator() |
99 continue; | 195 : tile_(nullptr), |
100 DCHECK_EQ(tile->required_for_activation(), required_for_activation); | 196 tilings_(nullptr), |
101 current_eviction_tile_ = tile; | 197 tree_(ACTIVE_TREE), |
102 return true; | 198 skip_shared_out_of_order_tiles_(false), |
103 } | 199 tiling_index_(0) { |
104 if (processing_soon_border_rect_) { | 200 } |
105 // Advance from soon border rect to skewport rect. | 201 |
106 processing_soon_border_rect_ = false; | 202 TilingSetEvictionQueue::EvictionRectIterator::EvictionRectIterator( |
107 if (current_tiling_->has_skewport_rect_tiles_) { | 203 std::vector<PictureLayerTiling*>* tilings, |
108 spiral_iterator_ = TilingData::ReverseSpiralDifferenceIterator( | 204 WhichTree tree, |
109 ¤t_tiling_->tiling_data_, | 205 bool skip_shared_out_of_order_tiles) |
110 current_tiling_->current_skewport_rect_, | 206 : tile_(nullptr), |
111 current_tiling_->current_visible_rect_, | 207 tilings_(tilings), |
112 current_tiling_->current_visible_rect_); | 208 tree_(tree), |
113 continue; | 209 skip_shared_out_of_order_tiles_(skip_shared_out_of_order_tiles), |
114 } | 210 tiling_index_(0) { |
| 211 } |
| 212 |
| 213 template <typename TilingIteratorType> |
| 214 bool TilingSetEvictionQueue::EvictionRectIterator::AdvanceToNextTile( |
| 215 TilingIteratorType* iterator) { |
| 216 bool found_tile = false; |
| 217 while (!found_tile) { |
| 218 ++(*iterator); |
| 219 if (!(*iterator)) { |
| 220 tile_ = nullptr; |
| 221 break; |
| 222 } |
| 223 found_tile = GetFirstTileAndCheckIfValid(iterator); |
| 224 } |
| 225 return found_tile; |
| 226 } |
| 227 |
| 228 template <typename TilingIteratorType> |
| 229 bool TilingSetEvictionQueue::EvictionRectIterator::GetFirstTileAndCheckIfValid( |
| 230 TilingIteratorType* iterator) { |
| 231 tile_ = (*tilings_)[tiling_index_]->TileAt(iterator->index_x(), |
| 232 iterator->index_y()); |
| 233 // If there's nothing to evict, return false. |
| 234 if (!tile_ || !tile_->HasResource()) |
| 235 return false; |
| 236 (*tilings_)[tiling_index_]->UpdateTileAndTwinPriority(tile_); |
| 237 // If the tile is out of order, return false. |
| 238 if (skip_shared_out_of_order_tiles_ && IsSharedOutOfOrderTile(tree_, tile_)) |
| 239 return false; |
| 240 // In other cases, the tile we got is a viable candidate, return true. |
| 241 return true; |
| 242 } |
| 243 |
| 244 // EventuallyTilingIterator |
| 245 TilingSetEvictionQueue::EventuallyTilingIterator::EventuallyTilingIterator( |
| 246 std::vector<PictureLayerTiling*>* tilings, |
| 247 WhichTree tree, |
| 248 bool skip_shared_out_of_order_tiles) |
| 249 : EvictionRectIterator(tilings, tree, skip_shared_out_of_order_tiles) { |
| 250 // Find the first tiling with a tile. |
| 251 while (tiling_index_ < tilings_->size()) { |
| 252 if (!((*tilings_))[tiling_index_]->has_eventually_rect_tiles()) { |
| 253 ++tiling_index_; |
| 254 continue; |
| 255 } |
| 256 iterator_ = TilingData::ReverseSpiralDifferenceIterator( |
| 257 ((*tilings_))[tiling_index_]->tiling_data(), |
| 258 ((*tilings_))[tiling_index_]->current_eventually_rect(), |
| 259 ((*tilings_))[tiling_index_]->current_skewport_rect(), |
| 260 ((*tilings_))[tiling_index_]->current_soon_border_rect()); |
| 261 if (!iterator_) { |
| 262 ++tiling_index_; |
| 263 continue; |
115 } | 264 } |
116 break; | 265 break; |
117 } | 266 } |
118 | 267 if (tiling_index_ >= tilings_->size()) |
119 TilePriority::PriorityBin max_tile_priority_bin = | 268 return; |
120 current_tiling_->client_->GetMaxTilePriorityBin(); | 269 if (!GetFirstTileAndCheckIfValid(&iterator_)) |
121 while (visible_iterator_) { | 270 ++(*this); |
122 std::pair<int, int> next_index = visible_iterator_.index(); | 271 } |
123 Tile* tile = current_tiling_->TileAt(next_index.first, next_index.second); | 272 |
124 ++visible_iterator_; | 273 TilingSetEvictionQueue::EventuallyTilingIterator& |
125 if (!tile || !tile->HasResource()) | 274 TilingSetEvictionQueue::EventuallyTilingIterator:: |
126 continue; | 275 operator++() { |
127 // If the max tile priority is not NOW, updated priorities for tiles | 276 bool found_tile = AdvanceToNextTile(&iterator_); |
128 // returned by the visible iterator will not have NOW (but EVENTUALLY) | 277 while (!found_tile && (tiling_index_ + 1) < tilings_->size()) { |
129 // priority bin and cannot therefore be required for activation tiles nor | 278 ++tiling_index_; |
130 // occluded NOW tiles in the current tiling. | 279 if (!((*tilings_))[tiling_index_]->has_eventually_rect_tiles()) |
131 if (max_tile_priority_bin <= TilePriority::NOW) { | 280 continue; |
132 // If the current tiling is a pending tree tiling, required for | 281 iterator_ = TilingData::ReverseSpiralDifferenceIterator( |
133 // activation tiles can be detected without updating tile priorities. | 282 ((*tilings_))[tiling_index_]->tiling_data(), |
134 if (tree_ == PENDING_TREE && | 283 ((*tilings_))[tiling_index_]->current_eventually_rect(), |
135 current_tiling_->IsTileRequiredForActivationIfVisible(tile) != | 284 ((*tilings_))[tiling_index_]->current_skewport_rect(), |
136 required_for_activation) { | 285 ((*tilings_))[tiling_index_]->current_soon_border_rect()); |
137 continue; | 286 if (!iterator_) |
138 } | 287 continue; |
139 // Unoccluded NOW tiles should be evicted (and thus returned) only after | 288 found_tile = GetFirstTileAndCheckIfValid(&iterator_); |
140 // all occluded NOW tiles. | 289 if (!found_tile) |
141 if (!current_tiling_->IsTileOccluded(tile)) { | 290 found_tile = AdvanceToNextTile(&iterator_); |
142 unoccluded_now_tiles_.push_back(tile); | 291 } |
143 continue; | 292 return *this; |
144 } | 293 } |
145 } | 294 |
146 current_tiling_->UpdateTileAndTwinPriority(tile); | 295 // SoonBorderTilingIterator |
147 if (skip_shared_out_of_order_tiles_ && IsSharedOutOfOrderTile(tree_, tile)) | 296 TilingSetEvictionQueue::SoonBorderTilingIterator::SoonBorderTilingIterator( |
148 continue; | 297 std::vector<PictureLayerTiling*>* tilings, |
149 if (tile->required_for_activation() != required_for_activation) | 298 WhichTree tree, |
150 continue; | 299 bool skip_shared_out_of_order_tiles) |
151 current_eviction_tile_ = tile; | 300 : EvictionRectIterator(tilings, tree, skip_shared_out_of_order_tiles) { |
152 return true; | 301 // Find the first tiling with a tile. |
153 } | 302 while (tiling_index_ < tilings_->size()) { |
154 | 303 if (!((*tilings_))[tiling_index_]->has_soon_border_rect_tiles()) { |
155 while (!unoccluded_now_tiles_.empty()) { | 304 ++tiling_index_; |
156 // All (unoccluded) NOW tiles have the same priority bin (NOW) and the same | 305 continue; |
157 // distance to visible (0.0), so it does not matter that tiles are popped | 306 } |
158 // in reversed (FILO) order. | 307 iterator_ = TilingData::ReverseSpiralDifferenceIterator( |
159 Tile* tile = unoccluded_now_tiles_.back(); | 308 ((*tilings_))[tiling_index_]->tiling_data(), |
160 unoccluded_now_tiles_.pop_back(); | 309 ((*tilings_))[tiling_index_]->current_soon_border_rect(), |
161 DCHECK(tile); | 310 ((*tilings_))[tiling_index_]->current_skewport_rect(), |
162 if (!tile->HasResource()) | 311 ((*tilings_))[tiling_index_]->current_visible_rect()); |
163 continue; | 312 if (!iterator_) { |
164 current_tiling_->UpdateTileAndTwinPriority(tile); | 313 ++tiling_index_; |
165 if (skip_shared_out_of_order_tiles_ && IsSharedOutOfOrderTile(tree_, tile)) | 314 continue; |
166 continue; | 315 } |
167 if (tile->required_for_activation() != required_for_activation) | 316 break; |
168 continue; | 317 } |
169 current_eviction_tile_ = tile; | 318 if (tiling_index_ >= tilings_->size()) |
170 return true; | 319 return; |
171 } | 320 if (!GetFirstTileAndCheckIfValid(&iterator_)) |
172 | 321 ++(*this); |
173 current_eviction_tile_ = nullptr; | 322 } |
174 return false; | 323 |
175 } | 324 TilingSetEvictionQueue::SoonBorderTilingIterator& |
176 | 325 TilingSetEvictionQueue::SoonBorderTilingIterator:: |
177 bool TilingSetEvictionQueue::AdvanceToNextPriorityBin() { | 326 operator++() { |
178 // Advance to the next priority bin. This is done only after all tiling range | 327 bool found_tile = AdvanceToNextTile(&iterator_); |
179 // types (including the required for activation tiling) within the previous | 328 while (!found_tile && (tiling_index_ + 1) < tilings_->size()) { |
180 // priority bin have been gone through. | 329 ++tiling_index_; |
181 DCHECK_EQ(current_tiling_range_type_, PictureLayerTilingSet::HIGH_RES); | 330 if (!((*tilings_))[tiling_index_]->has_soon_border_rect_tiles()) |
182 | 331 continue; |
183 switch (current_priority_bin_) { | 332 iterator_ = TilingData::ReverseSpiralDifferenceIterator( |
184 case TilePriority::EVENTUALLY: | 333 ((*tilings_))[tiling_index_]->tiling_data(), |
185 current_priority_bin_ = TilePriority::SOON; | 334 ((*tilings_))[tiling_index_]->current_soon_border_rect(), |
186 return true; | 335 ((*tilings_))[tiling_index_]->current_skewport_rect(), |
187 case TilePriority::SOON: | 336 ((*tilings_))[tiling_index_]->current_visible_rect()); |
188 current_priority_bin_ = TilePriority::NOW; | 337 if (!iterator_) |
189 return true; | 338 continue; |
190 case TilePriority::NOW: | 339 found_tile = GetFirstTileAndCheckIfValid(&iterator_); |
191 return false; | 340 if (!found_tile) |
192 } | 341 found_tile = AdvanceToNextTile(&iterator_); |
193 NOTREACHED(); | 342 } |
194 return false; | 343 return *this; |
195 } | 344 } |
196 | 345 |
197 bool TilingSetEvictionQueue::AdvanceToNextTilingRangeType() { | 346 // SkewportTilingIterator |
198 // Advance to the next tiling range type within the current priority bin, to | 347 TilingSetEvictionQueue::SkewportTilingIterator::SkewportTilingIterator( |
199 // the required for activation tiling range type within the current priority | 348 std::vector<PictureLayerTiling*>* tilings, |
200 // bin or to the first tiling range type within the next priority bin. This | 349 WhichTree tree, |
201 // is done only after all tilings within the previous tiling range type have | 350 bool skip_shared_out_of_order_tiles) |
202 // been gone through. | 351 : EvictionRectIterator(tilings, tree, skip_shared_out_of_order_tiles) { |
203 DCHECK_EQ(current_tiling_index_, CurrentTilingRange().end); | 352 // Find the first tiling with a tile. |
204 | 353 while (tiling_index_ < tilings_->size()) { |
205 switch (current_tiling_range_type_) { | 354 if (!((*tilings_))[tiling_index_]->has_skewport_rect_tiles()) { |
206 case PictureLayerTilingSet::HIGHER_THAN_HIGH_RES: | 355 ++tiling_index_; |
207 current_tiling_range_type_ = PictureLayerTilingSet::LOWER_THAN_LOW_RES; | 356 continue; |
208 return true; | 357 } |
209 case PictureLayerTilingSet::LOWER_THAN_LOW_RES: | 358 iterator_ = TilingData::ReverseSpiralDifferenceIterator( |
210 current_tiling_range_type_ = | 359 ((*tilings_))[tiling_index_]->tiling_data(), |
211 PictureLayerTilingSet::BETWEEN_HIGH_AND_LOW_RES; | 360 ((*tilings_))[tiling_index_]->current_skewport_rect(), |
212 return true; | 361 ((*tilings_))[tiling_index_]->current_visible_rect(), |
213 case PictureLayerTilingSet::BETWEEN_HIGH_AND_LOW_RES: | 362 ((*tilings_))[tiling_index_]->current_visible_rect()); |
214 current_tiling_range_type_ = PictureLayerTilingSet::LOW_RES; | 363 if (!iterator_) { |
215 return true; | 364 ++tiling_index_; |
216 case PictureLayerTilingSet::LOW_RES: | 365 continue; |
217 current_tiling_range_type_ = PictureLayerTilingSet::HIGH_RES; | 366 } |
218 return true; | 367 break; |
219 case PictureLayerTilingSet::HIGH_RES: | 368 } |
220 // Process required for activation tiles (unless that has already been | 369 if (tiling_index_ >= tilings_->size()) |
221 // done). Only pending tree NOW tiles may be required for activation. | 370 return; |
222 if (!processing_required_for_activation_tiles_ && | 371 if (!GetFirstTileAndCheckIfValid(&iterator_)) |
223 current_priority_bin_ == TilePriority::NOW && tree_ == PENDING_TREE) { | 372 ++(*this); |
224 processing_required_for_activation_tiles_ = true; | 373 } |
225 return true; | 374 |
226 } | 375 TilingSetEvictionQueue::SkewportTilingIterator& |
227 processing_required_for_activation_tiles_ = false; | 376 TilingSetEvictionQueue::SkewportTilingIterator:: |
228 | 377 operator++() { |
229 if (!AdvanceToNextPriorityBin()) | 378 bool found_tile = AdvanceToNextTile(&iterator_); |
230 return false; | 379 while (!found_tile && (tiling_index_ + 1) < tilings_->size()) { |
231 | 380 ++tiling_index_; |
232 current_tiling_range_type_ = PictureLayerTilingSet::HIGHER_THAN_HIGH_RES; | 381 if (!((*tilings_))[tiling_index_]->has_skewport_rect_tiles()) |
233 return true; | 382 continue; |
234 } | 383 iterator_ = TilingData::ReverseSpiralDifferenceIterator( |
235 NOTREACHED(); | 384 ((*tilings_))[tiling_index_]->tiling_data(), |
236 return false; | 385 ((*tilings_))[tiling_index_]->current_skewport_rect(), |
237 } | 386 ((*tilings_))[tiling_index_]->current_visible_rect(), |
238 | 387 ((*tilings_))[tiling_index_]->current_visible_rect()); |
239 bool TilingSetEvictionQueue::AdvanceToNextValidTiling() { | 388 if (!iterator_) |
240 // Advance to the next tiling within current tiling range type or to | 389 continue; |
241 // the first tiling within the next tiling range type or priority bin until | 390 found_tile = GetFirstTileAndCheckIfValid(&iterator_); |
242 // the next eviction tile is found. This is done only after all eviction | 391 if (!found_tile) |
243 // tiles within the previous tiling within the current priority bin and | 392 found_tile = AdvanceToNextTile(&iterator_); |
244 // tiling range type have been gone through. | 393 } |
245 DCHECK(!current_eviction_tile_); | 394 return *this; |
246 DCHECK_NE(current_tiling_index_, CurrentTilingRange().end); | 395 } |
247 | 396 |
248 for (;;) { | 397 // VisibleTilingIterator |
249 ++current_tiling_index_; | 398 TilingSetEvictionQueue::VisibleTilingIterator::VisibleTilingIterator( |
250 while (current_tiling_index_ == CurrentTilingRange().end) { | 399 std::vector<PictureLayerTiling*>* tilings, |
251 if (!AdvanceToNextTilingRangeType()) | 400 WhichTree tree, |
252 return false; | 401 bool skip_shared_out_of_order_tiles, |
253 current_tiling_index_ = CurrentTilingRange().start; | 402 bool return_occluded_tiles, |
254 } | 403 bool return_required_for_activation_tiles) |
255 current_tiling_ = tiling_set_->tiling_at(CurrentTilingIndex()); | 404 : EvictionRectIterator(tilings, tree, skip_shared_out_of_order_tiles), |
256 | 405 return_occluded_tiles_(return_occluded_tiles), |
257 switch (current_priority_bin_) { | 406 return_required_for_activation_tiles_( |
258 case TilePriority::EVENTUALLY: | 407 return_required_for_activation_tiles) { |
259 if (current_tiling_->has_eventually_rect_tiles_) { | 408 // Find the first tiling with a tile. |
260 spiral_iterator_ = TilingData::ReverseSpiralDifferenceIterator( | 409 while (tiling_index_ < tilings_->size()) { |
261 ¤t_tiling_->tiling_data_, | 410 if (!((*tilings_))[tiling_index_]->has_visible_rect_tiles()) { |
262 current_tiling_->current_eventually_rect_, | 411 ++tiling_index_; |
263 current_tiling_->current_skewport_rect_, | 412 continue; |
264 current_tiling_->current_soon_border_rect_); | 413 } |
265 if (AdvanceToNextEvictionTile()) | 414 iterator_ = TilingData::Iterator( |
266 return true; | 415 ((*tilings_))[tiling_index_]->tiling_data(), |
267 } | 416 ((*tilings_))[tiling_index_]->current_visible_rect(), false); |
268 break; | 417 if (!iterator_) { |
269 case TilePriority::SOON: | 418 ++tiling_index_; |
270 if (current_tiling_->has_skewport_rect_tiles_ || | 419 continue; |
271 current_tiling_->has_soon_border_rect_tiles_) { | 420 } |
272 processing_soon_border_rect_ = true; | 421 break; |
273 if (current_tiling_->has_soon_border_rect_tiles_) | 422 } |
274 spiral_iterator_ = TilingData::ReverseSpiralDifferenceIterator( | 423 if (tiling_index_ >= tilings_->size()) |
275 ¤t_tiling_->tiling_data_, | 424 return; |
276 current_tiling_->current_soon_border_rect_, | 425 if (!GetFirstTileAndCheckIfValid(&iterator_)) { |
277 current_tiling_->current_skewport_rect_, | 426 ++(*this); |
278 current_tiling_->current_visible_rect_); | 427 return; |
279 if (AdvanceToNextEvictionTile()) | 428 } |
280 return true; | 429 if (!TileMatchesRequiredFlags(tile_)) { |
281 } | 430 ++(*this); |
282 break; | 431 return; |
283 case TilePriority::NOW: | 432 } |
284 if (current_tiling_->has_visible_rect_tiles_) { | 433 } |
285 visible_iterator_ = | 434 |
286 TilingData::Iterator(¤t_tiling_->tiling_data_, | 435 TilingSetEvictionQueue::VisibleTilingIterator& |
287 current_tiling_->current_visible_rect_, | 436 TilingSetEvictionQueue::VisibleTilingIterator:: |
288 false /* include_borders */); | 437 operator++() { |
289 if (AdvanceToNextEvictionTile()) | 438 bool found_tile = AdvanceToNextTile(&iterator_); |
290 return true; | 439 while (found_tile && !TileMatchesRequiredFlags(tile_)) |
291 } | 440 found_tile = AdvanceToNextTile(&iterator_); |
292 break; | 441 |
293 } | 442 while (!found_tile && (tiling_index_ + 1) < tilings_->size()) { |
294 } | 443 ++tiling_index_; |
295 } | 444 if (!((*tilings_))[tiling_index_]->has_visible_rect_tiles()) |
296 | 445 continue; |
297 PictureLayerTilingSet::TilingRange | 446 iterator_ = TilingData::Iterator( |
298 TilingSetEvictionQueue::CurrentTilingRange() const { | 447 ((*tilings_))[tiling_index_]->tiling_data(), |
299 return tiling_set_->GetTilingRange(current_tiling_range_type_); | 448 ((*tilings_))[tiling_index_]->current_visible_rect(), false); |
300 } | 449 if (!iterator_) |
301 | 450 continue; |
302 size_t TilingSetEvictionQueue::CurrentTilingIndex() const { | 451 found_tile = GetFirstTileAndCheckIfValid(&iterator_); |
303 DCHECK_NE(current_tiling_index_, CurrentTilingRange().end); | 452 if (!found_tile) |
304 switch (current_tiling_range_type_) { | 453 found_tile = AdvanceToNextTile(&iterator_); |
305 case PictureLayerTilingSet::HIGHER_THAN_HIGH_RES: | 454 while (found_tile && !TileMatchesRequiredFlags(tile_)) |
306 case PictureLayerTilingSet::LOW_RES: | 455 found_tile = AdvanceToNextTile(&iterator_); |
307 case PictureLayerTilingSet::HIGH_RES: | 456 } |
308 return current_tiling_index_; | 457 return *this; |
309 // Tilings in the following ranges are accessed in reverse order. | 458 } |
310 case PictureLayerTilingSet::BETWEEN_HIGH_AND_LOW_RES: | 459 |
311 case PictureLayerTilingSet::LOWER_THAN_LOW_RES: { | 460 bool TilingSetEvictionQueue::VisibleTilingIterator::TileMatchesRequiredFlags( |
312 PictureLayerTilingSet::TilingRange tiling_range = CurrentTilingRange(); | 461 const Tile* tile) const { |
313 size_t current_tiling_range_offset = | 462 bool activation_flag_matches = |
314 current_tiling_index_ - tiling_range.start; | 463 tile->required_for_activation() == return_required_for_activation_tiles_; |
315 return tiling_range.end - 1 - current_tiling_range_offset; | 464 bool occluded_flag_matches = |
316 } | 465 tile->is_occluded(tree_) == return_occluded_tiles_; |
317 } | 466 return activation_flag_matches && occluded_flag_matches; |
318 NOTREACHED(); | |
319 return 0; | |
320 } | 467 } |
321 | 468 |
322 } // namespace cc | 469 } // namespace cc |
OLD | NEW |