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_raster_queue_all.h" | |
6 | |
7 #include <utility> | |
8 | |
9 #include "cc/resources/picture_layer_tiling_set.h" | |
10 #include "cc/resources/tile.h" | |
11 #include "cc/resources/tile_priority.h" | |
12 | |
13 namespace cc { | |
14 | |
15 TilingSetRasterQueueAll::IterationStage::IterationStage( | |
16 IteratorType type, | |
17 TilePriority::PriorityBin bin) | |
18 : iterator_type(type), tile_type(bin) { | |
19 } | |
20 | |
21 TilingSetRasterQueueAll::TilingSetRasterQueueAll( | |
22 PictureLayerTilingSet* tiling_set, | |
23 bool prioritize_low_res) | |
24 : tiling_set_(tiling_set), current_stage_(0) { | |
25 DCHECK(tiling_set_); | |
26 | |
27 // Early out if the tiling set has no tilings. | |
28 if (!tiling_set_->num_tilings()) | |
29 return; | |
30 | |
31 const PictureLayerTilingClient* client = tiling_set->client(); | |
32 WhichTree tree = tiling_set->tree(); | |
33 // Find high and low res tilings and initialize the iterators. | |
34 PictureLayerTiling* high_res_tiling = nullptr; | |
35 PictureLayerTiling* low_res_tiling = nullptr; | |
36 // This variable would point to a tiling that has a NON_IDEAL_RESOLUTION | |
37 // resolution on the active tree, but HIGH_RESOLUTION on the pending tree. | |
38 // These tilings are the only non-ideal tilings that could have required for | |
39 // activation tiles, so they need to be considered for rasterization. | |
40 PictureLayerTiling* active_non_ideal_pending_high_res_tiling = nullptr; | |
41 for (size_t i = 0; i < tiling_set_->num_tilings(); ++i) { | |
42 PictureLayerTiling* tiling = tiling_set_->tiling_at(i); | |
43 if (tiling->resolution() == HIGH_RESOLUTION) | |
44 high_res_tiling = tiling; | |
45 if (prioritize_low_res && tiling->resolution() == LOW_RESOLUTION) | |
46 low_res_tiling = tiling; | |
47 if (tree == ACTIVE_TREE && tiling->resolution() == NON_IDEAL_RESOLUTION) { | |
48 const PictureLayerTiling* twin = | |
49 client->GetPendingOrActiveTwinTiling(tiling); | |
50 if (twin && twin->resolution() == HIGH_RESOLUTION) | |
51 active_non_ideal_pending_high_res_tiling = tiling; | |
52 } | |
53 } | |
54 | |
55 bool use_low_res_tiling = low_res_tiling && low_res_tiling->has_tiles(); | |
56 if (use_low_res_tiling && prioritize_low_res) { | |
57 iterators_[LOW_RES] = | |
58 TilingIterator(low_res_tiling, &low_res_tiling->tiling_data_); | |
59 stages_->push_back(IterationStage(LOW_RES, TilePriority::NOW)); | |
60 } | |
61 | |
62 bool use_high_res_tiling = high_res_tiling && high_res_tiling->has_tiles(); | |
63 if (use_high_res_tiling) { | |
64 iterators_[HIGH_RES] = | |
65 TilingIterator(high_res_tiling, &high_res_tiling->tiling_data_); | |
66 stages_->push_back(IterationStage(HIGH_RES, TilePriority::NOW)); | |
67 } | |
68 | |
69 if (low_res_tiling && !prioritize_low_res) { | |
70 iterators_[LOW_RES] = | |
71 TilingIterator(low_res_tiling, &low_res_tiling->tiling_data_); | |
72 stages_->push_back(IterationStage(LOW_RES, TilePriority::NOW)); | |
73 } | |
74 | |
75 if (active_non_ideal_pending_high_res_tiling && | |
76 active_non_ideal_pending_high_res_tiling->has_tiles()) { | |
77 iterators_[ACTIVE_NON_IDEAL_PENDING_HIGH_RES] = | |
78 TilingIterator(active_non_ideal_pending_high_res_tiling, | |
79 &active_non_ideal_pending_high_res_tiling->tiling_data_); | |
80 | |
81 stages_->push_back( | |
82 IterationStage(ACTIVE_NON_IDEAL_PENDING_HIGH_RES, TilePriority::NOW)); | |
83 stages_->push_back( | |
84 IterationStage(ACTIVE_NON_IDEAL_PENDING_HIGH_RES, TilePriority::SOON)); | |
85 } | |
86 | |
87 if (use_high_res_tiling) { | |
88 stages_->push_back(IterationStage(HIGH_RES, TilePriority::SOON)); | |
89 stages_->push_back(IterationStage(HIGH_RES, TilePriority::EVENTUALLY)); | |
90 } | |
91 | |
92 if (stages_->empty()) | |
93 return; | |
94 | |
95 IteratorType index = stages_[current_stage_].iterator_type; | |
96 TilePriority::PriorityBin tile_type = stages_[current_stage_].tile_type; | |
97 if (iterators_[index].done() || iterators_[index].type() != tile_type) | |
98 AdvanceToNextStage(); | |
99 } | |
100 | |
101 TilingSetRasterQueueAll::~TilingSetRasterQueueAll() { | |
102 } | |
103 | |
104 bool TilingSetRasterQueueAll::IsEmpty() const { | |
105 return current_stage_ >= stages_->size(); | |
106 } | |
107 | |
108 void TilingSetRasterQueueAll::Pop() { | |
109 IteratorType index = stages_[current_stage_].iterator_type; | |
110 TilePriority::PriorityBin tile_type = stages_[current_stage_].tile_type; | |
111 | |
112 // First advance the iterator. | |
113 DCHECK(!iterators_[index].done()); | |
114 DCHECK(iterators_[index].type() == tile_type); | |
115 ++iterators_[index]; | |
116 | |
117 if (iterators_[index].done() || iterators_[index].type() != tile_type) | |
118 AdvanceToNextStage(); | |
119 } | |
120 | |
121 const PrioritizedTile& TilingSetRasterQueueAll::Top() const { | |
122 DCHECK(!IsEmpty()); | |
123 | |
124 IteratorType index = stages_[current_stage_].iterator_type; | |
125 DCHECK(!iterators_[index].done()); | |
126 DCHECK(iterators_[index].type() == stages_[current_stage_].tile_type); | |
127 | |
128 return *iterators_[index]; | |
129 } | |
130 | |
131 void TilingSetRasterQueueAll::AdvanceToNextStage() { | |
132 DCHECK_LT(current_stage_, stages_->size()); | |
133 ++current_stage_; | |
134 while (current_stage_ < stages_->size()) { | |
135 IteratorType index = stages_[current_stage_].iterator_type; | |
136 TilePriority::PriorityBin tile_type = stages_[current_stage_].tile_type; | |
137 | |
138 if (!iterators_[index].done() && iterators_[index].type() == tile_type) | |
139 break; | |
140 ++current_stage_; | |
141 } | |
142 } | |
143 | |
144 // OnePriorityRectIterator | |
145 TilingSetRasterQueueAll::OnePriorityRectIterator::OnePriorityRectIterator() | |
146 : tiling_(nullptr), tiling_data_(nullptr) { | |
147 } | |
148 | |
149 TilingSetRasterQueueAll::OnePriorityRectIterator::OnePriorityRectIterator( | |
150 PictureLayerTiling* tiling, | |
151 TilingData* tiling_data, | |
152 PictureLayerTiling::PriorityRectType priority_rect_type) | |
153 : tiling_(tiling), | |
154 tiling_data_(tiling_data), | |
155 priority_rect_type_(priority_rect_type) { | |
156 } | |
157 | |
158 template <typename TilingIteratorType> | |
159 void TilingSetRasterQueueAll::OnePriorityRectIterator::AdvanceToNextTile( | |
160 TilingIteratorType* iterator) { | |
161 bool found_tile = false; | |
162 while (!found_tile) { | |
163 ++(*iterator); | |
164 if (!(*iterator)) { | |
165 current_tile_ = PrioritizedTile(); | |
166 break; | |
167 } | |
168 found_tile = GetFirstTileAndCheckIfValid(iterator); | |
169 } | |
170 } | |
171 | |
172 template <typename TilingIteratorType> | |
173 bool TilingSetRasterQueueAll::OnePriorityRectIterator:: | |
174 GetFirstTileAndCheckIfValid(TilingIteratorType* iterator) { | |
175 Tile* tile = tiling_->TileAt(iterator->index_x(), iterator->index_y()); | |
176 if (!tile || !TileNeedsRaster(tile)) { | |
177 current_tile_ = PrioritizedTile(); | |
178 return false; | |
179 } | |
180 // After the pending visible rect has been processed, we must return false | |
181 // for pending visible rect tiles as tiling iterators do not ignore those | |
182 // tiles. | |
183 if (priority_rect_type_ > PictureLayerTiling::PENDING_VISIBLE_RECT && | |
184 tiling_->pending_visible_rect().Intersects(tile->content_rect())) { | |
185 current_tile_ = PrioritizedTile(); | |
186 return false; | |
187 } | |
188 tiling_->UpdateRequiredStatesOnTile(tile); | |
189 current_tile_ = tiling_->MakePrioritizedTile(tile, priority_rect_type_); | |
190 return true; | |
191 } | |
192 | |
193 // VisibleTilingIterator. | |
194 TilingSetRasterQueueAll::VisibleTilingIterator::VisibleTilingIterator( | |
195 PictureLayerTiling* tiling, | |
196 TilingData* tiling_data) | |
197 : OnePriorityRectIterator(tiling, | |
198 tiling_data, | |
199 PictureLayerTiling::VISIBLE_RECT) { | |
200 if (!tiling_->has_visible_rect_tiles()) | |
201 return; | |
202 iterator_ = | |
203 TilingData::Iterator(tiling_data_, tiling_->current_visible_rect(), | |
204 false /* include_borders */); | |
205 if (!iterator_) | |
206 return; | |
207 if (!GetFirstTileAndCheckIfValid(&iterator_)) | |
208 ++(*this); | |
209 } | |
210 | |
211 TilingSetRasterQueueAll::VisibleTilingIterator& | |
212 TilingSetRasterQueueAll::VisibleTilingIterator:: | |
213 operator++() { | |
214 AdvanceToNextTile(&iterator_); | |
215 return *this; | |
216 } | |
217 | |
218 // PendingVisibleTilingIterator. | |
219 TilingSetRasterQueueAll::PendingVisibleTilingIterator:: | |
220 PendingVisibleTilingIterator(PictureLayerTiling* tiling, | |
221 TilingData* tiling_data) | |
222 : OnePriorityRectIterator(tiling, | |
223 tiling_data, | |
224 PictureLayerTiling::PENDING_VISIBLE_RECT) { | |
225 iterator_ = TilingData::DifferenceIterator(tiling_data_, | |
226 tiling_->pending_visible_rect(), | |
227 tiling_->current_visible_rect()); | |
228 if (!iterator_) | |
229 return; | |
230 if (!GetFirstTileAndCheckIfValid(&iterator_)) | |
231 ++(*this); | |
232 } | |
233 | |
234 TilingSetRasterQueueAll::PendingVisibleTilingIterator& | |
235 TilingSetRasterQueueAll::PendingVisibleTilingIterator:: | |
236 operator++() { | |
237 AdvanceToNextTile(&iterator_); | |
238 return *this; | |
239 } | |
240 | |
241 // SkewportTilingIterator. | |
242 TilingSetRasterQueueAll::SkewportTilingIterator::SkewportTilingIterator( | |
243 PictureLayerTiling* tiling, | |
244 TilingData* tiling_data) | |
245 : OnePriorityRectIterator(tiling, | |
246 tiling_data, | |
247 PictureLayerTiling::SKEWPORT_RECT), | |
248 pending_visible_rect_(tiling->pending_visible_rect()) { | |
249 if (!tiling_->has_skewport_rect_tiles()) | |
250 return; | |
251 iterator_ = TilingData::SpiralDifferenceIterator( | |
252 tiling_data_, tiling_->current_skewport_rect(), | |
253 tiling_->current_visible_rect(), tiling_->current_visible_rect()); | |
254 if (!iterator_) | |
255 return; | |
256 if (!GetFirstTileAndCheckIfValid(&iterator_)) { | |
257 ++(*this); | |
258 return; | |
259 } | |
260 // TODO(e_hakkinen): This is not needed as GetFirstTileAndCheckIfValid | |
261 // does the same checking. | |
262 if (current_tile_.tile()->content_rect().Intersects(pending_visible_rect_)) | |
263 ++(*this); | |
264 } | |
265 | |
266 TilingSetRasterQueueAll::SkewportTilingIterator& | |
267 TilingSetRasterQueueAll::SkewportTilingIterator:: | |
268 operator++() { | |
269 AdvanceToNextTile(&iterator_); | |
270 // TODO(e_hakkinen): This is not needed as GetFirstTileAndCheckIfValid called | |
271 // by AdvanceToNextTile does the same checking. | |
272 while (!done()) { | |
273 if (!current_tile_.tile()->content_rect().Intersects(pending_visible_rect_)) | |
274 break; | |
275 AdvanceToNextTile(&iterator_); | |
276 } | |
277 return *this; | |
278 } | |
279 | |
280 // SoonBorderTilingIterator. | |
281 TilingSetRasterQueueAll::SoonBorderTilingIterator::SoonBorderTilingIterator( | |
282 PictureLayerTiling* tiling, | |
283 TilingData* tiling_data) | |
284 : OnePriorityRectIterator(tiling, | |
285 tiling_data, | |
286 PictureLayerTiling::SOON_BORDER_RECT), | |
287 pending_visible_rect_(tiling->pending_visible_rect()) { | |
288 if (!tiling_->has_soon_border_rect_tiles()) | |
289 return; | |
290 iterator_ = TilingData::SpiralDifferenceIterator( | |
291 tiling_data_, tiling_->current_soon_border_rect(), | |
292 tiling_->current_skewport_rect(), tiling_->current_visible_rect()); | |
293 if (!iterator_) | |
294 return; | |
295 if (!GetFirstTileAndCheckIfValid(&iterator_)) { | |
296 ++(*this); | |
297 return; | |
298 } | |
299 // TODO(e_hakkinen): This is not needed as GetFirstTileAndCheckIfValid | |
300 // does the same checking. | |
301 if (current_tile_.tile()->content_rect().Intersects(pending_visible_rect_)) | |
302 ++(*this); | |
303 } | |
304 | |
305 TilingSetRasterQueueAll::SoonBorderTilingIterator& | |
306 TilingSetRasterQueueAll::SoonBorderTilingIterator:: | |
307 operator++() { | |
308 AdvanceToNextTile(&iterator_); | |
309 // TODO(e_hakkinen): This is not needed as GetFirstTileAndCheckIfValid called | |
310 // by AdvanceToNextTile does the same checking. | |
311 while (!done()) { | |
312 if (!current_tile_.tile()->content_rect().Intersects(pending_visible_rect_)) | |
313 break; | |
314 AdvanceToNextTile(&iterator_); | |
315 } | |
316 return *this; | |
317 } | |
318 | |
319 // EventuallyTilingIterator. | |
320 TilingSetRasterQueueAll::EventuallyTilingIterator::EventuallyTilingIterator( | |
321 PictureLayerTiling* tiling, | |
322 TilingData* tiling_data) | |
323 : OnePriorityRectIterator(tiling, | |
324 tiling_data, | |
325 PictureLayerTiling::EVENTUALLY_RECT), | |
326 pending_visible_rect_(tiling->pending_visible_rect()) { | |
327 if (!tiling_->has_eventually_rect_tiles()) | |
328 return; | |
329 iterator_ = TilingData::SpiralDifferenceIterator( | |
330 tiling_data_, tiling_->current_eventually_rect(), | |
331 tiling_->current_skewport_rect(), tiling_->current_soon_border_rect()); | |
332 if (!iterator_) | |
333 return; | |
334 if (!GetFirstTileAndCheckIfValid(&iterator_)) { | |
335 ++(*this); | |
336 return; | |
337 } | |
338 // TODO(e_hakkinen): This is not needed as GetFirstTileAndCheckIfValid | |
339 // does the same checking. | |
340 if (current_tile_.tile()->content_rect().Intersects(pending_visible_rect_)) | |
341 ++(*this); | |
342 } | |
343 | |
344 TilingSetRasterQueueAll::EventuallyTilingIterator& | |
345 TilingSetRasterQueueAll::EventuallyTilingIterator:: | |
346 operator++() { | |
347 AdvanceToNextTile(&iterator_); | |
348 // TODO(e_hakkinen): This is not needed as GetFirstTileAndCheckIfValid called | |
349 // by AdvanceToNextTile does the same checking. | |
350 while (!done()) { | |
351 if (!current_tile_.tile()->content_rect().Intersects(pending_visible_rect_)) | |
352 break; | |
353 AdvanceToNextTile(&iterator_); | |
354 } | |
355 return *this; | |
356 } | |
357 | |
358 // TilingIterator | |
359 TilingSetRasterQueueAll::TilingIterator::TilingIterator() : tiling_(nullptr) { | |
360 } | |
361 | |
362 TilingSetRasterQueueAll::TilingIterator::TilingIterator( | |
363 PictureLayerTiling* tiling, | |
364 TilingData* tiling_data) | |
365 : tiling_(tiling), tiling_data_(tiling_data), phase_(Phase::VISIBLE_RECT) { | |
366 visible_iterator_ = VisibleTilingIterator(tiling_, tiling_data_); | |
367 if (visible_iterator_.done()) { | |
368 AdvancePhase(); | |
369 return; | |
370 } | |
371 current_tile_ = *visible_iterator_; | |
372 } | |
373 | |
374 TilingSetRasterQueueAll::TilingIterator::~TilingIterator() { | |
375 } | |
376 | |
377 void TilingSetRasterQueueAll::TilingIterator::AdvancePhase() { | |
378 DCHECK_LT(phase_, Phase::EVENTUALLY_RECT); | |
379 | |
380 current_tile_ = PrioritizedTile(); | |
381 while (!current_tile_.tile() && phase_ < Phase::EVENTUALLY_RECT) { | |
382 phase_ = static_cast<Phase>(phase_ + 1); | |
383 switch (phase_) { | |
384 case Phase::VISIBLE_RECT: | |
385 NOTREACHED(); | |
386 return; | |
387 case Phase::PENDING_VISIBLE_RECT: | |
388 pending_visible_iterator_ = | |
389 PendingVisibleTilingIterator(tiling_, tiling_data_); | |
390 if (!pending_visible_iterator_.done()) | |
391 current_tile_ = *pending_visible_iterator_; | |
392 break; | |
393 case Phase::SKEWPORT_RECT: | |
394 skewport_iterator_ = SkewportTilingIterator(tiling_, tiling_data_); | |
395 if (!skewport_iterator_.done()) | |
396 current_tile_ = *skewport_iterator_; | |
397 break; | |
398 case Phase::SOON_BORDER_RECT: | |
399 soon_border_iterator_ = SoonBorderTilingIterator(tiling_, tiling_data_); | |
400 if (!soon_border_iterator_.done()) | |
401 current_tile_ = *soon_border_iterator_; | |
402 break; | |
403 case Phase::EVENTUALLY_RECT: | |
404 eventually_iterator_ = EventuallyTilingIterator(tiling_, tiling_data_); | |
405 if (!eventually_iterator_.done()) | |
406 current_tile_ = *eventually_iterator_; | |
407 break; | |
408 } | |
409 } | |
410 } | |
411 | |
412 TilingSetRasterQueueAll::TilingIterator& | |
413 TilingSetRasterQueueAll::TilingIterator:: | |
414 operator++() { | |
415 switch (phase_) { | |
416 case Phase::VISIBLE_RECT: | |
417 ++visible_iterator_; | |
418 if (visible_iterator_.done()) { | |
419 AdvancePhase(); | |
420 return *this; | |
421 } | |
422 current_tile_ = *visible_iterator_; | |
423 break; | |
424 case Phase::PENDING_VISIBLE_RECT: | |
425 ++pending_visible_iterator_; | |
426 if (pending_visible_iterator_.done()) { | |
427 AdvancePhase(); | |
428 return *this; | |
429 } | |
430 current_tile_ = *pending_visible_iterator_; | |
431 break; | |
432 case Phase::SKEWPORT_RECT: | |
433 ++skewport_iterator_; | |
434 if (skewport_iterator_.done()) { | |
435 AdvancePhase(); | |
436 return *this; | |
437 } | |
438 current_tile_ = *skewport_iterator_; | |
439 break; | |
440 case Phase::SOON_BORDER_RECT: | |
441 ++soon_border_iterator_; | |
442 if (soon_border_iterator_.done()) { | |
443 AdvancePhase(); | |
444 return *this; | |
445 } | |
446 current_tile_ = *soon_border_iterator_; | |
447 break; | |
448 case Phase::EVENTUALLY_RECT: | |
449 ++eventually_iterator_; | |
450 if (eventually_iterator_.done()) { | |
451 current_tile_ = PrioritizedTile(); | |
452 return *this; | |
453 } | |
454 current_tile_ = *eventually_iterator_; | |
455 break; | |
456 } | |
457 return *this; | |
458 } | |
459 | |
460 } // namespace cc | |
OLD | NEW |