Supervised user import: Listen for profile creation/deletion
[chromium-blink-merge.git] / cc / resources / raster_tile_priority_queue_all.cc
blobe9b31822bb945668013fec41fd16fe7fc9c3146a
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
3 // found in the LICENSE file.
5 #include "cc/resources/raster_tile_priority_queue_all.h"
7 #include "cc/resources/tiling_set_raster_queue_all.h"
9 namespace cc {
11 namespace {
13 class RasterOrderComparator {
14 public:
15 explicit RasterOrderComparator(TreePriority tree_priority)
16 : tree_priority_(tree_priority) {}
18 bool operator()(
19 const RasterTilePriorityQueueAll::PairedTilingSetQueue* a,
20 const RasterTilePriorityQueueAll::PairedTilingSetQueue* b) const {
21 // Note that in this function, we have to return true if and only if
22 // a is strictly lower priority than b. Note that for the sake of
23 // completeness, empty queue is considered to have lowest priority.
24 if (a->IsEmpty() || b->IsEmpty())
25 return b->IsEmpty() < a->IsEmpty();
27 WhichTree a_tree = a->NextTileIteratorTree(tree_priority_);
28 const TilingSetRasterQueueAll* a_queue =
29 a_tree == ACTIVE_TREE ? a->active_queue() : a->pending_queue();
31 WhichTree b_tree = b->NextTileIteratorTree(tree_priority_);
32 const TilingSetRasterQueueAll* b_queue =
33 b_tree == ACTIVE_TREE ? b->active_queue() : b->pending_queue();
35 const Tile* a_tile = a_queue->Top();
36 const Tile* b_tile = b_queue->Top();
38 const TilePriority& a_priority = a_tile->priority();
39 const TilePriority& b_priority = b_tile->priority();
40 bool prioritize_low_res = tree_priority_ == SMOOTHNESS_TAKES_PRIORITY;
42 // 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.
44 // TODO(vmpstr): Remove this when TilePriority is no longer a member of Tile
45 // class but instead produced by the iterators.
46 if (b_priority.priority_bin == a_priority.priority_bin &&
47 b_priority.resolution != a_priority.resolution) {
48 // Non ideal resolution should be sorted lower than other resolutions.
49 if (a_priority.resolution == NON_IDEAL_RESOLUTION)
50 return true;
52 if (b_priority.resolution == NON_IDEAL_RESOLUTION)
53 return false;
55 if (prioritize_low_res)
56 return b_priority.resolution == LOW_RESOLUTION;
57 return b_priority.resolution == HIGH_RESOLUTION;
60 return b_priority.IsHigherPriorityThan(a_priority);
63 private:
64 TreePriority tree_priority_;
67 WhichTree HigherPriorityTree(TreePriority tree_priority,
68 const TilingSetRasterQueueAll* active_queue,
69 const TilingSetRasterQueueAll* pending_queue) {
70 const Tile* active_tile = active_queue->Top();
71 const Tile* pending_tile = pending_queue->Top();
73 const TilePriority& active_priority = active_tile->priority();
74 const TilePriority& pending_priority = pending_tile->priority();
76 switch (tree_priority) {
77 case SMOOTHNESS_TAKES_PRIORITY: {
78 // 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
80 // when memory policy only allows prepaint.
81 if (active_priority.priority_bin == TilePriority::EVENTUALLY &&
82 pending_priority.priority_bin == TilePriority::NOW) {
83 return PENDING_TREE;
85 return ACTIVE_TREE;
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;
96 return PENDING_TREE;
98 case SAME_PRIORITY_FOR_BOTH_TREES: {
99 if (active_priority.IsHigherPriorityThan(pending_priority))
100 return ACTIVE_TREE;
101 return PENDING_TREE;
103 default:
104 NOTREACHED();
105 return ACTIVE_TREE;
109 scoped_ptr<TilingSetRasterQueueAll> CreateTilingSetRasterQueue(
110 PictureLayerImpl* layer,
111 TreePriority tree_priority) {
112 if (!layer)
113 return nullptr;
114 PictureLayerTilingSet* tiling_set = layer->picture_layer_tiling_set();
115 bool prioritize_low_res = tree_priority == SMOOTHNESS_TAKES_PRIORITY;
116 return make_scoped_ptr(
117 new TilingSetRasterQueueAll(tiling_set, prioritize_low_res));
120 } // namespace
122 RasterTilePriorityQueueAll::RasterTilePriorityQueueAll() {
125 RasterTilePriorityQueueAll::~RasterTilePriorityQueueAll() {
128 void RasterTilePriorityQueueAll::Build(
129 const std::vector<PictureLayerImpl::Pair>& paired_layers,
130 TreePriority tree_priority) {
131 tree_priority_ = tree_priority;
132 for (std::vector<PictureLayerImpl::Pair>::const_iterator it =
133 paired_layers.begin();
134 it != paired_layers.end(); ++it) {
135 paired_queues_.push_back(
136 make_scoped_ptr(new PairedTilingSetQueue(*it, tree_priority_)));
138 paired_queues_.make_heap(RasterOrderComparator(tree_priority_));
141 bool RasterTilePriorityQueueAll::IsEmpty() const {
142 return paired_queues_.empty() || paired_queues_.front()->IsEmpty();
145 Tile* RasterTilePriorityQueueAll::Top() {
146 DCHECK(!IsEmpty());
147 return paired_queues_.front()->Top(tree_priority_);
150 void RasterTilePriorityQueueAll::Pop() {
151 DCHECK(!IsEmpty());
153 paired_queues_.pop_heap(RasterOrderComparator(tree_priority_));
154 PairedTilingSetQueue* paired_queue = paired_queues_.back();
155 paired_queue->Pop(tree_priority_);
156 paired_queues_.push_heap(RasterOrderComparator(tree_priority_));
159 RasterTilePriorityQueueAll::PairedTilingSetQueue::PairedTilingSetQueue() {
162 RasterTilePriorityQueueAll::PairedTilingSetQueue::PairedTilingSetQueue(
163 const PictureLayerImpl::Pair& layer_pair,
164 TreePriority tree_priority)
165 : active_queue_(
166 CreateTilingSetRasterQueue(layer_pair.active, tree_priority)),
167 pending_queue_(
168 CreateTilingSetRasterQueue(layer_pair.pending, tree_priority)) {
169 TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("cc.debug"),
170 "PairedTilingSetQueue::PairedTilingSetQueue",
171 TRACE_EVENT_SCOPE_THREAD, "state", StateAsValue());
174 RasterTilePriorityQueueAll::PairedTilingSetQueue::~PairedTilingSetQueue() {
175 TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("cc.debug"),
176 "PairedTilingSetQueue::~PairedTilingSetQueue",
177 TRACE_EVENT_SCOPE_THREAD, "state", StateAsValue());
180 bool RasterTilePriorityQueueAll::PairedTilingSetQueue::IsEmpty() const {
181 return (!active_queue_ || active_queue_->IsEmpty()) &&
182 (!pending_queue_ || pending_queue_->IsEmpty());
185 Tile* RasterTilePriorityQueueAll::PairedTilingSetQueue::Top(
186 TreePriority tree_priority) {
187 DCHECK(!IsEmpty());
189 WhichTree next_tree = NextTileIteratorTree(tree_priority);
190 TilingSetRasterQueueAll* next_queue =
191 next_tree == ACTIVE_TREE ? active_queue_.get() : pending_queue_.get();
192 DCHECK(next_queue && !next_queue->IsEmpty());
193 Tile* tile = next_queue->Top();
194 DCHECK(returned_tiles_for_debug_.find(tile) ==
195 returned_tiles_for_debug_.end());
196 return tile;
199 void RasterTilePriorityQueueAll::PairedTilingSetQueue::Pop(
200 TreePriority tree_priority) {
201 DCHECK(!IsEmpty());
203 WhichTree next_tree = NextTileIteratorTree(tree_priority);
204 TilingSetRasterQueueAll* next_queue =
205 next_tree == ACTIVE_TREE ? active_queue_.get() : pending_queue_.get();
206 DCHECK(next_queue && !next_queue->IsEmpty());
207 DCHECK(returned_tiles_for_debug_.insert(next_queue->Top()).second);
208 next_queue->Pop();
210 // If no empty, use Top to do DCHECK the next iterator.
211 DCHECK(IsEmpty() || Top(tree_priority));
214 WhichTree
215 RasterTilePriorityQueueAll::PairedTilingSetQueue::NextTileIteratorTree(
216 TreePriority tree_priority) const {
217 DCHECK(!IsEmpty());
219 // If we only have one queue with tiles, return it.
220 if (!active_queue_ || active_queue_->IsEmpty())
221 return PENDING_TREE;
222 if (!pending_queue_ || pending_queue_->IsEmpty())
223 return ACTIVE_TREE;
225 // Now both iterators have tiles, so we have to decide based on tree priority.
226 return HigherPriorityTree(tree_priority, active_queue_.get(),
227 pending_queue_.get());
230 scoped_refptr<base::trace_event::ConvertableToTraceFormat>
231 RasterTilePriorityQueueAll::PairedTilingSetQueue::StateAsValue() const {
232 scoped_refptr<base::trace_event::TracedValue> state =
233 new base::trace_event::TracedValue();
235 bool active_queue_has_tile = active_queue_ && !active_queue_->IsEmpty();
236 TilePriority::PriorityBin active_priority_bin = TilePriority::EVENTUALLY;
237 TilePriority::PriorityBin pending_priority_bin = TilePriority::EVENTUALLY;
238 if (active_queue_has_tile) {
239 active_priority_bin = active_queue_->Top()->priority().priority_bin;
240 pending_priority_bin = active_queue_->Top()->priority().priority_bin;
243 state->BeginDictionary("active_queue");
244 state->SetBoolean("has_tile", active_queue_has_tile);
245 state->SetInteger("active_priority_bin", active_priority_bin);
246 state->SetInteger("pending_priority_bin", pending_priority_bin);
247 state->EndDictionary();
249 bool pending_queue_has_tile = pending_queue_ && !pending_queue_->IsEmpty();
250 active_priority_bin = TilePriority::EVENTUALLY;
251 pending_priority_bin = TilePriority::EVENTUALLY;
252 if (pending_queue_has_tile) {
253 active_priority_bin = pending_queue_->Top()->priority().priority_bin;
254 pending_priority_bin = pending_queue_->Top()->priority().priority_bin;
257 state->BeginDictionary("pending_queue");
258 state->SetBoolean("has_tile", active_queue_has_tile);
259 state->SetInteger("active_priority_bin", active_priority_bin);
260 state->SetInteger("pending_priority_bin", pending_priority_bin);
261 state->EndDictionary();
262 return state;
265 } // namespace cc