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

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

Issue 1051473002: cc: Switch tiling set eviction queue to consider combined priority. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Clean up Created 5 years, 8 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
« no previous file with comments | « cc/resources/tiling_set_eviction_queue.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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, 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
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 (skip_shared_out_of_order_tiles_ &&
98 IsSharedOutOfOrderTile(tree_, tile))
81 continue; 99 continue;
82 current_tiling_->UpdateTileAndTwinPriority(tile); 100 DCHECK_EQ(tile->required_for_activation(), required_for_activation);
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; 101 current_eviction_tile_ = tile;
88 return true; 102 return true;
89 } 103 }
90 if (processing_soon_border_rect_) { 104 if (processing_soon_border_rect_) {
91 // Advance from soon border rect to skewport rect. 105 // Advance from soon border rect to skewport rect.
92 processing_soon_border_rect_ = false; 106 processing_soon_border_rect_ = false;
93 if (current_tiling_->has_skewport_rect_tiles_) { 107 if (current_tiling_->has_skewport_rect_tiles_) {
94 spiral_iterator_ = TilingData::ReverseSpiralDifferenceIterator( 108 spiral_iterator_ = TilingData::ReverseSpiralDifferenceIterator(
95 &current_tiling_->tiling_data_, 109 &current_tiling_->tiling_data_,
96 current_tiling_->current_skewport_rect_, 110 current_tiling_->current_skewport_rect_,
97 current_tiling_->current_visible_rect_, 111 current_tiling_->current_visible_rect_,
98 current_tiling_->current_visible_rect_); 112 current_tiling_->current_visible_rect_);
99 continue; 113 continue;
100 } 114 }
101 } 115 }
102 break; 116 break;
103 } 117 }
104 118
105 TilePriority::PriorityBin max_tile_priority_bin = 119 TilePriority::PriorityBin max_tile_priority_bin =
106 current_tiling_->client_->GetMaxTilePriorityBin(); 120 current_tiling_->client_->GetMaxTilePriorityBin();
107 while (visible_iterator_) { 121 while (visible_iterator_) {
108 std::pair<int, int> next_index = visible_iterator_.index(); 122 std::pair<int, int> next_index = visible_iterator_.index();
109 Tile* tile = current_tiling_->TileAt(next_index.first, next_index.second); 123 Tile* tile = current_tiling_->TileAt(next_index.first, next_index.second);
110 ++visible_iterator_; 124 ++visible_iterator_;
111 if (!tile || !tile->HasResource()) 125 if (!tile || !tile->HasResource())
112 continue; 126 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 127 // If the max tile priority is not NOW, updated priorities for tiles
116 // returned by the visible iterator will not have NOW (but EVENTUALLY) 128 // returned by the visible iterator will not have NOW (but EVENTUALLY)
117 // priority bin and cannot therefore be required for activation tiles nor 129 // priority bin and cannot therefore be required for activation tiles nor
118 // occluded NOW tiles in the current tiling. 130 // occluded NOW tiles in the current tiling.
119 if (max_tile_priority_bin <= TilePriority::NOW) { 131 if (max_tile_priority_bin <= TilePriority::NOW) {
120 // If the current tiling is a pending tree tiling, required for 132 // If the current tiling is a pending tree tiling, required for
121 // activation tiles can be detected without updating tile priorities. 133 // activation tiles can be detected without updating tile priorities.
122 if (tree_ == PENDING_TREE && 134 if (tree_ == PENDING_TREE &&
123 current_tiling_->IsTileRequiredForActivationIfVisible(tile) != 135 current_tiling_->IsTileRequiredForActivationIfVisible(tile) !=
124 required_for_activation) { 136 required_for_activation) {
125 continue; 137 continue;
126 } 138 }
127 // Unoccluded NOW tiles should be evicted (and thus returned) only after 139 // Unoccluded NOW tiles should be evicted (and thus returned) only after
128 // all occluded NOW tiles. 140 // all occluded NOW tiles.
129 if (!current_tiling_->IsTileOccluded(tile)) { 141 if (!current_tiling_->IsTileOccluded(tile)) {
130 unoccluded_now_tiles_.push_back(tile); 142 unoccluded_now_tiles_.push_back(tile);
131 continue; 143 continue;
132 } 144 }
133 } 145 }
134 current_tiling_->UpdateTileAndTwinPriority(tile); 146 current_tiling_->UpdateTileAndTwinPriority(tile);
135 if (skip_shared_out_of_order_tiles_ && IsSharedOutOfOrderTile(tile)) 147 if (skip_shared_out_of_order_tiles_ && IsSharedOutOfOrderTile(tree_, tile))
136 continue; 148 continue;
137 if (tile->required_for_activation() != required_for_activation) 149 if (tile->required_for_activation() != required_for_activation)
138 continue; 150 continue;
139 current_eviction_tile_ = tile; 151 current_eviction_tile_ = tile;
140 return true; 152 return true;
141 } 153 }
142 154
143 while (!unoccluded_now_tiles_.empty()) { 155 while (!unoccluded_now_tiles_.empty()) {
144 // All (unoccluded) NOW tiles have the same priority bin (NOW) and the same 156 // 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 157 // distance to visible (0.0), so it does not matter that tiles are popped
146 // in reversed (FILO) order. 158 // in reversed (FILO) order.
147 Tile* tile = unoccluded_now_tiles_.back(); 159 Tile* tile = unoccluded_now_tiles_.back();
148 unoccluded_now_tiles_.pop_back(); 160 unoccluded_now_tiles_.pop_back();
149 DCHECK(tile); 161 DCHECK(tile);
150 if (!tile->HasResource()) 162 if (!tile->HasResource())
151 continue; 163 continue;
152 current_tiling_->UpdateTileAndTwinPriority(tile); 164 current_tiling_->UpdateTileAndTwinPriority(tile);
153 if (skip_shared_out_of_order_tiles_ && IsSharedOutOfOrderTile(tile)) 165 if (skip_shared_out_of_order_tiles_ && IsSharedOutOfOrderTile(tree_, tile))
154 continue; 166 continue;
155 if (tile->required_for_activation() != required_for_activation) 167 if (tile->required_for_activation() != required_for_activation)
156 continue; 168 continue;
157 current_eviction_tile_ = tile; 169 current_eviction_tile_ = tile;
158 return true; 170 return true;
159 } 171 }
160 172
161 current_eviction_tile_ = nullptr; 173 current_eviction_tile_ = nullptr;
162 return false; 174 return false;
163 } 175 }
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
199 PictureLayerTilingSet::BETWEEN_HIGH_AND_LOW_RES; 211 PictureLayerTilingSet::BETWEEN_HIGH_AND_LOW_RES;
200 return true; 212 return true;
201 case PictureLayerTilingSet::BETWEEN_HIGH_AND_LOW_RES: 213 case PictureLayerTilingSet::BETWEEN_HIGH_AND_LOW_RES:
202 current_tiling_range_type_ = PictureLayerTilingSet::LOW_RES; 214 current_tiling_range_type_ = PictureLayerTilingSet::LOW_RES;
203 return true; 215 return true;
204 case PictureLayerTilingSet::LOW_RES: 216 case PictureLayerTilingSet::LOW_RES:
205 current_tiling_range_type_ = PictureLayerTilingSet::HIGH_RES; 217 current_tiling_range_type_ = PictureLayerTilingSet::HIGH_RES;
206 return true; 218 return true;
207 case PictureLayerTilingSet::HIGH_RES: 219 case PictureLayerTilingSet::HIGH_RES:
208 // Process required for activation tiles (unless that has already been 220 // Process required for activation tiles (unless that has already been
209 // done for the current priority bin) if there is a tiling with required 221 // done). Only pending tree NOW tiles may be required for activation.
210 // for activation tiles and that tiling may have required for activation 222 if (!processing_required_for_activation_tiles_ &&
211 // tiles having the current priority bin (in the pending tree only NOW 223 current_priority_bin_ == TilePriority::NOW && tree_ == PENDING_TREE) {
212 // tiles may be required for activation). 224 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; 225 return true;
220 } 226 }
221 processing_tiling_with_required_for_activation_tiles_ = false; 227 processing_required_for_activation_tiles_ = false;
222 228
223 if (!AdvanceToNextPriorityBin()) 229 if (!AdvanceToNextPriorityBin())
224 return false; 230 return false;
225 231
226 current_tiling_range_type_ = PictureLayerTilingSet::HIGHER_THAN_HIGH_RES; 232 current_tiling_range_type_ = PictureLayerTilingSet::HIGHER_THAN_HIGH_RES;
227 return true; 233 return true;
228 } 234 }
229 NOTREACHED(); 235 NOTREACHED();
230 return false; 236 return false;
231 } 237 }
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
283 if (AdvanceToNextEvictionTile()) 289 if (AdvanceToNextEvictionTile())
284 return true; 290 return true;
285 } 291 }
286 break; 292 break;
287 } 293 }
288 } 294 }
289 } 295 }
290 296
291 PictureLayerTilingSet::TilingRange 297 PictureLayerTilingSet::TilingRange
292 TilingSetEvictionQueue::CurrentTilingRange() const { 298 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_); 299 return tiling_set_->GetTilingRange(current_tiling_range_type_);
298 } 300 }
299 301
300 size_t TilingSetEvictionQueue::CurrentTilingIndex() const { 302 size_t TilingSetEvictionQueue::CurrentTilingIndex() const {
301 DCHECK_NE(current_tiling_index_, CurrentTilingRange().end); 303 DCHECK_NE(current_tiling_index_, CurrentTilingRange().end);
302 switch (current_tiling_range_type_) { 304 switch (current_tiling_range_type_) {
303 case PictureLayerTilingSet::HIGHER_THAN_HIGH_RES: 305 case PictureLayerTilingSet::HIGHER_THAN_HIGH_RES:
304 case PictureLayerTilingSet::LOW_RES: 306 case PictureLayerTilingSet::LOW_RES:
305 case PictureLayerTilingSet::HIGH_RES: 307 case PictureLayerTilingSet::HIGH_RES:
306 return current_tiling_index_; 308 return current_tiling_index_;
307 // Tilings in the following ranges are accessed in reverse order. 309 // Tilings in the following ranges are accessed in reverse order.
308 case PictureLayerTilingSet::BETWEEN_HIGH_AND_LOW_RES: 310 case PictureLayerTilingSet::BETWEEN_HIGH_AND_LOW_RES:
309 case PictureLayerTilingSet::LOWER_THAN_LOW_RES: { 311 case PictureLayerTilingSet::LOWER_THAN_LOW_RES: {
310 PictureLayerTilingSet::TilingRange tiling_range = CurrentTilingRange(); 312 PictureLayerTilingSet::TilingRange tiling_range = CurrentTilingRange();
311 size_t current_tiling_range_offset = 313 size_t current_tiling_range_offset =
312 current_tiling_index_ - tiling_range.start; 314 current_tiling_index_ - tiling_range.start;
313 return tiling_range.end - 1 - current_tiling_range_offset; 315 return tiling_range.end - 1 - current_tiling_range_offset;
314 } 316 }
315 } 317 }
316 NOTREACHED(); 318 NOTREACHED();
317 return 0; 319 return 0;
318 } 320 }
319 321
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 322 } // namespace cc
OLDNEW
« no previous file with comments | « 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