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