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

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

Issue 885443002: Roll Chrome into Mojo. (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: Rebase to ToT mojo Created 5 years, 10 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
OLDNEW
1 // Copyright 2014 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.h" 5 #include "cc/resources/raster_tile_priority_queue.h"
6 6
7 #include "cc/resources/tiling_set_raster_queue_all.h" 7 #include "cc/resources/raster_tile_priority_queue_all.h"
8 #include "cc/resources/tiling_set_raster_queue_required.h" 8 #include "cc/resources/raster_tile_priority_queue_required.h"
9 9
10 namespace cc { 10 namespace cc {
11 11
12 namespace { 12 // static
13 13 scoped_ptr<RasterTilePriorityQueue> RasterTilePriorityQueue::Create(
14 class RasterOrderComparator {
15 public:
16 explicit RasterOrderComparator(TreePriority tree_priority)
17 : tree_priority_(tree_priority) {}
18
19 bool operator()(
20 const RasterTilePriorityQueue::PairedTilingSetQueue* a,
21 const RasterTilePriorityQueue::PairedTilingSetQueue* b) const {
22 // Note that in this function, we have to return true if and only if
23 // a is strictly lower priority than b. Note that for the sake of
24 // completeness, empty queue is considered to have lowest priority.
25 if (a->IsEmpty() || b->IsEmpty())
26 return b->IsEmpty() < a->IsEmpty();
27
28 WhichTree a_tree = a->NextTileIteratorTree(tree_priority_);
29 const TilingSetRasterQueue* a_queue =
30 a_tree == ACTIVE_TREE ? a->active_queue() : a->pending_queue();
31
32 WhichTree b_tree = b->NextTileIteratorTree(tree_priority_);
33 const TilingSetRasterQueue* b_queue =
34 b_tree == ACTIVE_TREE ? b->active_queue() : b->pending_queue();
35
36 const Tile* a_tile = a_queue->Top();
37 const Tile* b_tile = b_queue->Top();
38
39 const TilePriority& a_priority =
40 a_tile->priority_for_tree_priority(tree_priority_);
41 const TilePriority& b_priority =
42 b_tile->priority_for_tree_priority(tree_priority_);
43 bool prioritize_low_res = tree_priority_ == SMOOTHNESS_TAKES_PRIORITY;
44
45 // In smoothness mode, we should return pending NOW tiles before active
46 // EVENTUALLY tiles. So if both priorities here are eventually, we need to
47 // check the pending priority.
48 if (prioritize_low_res &&
49 a_priority.priority_bin == TilePriority::EVENTUALLY &&
50 b_priority.priority_bin == TilePriority::EVENTUALLY) {
51 bool a_is_pending_now =
52 a_tile->priority(PENDING_TREE).priority_bin == TilePriority::NOW;
53 bool b_is_pending_now =
54 b_tile->priority(PENDING_TREE).priority_bin == TilePriority::NOW;
55 if (a_is_pending_now || b_is_pending_now)
56 return a_is_pending_now < b_is_pending_now;
57
58 // In case neither one is pending now, fall through.
59 }
60
61 // If the bin is the same but the resolution is not, then the order will be
62 // determined by whether we prioritize low res or not.
63 // TODO(vmpstr): Remove this when TilePriority is no longer a member of Tile
64 // class but instead produced by the iterators.
65 if (b_priority.priority_bin == a_priority.priority_bin &&
66 b_priority.resolution != a_priority.resolution) {
67 // Non ideal resolution should be sorted lower than other resolutions.
68 if (a_priority.resolution == NON_IDEAL_RESOLUTION)
69 return true;
70
71 if (b_priority.resolution == NON_IDEAL_RESOLUTION)
72 return false;
73
74 if (prioritize_low_res)
75 return b_priority.resolution == LOW_RESOLUTION;
76 return b_priority.resolution == HIGH_RESOLUTION;
77 }
78
79 return b_priority.IsHigherPriorityThan(a_priority);
80 }
81
82 private:
83 TreePriority tree_priority_;
84 };
85
86 WhichTree HigherPriorityTree(TreePriority tree_priority,
87 const TilingSetRasterQueue* active_queue,
88 const TilingSetRasterQueue* pending_queue,
89 const Tile* shared_tile) {
90 switch (tree_priority) {
91 case SMOOTHNESS_TAKES_PRIORITY: {
92 const Tile* active_tile = shared_tile ? shared_tile : active_queue->Top();
93 const Tile* pending_tile =
94 shared_tile ? shared_tile : pending_queue->Top();
95
96 const TilePriority& active_priority = active_tile->priority(ACTIVE_TREE);
97 const TilePriority& pending_priority =
98 pending_tile->priority(PENDING_TREE);
99
100 // If we're down to eventually bin tiles on the active tree, process the
101 // pending tree to allow tiles required for activation to be initialized
102 // when memory policy only allows prepaint.
103 if (active_priority.priority_bin == TilePriority::EVENTUALLY &&
104 pending_priority.priority_bin == TilePriority::NOW) {
105 return PENDING_TREE;
106 }
107 return ACTIVE_TREE;
108 }
109 case NEW_CONTENT_TAKES_PRIORITY:
110 return PENDING_TREE;
111 case SAME_PRIORITY_FOR_BOTH_TREES: {
112 const Tile* active_tile = shared_tile ? shared_tile : active_queue->Top();
113 const Tile* pending_tile =
114 shared_tile ? shared_tile : pending_queue->Top();
115
116 const TilePriority& active_priority = active_tile->priority(ACTIVE_TREE);
117 const TilePriority& pending_priority =
118 pending_tile->priority(PENDING_TREE);
119
120 if (active_priority.IsHigherPriorityThan(pending_priority))
121 return ACTIVE_TREE;
122 return PENDING_TREE;
123 }
124 default:
125 NOTREACHED();
126 return ACTIVE_TREE;
127 }
128 }
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
145 } // namespace
146
147 RasterTilePriorityQueue::RasterTilePriorityQueue() {
148 }
149
150 RasterTilePriorityQueue::~RasterTilePriorityQueue() {
151 }
152
153 void RasterTilePriorityQueue::Build(
154 const std::vector<PictureLayerImpl::Pair>& paired_layers, 14 const std::vector<PictureLayerImpl::Pair>& paired_layers,
155 TreePriority tree_priority, 15 TreePriority tree_priority,
156 Type type) { 16 Type type) {
157 tree_priority_ = tree_priority; 17 switch (type) {
158 for (std::vector<PictureLayerImpl::Pair>::const_iterator it = 18 case Type::ALL: {
159 paired_layers.begin(); 19 scoped_ptr<RasterTilePriorityQueueAll> queue(
160 it != paired_layers.end(); 20 new RasterTilePriorityQueueAll);
161 ++it) { 21 queue->Build(paired_layers, tree_priority);
162 paired_queues_.push_back( 22 return queue.Pass();
163 make_scoped_ptr(new PairedTilingSetQueue(*it, tree_priority_, type))); 23 }
24 case Type::REQUIRED_FOR_ACTIVATION:
25 case Type::REQUIRED_FOR_DRAW: {
26 scoped_ptr<RasterTilePriorityQueueRequired> queue(
27 new RasterTilePriorityQueueRequired);
28 queue->Build(paired_layers, type);
29 return queue.Pass();
30 }
164 } 31 }
165 paired_queues_.make_heap(RasterOrderComparator(tree_priority_)); 32 NOTREACHED();
166 } 33 return nullptr;
167
168 void RasterTilePriorityQueue::Reset() {
169 paired_queues_.clear();
170 }
171
172 bool RasterTilePriorityQueue::IsEmpty() const {
173 return paired_queues_.empty() || paired_queues_.front()->IsEmpty();
174 }
175
176 Tile* RasterTilePriorityQueue::Top() {
177 DCHECK(!IsEmpty());
178 return paired_queues_.front()->Top(tree_priority_);
179 }
180
181 void RasterTilePriorityQueue::Pop() {
182 DCHECK(!IsEmpty());
183
184 paired_queues_.pop_heap(RasterOrderComparator(tree_priority_));
185 PairedTilingSetQueue* paired_queue = paired_queues_.back();
186 paired_queue->Pop(tree_priority_);
187 paired_queues_.push_heap(RasterOrderComparator(tree_priority_));
188 }
189
190 RasterTilePriorityQueue::PairedTilingSetQueue::PairedTilingSetQueue() {
191 }
192
193 RasterTilePriorityQueue::PairedTilingSetQueue::PairedTilingSetQueue(
194 const PictureLayerImpl::Pair& layer_pair,
195 TreePriority tree_priority,
196 Type type)
197 : has_both_layers_(false) {
198 switch (type) {
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;
214 }
215 DCHECK_IMPLIES(has_both_layers_, active_queue_ && pending_queue_);
216
217 SkipTilesReturnedByTwin(tree_priority);
218
219 TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("cc.debug"),
220 "PairedTilingSetQueue::PairedTilingSetQueue",
221 TRACE_EVENT_SCOPE_THREAD, "state", StateAsValue());
222 }
223
224 RasterTilePriorityQueue::PairedTilingSetQueue::~PairedTilingSetQueue() {
225 TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("cc.debug"),
226 "PairedTilingSetQueue::~PairedTilingSetQueue",
227 TRACE_EVENT_SCOPE_THREAD, "state", StateAsValue());
228 }
229
230 bool RasterTilePriorityQueue::PairedTilingSetQueue::IsEmpty() const {
231 return (!active_queue_ || active_queue_->IsEmpty()) &&
232 (!pending_queue_ || pending_queue_->IsEmpty());
233 }
234
235 Tile* RasterTilePriorityQueue::PairedTilingSetQueue::Top(
236 TreePriority tree_priority) {
237 DCHECK(!IsEmpty());
238
239 WhichTree next_tree = NextTileIteratorTree(tree_priority);
240 TilingSetRasterQueue* next_queue =
241 next_tree == ACTIVE_TREE ? active_queue_.get() : pending_queue_.get();
242 DCHECK(next_queue && !next_queue->IsEmpty());
243 Tile* tile = next_queue->Top();
244 DCHECK(returned_tiles_for_debug_.find(tile) ==
245 returned_tiles_for_debug_.end());
246 return tile;
247 }
248
249 void RasterTilePriorityQueue::PairedTilingSetQueue::Pop(
250 TreePriority tree_priority) {
251 DCHECK(!IsEmpty());
252
253 WhichTree next_tree = NextTileIteratorTree(tree_priority);
254 TilingSetRasterQueue* next_queue =
255 next_tree == ACTIVE_TREE ? active_queue_.get() : pending_queue_.get();
256 DCHECK(next_queue && !next_queue->IsEmpty());
257 DCHECK(returned_tiles_for_debug_.insert(next_queue->Top()).second);
258 next_queue->Pop();
259
260 SkipTilesReturnedByTwin(tree_priority);
261
262 // If no empty, use Top to do DCHECK the next iterator.
263 DCHECK(IsEmpty() || Top(tree_priority));
264 }
265
266 void RasterTilePriorityQueue::PairedTilingSetQueue::SkipTilesReturnedByTwin(
267 TreePriority tree_priority) {
268 if (!has_both_layers_)
269 return;
270
271 // We have both layers (active and pending) thus we can encounter shared
272 // tiles twice (from the active iterator and from the pending iterator).
273 while (!IsEmpty()) {
274 WhichTree next_tree = NextTileIteratorTree(tree_priority);
275 TilingSetRasterQueue* next_queue =
276 next_tree == ACTIVE_TREE ? active_queue_.get() : pending_queue_.get();
277 DCHECK(next_queue && !next_queue->IsEmpty());
278
279 // Accept all non-shared tiles.
280 const Tile* tile = next_queue->Top();
281 if (!tile->is_shared())
282 break;
283
284 // Accept a shared tile if the next tree is the higher priority one
285 // corresponding the iterator (active or pending) which usually (but due
286 // to spiral iterators not always) returns the shared tile first.
287 if (next_tree == HigherPriorityTree(tree_priority, nullptr, nullptr, tile))
288 break;
289
290 next_queue->Pop();
291 }
292 }
293
294 WhichTree RasterTilePriorityQueue::PairedTilingSetQueue::NextTileIteratorTree(
295 TreePriority tree_priority) const {
296 DCHECK(!IsEmpty());
297
298 // If we only have one queue with tiles, return it.
299 if (!active_queue_ || active_queue_->IsEmpty())
300 return PENDING_TREE;
301 if (!pending_queue_ || pending_queue_->IsEmpty())
302 return ACTIVE_TREE;
303
304 // Now both iterators have tiles, so we have to decide based on tree priority.
305 return HigherPriorityTree(tree_priority, active_queue_.get(),
306 pending_queue_.get(), nullptr);
307 }
308
309 scoped_refptr<base::debug::ConvertableToTraceFormat>
310 RasterTilePriorityQueue::PairedTilingSetQueue::StateAsValue() const {
311 scoped_refptr<base::debug::TracedValue> state =
312 new base::debug::TracedValue();
313
314 bool active_queue_has_tile = active_queue_ && !active_queue_->IsEmpty();
315 TilePriority::PriorityBin active_priority_bin = TilePriority::EVENTUALLY;
316 TilePriority::PriorityBin pending_priority_bin = TilePriority::EVENTUALLY;
317 if (active_queue_has_tile) {
318 active_priority_bin =
319 active_queue_->Top()->priority(ACTIVE_TREE).priority_bin;
320 pending_priority_bin =
321 active_queue_->Top()->priority(PENDING_TREE).priority_bin;
322 }
323
324 state->BeginDictionary("active_queue");
325 state->SetBoolean("has_tile", active_queue_has_tile);
326 state->SetInteger("active_priority_bin", active_priority_bin);
327 state->SetInteger("pending_priority_bin", pending_priority_bin);
328 state->EndDictionary();
329
330 bool pending_queue_has_tile = pending_queue_ && !pending_queue_->IsEmpty();
331 active_priority_bin = TilePriority::EVENTUALLY;
332 pending_priority_bin = TilePriority::EVENTUALLY;
333 if (pending_queue_has_tile) {
334 active_priority_bin =
335 pending_queue_->Top()->priority(ACTIVE_TREE).priority_bin;
336 pending_priority_bin =
337 pending_queue_->Top()->priority(PENDING_TREE).priority_bin;
338 }
339
340 state->BeginDictionary("pending_queue");
341 state->SetBoolean("has_tile", active_queue_has_tile);
342 state->SetInteger("active_priority_bin", active_priority_bin);
343 state->SetInteger("pending_priority_bin", pending_priority_bin);
344 state->EndDictionary();
345 return state;
346 } 34 }
347 35
348 } // namespace cc 36 } // namespace cc
OLDNEW
« no previous file with comments | « cc/resources/raster_tile_priority_queue.h ('k') | cc/resources/raster_tile_priority_queue_all.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698