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 |