Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(483)

Side by Side Diff: cc/resources/tiling_set_eviction_queue.cc

Issue 1038793002: cc: Rework tiling set eviction iterator. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include <utility> 5 #include <utility>
6 6
7 #include "cc/resources/tiling_set_eviction_queue.h" 7 #include "cc/resources/tiling_set_eviction_queue.h"
8 8
9 namespace cc { 9 namespace cc {
10 namespace {
11
12 bool IsSharedOutOfOrderTile(WhichTree tree,
13 TreePriority tree_priority,
14 const Tile* tile) {
15 if (!tile->is_shared())
16 return false;
17
18 switch (tree_priority) {
19 case SMOOTHNESS_TAKES_PRIORITY:
20 DCHECK_EQ(ACTIVE_TREE, tree);
21 return false;
22 case NEW_CONTENT_TAKES_PRIORITY:
23 DCHECK_EQ(PENDING_TREE, tree);
24 return false;
25 case SAME_PRIORITY_FOR_BOTH_TREES:
26 break;
27 }
28
29 // The priority for tile priority of a shared tile will be a combined
30 // priority thus return shared tiles from a higher priority tree as
31 // it is out of order for a lower priority tree.
32 WhichTree twin_tree = tree == ACTIVE_TREE ? PENDING_TREE : ACTIVE_TREE;
33 const TilePriority& priority = tile->priority(tree);
34 const TilePriority& twin_priority = tile->priority(twin_tree);
35 if (priority.priority_bin != twin_priority.priority_bin)
36 return priority.priority_bin > twin_priority.priority_bin;
37 const bool occluded = tile->is_occluded(tree);
38 const bool twin_occluded = tile->is_occluded(twin_tree);
39 if (occluded != twin_occluded)
40 return occluded;
41 if (priority.distance_to_visible != twin_priority.distance_to_visible)
42 return priority.distance_to_visible > twin_priority.distance_to_visible;
43
44 // If priorities are the same, it does not matter which tree returns
45 // the tile. Let's pick the pending tree.
46 return tree != PENDING_TREE;
47 }
48
49 } // namespace
10 50
11 TilingSetEvictionQueue::TilingSetEvictionQueue( 51 TilingSetEvictionQueue::TilingSetEvictionQueue(
12 PictureLayerTilingSet* tiling_set, 52 PictureLayerTilingSet* tiling_set,
13 TreePriority tree_priority, 53 TreePriority tree_priority,
14 bool skip_shared_out_of_order_tiles) 54 bool skip_shared_out_of_order_tiles)
15 : tiling_set_(tiling_set), 55 : tree_(tiling_set->client()->GetTree()),
16 tree_(tiling_set->client()->GetTree()),
17 tree_priority_(tree_priority), 56 tree_priority_(tree_priority),
18 skip_all_shared_tiles_( 57 skip_all_shared_tiles_(
19 skip_shared_out_of_order_tiles && 58 skip_shared_out_of_order_tiles &&
20 tree_priority == (tree_ == ACTIVE_TREE ? NEW_CONTENT_TAKES_PRIORITY 59 tree_priority == (tree_ == ACTIVE_TREE ? NEW_CONTENT_TAKES_PRIORITY
21 : SMOOTHNESS_TAKES_PRIORITY)), 60 : SMOOTHNESS_TAKES_PRIORITY)),
22 skip_shared_out_of_order_tiles_(skip_shared_out_of_order_tiles), 61 skip_shared_out_of_order_tiles_(skip_shared_out_of_order_tiles),
23 processing_soon_border_rect_(false), 62 phase_(EVENTUALLY_RECT),
24 processing_tiling_with_required_for_activation_tiles_(false), 63 current_tile_(nullptr) {
25 tiling_index_with_required_for_activation_tiles_(0u),
26 current_priority_bin_(TilePriority::EVENTUALLY),
27 current_tiling_index_(0u),
28 current_tiling_range_type_(PictureLayerTilingSet::HIGHER_THAN_HIGH_RES),
29 current_eviction_tile_(nullptr) {
30 // Early out if the layer has no tilings. 64 // Early out if the layer has no tilings.
31 if (!tiling_set_->num_tilings()) 65 if (!tiling_set->num_tilings())
32 return; 66 return;
33 67 GenerateTilingOrder(tiling_set);
34 tiling_index_with_required_for_activation_tiles_ = 68 eventually_iterator_ = EventuallyTilingIterator(
35 TilingIndexWithRequiredForActivationTiles(); 69 &tilings_, tree_, tree_priority_, skip_shared_out_of_order_tiles_,
36 70 skip_all_shared_tiles_);
37 current_tiling_index_ = CurrentTilingRange().start - 1u; 71 if (eventually_iterator_.done()) {
38 AdvanceToNextValidTiling(); 72 AdvancePhase();
73 return;
74 }
75 current_tile_ = *eventually_iterator_;
39 } 76 }
40 77
41 TilingSetEvictionQueue::~TilingSetEvictionQueue() { 78 TilingSetEvictionQueue::~TilingSetEvictionQueue() {
42 } 79 }
43 80
81 void TilingSetEvictionQueue::GenerateTilingOrder(
82 PictureLayerTilingSet* tiling_set) {
83 tilings_.reserve(tiling_set->num_tilings());
84 // Generate all of the tilings in the following order:
85 // 1. Higher than high res from higher to lower resolution.
enne (OOO) 2015/03/27 19:12:11 This seems like a duplicate comment from some othe
vmpstr 2015/03/27 20:19:27 Done.
86 // 2. Lower than low res from lower to higher resolution.
87 // 3. Between high and low res from lower to higher resolution.
88 // 4. Low res tiling if one exists.
89 // 5. High res tiling if one exists.
90 auto range =
91 tiling_set->GetTilingRange(PictureLayerTilingSet::HIGHER_THAN_HIGH_RES);
92 for (int i = range.start; i < range.end; ++i)
93 tilings_.push_back(tiling_set->tiling_at(i));
94
95 range = tiling_set->GetTilingRange(PictureLayerTilingSet::LOWER_THAN_LOW_RES);
96 for (int i = range.end - 1; i >= range.start; --i)
97 tilings_.push_back(tiling_set->tiling_at(i));
98
99 range = tiling_set->GetTilingRange(
100 PictureLayerTilingSet::BETWEEN_HIGH_AND_LOW_RES);
101 for (int i = range.end - 1; i >= range.start; --i)
102 tilings_.push_back(tiling_set->tiling_at(i));
103
104 range = tiling_set->GetTilingRange(PictureLayerTilingSet::LOW_RES);
105 for (int i = range.start; i < range.end; ++i)
106 tilings_.push_back(tiling_set->tiling_at(i));
107
108 range = tiling_set->GetTilingRange(PictureLayerTilingSet::HIGH_RES);
109 for (int i = range.start; i < range.end; ++i)
110 tilings_.push_back(tiling_set->tiling_at(i));
111 DCHECK_EQ(tiling_set->num_tilings(), tilings_.size());
112 }
113
114 void TilingSetEvictionQueue::AdvancePhase() {
115 current_tile_ = nullptr;
116 while (!current_tile_ &&
117 phase_ != VISIBLE_RECT_REQUIRED_FOR_ACTIVATION_UNOCCLUDED) {
118 phase_ = static_cast<Phase>(phase_ + 1);
119 switch (phase_) {
120 case EVENTUALLY_RECT:
121 NOTREACHED();
122 break;
123 case SOON_BORDER_RECT:
124 soon_iterator_ = SoonBorderTilingIterator(
125 &tilings_, tree_, tree_priority_, skip_shared_out_of_order_tiles_,
126 skip_all_shared_tiles_);
127 if (!soon_iterator_.done())
128 current_tile_ = *soon_iterator_;
129 break;
130 case SKEWPORT_RECT:
131 skewport_iterator_ = SkewportTilingIterator(
132 &tilings_, tree_, tree_priority_, skip_shared_out_of_order_tiles_,
133 skip_all_shared_tiles_);
134 if (!skewport_iterator_.done())
135 current_tile_ = *skewport_iterator_;
136 break;
137 case VISIBLE_RECT_OCCLUDED:
138 visible_iterator_ = VisibleTilingIterator(
139 &tilings_, tree_, tree_priority_, skip_shared_out_of_order_tiles_,
140 skip_all_shared_tiles_, true /* return occluded tiles */,
141 false /* return required for activation tiles */);
142 if (!visible_iterator_.done())
143 current_tile_ = *visible_iterator_;
144 break;
145 case VISIBLE_RECT_UNOCCLUDED:
146 visible_iterator_ = VisibleTilingIterator(
147 &tilings_, tree_, tree_priority_, skip_shared_out_of_order_tiles_,
148 skip_all_shared_tiles_, false /* return occluded tiles */,
149 false /* return required for activation tiles */);
150 if (!visible_iterator_.done())
151 current_tile_ = *visible_iterator_;
152 break;
153 case VISIBLE_RECT_REQUIRED_FOR_ACTIVATION_OCCLUDED:
154 visible_iterator_ = VisibleTilingIterator(
155 &tilings_, tree_, tree_priority_, skip_shared_out_of_order_tiles_,
156 skip_all_shared_tiles_, true /* return occluded tiles */,
157 true /* return required for activation tiles */);
158 if (!visible_iterator_.done())
159 current_tile_ = *visible_iterator_;
160 break;
161 case VISIBLE_RECT_REQUIRED_FOR_ACTIVATION_UNOCCLUDED:
162 visible_iterator_ = VisibleTilingIterator(
163 &tilings_, tree_, tree_priority_, skip_shared_out_of_order_tiles_,
164 skip_all_shared_tiles_, false /* return occluded tiles */,
165 true /* return required for activation tiles */);
166 if (!visible_iterator_.done())
167 current_tile_ = *visible_iterator_;
168 break;
169 }
170 }
171 }
172
44 bool TilingSetEvictionQueue::IsEmpty() const { 173 bool TilingSetEvictionQueue::IsEmpty() const {
45 return !current_eviction_tile_; 174 return !current_tile_;
175 }
176
177 Tile* TilingSetEvictionQueue::Top() {
178 DCHECK(!IsEmpty());
179 return current_tile_;
180 }
181
182 const Tile* TilingSetEvictionQueue::Top() const {
183 DCHECK(!IsEmpty());
184 return current_tile_;
46 } 185 }
47 186
48 void TilingSetEvictionQueue::Pop() { 187 void TilingSetEvictionQueue::Pop() {
49 DCHECK(!IsEmpty()); 188 DCHECK(!IsEmpty());
50 189 current_tile_ = nullptr;
51 if (!AdvanceToNextEvictionTile()) 190 switch (phase_) {
52 AdvanceToNextValidTiling(); 191 case EVENTUALLY_RECT:
53 } 192 ++eventually_iterator_;
54 193 if (!eventually_iterator_.done())
55 Tile* TilingSetEvictionQueue::Top() { 194 current_tile_ = *eventually_iterator_;
56 DCHECK(!IsEmpty()); 195 break;
57 return current_eviction_tile_; 196 case SOON_BORDER_RECT:
58 } 197 ++soon_iterator_;
59 198 if (!soon_iterator_.done())
60 const Tile* TilingSetEvictionQueue::Top() const { 199 current_tile_ = *soon_iterator_;
61 DCHECK(!IsEmpty()); 200 break;
62 return current_eviction_tile_; 201 case SKEWPORT_RECT:
63 } 202 ++skewport_iterator_;
64 203 if (!skewport_iterator_.done())
65 bool TilingSetEvictionQueue::AdvanceToNextEvictionTile() { 204 current_tile_ = *skewport_iterator_;
66 // Advance to the next eviction tile within the current priority bin and 205 break;
67 // tiling. This is done while advancing to a new tiling and while popping 206 case VISIBLE_RECT_OCCLUDED:
68 // the current tile. 207 case VISIBLE_RECT_UNOCCLUDED:
69 208 case VISIBLE_RECT_REQUIRED_FOR_ACTIVATION_OCCLUDED:
70 bool required_for_activation = 209 case VISIBLE_RECT_REQUIRED_FOR_ACTIVATION_UNOCCLUDED:
71 processing_tiling_with_required_for_activation_tiles_; 210 ++visible_iterator_;
72 211 if (!visible_iterator_.done())
212 current_tile_ = *visible_iterator_;
213 break;
214 }
215 if (!current_tile_)
216 AdvancePhase();
217 }
218
219 // OnePriorityRectIterator
220 TilingSetEvictionQueue::OnePriorityRectIterator::OnePriorityRectIterator()
221 : tile_(nullptr),
222 tilings_(nullptr),
223 tree_(ACTIVE_TREE),
224 tree_priority_(SAME_PRIORITY_FOR_BOTH_TREES),
225 skip_shared_out_of_order_tiles_(false),
226 skip_all_shared_tiles_(false),
227 tiling_index_(0) {
228 }
229
230 TilingSetEvictionQueue::OnePriorityRectIterator::OnePriorityRectIterator(
231 std::vector<PictureLayerTiling*>* tilings,
232 WhichTree tree,
233 TreePriority tree_priority,
234 bool skip_shared_out_of_order_tiles,
235 bool skip_all_shared_tiles)
236 : tile_(nullptr),
237 tilings_(tilings),
238 tree_(tree),
239 tree_priority_(tree_priority),
240 skip_shared_out_of_order_tiles_(skip_shared_out_of_order_tiles),
241 skip_all_shared_tiles_(skip_all_shared_tiles),
242 tiling_index_(0) {
243 }
244
245 template <typename TilingIteratorType>
246 bool TilingSetEvictionQueue::OnePriorityRectIterator::AdvanceToNextTile(
247 TilingIteratorType* iterator) {
73 for (;;) { 248 for (;;) {
74 while (spiral_iterator_) { 249 ++(*iterator);
75 std::pair<int, int> next_index = spiral_iterator_.index(); 250 if (!(*iterator)) {
76 Tile* tile = current_tiling_->TileAt(next_index.first, next_index.second); 251 tile_ = nullptr;
77 ++spiral_iterator_; 252 return false;
78 if (!tile || !tile->HasResource()) 253 }
79 continue; 254 bool have_valid_tile = GetFirstTileAndCheckIfValid(iterator);
80 if (skip_all_shared_tiles_ && tile->is_shared()) 255 if (have_valid_tile)
81 continue;
82 current_tiling_->UpdateTileAndTwinPriority(tile);
83 if (skip_shared_out_of_order_tiles_ && IsSharedOutOfOrderTile(tile))
84 continue;
85 if (tile->required_for_activation() != required_for_activation)
86 continue;
87 current_eviction_tile_ = tile;
88 return true; 256 return true;
89 }
90 if (processing_soon_border_rect_) {
91 // Advance from soon border rect to skewport rect.
92 processing_soon_border_rect_ = false;
93 if (current_tiling_->has_skewport_rect_tiles_) {
94 spiral_iterator_ = TilingData::ReverseSpiralDifferenceIterator(
95 &current_tiling_->tiling_data_,
96 current_tiling_->current_skewport_rect_,
97 current_tiling_->current_visible_rect_,
98 current_tiling_->current_visible_rect_);
99 continue;
100 }
101 }
102 break;
103 }
104
105 TilePriority::PriorityBin max_tile_priority_bin =
106 current_tiling_->client_->GetMaxTilePriorityBin();
107 while (visible_iterator_) {
108 std::pair<int, int> next_index = visible_iterator_.index();
109 Tile* tile = current_tiling_->TileAt(next_index.first, next_index.second);
110 ++visible_iterator_;
111 if (!tile || !tile->HasResource())
112 continue;
113 if (skip_all_shared_tiles_ && tile->is_shared())
114 continue;
115 // If the max tile priority is not NOW, updated priorities for tiles
116 // returned by the visible iterator will not have NOW (but EVENTUALLY)
117 // priority bin and cannot therefore be required for activation tiles nor
118 // occluded NOW tiles in the current tiling.
119 if (max_tile_priority_bin <= TilePriority::NOW) {
120 // If the current tiling is a pending tree tiling, required for
121 // activation tiles can be detected without updating tile priorities.
122 if (tree_ == PENDING_TREE &&
123 current_tiling_->IsTileRequiredForActivationIfVisible(tile) !=
124 required_for_activation) {
125 continue;
126 }
127 // Unoccluded NOW tiles should be evicted (and thus returned) only after
128 // all occluded NOW tiles.
129 if (!current_tiling_->IsTileOccluded(tile)) {
130 unoccluded_now_tiles_.push_back(tile);
131 continue;
132 }
133 }
134 current_tiling_->UpdateTileAndTwinPriority(tile);
135 if (skip_shared_out_of_order_tiles_ && IsSharedOutOfOrderTile(tile))
136 continue;
137 if (tile->required_for_activation() != required_for_activation)
138 continue;
139 current_eviction_tile_ = tile;
140 return true;
141 }
142
143 while (!unoccluded_now_tiles_.empty()) {
144 // All (unoccluded) NOW tiles have the same priority bin (NOW) and the same
145 // distance to visible (0.0), so it does not matter that tiles are popped
146 // in reversed (FILO) order.
147 Tile* tile = unoccluded_now_tiles_.back();
148 unoccluded_now_tiles_.pop_back();
149 DCHECK(tile);
150 if (!tile->HasResource())
151 continue;
152 current_tiling_->UpdateTileAndTwinPriority(tile);
153 if (skip_shared_out_of_order_tiles_ && IsSharedOutOfOrderTile(tile))
154 continue;
155 if (tile->required_for_activation() != required_for_activation)
156 continue;
157 current_eviction_tile_ = tile;
158 return true;
159 }
160
161 current_eviction_tile_ = nullptr;
162 return false;
163 }
164
165 bool TilingSetEvictionQueue::AdvanceToNextPriorityBin() {
166 // Advance to the next priority bin. This is done only after all tiling range
167 // types (including the required for activation tiling) within the previous
168 // priority bin have been gone through.
169 DCHECK_EQ(current_tiling_range_type_, PictureLayerTilingSet::HIGH_RES);
170
171 switch (current_priority_bin_) {
172 case TilePriority::EVENTUALLY:
173 current_priority_bin_ = TilePriority::SOON;
174 return true;
175 case TilePriority::SOON:
176 current_priority_bin_ = TilePriority::NOW;
177 return true;
178 case TilePriority::NOW:
179 return false;
180 } 257 }
181 NOTREACHED(); 258 NOTREACHED();
182 return false; 259 return false;
183 } 260 }
184 261
185 bool TilingSetEvictionQueue::AdvanceToNextTilingRangeType() { 262 template <typename TilingIteratorType>
186 // Advance to the next tiling range type within the current priority bin, to 263 bool TilingSetEvictionQueue::OnePriorityRectIterator::
187 // the required for activation tiling range type within the current priority 264 GetFirstTileAndCheckIfValid(TilingIteratorType* iterator) {
188 // bin or to the first tiling range type within the next priority bin. This 265 tile_ = (*tilings_)[tiling_index_]->TileAt(iterator->index_x(),
189 // is done only after all tilings within the previous tiling range type have 266 iterator->index_y());
190 // been gone through. 267 // If there's nothing to evict, return false.
191 DCHECK_EQ(current_tiling_index_, CurrentTilingRange().end); 268 if (!tile_ || !tile_->HasResource())
192
193 switch (current_tiling_range_type_) {
194 case PictureLayerTilingSet::HIGHER_THAN_HIGH_RES:
195 current_tiling_range_type_ = PictureLayerTilingSet::LOWER_THAN_LOW_RES;
196 return true;
197 case PictureLayerTilingSet::LOWER_THAN_LOW_RES:
198 current_tiling_range_type_ =
199 PictureLayerTilingSet::BETWEEN_HIGH_AND_LOW_RES;
200 return true;
201 case PictureLayerTilingSet::BETWEEN_HIGH_AND_LOW_RES:
202 current_tiling_range_type_ = PictureLayerTilingSet::LOW_RES;
203 return true;
204 case PictureLayerTilingSet::LOW_RES:
205 current_tiling_range_type_ = PictureLayerTilingSet::HIGH_RES;
206 return true;
207 case PictureLayerTilingSet::HIGH_RES:
208 // Process required for activation tiles (unless that has already been
209 // done for the current priority bin) if there is a tiling with required
210 // for activation tiles and that tiling may have required for activation
211 // tiles having the current priority bin (in the pending tree only NOW
212 // tiles may be required for activation).
213 if (!processing_tiling_with_required_for_activation_tiles_ &&
214 tiling_index_with_required_for_activation_tiles_ <
215 tiling_set_->num_tilings() &&
216 (current_priority_bin_ == TilePriority::NOW ||
217 tree_ == ACTIVE_TREE)) {
218 processing_tiling_with_required_for_activation_tiles_ = true;
219 return true;
220 }
221 processing_tiling_with_required_for_activation_tiles_ = false;
222
223 if (!AdvanceToNextPriorityBin())
224 return false;
225
226 current_tiling_range_type_ = PictureLayerTilingSet::HIGHER_THAN_HIGH_RES;
227 return true;
228 }
229 NOTREACHED();
230 return false;
231 }
232
233 bool TilingSetEvictionQueue::AdvanceToNextValidTiling() {
234 // Advance to the next tiling within current tiling range type or to
235 // the first tiling within the next tiling range type or priority bin until
236 // the next eviction tile is found. This is done only after all eviction
237 // tiles within the previous tiling within the current priority bin and
238 // tiling range type have been gone through.
239 DCHECK(!current_eviction_tile_);
240 DCHECK_NE(current_tiling_index_, CurrentTilingRange().end);
241
242 for (;;) {
243 ++current_tiling_index_;
244 while (current_tiling_index_ == CurrentTilingRange().end) {
245 if (!AdvanceToNextTilingRangeType())
246 return false;
247 current_tiling_index_ = CurrentTilingRange().start;
248 }
249 current_tiling_ = tiling_set_->tiling_at(CurrentTilingIndex());
250
251 switch (current_priority_bin_) {
252 case TilePriority::EVENTUALLY:
253 if (current_tiling_->has_eventually_rect_tiles_) {
254 spiral_iterator_ = TilingData::ReverseSpiralDifferenceIterator(
255 &current_tiling_->tiling_data_,
256 current_tiling_->current_eventually_rect_,
257 current_tiling_->current_skewport_rect_,
258 current_tiling_->current_soon_border_rect_);
259 if (AdvanceToNextEvictionTile())
260 return true;
261 }
262 break;
263 case TilePriority::SOON:
264 if (current_tiling_->has_skewport_rect_tiles_ ||
265 current_tiling_->has_soon_border_rect_tiles_) {
266 processing_soon_border_rect_ = true;
267 if (current_tiling_->has_soon_border_rect_tiles_)
268 spiral_iterator_ = TilingData::ReverseSpiralDifferenceIterator(
269 &current_tiling_->tiling_data_,
270 current_tiling_->current_soon_border_rect_,
271 current_tiling_->current_skewport_rect_,
272 current_tiling_->current_visible_rect_);
273 if (AdvanceToNextEvictionTile())
274 return true;
275 }
276 break;
277 case TilePriority::NOW:
278 if (current_tiling_->has_visible_rect_tiles_) {
279 visible_iterator_ =
280 TilingData::Iterator(&current_tiling_->tiling_data_,
281 current_tiling_->current_visible_rect_,
282 false /* include_borders */);
283 if (AdvanceToNextEvictionTile())
284 return true;
285 }
286 break;
287 }
288 }
289 }
290
291 PictureLayerTilingSet::TilingRange
292 TilingSetEvictionQueue::CurrentTilingRange() const {
293 if (processing_tiling_with_required_for_activation_tiles_)
294 return PictureLayerTilingSet::TilingRange(
295 tiling_index_with_required_for_activation_tiles_,
296 tiling_index_with_required_for_activation_tiles_ + 1);
297 return tiling_set_->GetTilingRange(current_tiling_range_type_);
298 }
299
300 size_t TilingSetEvictionQueue::CurrentTilingIndex() const {
301 DCHECK_NE(current_tiling_index_, CurrentTilingRange().end);
302 switch (current_tiling_range_type_) {
303 case PictureLayerTilingSet::HIGHER_THAN_HIGH_RES:
304 case PictureLayerTilingSet::LOW_RES:
305 case PictureLayerTilingSet::HIGH_RES:
306 return current_tiling_index_;
307 // Tilings in the following ranges are accessed in reverse order.
308 case PictureLayerTilingSet::BETWEEN_HIGH_AND_LOW_RES:
309 case PictureLayerTilingSet::LOWER_THAN_LOW_RES: {
310 PictureLayerTilingSet::TilingRange tiling_range = CurrentTilingRange();
311 size_t current_tiling_range_offset =
312 current_tiling_index_ - tiling_range.start;
313 return tiling_range.end - 1 - current_tiling_range_offset;
314 }
315 }
316 NOTREACHED();
317 return 0;
318 }
319
320 bool TilingSetEvictionQueue::IsSharedOutOfOrderTile(const Tile* tile) const {
321 if (!tile->is_shared())
322 return false; 269 return false;
323 270 // If the tile is shared while we're skipping shared tiles, return false.
324 switch (tree_priority_) { 271 if (skip_all_shared_tiles_ && tile_->is_shared())
325 case SMOOTHNESS_TAKES_PRIORITY: 272 return false;
326 DCHECK_EQ(ACTIVE_TREE, tree_); 273 (*tilings_)[tiling_index_]->UpdateTileAndTwinPriority(tile_);
327 return false; 274 // If the tile is out of order, return false.
328 case NEW_CONTENT_TAKES_PRIORITY: 275 if (skip_shared_out_of_order_tiles_ &&
329 DCHECK_EQ(PENDING_TREE, tree_); 276 IsSharedOutOfOrderTile(tree_, tree_priority_, tile_)) {
330 return false; 277 return false;
331 case SAME_PRIORITY_FOR_BOTH_TREES: 278 }
332 break; 279 // In other cases, the tile we got is a viable candidate, return true.
333 } 280 return true;
334 281 }
335 // The priority for tile priority of a shared tile will be a combined 282
336 // priority thus return shared tiles from a higher priority tree as 283 // EventuallyTilingIterator
337 // it is out of order for a lower priority tree. 284 TilingSetEvictionQueue::EventuallyTilingIterator::EventuallyTilingIterator(
338 WhichTree twin_tree = tree_ == ACTIVE_TREE ? PENDING_TREE : ACTIVE_TREE; 285 std::vector<PictureLayerTiling*>* tilings,
339 const TilePriority& priority = tile->priority(tree_); 286 WhichTree tree,
340 const TilePriority& twin_priority = tile->priority(twin_tree); 287 TreePriority tree_priority,
341 if (priority.priority_bin != twin_priority.priority_bin) 288 bool skip_shared_out_of_order_tiles,
342 return priority.priority_bin > twin_priority.priority_bin; 289 bool skip_all_shared_tiles)
343 const bool occluded = tile->is_occluded(tree_); 290 : OnePriorityRectIterator(tilings,
344 const bool twin_occluded = tile->is_occluded(twin_tree); 291 tree,
345 if (occluded != twin_occluded) 292 tree_priority,
346 return occluded; 293 skip_shared_out_of_order_tiles,
347 if (priority.distance_to_visible != twin_priority.distance_to_visible) 294 skip_all_shared_tiles) {
348 return priority.distance_to_visible > twin_priority.distance_to_visible; 295 // Find the first tiling with a tile.
349 296 while (tiling_index_ < tilings_->size()) {
350 // If priorities are the same, it does not matter which tree returns 297 if (!((*tilings_))[tiling_index_]->has_eventually_rect_tiles()) {
351 // the tile. Let's pick the pending tree. 298 ++tiling_index_;
352 return tree_ != PENDING_TREE; 299 continue;
353 } 300 }
354 301 iterator_ = TilingData::ReverseSpiralDifferenceIterator(
355 size_t TilingSetEvictionQueue::TilingIndexWithRequiredForActivationTiles() 302 ((*tilings_))[tiling_index_]->tiling_data(),
356 const { 303 ((*tilings_))[tiling_index_]->current_eventually_rect(),
357 // Returns the tiling index of the tiling with requuired for activation tiles. 304 ((*tilings_))[tiling_index_]->current_skewport_rect(),
358 // If no such tiling exists, returns the past-the-last index (num_tilings). 305 ((*tilings_))[tiling_index_]->current_soon_border_rect());
359 size_t num_tilings = tiling_set_->num_tilings(); 306 if (!iterator_) {
360 307 ++tiling_index_;
361 if (tree_ == PENDING_TREE) { 308 continue;
362 // For the pending tree, the tiling with required for activation tiles is 309 }
363 // the high res one. 310 break;
364 PictureLayerTilingSet::TilingRange high_res_tiling_range = 311 }
365 tiling_set_->GetTilingRange(PictureLayerTilingSet::HIGH_RES); 312 if (tiling_index_ >= tilings_->size())
366 if (high_res_tiling_range.start != high_res_tiling_range.end) 313 return;
367 return high_res_tiling_range.start; 314 if (!GetFirstTileAndCheckIfValid(&iterator_))
368 } else { 315 ++(*this);
369 DCHECK_EQ(ACTIVE_TREE, tree_); 316 }
370 // Only pending tree tiles can be required for activation. They can appear 317
371 // also in the active tree only if they are shared. If we skip all shared 318 TilingSetEvictionQueue::EventuallyTilingIterator&
372 // tiles, there is no need to find them as they will not be returned. 319 TilingSetEvictionQueue::EventuallyTilingIterator::
373 if (skip_all_shared_tiles_) 320 operator++() {
374 return num_tilings; 321 bool found_tile = AdvanceToNextTile(&iterator_);
375 322 while (!found_tile && (tiling_index_ + 1) < tilings_->size()) {
376 // For the active tree, the tiling with required for activation tiles is 323 ++tiling_index_;
377 // the one whose twin tiling is the high res pending tiling. 324 if (!((*tilings_))[tiling_index_]->has_eventually_rect_tiles())
378 for (size_t i = 0; i < num_tilings; ++i) { 325 continue;
379 const PictureLayerTiling* tiling = tiling_set_->tiling_at(i); 326 iterator_ = TilingData::ReverseSpiralDifferenceIterator(
380 const PictureLayerTiling* pending_tiling = 327 ((*tilings_))[tiling_index_]->tiling_data(),
381 tiling_set_->client()->GetPendingOrActiveTwinTiling(tiling); 328 ((*tilings_))[tiling_index_]->current_eventually_rect(),
382 if (pending_tiling && pending_tiling->resolution() == HIGH_RESOLUTION) 329 ((*tilings_))[tiling_index_]->current_skewport_rect(),
383 return i; 330 ((*tilings_))[tiling_index_]->current_soon_border_rect());
384 } 331 if (!iterator_)
385 } 332 continue;
386 333 found_tile = GetFirstTileAndCheckIfValid(&iterator_);
387 return num_tilings; 334 if (!found_tile)
335 found_tile = AdvanceToNextTile(&iterator_);
336 }
337 return *this;
338 }
339
340 // SoonBorderTilingIterator
341 TilingSetEvictionQueue::SoonBorderTilingIterator::SoonBorderTilingIterator(
342 std::vector<PictureLayerTiling*>* tilings,
343 WhichTree tree,
344 TreePriority tree_priority,
345 bool skip_shared_out_of_order_tiles,
346 bool skip_all_shared_tiles)
347 : OnePriorityRectIterator(tilings,
348 tree,
349 tree_priority,
350 skip_shared_out_of_order_tiles,
351 skip_all_shared_tiles) {
352 // Find the first tiling with a tile.
353 while (tiling_index_ < tilings_->size()) {
354 if (!((*tilings_))[tiling_index_]->has_soon_border_rect_tiles()) {
355 ++tiling_index_;
356 continue;
357 }
358 iterator_ = TilingData::ReverseSpiralDifferenceIterator(
359 ((*tilings_))[tiling_index_]->tiling_data(),
360 ((*tilings_))[tiling_index_]->current_soon_border_rect(),
361 ((*tilings_))[tiling_index_]->current_skewport_rect(),
362 ((*tilings_))[tiling_index_]->current_visible_rect());
363 if (!iterator_) {
364 ++tiling_index_;
365 continue;
366 }
367 break;
368 }
369 if (tiling_index_ >= tilings_->size())
370 return;
371 if (!GetFirstTileAndCheckIfValid(&iterator_))
372 ++(*this);
373 }
374
375 TilingSetEvictionQueue::SoonBorderTilingIterator&
376 TilingSetEvictionQueue::SoonBorderTilingIterator::
377 operator++() {
378 bool found_tile = AdvanceToNextTile(&iterator_);
379 while (!found_tile && (tiling_index_ + 1) < tilings_->size()) {
380 ++tiling_index_;
381 if (!((*tilings_))[tiling_index_]->has_soon_border_rect_tiles())
382 continue;
383 iterator_ = TilingData::ReverseSpiralDifferenceIterator(
384 ((*tilings_))[tiling_index_]->tiling_data(),
385 ((*tilings_))[tiling_index_]->current_soon_border_rect(),
386 ((*tilings_))[tiling_index_]->current_skewport_rect(),
387 ((*tilings_))[tiling_index_]->current_visible_rect());
388 if (!iterator_)
389 continue;
390 found_tile = GetFirstTileAndCheckIfValid(&iterator_);
391 if (!found_tile)
392 found_tile = AdvanceToNextTile(&iterator_);
393 }
394 return *this;
395 }
396
397 // SkewportTilingIterator
398 TilingSetEvictionQueue::SkewportTilingIterator::SkewportTilingIterator(
399 std::vector<PictureLayerTiling*>* tilings,
400 WhichTree tree,
401 TreePriority tree_priority,
402 bool skip_shared_out_of_order_tiles,
403 bool skip_all_shared_tiles)
404 : OnePriorityRectIterator(tilings,
405 tree,
406 tree_priority,
407 skip_shared_out_of_order_tiles,
408 skip_all_shared_tiles) {
409 // Find the first tiling with a tile.
410 while (tiling_index_ < tilings_->size()) {
411 if (!((*tilings_))[tiling_index_]->has_skewport_rect_tiles()) {
412 ++tiling_index_;
413 continue;
enne (OOO) 2015/03/27 19:12:11 This is maybe just a style nit, but these loops ar
vmpstr 2015/03/27 20:19:27 The has skewport rect tiles check is on the tiling
enne (OOO) 2015/03/27 21:48:05 Oh, right. I think I was thinking about the wrong
414 }
415 iterator_ = TilingData::ReverseSpiralDifferenceIterator(
416 ((*tilings_))[tiling_index_]->tiling_data(),
417 ((*tilings_))[tiling_index_]->current_skewport_rect(),
418 ((*tilings_))[tiling_index_]->current_visible_rect(),
419 ((*tilings_))[tiling_index_]->current_visible_rect());
420 if (!iterator_) {
421 ++tiling_index_;
422 continue;
423 }
424 break;
425 }
426 if (tiling_index_ >= tilings_->size())
427 return;
428 if (!GetFirstTileAndCheckIfValid(&iterator_))
429 ++(*this);
430 }
431
432 TilingSetEvictionQueue::SkewportTilingIterator&
433 TilingSetEvictionQueue::SkewportTilingIterator::
434 operator++() {
435 bool found_tile = AdvanceToNextTile(&iterator_);
436 while (!found_tile && (tiling_index_ + 1) < tilings_->size()) {
437 ++tiling_index_;
438 if (!((*tilings_))[tiling_index_]->has_skewport_rect_tiles())
439 continue;
440 iterator_ = TilingData::ReverseSpiralDifferenceIterator(
441 ((*tilings_))[tiling_index_]->tiling_data(),
442 ((*tilings_))[tiling_index_]->current_skewport_rect(),
443 ((*tilings_))[tiling_index_]->current_visible_rect(),
444 ((*tilings_))[tiling_index_]->current_visible_rect());
445 if (!iterator_)
446 continue;
447 found_tile = GetFirstTileAndCheckIfValid(&iterator_);
448 if (!found_tile)
449 found_tile = AdvanceToNextTile(&iterator_);
450 }
451 return *this;
452 }
453
454 // VisibleTilingIterator
455 TilingSetEvictionQueue::VisibleTilingIterator::VisibleTilingIterator(
456 std::vector<PictureLayerTiling*>* tilings,
457 WhichTree tree,
458 TreePriority tree_priority,
459 bool skip_shared_out_of_order_tiles,
460 bool skip_all_shared_tiles,
461 bool return_occluded_tiles,
462 bool return_required_for_activation_tiles)
463 : OnePriorityRectIterator(tilings,
464 tree,
465 tree_priority,
466 skip_shared_out_of_order_tiles,
467 skip_all_shared_tiles),
468 return_occluded_tiles_(return_occluded_tiles),
469 return_required_for_activation_tiles_(
470 return_required_for_activation_tiles) {
471 // Find the first tiling with a tile.
472 while (tiling_index_ < tilings_->size()) {
473 if (!((*tilings_))[tiling_index_]->has_visible_rect_tiles()) {
474 ++tiling_index_;
475 continue;
476 }
477 iterator_ = TilingData::Iterator(
478 ((*tilings_))[tiling_index_]->tiling_data(),
479 ((*tilings_))[tiling_index_]->current_visible_rect(), false);
480 if (!iterator_) {
481 ++tiling_index_;
482 continue;
483 }
484 break;
485 }
486 if (tiling_index_ >= tilings_->size())
487 return;
488 if (!GetFirstTileAndCheckIfValid(&iterator_)) {
489 ++(*this);
490 return;
491 }
492 if (!TileMatchesRequiredFlags(tile_)) {
493 ++(*this);
494 return;
495 }
496 }
497
498 TilingSetEvictionQueue::VisibleTilingIterator&
499 TilingSetEvictionQueue::VisibleTilingIterator::
500 operator++() {
501 bool found_tile = AdvanceToNextTile(&iterator_);
502 while (found_tile && !TileMatchesRequiredFlags(tile_))
503 found_tile = AdvanceToNextTile(&iterator_);
504
505 while (!found_tile && (tiling_index_ + 1) < tilings_->size()) {
506 ++tiling_index_;
507 if (!((*tilings_))[tiling_index_]->has_visible_rect_tiles())
508 continue;
509 iterator_ = TilingData::Iterator(
510 ((*tilings_))[tiling_index_]->tiling_data(),
511 ((*tilings_))[tiling_index_]->current_visible_rect(), false);
512 if (!iterator_)
513 continue;
514 found_tile = GetFirstTileAndCheckIfValid(&iterator_);
515 if (!found_tile)
516 found_tile = AdvanceToNextTile(&iterator_);
517 while (found_tile && !TileMatchesRequiredFlags(tile_))
518 found_tile = AdvanceToNextTile(&iterator_);
519 }
520 return *this;
521 }
522
523 bool TilingSetEvictionQueue::VisibleTilingIterator::TileMatchesRequiredFlags(
524 const Tile* tile) const {
525 return (tile->required_for_activation() ==
enne (OOO) 2015/03/27 19:12:11 style nit: no need for parens. You could also bre
vmpstr 2015/03/27 20:19:27 Eh, I'm not so worried about length, but I did cha
526 return_required_for_activation_tiles_ &&
527 tile->is_occluded(tree_) == return_occluded_tiles_);
388 } 528 }
389 529
390 } // namespace cc 530 } // namespace cc
OLDNEW
« cc/resources/tiling_set_eviction_queue.h ('K') | « cc/resources/tiling_set_eviction_queue.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698