Roll src/third_party/WebKit d9c6159:8139f33 (svn 201974:201975)
[chromium-blink-merge.git] / cc / tiles / tiling_set_raster_queue_all.cc
blob1cac85d2ad001d37c09b39b6981eba9cfc038609
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.
5 #include "cc/tiles/tiling_set_raster_queue_all.h"
7 #include <utility>
9 #include "cc/tiles/picture_layer_tiling_set.h"
10 #include "cc/tiles/tile.h"
11 #include "cc/tiles/tile_priority.h"
13 namespace cc {
15 TilingSetRasterQueueAll::IterationStage::IterationStage(
16 IteratorType type,
17 TilePriority::PriorityBin bin)
18 : iterator_type(type), tile_type(bin) {
21 TilingSetRasterQueueAll::TilingSetRasterQueueAll(
22 PictureLayerTilingSet* tiling_set,
23 bool prioritize_low_res)
24 : tiling_set_(tiling_set), current_stage_(0) {
25 DCHECK(tiling_set_);
27 // Early out if the tiling set has no tilings.
28 if (!tiling_set_->num_tilings())
29 return;
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;
55 bool use_low_res_tiling = low_res_tiling && low_res_tiling->has_tiles() &&
56 !low_res_tiling->all_tiles_done();
57 bool use_high_res_tiling = high_res_tiling && high_res_tiling->has_tiles() &&
58 !high_res_tiling->all_tiles_done();
59 bool use_active_non_ideal_pending_high_res_tiling =
60 active_non_ideal_pending_high_res_tiling &&
61 active_non_ideal_pending_high_res_tiling->has_tiles() &&
62 !active_non_ideal_pending_high_res_tiling->all_tiles_done();
64 // Make the tiling iterators.
65 if (use_low_res_tiling)
66 MakeTilingIterator(LOW_RES, low_res_tiling);
67 if (use_high_res_tiling)
68 MakeTilingIterator(HIGH_RES, high_res_tiling);
69 if (use_active_non_ideal_pending_high_res_tiling) {
70 MakeTilingIterator(ACTIVE_NON_IDEAL_PENDING_HIGH_RES,
71 active_non_ideal_pending_high_res_tiling);
74 // Set up the stages.
75 if (use_low_res_tiling && prioritize_low_res)
76 stages_->push_back(IterationStage(LOW_RES, TilePriority::NOW));
78 if (use_high_res_tiling)
79 stages_->push_back(IterationStage(HIGH_RES, TilePriority::NOW));
81 if (low_res_tiling && !prioritize_low_res)
82 stages_->push_back(IterationStage(LOW_RES, TilePriority::NOW));
84 if (use_active_non_ideal_pending_high_res_tiling) {
85 stages_->push_back(
86 IterationStage(ACTIVE_NON_IDEAL_PENDING_HIGH_RES, TilePriority::NOW));
87 stages_->push_back(
88 IterationStage(ACTIVE_NON_IDEAL_PENDING_HIGH_RES, TilePriority::SOON));
91 if (use_high_res_tiling) {
92 stages_->push_back(IterationStage(HIGH_RES, TilePriority::SOON));
93 stages_->push_back(IterationStage(HIGH_RES, TilePriority::EVENTUALLY));
96 if (stages_->empty())
97 return;
99 IteratorType index = stages_[current_stage_].iterator_type;
100 TilePriority::PriorityBin tile_type = stages_[current_stage_].tile_type;
101 if (iterators_[index].done() || iterators_[index].type() != tile_type)
102 AdvanceToNextStage();
105 TilingSetRasterQueueAll::~TilingSetRasterQueueAll() {
108 void TilingSetRasterQueueAll::MakeTilingIterator(IteratorType type,
109 PictureLayerTiling* tiling) {
110 iterators_[type] = TilingIterator(tiling, &tiling->tiling_data_);
111 if (iterators_[type].done()) {
112 tiling->set_all_tiles_done(true);
113 // If we've marked the tiling as done, make sure we're actually done.
114 tiling->VerifyNoTileNeedsRaster();
118 bool TilingSetRasterQueueAll::IsEmpty() const {
119 return current_stage_ >= stages_->size();
122 void TilingSetRasterQueueAll::Pop() {
123 IteratorType index = stages_[current_stage_].iterator_type;
124 TilePriority::PriorityBin tile_type = stages_[current_stage_].tile_type;
126 // First advance the iterator.
127 DCHECK(!iterators_[index].done());
128 DCHECK(iterators_[index].type() == tile_type);
129 ++iterators_[index];
131 if (iterators_[index].done() || iterators_[index].type() != tile_type)
132 AdvanceToNextStage();
135 const PrioritizedTile& TilingSetRasterQueueAll::Top() const {
136 DCHECK(!IsEmpty());
138 IteratorType index = stages_[current_stage_].iterator_type;
139 DCHECK(!iterators_[index].done());
140 DCHECK(iterators_[index].type() == stages_[current_stage_].tile_type);
142 return *iterators_[index];
145 void TilingSetRasterQueueAll::AdvanceToNextStage() {
146 DCHECK_LT(current_stage_, stages_->size());
147 ++current_stage_;
148 while (current_stage_ < stages_->size()) {
149 IteratorType index = stages_[current_stage_].iterator_type;
150 TilePriority::PriorityBin tile_type = stages_[current_stage_].tile_type;
152 if (!iterators_[index].done() && iterators_[index].type() == tile_type)
153 break;
154 ++current_stage_;
158 // OnePriorityRectIterator
159 TilingSetRasterQueueAll::OnePriorityRectIterator::OnePriorityRectIterator()
160 : tiling_(nullptr), tiling_data_(nullptr) {
163 TilingSetRasterQueueAll::OnePriorityRectIterator::OnePriorityRectIterator(
164 PictureLayerTiling* tiling,
165 TilingData* tiling_data,
166 PictureLayerTiling::PriorityRectType priority_rect_type)
167 : tiling_(tiling),
168 tiling_data_(tiling_data),
169 priority_rect_type_(priority_rect_type),
170 pending_visible_rect_(tiling->pending_visible_rect()) {
173 template <typename TilingIteratorType>
174 void TilingSetRasterQueueAll::OnePriorityRectIterator::AdvanceToNextTile(
175 TilingIteratorType* iterator) {
176 for (;;) {
177 ++(*iterator);
178 if (!(*iterator)) {
179 current_tile_ = PrioritizedTile();
180 break;
182 Tile* tile = tiling_->TileAt(iterator->index_x(), iterator->index_y());
183 if (IsTileValid(tile)) {
184 tiling_->UpdateRequiredStatesOnTile(tile);
185 current_tile_ = tiling_->MakePrioritizedTile(tile, priority_rect_type_);
186 break;
191 template <typename TilingIteratorType>
192 bool TilingSetRasterQueueAll::OnePriorityRectIterator::
193 GetFirstTileAndCheckIfValid(TilingIteratorType* iterator) {
194 Tile* tile = tiling_->TileAt(iterator->index_x(), iterator->index_y());
195 if (!IsTileValid(tile)) {
196 current_tile_ = PrioritizedTile();
197 return false;
199 tiling_->UpdateRequiredStatesOnTile(tile);
200 current_tile_ = tiling_->MakePrioritizedTile(tile, priority_rect_type_);
201 return true;
204 bool TilingSetRasterQueueAll::OnePriorityRectIterator::IsTileValid(
205 const Tile* tile) const {
206 if (!tile || !TileNeedsRaster(tile))
207 return false;
208 // After the pending visible rect has been processed, we must return false
209 // for pending visible rect tiles as tiling iterators do not ignore those
210 // tiles.
211 if (priority_rect_type_ > PictureLayerTiling::PENDING_VISIBLE_RECT) {
212 gfx::Rect tile_rect = tiling_->tiling_data()->TileBounds(
213 tile->tiling_i_index(), tile->tiling_j_index());
214 if (pending_visible_rect_.Intersects(tile_rect))
215 return false;
217 return true;
220 // VisibleTilingIterator.
221 TilingSetRasterQueueAll::VisibleTilingIterator::VisibleTilingIterator(
222 PictureLayerTiling* tiling,
223 TilingData* tiling_data)
224 : OnePriorityRectIterator(tiling,
225 tiling_data,
226 PictureLayerTiling::VISIBLE_RECT) {
227 if (!tiling_->has_visible_rect_tiles())
228 return;
229 iterator_ =
230 TilingData::Iterator(tiling_data_, tiling_->current_visible_rect(),
231 false /* include_borders */);
232 if (!iterator_)
233 return;
234 if (!GetFirstTileAndCheckIfValid(&iterator_))
235 ++(*this);
238 TilingSetRasterQueueAll::VisibleTilingIterator&
239 TilingSetRasterQueueAll::VisibleTilingIterator::
240 operator++() {
241 AdvanceToNextTile(&iterator_);
242 return *this;
245 // PendingVisibleTilingIterator.
246 TilingSetRasterQueueAll::PendingVisibleTilingIterator::
247 PendingVisibleTilingIterator(PictureLayerTiling* tiling,
248 TilingData* tiling_data)
249 : OnePriorityRectIterator(tiling,
250 tiling_data,
251 PictureLayerTiling::PENDING_VISIBLE_RECT) {
252 iterator_ = TilingData::DifferenceIterator(
253 tiling_data_, pending_visible_rect_, tiling_->current_visible_rect());
254 if (!iterator_)
255 return;
256 if (!GetFirstTileAndCheckIfValid(&iterator_))
257 ++(*this);
260 TilingSetRasterQueueAll::PendingVisibleTilingIterator&
261 TilingSetRasterQueueAll::PendingVisibleTilingIterator::
262 operator++() {
263 AdvanceToNextTile(&iterator_);
264 return *this;
267 // SkewportTilingIterator.
268 TilingSetRasterQueueAll::SkewportTilingIterator::SkewportTilingIterator(
269 PictureLayerTiling* tiling,
270 TilingData* tiling_data)
271 : OnePriorityRectIterator(tiling,
272 tiling_data,
273 PictureLayerTiling::SKEWPORT_RECT) {
274 if (!tiling_->has_skewport_rect_tiles())
275 return;
276 iterator_ = TilingData::SpiralDifferenceIterator(
277 tiling_data_, tiling_->current_skewport_rect(),
278 tiling_->current_visible_rect(), tiling_->current_visible_rect());
279 if (!iterator_)
280 return;
281 if (!GetFirstTileAndCheckIfValid(&iterator_)) {
282 ++(*this);
283 return;
287 TilingSetRasterQueueAll::SkewportTilingIterator&
288 TilingSetRasterQueueAll::SkewportTilingIterator::
289 operator++() {
290 AdvanceToNextTile(&iterator_);
291 return *this;
294 // SoonBorderTilingIterator.
295 TilingSetRasterQueueAll::SoonBorderTilingIterator::SoonBorderTilingIterator(
296 PictureLayerTiling* tiling,
297 TilingData* tiling_data)
298 : OnePriorityRectIterator(tiling,
299 tiling_data,
300 PictureLayerTiling::SOON_BORDER_RECT) {
301 if (!tiling_->has_soon_border_rect_tiles())
302 return;
303 iterator_ = TilingData::SpiralDifferenceIterator(
304 tiling_data_, tiling_->current_soon_border_rect(),
305 tiling_->current_skewport_rect(), tiling_->current_visible_rect());
306 if (!iterator_)
307 return;
308 if (!GetFirstTileAndCheckIfValid(&iterator_)) {
309 ++(*this);
310 return;
314 TilingSetRasterQueueAll::SoonBorderTilingIterator&
315 TilingSetRasterQueueAll::SoonBorderTilingIterator::
316 operator++() {
317 AdvanceToNextTile(&iterator_);
318 return *this;
321 // EventuallyTilingIterator.
322 TilingSetRasterQueueAll::EventuallyTilingIterator::EventuallyTilingIterator(
323 PictureLayerTiling* tiling,
324 TilingData* tiling_data)
325 : OnePriorityRectIterator(tiling,
326 tiling_data,
327 PictureLayerTiling::EVENTUALLY_RECT) {
328 if (!tiling_->has_eventually_rect_tiles())
329 return;
330 iterator_ = TilingData::SpiralDifferenceIterator(
331 tiling_data_, tiling_->current_eventually_rect(),
332 tiling_->current_skewport_rect(), tiling_->current_soon_border_rect());
333 if (!iterator_)
334 return;
335 if (!GetFirstTileAndCheckIfValid(&iterator_)) {
336 ++(*this);
337 return;
341 TilingSetRasterQueueAll::EventuallyTilingIterator&
342 TilingSetRasterQueueAll::EventuallyTilingIterator::
343 operator++() {
344 AdvanceToNextTile(&iterator_);
345 return *this;
348 // TilingIterator
349 TilingSetRasterQueueAll::TilingIterator::TilingIterator() : tiling_(nullptr) {
352 TilingSetRasterQueueAll::TilingIterator::TilingIterator(
353 PictureLayerTiling* tiling,
354 TilingData* tiling_data)
355 : tiling_(tiling), tiling_data_(tiling_data), phase_(Phase::VISIBLE_RECT) {
356 visible_iterator_ = VisibleTilingIterator(tiling_, tiling_data_);
357 if (visible_iterator_.done()) {
358 AdvancePhase();
359 return;
361 current_tile_ = *visible_iterator_;
364 TilingSetRasterQueueAll::TilingIterator::~TilingIterator() {
367 void TilingSetRasterQueueAll::TilingIterator::AdvancePhase() {
368 DCHECK_LT(phase_, Phase::EVENTUALLY_RECT);
370 current_tile_ = PrioritizedTile();
371 while (!current_tile_.tile() && phase_ < Phase::EVENTUALLY_RECT) {
372 phase_ = static_cast<Phase>(phase_ + 1);
373 switch (phase_) {
374 case Phase::VISIBLE_RECT:
375 NOTREACHED();
376 return;
377 case Phase::PENDING_VISIBLE_RECT:
378 pending_visible_iterator_ =
379 PendingVisibleTilingIterator(tiling_, tiling_data_);
380 if (!pending_visible_iterator_.done())
381 current_tile_ = *pending_visible_iterator_;
382 break;
383 case Phase::SKEWPORT_RECT:
384 skewport_iterator_ = SkewportTilingIterator(tiling_, tiling_data_);
385 if (!skewport_iterator_.done())
386 current_tile_ = *skewport_iterator_;
387 break;
388 case Phase::SOON_BORDER_RECT:
389 soon_border_iterator_ = SoonBorderTilingIterator(tiling_, tiling_data_);
390 if (!soon_border_iterator_.done())
391 current_tile_ = *soon_border_iterator_;
392 break;
393 case Phase::EVENTUALLY_RECT:
394 eventually_iterator_ = EventuallyTilingIterator(tiling_, tiling_data_);
395 if (!eventually_iterator_.done())
396 current_tile_ = *eventually_iterator_;
397 break;
402 TilingSetRasterQueueAll::TilingIterator&
403 TilingSetRasterQueueAll::TilingIterator::
404 operator++() {
405 switch (phase_) {
406 case Phase::VISIBLE_RECT:
407 ++visible_iterator_;
408 if (visible_iterator_.done()) {
409 AdvancePhase();
410 return *this;
412 current_tile_ = *visible_iterator_;
413 break;
414 case Phase::PENDING_VISIBLE_RECT:
415 ++pending_visible_iterator_;
416 if (pending_visible_iterator_.done()) {
417 AdvancePhase();
418 return *this;
420 current_tile_ = *pending_visible_iterator_;
421 break;
422 case Phase::SKEWPORT_RECT:
423 ++skewport_iterator_;
424 if (skewport_iterator_.done()) {
425 AdvancePhase();
426 return *this;
428 current_tile_ = *skewport_iterator_;
429 break;
430 case Phase::SOON_BORDER_RECT:
431 ++soon_border_iterator_;
432 if (soon_border_iterator_.done()) {
433 AdvancePhase();
434 return *this;
436 current_tile_ = *soon_border_iterator_;
437 break;
438 case Phase::EVENTUALLY_RECT:
439 ++eventually_iterator_;
440 if (eventually_iterator_.done()) {
441 current_tile_ = PrioritizedTile();
442 return *this;
444 current_tile_ = *eventually_iterator_;
445 break;
447 return *this;
450 } // namespace cc