OLD | NEW |
---|---|
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, const Tile* tile) { | |
13 if (!tile->is_shared()) | |
14 return false; | |
15 | |
16 // The priority for tile priority of a shared tile will be a combined | |
17 // priority thus return shared tiles from a higher priority tree as | |
18 // it is out of order for a lower priority tree. | |
19 WhichTree twin_tree = tree == ACTIVE_TREE ? PENDING_TREE : ACTIVE_TREE; | |
20 const TilePriority& priority = tile->priority(tree); | |
21 const TilePriority& twin_priority = tile->priority(twin_tree); | |
22 if (priority.priority_bin != twin_priority.priority_bin) | |
23 return priority.priority_bin > twin_priority.priority_bin; | |
24 const bool occluded = tile->is_occluded(tree); | |
25 const bool twin_occluded = tile->is_occluded(twin_tree); | |
26 if (occluded != twin_occluded) | |
27 return occluded; | |
28 if (priority.distance_to_visible != twin_priority.distance_to_visible) | |
29 return priority.distance_to_visible > twin_priority.distance_to_visible; | |
30 | |
31 // If priorities are the same, it does not matter which tree returns | |
32 // the tile. Let's pick the pending tree. | |
33 return tree != PENDING_TREE; | |
34 } | |
35 | |
36 } // namespace | |
10 | 37 |
11 TilingSetEvictionQueue::TilingSetEvictionQueue( | 38 TilingSetEvictionQueue::TilingSetEvictionQueue( |
12 PictureLayerTilingSet* tiling_set, | 39 PictureLayerTilingSet* tiling_set, |
13 TreePriority tree_priority, | |
14 bool skip_shared_out_of_order_tiles) | 40 bool skip_shared_out_of_order_tiles) |
15 : tiling_set_(tiling_set), | 41 : tiling_set_(tiling_set), |
16 tree_(tiling_set->client()->GetTree()), | 42 tree_(tiling_set->client()->GetTree()), |
17 tree_priority_(tree_priority), | |
18 skip_all_shared_tiles_( | |
19 skip_shared_out_of_order_tiles && | |
20 tree_priority == (tree_ == ACTIVE_TREE ? NEW_CONTENT_TAKES_PRIORITY | |
21 : SMOOTHNESS_TAKES_PRIORITY)), | |
22 skip_shared_out_of_order_tiles_(skip_shared_out_of_order_tiles), | 43 skip_shared_out_of_order_tiles_(skip_shared_out_of_order_tiles), |
23 processing_soon_border_rect_(false), | 44 processing_soon_border_rect_(false), |
24 processing_tiling_with_required_for_activation_tiles_(false), | 45 processing_required_for_activation_tiles_(false), |
25 tiling_index_with_required_for_activation_tiles_(0u), | |
26 current_priority_bin_(TilePriority::EVENTUALLY), | 46 current_priority_bin_(TilePriority::EVENTUALLY), |
27 current_tiling_index_(0u), | 47 current_tiling_index_(0u), |
28 current_tiling_range_type_(PictureLayerTilingSet::HIGHER_THAN_HIGH_RES), | 48 current_tiling_range_type_(PictureLayerTilingSet::HIGHER_THAN_HIGH_RES), |
29 current_eviction_tile_(nullptr) { | 49 current_eviction_tile_(nullptr) { |
30 // Early out if the layer has no tilings. | 50 // Early out if the layer has no tilings. |
31 if (!tiling_set_->num_tilings()) | 51 if (!tiling_set_->num_tilings()) |
32 return; | 52 return; |
33 | 53 |
34 tiling_index_with_required_for_activation_tiles_ = | |
35 TilingIndexWithRequiredForActivationTiles(); | |
36 | |
37 current_tiling_index_ = CurrentTilingRange().start - 1u; | 54 current_tiling_index_ = CurrentTilingRange().start - 1u; |
38 AdvanceToNextValidTiling(); | 55 AdvanceToNextValidTiling(); |
39 } | 56 } |
40 | 57 |
41 TilingSetEvictionQueue::~TilingSetEvictionQueue() { | 58 TilingSetEvictionQueue::~TilingSetEvictionQueue() { |
42 } | 59 } |
43 | 60 |
44 bool TilingSetEvictionQueue::IsEmpty() const { | 61 bool TilingSetEvictionQueue::IsEmpty() const { |
45 return !current_eviction_tile_; | 62 return !current_eviction_tile_; |
46 } | 63 } |
(...skipping 13 matching lines...) Expand all Loading... | |
60 const Tile* TilingSetEvictionQueue::Top() const { | 77 const Tile* TilingSetEvictionQueue::Top() const { |
61 DCHECK(!IsEmpty()); | 78 DCHECK(!IsEmpty()); |
62 return current_eviction_tile_; | 79 return current_eviction_tile_; |
63 } | 80 } |
64 | 81 |
65 bool TilingSetEvictionQueue::AdvanceToNextEvictionTile() { | 82 bool TilingSetEvictionQueue::AdvanceToNextEvictionTile() { |
66 // Advance to the next eviction tile within the current priority bin and | 83 // Advance to the next eviction tile within the current priority bin and |
67 // tiling. This is done while advancing to a new tiling and while popping | 84 // tiling. This is done while advancing to a new tiling and while popping |
68 // the current tile. | 85 // the current tile. |
69 | 86 |
70 bool required_for_activation = | 87 bool required_for_activation = processing_required_for_activation_tiles_; |
71 processing_tiling_with_required_for_activation_tiles_; | |
72 | 88 |
73 for (;;) { | 89 for (;;) { |
74 while (spiral_iterator_) { | 90 while (spiral_iterator_) { |
75 std::pair<int, int> next_index = spiral_iterator_.index(); | 91 std::pair<int, int> next_index = spiral_iterator_.index(); |
76 Tile* tile = current_tiling_->TileAt(next_index.first, next_index.second); | 92 Tile* tile = current_tiling_->TileAt(next_index.first, next_index.second); |
77 ++spiral_iterator_; | 93 ++spiral_iterator_; |
78 if (!tile || !tile->HasResource()) | 94 if (!tile || !tile->HasResource()) |
79 continue; | 95 continue; |
80 if (skip_all_shared_tiles_ && tile->is_shared()) | 96 current_tiling_->UpdateTileAndTwinPriority(tile); |
97 if (tile->required_for_activation() != required_for_activation) | |
vmpstr
2015/04/02 17:30:29
Would this case be skipped by IsSharedOutOfOrderTi
USE eero AT chromium.org
2015/04/07 13:17:07
Yes, I replaced it with DCHECK. I also reverted th
| |
81 continue; | 98 continue; |
82 current_tiling_->UpdateTileAndTwinPriority(tile); | 99 if (skip_shared_out_of_order_tiles_ && |
83 if (skip_shared_out_of_order_tiles_ && IsSharedOutOfOrderTile(tile)) | 100 IsSharedOutOfOrderTile(tree_, tile)) |
84 continue; | |
85 if (tile->required_for_activation() != required_for_activation) | |
86 continue; | 101 continue; |
87 current_eviction_tile_ = tile; | 102 current_eviction_tile_ = tile; |
88 return true; | 103 return true; |
89 } | 104 } |
90 if (processing_soon_border_rect_) { | 105 if (processing_soon_border_rect_) { |
91 // Advance from soon border rect to skewport rect. | 106 // Advance from soon border rect to skewport rect. |
92 processing_soon_border_rect_ = false; | 107 processing_soon_border_rect_ = false; |
93 if (current_tiling_->has_skewport_rect_tiles_) { | 108 if (current_tiling_->has_skewport_rect_tiles_) { |
94 spiral_iterator_ = TilingData::ReverseSpiralDifferenceIterator( | 109 spiral_iterator_ = TilingData::ReverseSpiralDifferenceIterator( |
95 ¤t_tiling_->tiling_data_, | 110 ¤t_tiling_->tiling_data_, |
96 current_tiling_->current_skewport_rect_, | 111 current_tiling_->current_skewport_rect_, |
97 current_tiling_->current_visible_rect_, | 112 current_tiling_->current_visible_rect_, |
98 current_tiling_->current_visible_rect_); | 113 current_tiling_->current_visible_rect_); |
99 continue; | 114 continue; |
100 } | 115 } |
101 } | 116 } |
102 break; | 117 break; |
103 } | 118 } |
104 | 119 |
105 TilePriority::PriorityBin max_tile_priority_bin = | 120 TilePriority::PriorityBin max_tile_priority_bin = |
106 current_tiling_->client_->GetMaxTilePriorityBin(); | 121 current_tiling_->client_->GetMaxTilePriorityBin(); |
107 while (visible_iterator_) { | 122 while (visible_iterator_) { |
108 std::pair<int, int> next_index = visible_iterator_.index(); | 123 std::pair<int, int> next_index = visible_iterator_.index(); |
109 Tile* tile = current_tiling_->TileAt(next_index.first, next_index.second); | 124 Tile* tile = current_tiling_->TileAt(next_index.first, next_index.second); |
110 ++visible_iterator_; | 125 ++visible_iterator_; |
111 if (!tile || !tile->HasResource()) | 126 if (!tile || !tile->HasResource()) |
112 continue; | 127 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 | 128 // If the max tile priority is not NOW, updated priorities for tiles |
116 // returned by the visible iterator will not have NOW (but EVENTUALLY) | 129 // returned by the visible iterator will not have NOW (but EVENTUALLY) |
117 // priority bin and cannot therefore be required for activation tiles nor | 130 // priority bin and cannot therefore be required for activation tiles nor |
118 // occluded NOW tiles in the current tiling. | 131 // occluded NOW tiles in the current tiling. |
119 if (max_tile_priority_bin <= TilePriority::NOW) { | 132 if (max_tile_priority_bin <= TilePriority::NOW) { |
120 // If the current tiling is a pending tree tiling, required for | 133 // If the current tiling is a pending tree tiling, required for |
121 // activation tiles can be detected without updating tile priorities. | 134 // activation tiles can be detected without updating tile priorities. |
122 if (tree_ == PENDING_TREE && | 135 if (tree_ == PENDING_TREE && |
123 current_tiling_->IsTileRequiredForActivationIfVisible(tile) != | 136 current_tiling_->IsTileRequiredForActivationIfVisible(tile) != |
124 required_for_activation) { | 137 required_for_activation) { |
125 continue; | 138 continue; |
126 } | 139 } |
127 // Unoccluded NOW tiles should be evicted (and thus returned) only after | 140 // Unoccluded NOW tiles should be evicted (and thus returned) only after |
128 // all occluded NOW tiles. | 141 // all occluded NOW tiles. |
129 if (!current_tiling_->IsTileOccluded(tile)) { | 142 if (!current_tiling_->IsTileOccluded(tile)) { |
130 unoccluded_now_tiles_.push_back(tile); | 143 unoccluded_now_tiles_.push_back(tile); |
131 continue; | 144 continue; |
132 } | 145 } |
133 } | 146 } |
134 current_tiling_->UpdateTileAndTwinPriority(tile); | 147 current_tiling_->UpdateTileAndTwinPriority(tile); |
135 if (skip_shared_out_of_order_tiles_ && IsSharedOutOfOrderTile(tile)) | 148 if (tile->required_for_activation() != required_for_activation) |
136 continue; | 149 continue; |
137 if (tile->required_for_activation() != required_for_activation) | 150 if (skip_shared_out_of_order_tiles_ && IsSharedOutOfOrderTile(tree_, tile)) |
138 continue; | 151 continue; |
139 current_eviction_tile_ = tile; | 152 current_eviction_tile_ = tile; |
140 return true; | 153 return true; |
141 } | 154 } |
142 | 155 |
143 while (!unoccluded_now_tiles_.empty()) { | 156 while (!unoccluded_now_tiles_.empty()) { |
144 // All (unoccluded) NOW tiles have the same priority bin (NOW) and the same | 157 // 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 | 158 // distance to visible (0.0), so it does not matter that tiles are popped |
146 // in reversed (FILO) order. | 159 // in reversed (FILO) order. |
147 Tile* tile = unoccluded_now_tiles_.back(); | 160 Tile* tile = unoccluded_now_tiles_.back(); |
148 unoccluded_now_tiles_.pop_back(); | 161 unoccluded_now_tiles_.pop_back(); |
149 DCHECK(tile); | 162 DCHECK(tile); |
150 if (!tile->HasResource()) | 163 if (!tile->HasResource()) |
151 continue; | 164 continue; |
152 current_tiling_->UpdateTileAndTwinPriority(tile); | 165 current_tiling_->UpdateTileAndTwinPriority(tile); |
153 if (skip_shared_out_of_order_tiles_ && IsSharedOutOfOrderTile(tile)) | 166 if (tile->required_for_activation() != required_for_activation) |
154 continue; | 167 continue; |
155 if (tile->required_for_activation() != required_for_activation) | 168 if (skip_shared_out_of_order_tiles_ && IsSharedOutOfOrderTile(tree_, tile)) |
vmpstr
2015/04/02 17:30:29
Is there a reason why switched these conditions?
USE eero AT chromium.org
2015/04/07 13:17:07
For optimisation. Testing rfa status is much faste
| |
156 continue; | 169 continue; |
157 current_eviction_tile_ = tile; | 170 current_eviction_tile_ = tile; |
158 return true; | 171 return true; |
159 } | 172 } |
160 | 173 |
161 current_eviction_tile_ = nullptr; | 174 current_eviction_tile_ = nullptr; |
162 return false; | 175 return false; |
163 } | 176 } |
164 | 177 |
165 bool TilingSetEvictionQueue::AdvanceToNextPriorityBin() { | 178 bool TilingSetEvictionQueue::AdvanceToNextPriorityBin() { |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
199 PictureLayerTilingSet::BETWEEN_HIGH_AND_LOW_RES; | 212 PictureLayerTilingSet::BETWEEN_HIGH_AND_LOW_RES; |
200 return true; | 213 return true; |
201 case PictureLayerTilingSet::BETWEEN_HIGH_AND_LOW_RES: | 214 case PictureLayerTilingSet::BETWEEN_HIGH_AND_LOW_RES: |
202 current_tiling_range_type_ = PictureLayerTilingSet::LOW_RES; | 215 current_tiling_range_type_ = PictureLayerTilingSet::LOW_RES; |
203 return true; | 216 return true; |
204 case PictureLayerTilingSet::LOW_RES: | 217 case PictureLayerTilingSet::LOW_RES: |
205 current_tiling_range_type_ = PictureLayerTilingSet::HIGH_RES; | 218 current_tiling_range_type_ = PictureLayerTilingSet::HIGH_RES; |
206 return true; | 219 return true; |
207 case PictureLayerTilingSet::HIGH_RES: | 220 case PictureLayerTilingSet::HIGH_RES: |
208 // Process required for activation tiles (unless that has already been | 221 // Process required for activation tiles (unless that has already been |
209 // done for the current priority bin) if there is a tiling with required | 222 // done). Only pending tree NOW tiles may be required for activation. |
210 // for activation tiles and that tiling may have required for activation | 223 if (!processing_required_for_activation_tiles_ && |
211 // tiles having the current priority bin (in the pending tree only NOW | 224 current_priority_bin_ == TilePriority::NOW && tree_ == PENDING_TREE) { |
212 // tiles may be required for activation). | 225 processing_required_for_activation_tiles_ = true; |
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; | 226 return true; |
220 } | 227 } |
221 processing_tiling_with_required_for_activation_tiles_ = false; | 228 processing_required_for_activation_tiles_ = false; |
222 | 229 |
223 if (!AdvanceToNextPriorityBin()) | 230 if (!AdvanceToNextPriorityBin()) |
224 return false; | 231 return false; |
225 | 232 |
226 current_tiling_range_type_ = PictureLayerTilingSet::HIGHER_THAN_HIGH_RES; | 233 current_tiling_range_type_ = PictureLayerTilingSet::HIGHER_THAN_HIGH_RES; |
227 return true; | 234 return true; |
228 } | 235 } |
229 NOTREACHED(); | 236 NOTREACHED(); |
230 return false; | 237 return false; |
231 } | 238 } |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
283 if (AdvanceToNextEvictionTile()) | 290 if (AdvanceToNextEvictionTile()) |
284 return true; | 291 return true; |
285 } | 292 } |
286 break; | 293 break; |
287 } | 294 } |
288 } | 295 } |
289 } | 296 } |
290 | 297 |
291 PictureLayerTilingSet::TilingRange | 298 PictureLayerTilingSet::TilingRange |
292 TilingSetEvictionQueue::CurrentTilingRange() const { | 299 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_); | 300 return tiling_set_->GetTilingRange(current_tiling_range_type_); |
298 } | 301 } |
299 | 302 |
300 size_t TilingSetEvictionQueue::CurrentTilingIndex() const { | 303 size_t TilingSetEvictionQueue::CurrentTilingIndex() const { |
301 DCHECK_NE(current_tiling_index_, CurrentTilingRange().end); | 304 DCHECK_NE(current_tiling_index_, CurrentTilingRange().end); |
302 switch (current_tiling_range_type_) { | 305 switch (current_tiling_range_type_) { |
303 case PictureLayerTilingSet::HIGHER_THAN_HIGH_RES: | 306 case PictureLayerTilingSet::HIGHER_THAN_HIGH_RES: |
304 case PictureLayerTilingSet::LOW_RES: | 307 case PictureLayerTilingSet::LOW_RES: |
305 case PictureLayerTilingSet::HIGH_RES: | 308 case PictureLayerTilingSet::HIGH_RES: |
306 return current_tiling_index_; | 309 return current_tiling_index_; |
307 // Tilings in the following ranges are accessed in reverse order. | 310 // Tilings in the following ranges are accessed in reverse order. |
308 case PictureLayerTilingSet::BETWEEN_HIGH_AND_LOW_RES: | 311 case PictureLayerTilingSet::BETWEEN_HIGH_AND_LOW_RES: |
309 case PictureLayerTilingSet::LOWER_THAN_LOW_RES: { | 312 case PictureLayerTilingSet::LOWER_THAN_LOW_RES: { |
310 PictureLayerTilingSet::TilingRange tiling_range = CurrentTilingRange(); | 313 PictureLayerTilingSet::TilingRange tiling_range = CurrentTilingRange(); |
311 size_t current_tiling_range_offset = | 314 size_t current_tiling_range_offset = |
312 current_tiling_index_ - tiling_range.start; | 315 current_tiling_index_ - tiling_range.start; |
313 return tiling_range.end - 1 - current_tiling_range_offset; | 316 return tiling_range.end - 1 - current_tiling_range_offset; |
314 } | 317 } |
315 } | 318 } |
316 NOTREACHED(); | 319 NOTREACHED(); |
317 return 0; | 320 return 0; |
318 } | 321 } |
319 | 322 |
320 bool TilingSetEvictionQueue::IsSharedOutOfOrderTile(const Tile* tile) const { | |
321 if (!tile->is_shared()) | |
322 return false; | |
323 | |
324 switch (tree_priority_) { | |
325 case SMOOTHNESS_TAKES_PRIORITY: | |
326 DCHECK_EQ(ACTIVE_TREE, tree_); | |
327 return false; | |
328 case NEW_CONTENT_TAKES_PRIORITY: | |
329 DCHECK_EQ(PENDING_TREE, tree_); | |
330 return false; | |
331 case SAME_PRIORITY_FOR_BOTH_TREES: | |
332 break; | |
333 } | |
334 | |
335 // The priority for tile priority of a shared tile will be a combined | |
336 // priority thus return shared tiles from a higher priority tree as | |
337 // it is out of order for a lower priority tree. | |
338 WhichTree twin_tree = tree_ == ACTIVE_TREE ? PENDING_TREE : ACTIVE_TREE; | |
339 const TilePriority& priority = tile->priority(tree_); | |
340 const TilePriority& twin_priority = tile->priority(twin_tree); | |
341 if (priority.priority_bin != twin_priority.priority_bin) | |
342 return priority.priority_bin > twin_priority.priority_bin; | |
343 const bool occluded = tile->is_occluded(tree_); | |
344 const bool twin_occluded = tile->is_occluded(twin_tree); | |
345 if (occluded != twin_occluded) | |
346 return occluded; | |
347 if (priority.distance_to_visible != twin_priority.distance_to_visible) | |
348 return priority.distance_to_visible > twin_priority.distance_to_visible; | |
349 | |
350 // If priorities are the same, it does not matter which tree returns | |
351 // the tile. Let's pick the pending tree. | |
352 return tree_ != PENDING_TREE; | |
353 } | |
354 | |
355 size_t TilingSetEvictionQueue::TilingIndexWithRequiredForActivationTiles() | |
356 const { | |
357 // Returns the tiling index of the tiling with requuired for activation tiles. | |
358 // If no such tiling exists, returns the past-the-last index (num_tilings). | |
359 size_t num_tilings = tiling_set_->num_tilings(); | |
360 | |
361 if (tree_ == PENDING_TREE) { | |
362 // For the pending tree, the tiling with required for activation tiles is | |
363 // the high res one. | |
364 PictureLayerTilingSet::TilingRange high_res_tiling_range = | |
365 tiling_set_->GetTilingRange(PictureLayerTilingSet::HIGH_RES); | |
366 if (high_res_tiling_range.start != high_res_tiling_range.end) | |
367 return high_res_tiling_range.start; | |
368 } else { | |
369 DCHECK_EQ(ACTIVE_TREE, tree_); | |
370 // Only pending tree tiles can be required for activation. They can appear | |
371 // also in the active tree only if they are shared. If we skip all shared | |
372 // tiles, there is no need to find them as they will not be returned. | |
373 if (skip_all_shared_tiles_) | |
374 return num_tilings; | |
375 | |
376 // For the active tree, the tiling with required for activation tiles is | |
377 // the one whose twin tiling is the high res pending tiling. | |
378 for (size_t i = 0; i < num_tilings; ++i) { | |
379 const PictureLayerTiling* tiling = tiling_set_->tiling_at(i); | |
380 const PictureLayerTiling* pending_tiling = | |
381 tiling_set_->client()->GetPendingOrActiveTwinTiling(tiling); | |
382 if (pending_tiling && pending_tiling->resolution() == HIGH_RESOLUTION) | |
383 return i; | |
384 } | |
385 } | |
386 | |
387 return num_tilings; | |
388 } | |
389 | |
390 } // namespace cc | 323 } // namespace cc |
OLD | NEW |