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 "cc/resources/raster_tile_priority_queue.h" | 5 #include "cc/resources/raster_tile_priority_queue.h" |
6 | 6 |
| 7 #include "cc/resources/tiling_set_raster_queue_all.h" |
| 8 #include "cc/resources/tiling_set_raster_queue_required.h" |
| 9 |
7 namespace cc { | 10 namespace cc { |
8 | 11 |
9 namespace { | 12 namespace { |
10 | 13 |
11 class RasterOrderComparator { | 14 class RasterOrderComparator { |
12 public: | 15 public: |
13 explicit RasterOrderComparator(TreePriority tree_priority) | 16 explicit RasterOrderComparator(TreePriority tree_priority) |
14 : tree_priority_(tree_priority) {} | 17 : tree_priority_(tree_priority) {} |
15 | 18 |
16 bool operator()( | 19 bool operator()( |
17 const RasterTilePriorityQueue::PairedTilingSetQueue* a, | 20 const RasterTilePriorityQueue::PairedTilingSetQueue* a, |
18 const RasterTilePriorityQueue::PairedTilingSetQueue* b) const { | 21 const RasterTilePriorityQueue::PairedTilingSetQueue* b) const { |
19 // Note that in this function, we have to return true if and only if | 22 // Note that in this function, we have to return true if and only if |
20 // a is strictly lower priority than b. Note that for the sake of | 23 // a is strictly lower priority than b. Note that for the sake of |
21 // completeness, empty queue is considered to have lowest priority. | 24 // completeness, empty queue is considered to have lowest priority. |
22 if (a->IsEmpty() || b->IsEmpty()) | 25 if (a->IsEmpty() || b->IsEmpty()) |
23 return b->IsEmpty() < a->IsEmpty(); | 26 return b->IsEmpty() < a->IsEmpty(); |
24 | 27 |
25 WhichTree a_tree = a->NextTileIteratorTree(tree_priority_); | 28 WhichTree a_tree = a->NextTileIteratorTree(tree_priority_); |
26 const auto* a_queue = | 29 const TilingSetRasterQueue* a_queue = |
27 a_tree == ACTIVE_TREE ? a->active_queue.get() : a->pending_queue.get(); | 30 a_tree == ACTIVE_TREE ? a->active_queue() : a->pending_queue(); |
28 | 31 |
29 WhichTree b_tree = b->NextTileIteratorTree(tree_priority_); | 32 WhichTree b_tree = b->NextTileIteratorTree(tree_priority_); |
30 const auto* b_queue = | 33 const TilingSetRasterQueue* b_queue = |
31 b_tree == ACTIVE_TREE ? b->active_queue.get() : b->pending_queue.get(); | 34 b_tree == ACTIVE_TREE ? b->active_queue() : b->pending_queue(); |
32 | 35 |
33 const Tile* a_tile = a_queue->Top(); | 36 const Tile* a_tile = a_queue->Top(); |
34 const Tile* b_tile = b_queue->Top(); | 37 const Tile* b_tile = b_queue->Top(); |
35 | 38 |
36 const TilePriority& a_priority = | 39 const TilePriority& a_priority = |
37 a_tile->priority_for_tree_priority(tree_priority_); | 40 a_tile->priority_for_tree_priority(tree_priority_); |
38 const TilePriority& b_priority = | 41 const TilePriority& b_priority = |
39 b_tile->priority_for_tree_priority(tree_priority_); | 42 b_tile->priority_for_tree_priority(tree_priority_); |
40 bool prioritize_low_res = tree_priority_ == SMOOTHNESS_TAKES_PRIORITY; | 43 bool prioritize_low_res = tree_priority_ == SMOOTHNESS_TAKES_PRIORITY; |
41 | 44 |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
117 if (active_priority.IsHigherPriorityThan(pending_priority)) | 120 if (active_priority.IsHigherPriorityThan(pending_priority)) |
118 return ACTIVE_TREE; | 121 return ACTIVE_TREE; |
119 return PENDING_TREE; | 122 return PENDING_TREE; |
120 } | 123 } |
121 default: | 124 default: |
122 NOTREACHED(); | 125 NOTREACHED(); |
123 return ACTIVE_TREE; | 126 return ACTIVE_TREE; |
124 } | 127 } |
125 } | 128 } |
126 | 129 |
| 130 scoped_ptr<TilingSetRasterQueue> CreateTilingSetRasterQueue( |
| 131 PictureLayerImpl* layer, |
| 132 TreePriority tree_priority, |
| 133 RasterTilePriorityQueue::Type type) { |
| 134 if (!layer) |
| 135 return nullptr; |
| 136 PictureLayerTilingSet* tiling_set = layer->picture_layer_tiling_set(); |
| 137 if (type == RasterTilePriorityQueue::Type::ALL) { |
| 138 bool prioritize_low_res = tree_priority == SMOOTHNESS_TAKES_PRIORITY; |
| 139 return make_scoped_ptr( |
| 140 new TilingSetRasterQueueAll(tiling_set, prioritize_low_res)); |
| 141 } |
| 142 return make_scoped_ptr(new TilingSetRasterQueueRequired(tiling_set, type)); |
| 143 } |
| 144 |
127 } // namespace | 145 } // namespace |
128 | 146 |
129 RasterTilePriorityQueue::RasterTilePriorityQueue() { | 147 RasterTilePriorityQueue::RasterTilePriorityQueue() { |
130 } | 148 } |
131 | 149 |
132 RasterTilePriorityQueue::~RasterTilePriorityQueue() { | 150 RasterTilePriorityQueue::~RasterTilePriorityQueue() { |
133 } | 151 } |
134 | 152 |
135 void RasterTilePriorityQueue::Build( | 153 void RasterTilePriorityQueue::Build( |
136 const std::vector<PictureLayerImpl::Pair>& paired_layers, | 154 const std::vector<PictureLayerImpl::Pair>& paired_layers, |
137 TreePriority tree_priority) { | 155 TreePriority tree_priority, |
| 156 Type type) { |
138 tree_priority_ = tree_priority; | 157 tree_priority_ = tree_priority; |
139 for (std::vector<PictureLayerImpl::Pair>::const_iterator it = | 158 for (std::vector<PictureLayerImpl::Pair>::const_iterator it = |
140 paired_layers.begin(); | 159 paired_layers.begin(); |
141 it != paired_layers.end(); | 160 it != paired_layers.end(); |
142 ++it) { | 161 ++it) { |
143 paired_queues_.push_back( | 162 paired_queues_.push_back( |
144 make_scoped_ptr(new PairedTilingSetQueue(*it, tree_priority_))); | 163 make_scoped_ptr(new PairedTilingSetQueue(*it, tree_priority_, type))); |
145 } | 164 } |
146 paired_queues_.make_heap(RasterOrderComparator(tree_priority_)); | 165 paired_queues_.make_heap(RasterOrderComparator(tree_priority_)); |
147 } | 166 } |
148 | 167 |
149 void RasterTilePriorityQueue::Reset() { | 168 void RasterTilePriorityQueue::Reset() { |
150 paired_queues_.clear(); | 169 paired_queues_.clear(); |
151 } | 170 } |
152 | 171 |
153 bool RasterTilePriorityQueue::IsEmpty() const { | 172 bool RasterTilePriorityQueue::IsEmpty() const { |
154 return paired_queues_.empty() || paired_queues_.front()->IsEmpty(); | 173 return paired_queues_.empty() || paired_queues_.front()->IsEmpty(); |
(...skipping 11 matching lines...) Expand all Loading... |
166 PairedTilingSetQueue* paired_queue = paired_queues_.back(); | 185 PairedTilingSetQueue* paired_queue = paired_queues_.back(); |
167 paired_queue->Pop(tree_priority_); | 186 paired_queue->Pop(tree_priority_); |
168 paired_queues_.push_heap(RasterOrderComparator(tree_priority_)); | 187 paired_queues_.push_heap(RasterOrderComparator(tree_priority_)); |
169 } | 188 } |
170 | 189 |
171 RasterTilePriorityQueue::PairedTilingSetQueue::PairedTilingSetQueue() { | 190 RasterTilePriorityQueue::PairedTilingSetQueue::PairedTilingSetQueue() { |
172 } | 191 } |
173 | 192 |
174 RasterTilePriorityQueue::PairedTilingSetQueue::PairedTilingSetQueue( | 193 RasterTilePriorityQueue::PairedTilingSetQueue::PairedTilingSetQueue( |
175 const PictureLayerImpl::Pair& layer_pair, | 194 const PictureLayerImpl::Pair& layer_pair, |
176 TreePriority tree_priority) | 195 TreePriority tree_priority, |
177 : has_both_layers(layer_pair.active && layer_pair.pending) { | 196 Type type) |
178 if (layer_pair.active) { | 197 : has_both_layers_(false) { |
179 active_queue = layer_pair.active->CreateRasterQueue( | 198 switch (type) { |
180 tree_priority == SMOOTHNESS_TAKES_PRIORITY); | 199 case RasterTilePriorityQueue::Type::ALL: |
| 200 has_both_layers_ = layer_pair.active && layer_pair.pending; |
| 201 active_queue_ = |
| 202 CreateTilingSetRasterQueue(layer_pair.active, tree_priority, type); |
| 203 pending_queue_ = |
| 204 CreateTilingSetRasterQueue(layer_pair.pending, tree_priority, type); |
| 205 break; |
| 206 case RasterTilePriorityQueue::Type::REQUIRED_FOR_ACTIVATION: |
| 207 pending_queue_ = |
| 208 CreateTilingSetRasterQueue(layer_pair.pending, tree_priority, type); |
| 209 break; |
| 210 case RasterTilePriorityQueue::Type::REQUIRED_FOR_DRAW: |
| 211 active_queue_ = |
| 212 CreateTilingSetRasterQueue(layer_pair.active, tree_priority, type); |
| 213 break; |
181 } | 214 } |
| 215 DCHECK_IMPLIES(has_both_layers_, active_queue_ && pending_queue_); |
182 | 216 |
183 if (layer_pair.pending) { | 217 SkipTilesReturnedByTwin(tree_priority); |
184 pending_queue = layer_pair.pending->CreateRasterQueue( | |
185 tree_priority == SMOOTHNESS_TAKES_PRIORITY); | |
186 } | |
187 | |
188 if (has_both_layers) | |
189 SkipTilesReturnedByTwin(tree_priority); | |
190 | 218 |
191 TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("cc.debug"), | 219 TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("cc.debug"), |
192 "PairedTilingSetQueue::PairedTilingSetQueue", | 220 "PairedTilingSetQueue::PairedTilingSetQueue", |
193 TRACE_EVENT_SCOPE_THREAD, "state", StateAsValue()); | 221 TRACE_EVENT_SCOPE_THREAD, "state", StateAsValue()); |
194 } | 222 } |
195 | 223 |
196 RasterTilePriorityQueue::PairedTilingSetQueue::~PairedTilingSetQueue() { | 224 RasterTilePriorityQueue::PairedTilingSetQueue::~PairedTilingSetQueue() { |
197 TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("cc.debug"), | 225 TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("cc.debug"), |
198 "PairedTilingSetQueue::~PairedTilingSetQueue", | 226 "PairedTilingSetQueue::~PairedTilingSetQueue", |
199 TRACE_EVENT_SCOPE_THREAD, "state", StateAsValue()); | 227 TRACE_EVENT_SCOPE_THREAD, "state", StateAsValue()); |
200 } | 228 } |
201 | 229 |
202 bool RasterTilePriorityQueue::PairedTilingSetQueue::IsEmpty() const { | 230 bool RasterTilePriorityQueue::PairedTilingSetQueue::IsEmpty() const { |
203 return (!active_queue || active_queue->IsEmpty()) && | 231 return (!active_queue_ || active_queue_->IsEmpty()) && |
204 (!pending_queue || pending_queue->IsEmpty()); | 232 (!pending_queue_ || pending_queue_->IsEmpty()); |
205 } | 233 } |
206 | 234 |
207 Tile* RasterTilePriorityQueue::PairedTilingSetQueue::Top( | 235 Tile* RasterTilePriorityQueue::PairedTilingSetQueue::Top( |
208 TreePriority tree_priority) { | 236 TreePriority tree_priority) { |
209 DCHECK(!IsEmpty()); | 237 DCHECK(!IsEmpty()); |
210 | 238 |
211 WhichTree next_tree = NextTileIteratorTree(tree_priority); | 239 WhichTree next_tree = NextTileIteratorTree(tree_priority); |
212 TilingSetRasterQueue* next_queue = | 240 TilingSetRasterQueue* next_queue = |
213 next_tree == ACTIVE_TREE ? active_queue.get() : pending_queue.get(); | 241 next_tree == ACTIVE_TREE ? active_queue_.get() : pending_queue_.get(); |
214 DCHECK(next_queue && !next_queue->IsEmpty()); | 242 DCHECK(next_queue && !next_queue->IsEmpty()); |
215 Tile* tile = next_queue->Top(); | 243 Tile* tile = next_queue->Top(); |
216 DCHECK(returned_tiles_for_debug.find(tile) == returned_tiles_for_debug.end()); | 244 DCHECK(returned_tiles_for_debug_.find(tile) == |
| 245 returned_tiles_for_debug_.end()); |
217 return tile; | 246 return tile; |
218 } | 247 } |
219 | 248 |
220 void RasterTilePriorityQueue::PairedTilingSetQueue::Pop( | 249 void RasterTilePriorityQueue::PairedTilingSetQueue::Pop( |
221 TreePriority tree_priority) { | 250 TreePriority tree_priority) { |
222 DCHECK(!IsEmpty()); | 251 DCHECK(!IsEmpty()); |
223 | 252 |
224 WhichTree next_tree = NextTileIteratorTree(tree_priority); | 253 WhichTree next_tree = NextTileIteratorTree(tree_priority); |
225 TilingSetRasterQueue* next_queue = | 254 TilingSetRasterQueue* next_queue = |
226 next_tree == ACTIVE_TREE ? active_queue.get() : pending_queue.get(); | 255 next_tree == ACTIVE_TREE ? active_queue_.get() : pending_queue_.get(); |
227 DCHECK(next_queue && !next_queue->IsEmpty()); | 256 DCHECK(next_queue && !next_queue->IsEmpty()); |
228 DCHECK(returned_tiles_for_debug.insert(next_queue->Top()).second); | 257 DCHECK(returned_tiles_for_debug_.insert(next_queue->Top()).second); |
229 next_queue->Pop(); | 258 next_queue->Pop(); |
230 | 259 |
231 if (has_both_layers) | 260 SkipTilesReturnedByTwin(tree_priority); |
232 SkipTilesReturnedByTwin(tree_priority); | |
233 | 261 |
234 // If no empty, use Top to do DCHECK the next iterator. | 262 // If no empty, use Top to do DCHECK the next iterator. |
235 DCHECK(IsEmpty() || Top(tree_priority)); | 263 DCHECK(IsEmpty() || Top(tree_priority)); |
236 } | 264 } |
237 | 265 |
238 void RasterTilePriorityQueue::PairedTilingSetQueue::SkipTilesReturnedByTwin( | 266 void RasterTilePriorityQueue::PairedTilingSetQueue::SkipTilesReturnedByTwin( |
239 TreePriority tree_priority) { | 267 TreePriority tree_priority) { |
| 268 if (!has_both_layers_) |
| 269 return; |
| 270 |
240 // We have both layers (active and pending) thus we can encounter shared | 271 // We have both layers (active and pending) thus we can encounter shared |
241 // tiles twice (from the active iterator and from the pending iterator). | 272 // tiles twice (from the active iterator and from the pending iterator). |
242 while (!IsEmpty()) { | 273 while (!IsEmpty()) { |
243 WhichTree next_tree = NextTileIteratorTree(tree_priority); | 274 WhichTree next_tree = NextTileIteratorTree(tree_priority); |
244 TilingSetRasterQueue* next_queue = | 275 TilingSetRasterQueue* next_queue = |
245 next_tree == ACTIVE_TREE ? active_queue.get() : pending_queue.get(); | 276 next_tree == ACTIVE_TREE ? active_queue_.get() : pending_queue_.get(); |
246 DCHECK(next_queue && !next_queue->IsEmpty()); | 277 DCHECK(next_queue && !next_queue->IsEmpty()); |
247 | 278 |
248 // Accept all non-shared tiles. | 279 // Accept all non-shared tiles. |
249 const Tile* tile = next_queue->Top(); | 280 const Tile* tile = next_queue->Top(); |
250 if (!tile->is_shared()) | 281 if (!tile->is_shared()) |
251 break; | 282 break; |
252 | 283 |
253 // Accept a shared tile if the next tree is the higher priority one | 284 // Accept a shared tile if the next tree is the higher priority one |
254 // corresponding the iterator (active or pending) which usually (but due | 285 // corresponding the iterator (active or pending) which usually (but due |
255 // to spiral iterators not always) returns the shared tile first. | 286 // to spiral iterators not always) returns the shared tile first. |
256 if (next_tree == HigherPriorityTree(tree_priority, nullptr, nullptr, tile)) | 287 if (next_tree == HigherPriorityTree(tree_priority, nullptr, nullptr, tile)) |
257 break; | 288 break; |
258 | 289 |
259 next_queue->Pop(); | 290 next_queue->Pop(); |
260 } | 291 } |
261 } | 292 } |
262 | 293 |
263 WhichTree RasterTilePriorityQueue::PairedTilingSetQueue::NextTileIteratorTree( | 294 WhichTree RasterTilePriorityQueue::PairedTilingSetQueue::NextTileIteratorTree( |
264 TreePriority tree_priority) const { | 295 TreePriority tree_priority) const { |
265 DCHECK(!IsEmpty()); | 296 DCHECK(!IsEmpty()); |
266 | 297 |
267 // If we only have one queue with tiles, return it. | 298 // If we only have one queue with tiles, return it. |
268 if (!active_queue || active_queue->IsEmpty()) | 299 if (!active_queue_ || active_queue_->IsEmpty()) |
269 return PENDING_TREE; | 300 return PENDING_TREE; |
270 if (!pending_queue || pending_queue->IsEmpty()) | 301 if (!pending_queue_ || pending_queue_->IsEmpty()) |
271 return ACTIVE_TREE; | 302 return ACTIVE_TREE; |
272 | 303 |
273 // Now both iterators have tiles, so we have to decide based on tree priority. | 304 // Now both iterators have tiles, so we have to decide based on tree priority. |
274 return HigherPriorityTree(tree_priority, active_queue.get(), | 305 return HigherPriorityTree(tree_priority, active_queue_.get(), |
275 pending_queue.get(), nullptr); | 306 pending_queue_.get(), nullptr); |
276 } | 307 } |
277 | 308 |
278 scoped_refptr<base::debug::ConvertableToTraceFormat> | 309 scoped_refptr<base::debug::ConvertableToTraceFormat> |
279 RasterTilePriorityQueue::PairedTilingSetQueue::StateAsValue() const { | 310 RasterTilePriorityQueue::PairedTilingSetQueue::StateAsValue() const { |
280 scoped_refptr<base::debug::TracedValue> state = | 311 scoped_refptr<base::debug::TracedValue> state = |
281 new base::debug::TracedValue(); | 312 new base::debug::TracedValue(); |
282 | 313 |
283 bool active_queue_has_tile = active_queue && !active_queue->IsEmpty(); | 314 bool active_queue_has_tile = active_queue_ && !active_queue_->IsEmpty(); |
284 TilePriority::PriorityBin active_priority_bin = TilePriority::EVENTUALLY; | 315 TilePriority::PriorityBin active_priority_bin = TilePriority::EVENTUALLY; |
285 TilePriority::PriorityBin pending_priority_bin = TilePriority::EVENTUALLY; | 316 TilePriority::PriorityBin pending_priority_bin = TilePriority::EVENTUALLY; |
286 if (active_queue_has_tile) { | 317 if (active_queue_has_tile) { |
287 active_priority_bin = | 318 active_priority_bin = |
288 active_queue->Top()->priority(ACTIVE_TREE).priority_bin; | 319 active_queue_->Top()->priority(ACTIVE_TREE).priority_bin; |
289 pending_priority_bin = | 320 pending_priority_bin = |
290 active_queue->Top()->priority(PENDING_TREE).priority_bin; | 321 active_queue_->Top()->priority(PENDING_TREE).priority_bin; |
291 } | 322 } |
292 | 323 |
293 state->BeginDictionary("active_queue"); | 324 state->BeginDictionary("active_queue"); |
294 state->SetBoolean("has_tile", active_queue_has_tile); | 325 state->SetBoolean("has_tile", active_queue_has_tile); |
295 state->SetInteger("active_priority_bin", active_priority_bin); | 326 state->SetInteger("active_priority_bin", active_priority_bin); |
296 state->SetInteger("pending_priority_bin", pending_priority_bin); | 327 state->SetInteger("pending_priority_bin", pending_priority_bin); |
297 state->EndDictionary(); | 328 state->EndDictionary(); |
298 | 329 |
299 bool pending_queue_has_tile = pending_queue && !pending_queue->IsEmpty(); | 330 bool pending_queue_has_tile = pending_queue_ && !pending_queue_->IsEmpty(); |
300 active_priority_bin = TilePriority::EVENTUALLY; | 331 active_priority_bin = TilePriority::EVENTUALLY; |
301 pending_priority_bin = TilePriority::EVENTUALLY; | 332 pending_priority_bin = TilePriority::EVENTUALLY; |
302 if (pending_queue_has_tile) { | 333 if (pending_queue_has_tile) { |
303 active_priority_bin = | 334 active_priority_bin = |
304 pending_queue->Top()->priority(ACTIVE_TREE).priority_bin; | 335 pending_queue_->Top()->priority(ACTIVE_TREE).priority_bin; |
305 pending_priority_bin = | 336 pending_priority_bin = |
306 pending_queue->Top()->priority(PENDING_TREE).priority_bin; | 337 pending_queue_->Top()->priority(PENDING_TREE).priority_bin; |
307 } | 338 } |
308 | 339 |
309 state->BeginDictionary("pending_queue"); | 340 state->BeginDictionary("pending_queue"); |
310 state->SetBoolean("has_tile", active_queue_has_tile); | 341 state->SetBoolean("has_tile", active_queue_has_tile); |
311 state->SetInteger("active_priority_bin", active_priority_bin); | 342 state->SetInteger("active_priority_bin", active_priority_bin); |
312 state->SetInteger("pending_priority_bin", pending_priority_bin); | 343 state->SetInteger("pending_priority_bin", pending_priority_bin); |
313 state->EndDictionary(); | 344 state->EndDictionary(); |
314 return state; | 345 return state; |
315 } | 346 } |
316 | 347 |
317 } // namespace cc | 348 } // namespace cc |
OLD | NEW |