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"
9 #include "cc/tiles/picture_layer_tiling_set.h"
10 #include "cc/tiles/tile.h"
11 #include "cc/tiles/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 !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
);
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
) {
86 IterationStage(ACTIVE_NON_IDEAL_PENDING_HIGH_RES
, TilePriority::NOW
));
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
));
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
);
131 if (iterators_
[index
].done() || iterators_
[index
].type() != tile_type
)
132 AdvanceToNextStage();
135 const PrioritizedTile
& TilingSetRasterQueueAll::Top() const {
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());
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
)
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
)
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
) {
179 current_tile_
= PrioritizedTile();
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_
);
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();
199 tiling_
->UpdateRequiredStatesOnTile(tile
);
200 current_tile_
= tiling_
->MakePrioritizedTile(tile
, priority_rect_type_
);
204 bool TilingSetRasterQueueAll::OnePriorityRectIterator::IsTileValid(
205 const Tile
* tile
) const {
206 if (!tile
|| !TileNeedsRaster(tile
))
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
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
))
220 // VisibleTilingIterator.
221 TilingSetRasterQueueAll::VisibleTilingIterator::VisibleTilingIterator(
222 PictureLayerTiling
* tiling
,
223 TilingData
* tiling_data
)
224 : OnePriorityRectIterator(tiling
,
226 PictureLayerTiling::VISIBLE_RECT
) {
227 if (!tiling_
->has_visible_rect_tiles())
230 TilingData::Iterator(tiling_data_
, tiling_
->current_visible_rect(),
231 false /* include_borders */);
234 if (!GetFirstTileAndCheckIfValid(&iterator_
))
238 TilingSetRasterQueueAll::VisibleTilingIterator
&
239 TilingSetRasterQueueAll::VisibleTilingIterator::
241 AdvanceToNextTile(&iterator_
);
245 // PendingVisibleTilingIterator.
246 TilingSetRasterQueueAll::PendingVisibleTilingIterator::
247 PendingVisibleTilingIterator(PictureLayerTiling
* tiling
,
248 TilingData
* tiling_data
)
249 : OnePriorityRectIterator(tiling
,
251 PictureLayerTiling::PENDING_VISIBLE_RECT
) {
252 iterator_
= TilingData::DifferenceIterator(
253 tiling_data_
, pending_visible_rect_
, tiling_
->current_visible_rect());
256 if (!GetFirstTileAndCheckIfValid(&iterator_
))
260 TilingSetRasterQueueAll::PendingVisibleTilingIterator
&
261 TilingSetRasterQueueAll::PendingVisibleTilingIterator::
263 AdvanceToNextTile(&iterator_
);
267 // SkewportTilingIterator.
268 TilingSetRasterQueueAll::SkewportTilingIterator::SkewportTilingIterator(
269 PictureLayerTiling
* tiling
,
270 TilingData
* tiling_data
)
271 : OnePriorityRectIterator(tiling
,
273 PictureLayerTiling::SKEWPORT_RECT
) {
274 if (!tiling_
->has_skewport_rect_tiles())
276 iterator_
= TilingData::SpiralDifferenceIterator(
277 tiling_data_
, tiling_
->current_skewport_rect(),
278 tiling_
->current_visible_rect(), tiling_
->current_visible_rect());
281 if (!GetFirstTileAndCheckIfValid(&iterator_
)) {
287 TilingSetRasterQueueAll::SkewportTilingIterator
&
288 TilingSetRasterQueueAll::SkewportTilingIterator::
290 AdvanceToNextTile(&iterator_
);
294 // SoonBorderTilingIterator.
295 TilingSetRasterQueueAll::SoonBorderTilingIterator::SoonBorderTilingIterator(
296 PictureLayerTiling
* tiling
,
297 TilingData
* tiling_data
)
298 : OnePriorityRectIterator(tiling
,
300 PictureLayerTiling::SOON_BORDER_RECT
) {
301 if (!tiling_
->has_soon_border_rect_tiles())
303 iterator_
= TilingData::SpiralDifferenceIterator(
304 tiling_data_
, tiling_
->current_soon_border_rect(),
305 tiling_
->current_skewport_rect(), tiling_
->current_visible_rect());
308 if (!GetFirstTileAndCheckIfValid(&iterator_
)) {
314 TilingSetRasterQueueAll::SoonBorderTilingIterator
&
315 TilingSetRasterQueueAll::SoonBorderTilingIterator::
317 AdvanceToNextTile(&iterator_
);
321 // EventuallyTilingIterator.
322 TilingSetRasterQueueAll::EventuallyTilingIterator::EventuallyTilingIterator(
323 PictureLayerTiling
* tiling
,
324 TilingData
* tiling_data
)
325 : OnePriorityRectIterator(tiling
,
327 PictureLayerTiling::EVENTUALLY_RECT
) {
328 if (!tiling_
->has_eventually_rect_tiles())
330 iterator_
= TilingData::SpiralDifferenceIterator(
331 tiling_data_
, tiling_
->current_eventually_rect(),
332 tiling_
->current_skewport_rect(), tiling_
->current_soon_border_rect());
335 if (!GetFirstTileAndCheckIfValid(&iterator_
)) {
341 TilingSetRasterQueueAll::EventuallyTilingIterator
&
342 TilingSetRasterQueueAll::EventuallyTilingIterator::
344 AdvanceToNextTile(&iterator_
);
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()) {
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);
374 case Phase::VISIBLE_RECT
:
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_
;
383 case Phase::SKEWPORT_RECT
:
384 skewport_iterator_
= SkewportTilingIterator(tiling_
, tiling_data_
);
385 if (!skewport_iterator_
.done())
386 current_tile_
= *skewport_iterator_
;
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_
;
393 case Phase::EVENTUALLY_RECT
:
394 eventually_iterator_
= EventuallyTilingIterator(tiling_
, tiling_data_
);
395 if (!eventually_iterator_
.done())
396 current_tile_
= *eventually_iterator_
;
402 TilingSetRasterQueueAll::TilingIterator
&
403 TilingSetRasterQueueAll::TilingIterator::
406 case Phase::VISIBLE_RECT
:
408 if (visible_iterator_
.done()) {
412 current_tile_
= *visible_iterator_
;
414 case Phase::PENDING_VISIBLE_RECT
:
415 ++pending_visible_iterator_
;
416 if (pending_visible_iterator_
.done()) {
420 current_tile_
= *pending_visible_iterator_
;
422 case Phase::SKEWPORT_RECT
:
423 ++skewport_iterator_
;
424 if (skewport_iterator_
.done()) {
428 current_tile_
= *skewport_iterator_
;
430 case Phase::SOON_BORDER_RECT
:
431 ++soon_border_iterator_
;
432 if (soon_border_iterator_
.done()) {
436 current_tile_
= *soon_border_iterator_
;
438 case Phase::EVENTUALLY_RECT
:
439 ++eventually_iterator_
;
440 if (eventually_iterator_
.done()) {
441 current_tile_
= PrioritizedTile();
444 current_tile_
= *eventually_iterator_
;