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);
115 bool TilingSetRasterQueueAll::IsEmpty() const {
116 return current_stage_
>= stages_
->size();
119 void TilingSetRasterQueueAll::Pop() {
120 IteratorType index
= stages_
[current_stage_
].iterator_type
;
121 TilePriority::PriorityBin tile_type
= stages_
[current_stage_
].tile_type
;
123 // First advance the iterator.
124 DCHECK(!iterators_
[index
].done());
125 DCHECK(iterators_
[index
].type() == tile_type
);
128 if (iterators_
[index
].done() || iterators_
[index
].type() != tile_type
)
129 AdvanceToNextStage();
132 const PrioritizedTile
& TilingSetRasterQueueAll::Top() const {
135 IteratorType index
= stages_
[current_stage_
].iterator_type
;
136 DCHECK(!iterators_
[index
].done());
137 DCHECK(iterators_
[index
].type() == stages_
[current_stage_
].tile_type
);
139 return *iterators_
[index
];
142 void TilingSetRasterQueueAll::AdvanceToNextStage() {
143 DCHECK_LT(current_stage_
, stages_
->size());
145 while (current_stage_
< stages_
->size()) {
146 IteratorType index
= stages_
[current_stage_
].iterator_type
;
147 TilePriority::PriorityBin tile_type
= stages_
[current_stage_
].tile_type
;
149 if (!iterators_
[index
].done() && iterators_
[index
].type() == tile_type
)
155 // OnePriorityRectIterator
156 TilingSetRasterQueueAll::OnePriorityRectIterator::OnePriorityRectIterator()
157 : tiling_(nullptr), tiling_data_(nullptr) {
160 TilingSetRasterQueueAll::OnePriorityRectIterator::OnePriorityRectIterator(
161 PictureLayerTiling
* tiling
,
162 TilingData
* tiling_data
,
163 PictureLayerTiling::PriorityRectType priority_rect_type
)
165 tiling_data_(tiling_data
),
166 priority_rect_type_(priority_rect_type
),
167 pending_visible_rect_(tiling
->pending_visible_rect()) {
170 template <typename TilingIteratorType
>
171 void TilingSetRasterQueueAll::OnePriorityRectIterator::AdvanceToNextTile(
172 TilingIteratorType
* iterator
) {
176 current_tile_
= PrioritizedTile();
179 Tile
* tile
= tiling_
->TileAt(iterator
->index_x(), iterator
->index_y());
180 if (IsTileValid(tile
)) {
181 tiling_
->UpdateRequiredStatesOnTile(tile
);
182 current_tile_
= tiling_
->MakePrioritizedTile(tile
, priority_rect_type_
);
188 template <typename TilingIteratorType
>
189 bool TilingSetRasterQueueAll::OnePriorityRectIterator::
190 GetFirstTileAndCheckIfValid(TilingIteratorType
* iterator
) {
191 Tile
* tile
= tiling_
->TileAt(iterator
->index_x(), iterator
->index_y());
192 if (!IsTileValid(tile
)) {
193 current_tile_
= PrioritizedTile();
196 tiling_
->UpdateRequiredStatesOnTile(tile
);
197 current_tile_
= tiling_
->MakePrioritizedTile(tile
, priority_rect_type_
);
201 bool TilingSetRasterQueueAll::OnePriorityRectIterator::IsTileValid(
202 const Tile
* tile
) const {
203 if (!tile
|| !TileNeedsRaster(tile
))
205 // After the pending visible rect has been processed, we must return false
206 // for pending visible rect tiles as tiling iterators do not ignore those
208 if (priority_rect_type_
> PictureLayerTiling::PENDING_VISIBLE_RECT
&&
209 pending_visible_rect_
.Intersects(tile
->content_rect())) {
215 // VisibleTilingIterator.
216 TilingSetRasterQueueAll::VisibleTilingIterator::VisibleTilingIterator(
217 PictureLayerTiling
* tiling
,
218 TilingData
* tiling_data
)
219 : OnePriorityRectIterator(tiling
,
221 PictureLayerTiling::VISIBLE_RECT
) {
222 if (!tiling_
->has_visible_rect_tiles())
225 TilingData::Iterator(tiling_data_
, tiling_
->current_visible_rect(),
226 false /* include_borders */);
229 if (!GetFirstTileAndCheckIfValid(&iterator_
))
233 TilingSetRasterQueueAll::VisibleTilingIterator
&
234 TilingSetRasterQueueAll::VisibleTilingIterator::
236 AdvanceToNextTile(&iterator_
);
240 // PendingVisibleTilingIterator.
241 TilingSetRasterQueueAll::PendingVisibleTilingIterator::
242 PendingVisibleTilingIterator(PictureLayerTiling
* tiling
,
243 TilingData
* tiling_data
)
244 : OnePriorityRectIterator(tiling
,
246 PictureLayerTiling::PENDING_VISIBLE_RECT
) {
247 iterator_
= TilingData::DifferenceIterator(
248 tiling_data_
, pending_visible_rect_
, tiling_
->current_visible_rect());
251 if (!GetFirstTileAndCheckIfValid(&iterator_
))
255 TilingSetRasterQueueAll::PendingVisibleTilingIterator
&
256 TilingSetRasterQueueAll::PendingVisibleTilingIterator::
258 AdvanceToNextTile(&iterator_
);
262 // SkewportTilingIterator.
263 TilingSetRasterQueueAll::SkewportTilingIterator::SkewportTilingIterator(
264 PictureLayerTiling
* tiling
,
265 TilingData
* tiling_data
)
266 : OnePriorityRectIterator(tiling
,
268 PictureLayerTiling::SKEWPORT_RECT
) {
269 if (!tiling_
->has_skewport_rect_tiles())
271 iterator_
= TilingData::SpiralDifferenceIterator(
272 tiling_data_
, tiling_
->current_skewport_rect(),
273 tiling_
->current_visible_rect(), tiling_
->current_visible_rect());
276 if (!GetFirstTileAndCheckIfValid(&iterator_
)) {
282 TilingSetRasterQueueAll::SkewportTilingIterator
&
283 TilingSetRasterQueueAll::SkewportTilingIterator::
285 AdvanceToNextTile(&iterator_
);
289 // SoonBorderTilingIterator.
290 TilingSetRasterQueueAll::SoonBorderTilingIterator::SoonBorderTilingIterator(
291 PictureLayerTiling
* tiling
,
292 TilingData
* tiling_data
)
293 : OnePriorityRectIterator(tiling
,
295 PictureLayerTiling::SOON_BORDER_RECT
) {
296 if (!tiling_
->has_soon_border_rect_tiles())
298 iterator_
= TilingData::SpiralDifferenceIterator(
299 tiling_data_
, tiling_
->current_soon_border_rect(),
300 tiling_
->current_skewport_rect(), tiling_
->current_visible_rect());
303 if (!GetFirstTileAndCheckIfValid(&iterator_
)) {
309 TilingSetRasterQueueAll::SoonBorderTilingIterator
&
310 TilingSetRasterQueueAll::SoonBorderTilingIterator::
312 AdvanceToNextTile(&iterator_
);
316 // EventuallyTilingIterator.
317 TilingSetRasterQueueAll::EventuallyTilingIterator::EventuallyTilingIterator(
318 PictureLayerTiling
* tiling
,
319 TilingData
* tiling_data
)
320 : OnePriorityRectIterator(tiling
,
322 PictureLayerTiling::EVENTUALLY_RECT
) {
323 if (!tiling_
->has_eventually_rect_tiles())
325 iterator_
= TilingData::SpiralDifferenceIterator(
326 tiling_data_
, tiling_
->current_eventually_rect(),
327 tiling_
->current_skewport_rect(), tiling_
->current_soon_border_rect());
330 if (!GetFirstTileAndCheckIfValid(&iterator_
)) {
336 TilingSetRasterQueueAll::EventuallyTilingIterator
&
337 TilingSetRasterQueueAll::EventuallyTilingIterator::
339 AdvanceToNextTile(&iterator_
);
344 TilingSetRasterQueueAll::TilingIterator::TilingIterator() : tiling_(nullptr) {
347 TilingSetRasterQueueAll::TilingIterator::TilingIterator(
348 PictureLayerTiling
* tiling
,
349 TilingData
* tiling_data
)
350 : tiling_(tiling
), tiling_data_(tiling_data
), phase_(Phase::VISIBLE_RECT
) {
351 visible_iterator_
= VisibleTilingIterator(tiling_
, tiling_data_
);
352 if (visible_iterator_
.done()) {
356 current_tile_
= *visible_iterator_
;
359 TilingSetRasterQueueAll::TilingIterator::~TilingIterator() {
362 void TilingSetRasterQueueAll::TilingIterator::AdvancePhase() {
363 DCHECK_LT(phase_
, Phase::EVENTUALLY_RECT
);
365 current_tile_
= PrioritizedTile();
366 while (!current_tile_
.tile() && phase_
< Phase::EVENTUALLY_RECT
) {
367 phase_
= static_cast<Phase
>(phase_
+ 1);
369 case Phase::VISIBLE_RECT
:
372 case Phase::PENDING_VISIBLE_RECT
:
373 pending_visible_iterator_
=
374 PendingVisibleTilingIterator(tiling_
, tiling_data_
);
375 if (!pending_visible_iterator_
.done())
376 current_tile_
= *pending_visible_iterator_
;
378 case Phase::SKEWPORT_RECT
:
379 skewport_iterator_
= SkewportTilingIterator(tiling_
, tiling_data_
);
380 if (!skewport_iterator_
.done())
381 current_tile_
= *skewport_iterator_
;
383 case Phase::SOON_BORDER_RECT
:
384 soon_border_iterator_
= SoonBorderTilingIterator(tiling_
, tiling_data_
);
385 if (!soon_border_iterator_
.done())
386 current_tile_
= *soon_border_iterator_
;
388 case Phase::EVENTUALLY_RECT
:
389 eventually_iterator_
= EventuallyTilingIterator(tiling_
, tiling_data_
);
390 if (!eventually_iterator_
.done())
391 current_tile_
= *eventually_iterator_
;
397 TilingSetRasterQueueAll::TilingIterator
&
398 TilingSetRasterQueueAll::TilingIterator::
401 case Phase::VISIBLE_RECT
:
403 if (visible_iterator_
.done()) {
407 current_tile_
= *visible_iterator_
;
409 case Phase::PENDING_VISIBLE_RECT
:
410 ++pending_visible_iterator_
;
411 if (pending_visible_iterator_
.done()) {
415 current_tile_
= *pending_visible_iterator_
;
417 case Phase::SKEWPORT_RECT
:
418 ++skewport_iterator_
;
419 if (skewport_iterator_
.done()) {
423 current_tile_
= *skewport_iterator_
;
425 case Phase::SOON_BORDER_RECT
:
426 ++soon_border_iterator_
;
427 if (soon_border_iterator_
.done()) {
431 current_tile_
= *soon_border_iterator_
;
433 case Phase::EVENTUALLY_RECT
:
434 ++eventually_iterator_
;
435 if (eventually_iterator_
.done()) {
436 current_tile_
= PrioritizedTile();
439 current_tile_
= *eventually_iterator_
;