cc: Adding DidFinishImplFrame to LTHI.
[chromium-blink-merge.git] / cc / resources / tiling_set_raster_queue_all.cc
blob6f212152a98cfcfb3caebe1951cc4ff1a77f1158
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/resources/tiling_set_raster_queue_all.h"
7 #include <utility>
9 #include "cc/resources/picture_layer_tiling_set.h"
10 #include "cc/resources/tile.h"
11 #include "cc/resources/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 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));
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));
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));
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_);
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));
87 if (use_high_res_tiling) {
88 stages_->push_back(IterationStage(HIGH_RES, TilePriority::SOON));
89 stages_->push_back(IterationStage(HIGH_RES, TilePriority::EVENTUALLY));
92 if (stages_->empty())
93 return;
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();
101 TilingSetRasterQueueAll::~TilingSetRasterQueueAll() {
104 bool TilingSetRasterQueueAll::IsEmpty() const {
105 return current_stage_ >= stages_->size();
108 void TilingSetRasterQueueAll::Pop() {
109 IteratorType index = stages_[current_stage_].iterator_type;
110 TilePriority::PriorityBin tile_type = stages_[current_stage_].tile_type;
112 // First advance the iterator.
113 DCHECK(!iterators_[index].done());
114 DCHECK(iterators_[index].type() == tile_type);
115 ++iterators_[index];
117 if (iterators_[index].done() || iterators_[index].type() != tile_type)
118 AdvanceToNextStage();
121 Tile* TilingSetRasterQueueAll::Top() {
122 DCHECK(!IsEmpty());
124 IteratorType index = stages_[current_stage_].iterator_type;
125 DCHECK(!iterators_[index].done());
126 DCHECK(iterators_[index].type() == stages_[current_stage_].tile_type);
128 return *iterators_[index];
131 const Tile* TilingSetRasterQueueAll::Top() const {
132 DCHECK(!IsEmpty());
134 IteratorType index = stages_[current_stage_].iterator_type;
135 DCHECK(!iterators_[index].done());
136 DCHECK(iterators_[index].type() == stages_[current_stage_].tile_type);
138 return *iterators_[index];
141 void TilingSetRasterQueueAll::AdvanceToNextStage() {
142 DCHECK_LT(current_stage_, stages_->size());
143 ++current_stage_;
144 while (current_stage_ < stages_->size()) {
145 IteratorType index = stages_[current_stage_].iterator_type;
146 TilePriority::PriorityBin tile_type = stages_[current_stage_].tile_type;
148 if (!iterators_[index].done() && iterators_[index].type() == tile_type)
149 break;
150 ++current_stage_;
154 // OnePriorityRectIterator
155 TilingSetRasterQueueAll::OnePriorityRectIterator::OnePriorityRectIterator()
156 : tile_(nullptr), tiling_(nullptr), tiling_data_(nullptr) {
159 TilingSetRasterQueueAll::OnePriorityRectIterator::OnePriorityRectIterator(
160 PictureLayerTiling* tiling,
161 TilingData* tiling_data)
162 : tile_(nullptr), tiling_(tiling), tiling_data_(tiling_data) {
165 template <typename TilingIteratorType>
166 void TilingSetRasterQueueAll::OnePriorityRectIterator::AdvanceToNextTile(
167 TilingIteratorType* iterator) {
168 tile_ = nullptr;
169 while (!tile_ || !TileNeedsRaster(tile_)) {
170 ++(*iterator);
171 if (!(*iterator)) {
172 tile_ = nullptr;
173 return;
175 tile_ = tiling_->TileAt(iterator->index_x(), iterator->index_y());
177 tiling_->UpdateTilePriority(tile_);
180 template <typename TilingIteratorType>
181 bool TilingSetRasterQueueAll::OnePriorityRectIterator::
182 GetFirstTileAndCheckIfValid(TilingIteratorType* iterator) {
183 tile_ = tiling_->TileAt(iterator->index_x(), iterator->index_y());
184 if (!tile_ || !TileNeedsRaster(tile_)) {
185 tile_ = nullptr;
186 return false;
188 tiling_->UpdateTilePriority(tile_);
189 return true;
192 // VisibleTilingIterator.
193 TilingSetRasterQueueAll::VisibleTilingIterator::VisibleTilingIterator(
194 PictureLayerTiling* tiling,
195 TilingData* tiling_data)
196 : OnePriorityRectIterator(tiling, tiling_data) {
197 if (!tiling_->has_visible_rect_tiles())
198 return;
199 iterator_ =
200 TilingData::Iterator(tiling_data_, tiling_->current_visible_rect(),
201 false /* include_borders */);
202 if (!iterator_)
203 return;
204 if (!GetFirstTileAndCheckIfValid(&iterator_))
205 ++(*this);
208 TilingSetRasterQueueAll::VisibleTilingIterator&
209 TilingSetRasterQueueAll::VisibleTilingIterator::
210 operator++() {
211 AdvanceToNextTile(&iterator_);
212 return *this;
215 // PendingVisibleTilingIterator.
216 TilingSetRasterQueueAll::PendingVisibleTilingIterator::
217 PendingVisibleTilingIterator(PictureLayerTiling* tiling,
218 TilingData* tiling_data)
219 : OnePriorityRectIterator(tiling, tiling_data) {
220 iterator_ = TilingData::DifferenceIterator(tiling_data_,
221 tiling_->pending_visible_rect(),
222 tiling_->current_visible_rect());
223 if (!iterator_)
224 return;
225 if (!GetFirstTileAndCheckIfValid(&iterator_))
226 ++(*this);
229 TilingSetRasterQueueAll::PendingVisibleTilingIterator&
230 TilingSetRasterQueueAll::PendingVisibleTilingIterator::
231 operator++() {
232 AdvanceToNextTile(&iterator_);
233 return *this;
236 // SkewportTilingIterator.
237 TilingSetRasterQueueAll::SkewportTilingIterator::SkewportTilingIterator(
238 PictureLayerTiling* tiling,
239 TilingData* tiling_data)
240 : OnePriorityRectIterator(tiling, tiling_data),
241 pending_visible_rect_(tiling->pending_visible_rect()) {
242 if (!tiling_->has_skewport_rect_tiles())
243 return;
244 iterator_ = TilingData::SpiralDifferenceIterator(
245 tiling_data_, tiling_->current_skewport_rect(),
246 tiling_->current_visible_rect(), tiling_->current_visible_rect());
247 if (!iterator_)
248 return;
249 if (!GetFirstTileAndCheckIfValid(&iterator_)) {
250 ++(*this);
251 return;
253 if (tile_->content_rect().Intersects(pending_visible_rect_))
254 ++(*this);
257 TilingSetRasterQueueAll::SkewportTilingIterator&
258 TilingSetRasterQueueAll::SkewportTilingIterator::
259 operator++() {
260 AdvanceToNextTile(&iterator_);
261 while (!done()) {
262 if (!tile_->content_rect().Intersects(pending_visible_rect_))
263 break;
264 AdvanceToNextTile(&iterator_);
266 return *this;
269 // SoonBorderTilingIterator.
270 TilingSetRasterQueueAll::SoonBorderTilingIterator::SoonBorderTilingIterator(
271 PictureLayerTiling* tiling,
272 TilingData* tiling_data)
273 : OnePriorityRectIterator(tiling, tiling_data),
274 pending_visible_rect_(tiling->pending_visible_rect()) {
275 if (!tiling_->has_soon_border_rect_tiles())
276 return;
277 iterator_ = TilingData::SpiralDifferenceIterator(
278 tiling_data_, tiling_->current_soon_border_rect(),
279 tiling_->current_skewport_rect(), tiling_->current_visible_rect());
280 if (!iterator_)
281 return;
282 if (!GetFirstTileAndCheckIfValid(&iterator_)) {
283 ++(*this);
284 return;
286 if (tile_->content_rect().Intersects(pending_visible_rect_))
287 ++(*this);
290 TilingSetRasterQueueAll::SoonBorderTilingIterator&
291 TilingSetRasterQueueAll::SoonBorderTilingIterator::
292 operator++() {
293 AdvanceToNextTile(&iterator_);
294 while (!done()) {
295 if (!tile_->content_rect().Intersects(pending_visible_rect_))
296 break;
297 AdvanceToNextTile(&iterator_);
299 return *this;
302 // EventuallyTilingIterator.
303 TilingSetRasterQueueAll::EventuallyTilingIterator::EventuallyTilingIterator(
304 PictureLayerTiling* tiling,
305 TilingData* tiling_data)
306 : OnePriorityRectIterator(tiling, tiling_data),
307 pending_visible_rect_(tiling->pending_visible_rect()) {
308 if (!tiling_->has_eventually_rect_tiles())
309 return;
310 iterator_ = TilingData::SpiralDifferenceIterator(
311 tiling_data_, tiling_->current_eventually_rect(),
312 tiling_->current_skewport_rect(), tiling_->current_soon_border_rect());
313 if (!iterator_)
314 return;
315 if (!GetFirstTileAndCheckIfValid(&iterator_)) {
316 ++(*this);
317 return;
319 if (tile_->content_rect().Intersects(pending_visible_rect_))
320 ++(*this);
323 TilingSetRasterQueueAll::EventuallyTilingIterator&
324 TilingSetRasterQueueAll::EventuallyTilingIterator::
325 operator++() {
326 AdvanceToNextTile(&iterator_);
327 while (!done()) {
328 if (!tile_->content_rect().Intersects(pending_visible_rect_))
329 break;
330 AdvanceToNextTile(&iterator_);
332 return *this;
335 // TilingIterator
336 TilingSetRasterQueueAll::TilingIterator::TilingIterator()
337 : tiling_(NULL), current_tile_(NULL) {
340 TilingSetRasterQueueAll::TilingIterator::TilingIterator(
341 PictureLayerTiling* tiling,
342 TilingData* tiling_data)
343 : tiling_(tiling),
344 tiling_data_(tiling_data),
345 phase_(VISIBLE_RECT),
346 current_tile_(NULL) {
347 visible_iterator_ = VisibleTilingIterator(tiling_, tiling_data_);
348 if (visible_iterator_.done()) {
349 AdvancePhase();
350 return;
352 current_tile_ = *visible_iterator_;
355 TilingSetRasterQueueAll::TilingIterator::~TilingIterator() {
358 void TilingSetRasterQueueAll::TilingIterator::AdvancePhase() {
359 DCHECK_LT(phase_, EVENTUALLY_RECT);
361 current_tile_ = nullptr;
362 while (!current_tile_ && phase_ < EVENTUALLY_RECT) {
363 phase_ = static_cast<Phase>(phase_ + 1);
364 switch (phase_) {
365 case VISIBLE_RECT:
366 NOTREACHED();
367 return;
368 case PENDING_VISIBLE_RECT:
369 pending_visible_iterator_ =
370 PendingVisibleTilingIterator(tiling_, tiling_data_);
371 if (!pending_visible_iterator_.done())
372 current_tile_ = *pending_visible_iterator_;
373 break;
374 case SKEWPORT_RECT:
375 skewport_iterator_ = SkewportTilingIterator(tiling_, tiling_data_);
376 if (!skewport_iterator_.done())
377 current_tile_ = *skewport_iterator_;
378 break;
379 case SOON_BORDER_RECT:
380 soon_border_iterator_ = SoonBorderTilingIterator(tiling_, tiling_data_);
381 if (!soon_border_iterator_.done())
382 current_tile_ = *soon_border_iterator_;
383 break;
384 case EVENTUALLY_RECT:
385 eventually_iterator_ = EventuallyTilingIterator(tiling_, tiling_data_);
386 if (!eventually_iterator_.done())
387 current_tile_ = *eventually_iterator_;
388 break;
393 TilingSetRasterQueueAll::TilingIterator&
394 TilingSetRasterQueueAll::TilingIterator::
395 operator++() {
396 switch (phase_) {
397 case VISIBLE_RECT:
398 ++visible_iterator_;
399 if (visible_iterator_.done()) {
400 AdvancePhase();
401 return *this;
403 current_tile_ = *visible_iterator_;
404 break;
405 case PENDING_VISIBLE_RECT:
406 ++pending_visible_iterator_;
407 if (pending_visible_iterator_.done()) {
408 AdvancePhase();
409 return *this;
411 current_tile_ = *pending_visible_iterator_;
412 break;
413 case SKEWPORT_RECT:
414 ++skewport_iterator_;
415 if (skewport_iterator_.done()) {
416 AdvancePhase();
417 return *this;
419 current_tile_ = *skewport_iterator_;
420 break;
421 case SOON_BORDER_RECT:
422 ++soon_border_iterator_;
423 if (soon_border_iterator_.done()) {
424 AdvancePhase();
425 return *this;
427 current_tile_ = *soon_border_iterator_;
428 break;
429 case EVENTUALLY_RECT:
430 ++eventually_iterator_;
431 if (eventually_iterator_.done()) {
432 current_tile_ = nullptr;
433 return *this;
435 current_tile_ = *eventually_iterator_;
436 break;
438 return *this;
441 } // namespace cc