| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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 "cc/resources/raster_tile_priority_queue_all.h" | 5 #include "cc/resources/raster_tile_priority_queue_all.h" |
| 6 | 6 |
| 7 #include "cc/resources/tiling_set_raster_queue_all.h" | 7 #include "cc/resources/tiling_set_raster_queue_all.h" |
| 8 | 8 |
| 9 namespace cc { | 9 namespace cc { |
| 10 | 10 |
| (...skipping 17 matching lines...) Expand all Loading... |
| 28 const TilingSetRasterQueueAll* a_queue = | 28 const TilingSetRasterQueueAll* a_queue = |
| 29 a_tree == ACTIVE_TREE ? a->active_queue() : a->pending_queue(); | 29 a_tree == ACTIVE_TREE ? a->active_queue() : a->pending_queue(); |
| 30 | 30 |
| 31 WhichTree b_tree = b->NextTileIteratorTree(tree_priority_); | 31 WhichTree b_tree = b->NextTileIteratorTree(tree_priority_); |
| 32 const TilingSetRasterQueueAll* b_queue = | 32 const TilingSetRasterQueueAll* b_queue = |
| 33 b_tree == ACTIVE_TREE ? b->active_queue() : b->pending_queue(); | 33 b_tree == ACTIVE_TREE ? b->active_queue() : b->pending_queue(); |
| 34 | 34 |
| 35 const Tile* a_tile = a_queue->Top(); | 35 const Tile* a_tile = a_queue->Top(); |
| 36 const Tile* b_tile = b_queue->Top(); | 36 const Tile* b_tile = b_queue->Top(); |
| 37 | 37 |
| 38 const TilePriority& a_priority = | 38 const TilePriority& a_priority = a_tile->priority(); |
| 39 a_tile->priority_for_tree_priority(tree_priority_); | 39 const TilePriority& b_priority = b_tile->priority(); |
| 40 const TilePriority& b_priority = | |
| 41 b_tile->priority_for_tree_priority(tree_priority_); | |
| 42 bool prioritize_low_res = tree_priority_ == SMOOTHNESS_TAKES_PRIORITY; | 40 bool prioritize_low_res = tree_priority_ == SMOOTHNESS_TAKES_PRIORITY; |
| 43 | 41 |
| 44 // In smoothness mode, we should return pending NOW tiles before active | |
| 45 // EVENTUALLY tiles. So if both priorities here are eventually, we need to | |
| 46 // check the pending priority. | |
| 47 if (prioritize_low_res && | |
| 48 a_priority.priority_bin == TilePriority::EVENTUALLY && | |
| 49 b_priority.priority_bin == TilePriority::EVENTUALLY) { | |
| 50 bool a_is_pending_now = | |
| 51 a_tile->priority(PENDING_TREE).priority_bin == TilePriority::NOW; | |
| 52 bool b_is_pending_now = | |
| 53 b_tile->priority(PENDING_TREE).priority_bin == TilePriority::NOW; | |
| 54 if (a_is_pending_now || b_is_pending_now) | |
| 55 return a_is_pending_now < b_is_pending_now; | |
| 56 | |
| 57 // In case neither one is pending now, fall through. | |
| 58 } | |
| 59 | |
| 60 // If the bin is the same but the resolution is not, then the order will be | 42 // If the bin is the same but the resolution is not, then the order will be |
| 61 // determined by whether we prioritize low res or not. | 43 // determined by whether we prioritize low res or not. |
| 62 // TODO(vmpstr): Remove this when TilePriority is no longer a member of Tile | 44 // TODO(vmpstr): Remove this when TilePriority is no longer a member of Tile |
| 63 // class but instead produced by the iterators. | 45 // class but instead produced by the iterators. |
| 64 if (b_priority.priority_bin == a_priority.priority_bin && | 46 if (b_priority.priority_bin == a_priority.priority_bin && |
| 65 b_priority.resolution != a_priority.resolution) { | 47 b_priority.resolution != a_priority.resolution) { |
| 66 // Non ideal resolution should be sorted lower than other resolutions. | 48 // Non ideal resolution should be sorted lower than other resolutions. |
| 67 if (a_priority.resolution == NON_IDEAL_RESOLUTION) | 49 if (a_priority.resolution == NON_IDEAL_RESOLUTION) |
| 68 return true; | 50 return true; |
| 69 | 51 |
| 70 if (b_priority.resolution == NON_IDEAL_RESOLUTION) | 52 if (b_priority.resolution == NON_IDEAL_RESOLUTION) |
| 71 return false; | 53 return false; |
| 72 | 54 |
| 73 if (prioritize_low_res) | 55 if (prioritize_low_res) |
| 74 return b_priority.resolution == LOW_RESOLUTION; | 56 return b_priority.resolution == LOW_RESOLUTION; |
| 75 return b_priority.resolution == HIGH_RESOLUTION; | 57 return b_priority.resolution == HIGH_RESOLUTION; |
| 76 } | 58 } |
| 77 | 59 |
| 78 return b_priority.IsHigherPriorityThan(a_priority); | 60 return b_priority.IsHigherPriorityThan(a_priority); |
| 79 } | 61 } |
| 80 | 62 |
| 81 private: | 63 private: |
| 82 TreePriority tree_priority_; | 64 TreePriority tree_priority_; |
| 83 }; | 65 }; |
| 84 | 66 |
| 85 WhichTree HigherPriorityTree(TreePriority tree_priority, | 67 WhichTree HigherPriorityTree(TreePriority tree_priority, |
| 86 const TilingSetRasterQueueAll* active_queue, | 68 const TilingSetRasterQueueAll* active_queue, |
| 87 const TilingSetRasterQueueAll* pending_queue, | 69 const TilingSetRasterQueueAll* pending_queue) { |
| 88 const Tile* shared_tile) { | 70 const Tile* active_tile = active_queue->Top(); |
| 89 // In cases when we're given an active tile with a non ideal active resolution | 71 const Tile* pending_tile = pending_queue->Top(); |
| 90 // (or pending tile with non ideal pending resolution), we should return the | 72 |
| 91 // other tree. The reason for this is that tiling set iterators will not | 73 const TilePriority& active_priority = active_tile->priority(); |
| 92 // return non ideal tiles and the only way we get here is if we're skipping | 74 const TilePriority& pending_priority = pending_tile->priority(); |
| 93 // twin tiles, but since it's non-ideal on the twin, we shouldn't skip it. | |
| 94 // TODO(vmpstr): Remove when tiles aren't shared. | |
| 95 const Tile* active_tile = shared_tile ? shared_tile : active_queue->Top(); | |
| 96 const Tile* pending_tile = shared_tile ? shared_tile : pending_queue->Top(); | |
| 97 if (active_tile->priority(ACTIVE_TREE).resolution == NON_IDEAL_RESOLUTION) | |
| 98 return PENDING_TREE; | |
| 99 if (pending_tile->priority(PENDING_TREE).resolution == NON_IDEAL_RESOLUTION) | |
| 100 return ACTIVE_TREE; | |
| 101 | 75 |
| 102 switch (tree_priority) { | 76 switch (tree_priority) { |
| 103 case SMOOTHNESS_TAKES_PRIORITY: { | 77 case SMOOTHNESS_TAKES_PRIORITY: { |
| 104 const TilePriority& active_priority = active_tile->priority(ACTIVE_TREE); | |
| 105 const TilePriority& pending_priority = | |
| 106 pending_tile->priority(PENDING_TREE); | |
| 107 | |
| 108 // If we're down to eventually bin tiles on the active tree, process the | 78 // If we're down to eventually bin tiles on the active tree, process the |
| 109 // pending tree to allow tiles required for activation to be initialized | 79 // pending tree to allow tiles required for activation to be initialized |
| 110 // when memory policy only allows prepaint. | 80 // when memory policy only allows prepaint. |
| 111 if (active_priority.priority_bin == TilePriority::EVENTUALLY && | 81 if (active_priority.priority_bin == TilePriority::EVENTUALLY && |
| 112 pending_priority.priority_bin == TilePriority::NOW) { | 82 pending_priority.priority_bin == TilePriority::NOW) { |
| 113 return PENDING_TREE; | 83 return PENDING_TREE; |
| 114 } | 84 } |
| 115 return ACTIVE_TREE; | 85 return ACTIVE_TREE; |
| 116 } | 86 } |
| 117 case NEW_CONTENT_TAKES_PRIORITY: | 87 case NEW_CONTENT_TAKES_PRIORITY: { |
| 88 // If we're down to soon bin tiles on the pending tree, process the |
| 89 // active tree to allow tiles required for activation to be initialized |
| 90 // when memory policy only allows prepaint. Note that active required for |
| 91 // activation tiles might come from either now or soon bins. |
| 92 if (pending_priority.priority_bin >= TilePriority::SOON && |
| 93 active_priority.priority_bin <= TilePriority::SOON) { |
| 94 return ACTIVE_TREE; |
| 95 } |
| 118 return PENDING_TREE; | 96 return PENDING_TREE; |
| 97 } |
| 119 case SAME_PRIORITY_FOR_BOTH_TREES: { | 98 case SAME_PRIORITY_FOR_BOTH_TREES: { |
| 120 const TilePriority& active_priority = active_tile->priority(ACTIVE_TREE); | |
| 121 const TilePriority& pending_priority = | |
| 122 pending_tile->priority(PENDING_TREE); | |
| 123 | |
| 124 if (active_priority.IsHigherPriorityThan(pending_priority)) | 99 if (active_priority.IsHigherPriorityThan(pending_priority)) |
| 125 return ACTIVE_TREE; | 100 return ACTIVE_TREE; |
| 126 return PENDING_TREE; | 101 return PENDING_TREE; |
| 127 } | 102 } |
| 128 default: | 103 default: |
| 129 NOTREACHED(); | 104 NOTREACHED(); |
| 130 return ACTIVE_TREE; | 105 return ACTIVE_TREE; |
| 131 } | 106 } |
| 132 } | 107 } |
| 133 | 108 |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 183 | 158 |
| 184 RasterTilePriorityQueueAll::PairedTilingSetQueue::PairedTilingSetQueue() { | 159 RasterTilePriorityQueueAll::PairedTilingSetQueue::PairedTilingSetQueue() { |
| 185 } | 160 } |
| 186 | 161 |
| 187 RasterTilePriorityQueueAll::PairedTilingSetQueue::PairedTilingSetQueue( | 162 RasterTilePriorityQueueAll::PairedTilingSetQueue::PairedTilingSetQueue( |
| 188 const PictureLayerImpl::Pair& layer_pair, | 163 const PictureLayerImpl::Pair& layer_pair, |
| 189 TreePriority tree_priority) | 164 TreePriority tree_priority) |
| 190 : active_queue_( | 165 : active_queue_( |
| 191 CreateTilingSetRasterQueue(layer_pair.active, tree_priority)), | 166 CreateTilingSetRasterQueue(layer_pair.active, tree_priority)), |
| 192 pending_queue_( | 167 pending_queue_( |
| 193 CreateTilingSetRasterQueue(layer_pair.pending, tree_priority)), | 168 CreateTilingSetRasterQueue(layer_pair.pending, tree_priority)) { |
| 194 has_both_layers_(layer_pair.active && layer_pair.pending) { | |
| 195 SkipTilesReturnedByTwin(tree_priority); | |
| 196 | |
| 197 TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("cc.debug"), | 169 TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("cc.debug"), |
| 198 "PairedTilingSetQueue::PairedTilingSetQueue", | 170 "PairedTilingSetQueue::PairedTilingSetQueue", |
| 199 TRACE_EVENT_SCOPE_THREAD, "state", StateAsValue()); | 171 TRACE_EVENT_SCOPE_THREAD, "state", StateAsValue()); |
| 200 } | 172 } |
| 201 | 173 |
| 202 RasterTilePriorityQueueAll::PairedTilingSetQueue::~PairedTilingSetQueue() { | 174 RasterTilePriorityQueueAll::PairedTilingSetQueue::~PairedTilingSetQueue() { |
| 203 TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("cc.debug"), | 175 TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("cc.debug"), |
| 204 "PairedTilingSetQueue::~PairedTilingSetQueue", | 176 "PairedTilingSetQueue::~PairedTilingSetQueue", |
| 205 TRACE_EVENT_SCOPE_THREAD, "state", StateAsValue()); | 177 TRACE_EVENT_SCOPE_THREAD, "state", StateAsValue()); |
| 206 } | 178 } |
| (...skipping 21 matching lines...) Expand all Loading... |
| 228 TreePriority tree_priority) { | 200 TreePriority tree_priority) { |
| 229 DCHECK(!IsEmpty()); | 201 DCHECK(!IsEmpty()); |
| 230 | 202 |
| 231 WhichTree next_tree = NextTileIteratorTree(tree_priority); | 203 WhichTree next_tree = NextTileIteratorTree(tree_priority); |
| 232 TilingSetRasterQueueAll* next_queue = | 204 TilingSetRasterQueueAll* next_queue = |
| 233 next_tree == ACTIVE_TREE ? active_queue_.get() : pending_queue_.get(); | 205 next_tree == ACTIVE_TREE ? active_queue_.get() : pending_queue_.get(); |
| 234 DCHECK(next_queue && !next_queue->IsEmpty()); | 206 DCHECK(next_queue && !next_queue->IsEmpty()); |
| 235 DCHECK(returned_tiles_for_debug_.insert(next_queue->Top()).second); | 207 DCHECK(returned_tiles_for_debug_.insert(next_queue->Top()).second); |
| 236 next_queue->Pop(); | 208 next_queue->Pop(); |
| 237 | 209 |
| 238 SkipTilesReturnedByTwin(tree_priority); | |
| 239 | |
| 240 // If no empty, use Top to do DCHECK the next iterator. | 210 // If no empty, use Top to do DCHECK the next iterator. |
| 241 DCHECK(IsEmpty() || Top(tree_priority)); | 211 DCHECK(IsEmpty() || Top(tree_priority)); |
| 242 } | 212 } |
| 243 | 213 |
| 244 void RasterTilePriorityQueueAll::PairedTilingSetQueue::SkipTilesReturnedByTwin( | |
| 245 TreePriority tree_priority) { | |
| 246 if (!has_both_layers_) | |
| 247 return; | |
| 248 | |
| 249 // We have both layers (active and pending) thus we can encounter shared | |
| 250 // tiles twice (from the active iterator and from the pending iterator). | |
| 251 while (!IsEmpty()) { | |
| 252 WhichTree next_tree = NextTileIteratorTree(tree_priority); | |
| 253 TilingSetRasterQueueAll* next_queue = | |
| 254 next_tree == ACTIVE_TREE ? active_queue_.get() : pending_queue_.get(); | |
| 255 DCHECK(next_queue && !next_queue->IsEmpty()); | |
| 256 | |
| 257 // Accept all non-shared tiles. | |
| 258 const Tile* tile = next_queue->Top(); | |
| 259 if (!tile->is_shared()) | |
| 260 break; | |
| 261 | |
| 262 // Accept a shared tile if the next tree is the higher priority one | |
| 263 // corresponding the iterator (active or pending) which usually (but due | |
| 264 // to spiral iterators not always) returns the shared tile first. | |
| 265 if (next_tree == HigherPriorityTree(tree_priority, nullptr, nullptr, tile)) | |
| 266 break; | |
| 267 | |
| 268 next_queue->Pop(); | |
| 269 } | |
| 270 } | |
| 271 | |
| 272 WhichTree | 214 WhichTree |
| 273 RasterTilePriorityQueueAll::PairedTilingSetQueue::NextTileIteratorTree( | 215 RasterTilePriorityQueueAll::PairedTilingSetQueue::NextTileIteratorTree( |
| 274 TreePriority tree_priority) const { | 216 TreePriority tree_priority) const { |
| 275 DCHECK(!IsEmpty()); | 217 DCHECK(!IsEmpty()); |
| 276 | 218 |
| 277 // If we only have one queue with tiles, return it. | 219 // If we only have one queue with tiles, return it. |
| 278 if (!active_queue_ || active_queue_->IsEmpty()) | 220 if (!active_queue_ || active_queue_->IsEmpty()) |
| 279 return PENDING_TREE; | 221 return PENDING_TREE; |
| 280 if (!pending_queue_ || pending_queue_->IsEmpty()) | 222 if (!pending_queue_ || pending_queue_->IsEmpty()) |
| 281 return ACTIVE_TREE; | 223 return ACTIVE_TREE; |
| 282 | 224 |
| 283 // Now both iterators have tiles, so we have to decide based on tree priority. | 225 // Now both iterators have tiles, so we have to decide based on tree priority. |
| 284 return HigherPriorityTree(tree_priority, active_queue_.get(), | 226 return HigherPriorityTree(tree_priority, active_queue_.get(), |
| 285 pending_queue_.get(), nullptr); | 227 pending_queue_.get()); |
| 286 } | 228 } |
| 287 | 229 |
| 288 scoped_refptr<base::trace_event::ConvertableToTraceFormat> | 230 scoped_refptr<base::trace_event::ConvertableToTraceFormat> |
| 289 RasterTilePriorityQueueAll::PairedTilingSetQueue::StateAsValue() const { | 231 RasterTilePriorityQueueAll::PairedTilingSetQueue::StateAsValue() const { |
| 290 scoped_refptr<base::trace_event::TracedValue> state = | 232 scoped_refptr<base::trace_event::TracedValue> state = |
| 291 new base::trace_event::TracedValue(); | 233 new base::trace_event::TracedValue(); |
| 292 | 234 |
| 293 bool active_queue_has_tile = active_queue_ && !active_queue_->IsEmpty(); | 235 bool active_queue_has_tile = active_queue_ && !active_queue_->IsEmpty(); |
| 294 TilePriority::PriorityBin active_priority_bin = TilePriority::EVENTUALLY; | 236 TilePriority::PriorityBin active_priority_bin = TilePriority::EVENTUALLY; |
| 295 TilePriority::PriorityBin pending_priority_bin = TilePriority::EVENTUALLY; | 237 TilePriority::PriorityBin pending_priority_bin = TilePriority::EVENTUALLY; |
| 296 if (active_queue_has_tile) { | 238 if (active_queue_has_tile) { |
| 297 active_priority_bin = | 239 active_priority_bin = active_queue_->Top()->priority().priority_bin; |
| 298 active_queue_->Top()->priority(ACTIVE_TREE).priority_bin; | 240 pending_priority_bin = active_queue_->Top()->priority().priority_bin; |
| 299 pending_priority_bin = | |
| 300 active_queue_->Top()->priority(PENDING_TREE).priority_bin; | |
| 301 } | 241 } |
| 302 | 242 |
| 303 state->BeginDictionary("active_queue"); | 243 state->BeginDictionary("active_queue"); |
| 304 state->SetBoolean("has_tile", active_queue_has_tile); | 244 state->SetBoolean("has_tile", active_queue_has_tile); |
| 305 state->SetInteger("active_priority_bin", active_priority_bin); | 245 state->SetInteger("active_priority_bin", active_priority_bin); |
| 306 state->SetInteger("pending_priority_bin", pending_priority_bin); | 246 state->SetInteger("pending_priority_bin", pending_priority_bin); |
| 307 state->EndDictionary(); | 247 state->EndDictionary(); |
| 308 | 248 |
| 309 bool pending_queue_has_tile = pending_queue_ && !pending_queue_->IsEmpty(); | 249 bool pending_queue_has_tile = pending_queue_ && !pending_queue_->IsEmpty(); |
| 310 active_priority_bin = TilePriority::EVENTUALLY; | 250 active_priority_bin = TilePriority::EVENTUALLY; |
| 311 pending_priority_bin = TilePriority::EVENTUALLY; | 251 pending_priority_bin = TilePriority::EVENTUALLY; |
| 312 if (pending_queue_has_tile) { | 252 if (pending_queue_has_tile) { |
| 313 active_priority_bin = | 253 active_priority_bin = pending_queue_->Top()->priority().priority_bin; |
| 314 pending_queue_->Top()->priority(ACTIVE_TREE).priority_bin; | 254 pending_priority_bin = pending_queue_->Top()->priority().priority_bin; |
| 315 pending_priority_bin = | |
| 316 pending_queue_->Top()->priority(PENDING_TREE).priority_bin; | |
| 317 } | 255 } |
| 318 | 256 |
| 319 state->BeginDictionary("pending_queue"); | 257 state->BeginDictionary("pending_queue"); |
| 320 state->SetBoolean("has_tile", active_queue_has_tile); | 258 state->SetBoolean("has_tile", active_queue_has_tile); |
| 321 state->SetInteger("active_priority_bin", active_priority_bin); | 259 state->SetInteger("active_priority_bin", active_priority_bin); |
| 322 state->SetInteger("pending_priority_bin", pending_priority_bin); | 260 state->SetInteger("pending_priority_bin", pending_priority_bin); |
| 323 state->EndDictionary(); | 261 state->EndDictionary(); |
| 324 return state; | 262 return state; |
| 325 } | 263 } |
| 326 | 264 |
| 327 } // namespace cc | 265 } // namespace cc |
| OLD | NEW |