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"
9 #include "cc/resources/picture_layer_tiling_set.h"
10 #include "cc/resources/tile.h"
11 #include "cc/resources/tile_priority.h"
15 TilingSetRasterQueueAll::IterationStage::IterationStage(
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) {
27 // Early out if the tiling set has no tilings.
28 if (!tiling_set_
->num_tilings())
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
) {
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
) {
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_
);
82 IterationStage(ACTIVE_NON_IDEAL_PENDING_HIGH_RES
, TilePriority::NOW
));
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
));
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
)
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
);
117 if (iterators_
[index
].done() || iterators_
[index
].type() != tile_type
)
118 AdvanceToNextStage();
121 Tile
* TilingSetRasterQueueAll::Top() {
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 {
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());
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
)
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
) {
169 while (!tile_
|| !TileNeedsRaster(tile_
)) {
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_
)) {
188 tiling_
->UpdateTilePriority(tile_
);
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())
200 TilingData::Iterator(tiling_data_
, tiling_
->current_visible_rect(),
201 false /* include_borders */);
204 if (!GetFirstTileAndCheckIfValid(&iterator_
))
208 TilingSetRasterQueueAll::VisibleTilingIterator
&
209 TilingSetRasterQueueAll::VisibleTilingIterator::
211 AdvanceToNextTile(&iterator_
);
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());
225 if (!GetFirstTileAndCheckIfValid(&iterator_
))
229 TilingSetRasterQueueAll::PendingVisibleTilingIterator
&
230 TilingSetRasterQueueAll::PendingVisibleTilingIterator::
232 AdvanceToNextTile(&iterator_
);
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())
244 iterator_
= TilingData::SpiralDifferenceIterator(
245 tiling_data_
, tiling_
->current_skewport_rect(),
246 tiling_
->current_visible_rect(), tiling_
->current_visible_rect());
249 if (!GetFirstTileAndCheckIfValid(&iterator_
)) {
253 if (tile_
->content_rect().Intersects(pending_visible_rect_
))
257 TilingSetRasterQueueAll::SkewportTilingIterator
&
258 TilingSetRasterQueueAll::SkewportTilingIterator::
260 AdvanceToNextTile(&iterator_
);
262 if (!tile_
->content_rect().Intersects(pending_visible_rect_
))
264 AdvanceToNextTile(&iterator_
);
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())
277 iterator_
= TilingData::SpiralDifferenceIterator(
278 tiling_data_
, tiling_
->current_soon_border_rect(),
279 tiling_
->current_skewport_rect(), tiling_
->current_visible_rect());
282 if (!GetFirstTileAndCheckIfValid(&iterator_
)) {
286 if (tile_
->content_rect().Intersects(pending_visible_rect_
))
290 TilingSetRasterQueueAll::SoonBorderTilingIterator
&
291 TilingSetRasterQueueAll::SoonBorderTilingIterator::
293 AdvanceToNextTile(&iterator_
);
295 if (!tile_
->content_rect().Intersects(pending_visible_rect_
))
297 AdvanceToNextTile(&iterator_
);
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())
310 iterator_
= TilingData::SpiralDifferenceIterator(
311 tiling_data_
, tiling_
->current_eventually_rect(),
312 tiling_
->current_skewport_rect(), tiling_
->current_soon_border_rect());
315 if (!GetFirstTileAndCheckIfValid(&iterator_
)) {
319 if (tile_
->content_rect().Intersects(pending_visible_rect_
))
323 TilingSetRasterQueueAll::EventuallyTilingIterator
&
324 TilingSetRasterQueueAll::EventuallyTilingIterator::
326 AdvanceToNextTile(&iterator_
);
328 if (!tile_
->content_rect().Intersects(pending_visible_rect_
))
330 AdvanceToNextTile(&iterator_
);
336 TilingSetRasterQueueAll::TilingIterator::TilingIterator()
337 : tiling_(NULL
), current_tile_(NULL
) {
340 TilingSetRasterQueueAll::TilingIterator::TilingIterator(
341 PictureLayerTiling
* tiling
,
342 TilingData
* tiling_data
)
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()) {
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);
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_
;
375 skewport_iterator_
= SkewportTilingIterator(tiling_
, tiling_data_
);
376 if (!skewport_iterator_
.done())
377 current_tile_
= *skewport_iterator_
;
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_
;
384 case EVENTUALLY_RECT
:
385 eventually_iterator_
= EventuallyTilingIterator(tiling_
, tiling_data_
);
386 if (!eventually_iterator_
.done())
387 current_tile_
= *eventually_iterator_
;
393 TilingSetRasterQueueAll::TilingIterator
&
394 TilingSetRasterQueueAll::TilingIterator::
399 if (visible_iterator_
.done()) {
403 current_tile_
= *visible_iterator_
;
405 case PENDING_VISIBLE_RECT
:
406 ++pending_visible_iterator_
;
407 if (pending_visible_iterator_
.done()) {
411 current_tile_
= *pending_visible_iterator_
;
414 ++skewport_iterator_
;
415 if (skewport_iterator_
.done()) {
419 current_tile_
= *skewport_iterator_
;
421 case SOON_BORDER_RECT
:
422 ++soon_border_iterator_
;
423 if (soon_border_iterator_
.done()) {
427 current_tile_
= *soon_border_iterator_
;
429 case EVENTUALLY_RECT
:
430 ++eventually_iterator_
;
431 if (eventually_iterator_
.done()) {
432 current_tile_
= nullptr;
435 current_tile_
= *eventually_iterator_
;