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/tiles/raster_tile_priority_queue_all.h"
7 #include "cc/tiles/tiling_set_raster_queue_all.h"
13 class RasterOrderComparator
{
15 explicit RasterOrderComparator(TreePriority tree_priority
)
16 : tree_priority_(tree_priority
) {}
18 bool operator()(const TilingSetRasterQueueAll
* a_queue
,
19 const TilingSetRasterQueueAll
* b_queue
) const {
20 // Note that in this function, we have to return true if and only if
21 // a is strictly lower priority than b.
22 const TilePriority
& a_priority
= a_queue
->Top().priority();
23 const TilePriority
& b_priority
= b_queue
->Top().priority();
24 bool prioritize_low_res
= tree_priority_
== SMOOTHNESS_TAKES_PRIORITY
;
26 // If the bin is the same but the resolution is not, then the order will be
27 // determined by whether we prioritize low res or not.
28 // TODO(vmpstr): Remove this when TilePriority is no longer a member of Tile
29 // class but instead produced by the iterators.
30 if (b_priority
.priority_bin
== a_priority
.priority_bin
&&
31 b_priority
.resolution
!= a_priority
.resolution
) {
32 // Non ideal resolution should be sorted lower than other resolutions.
33 if (a_priority
.resolution
== NON_IDEAL_RESOLUTION
)
36 if (b_priority
.resolution
== NON_IDEAL_RESOLUTION
)
39 if (prioritize_low_res
)
40 return b_priority
.resolution
== LOW_RESOLUTION
;
41 return b_priority
.resolution
== HIGH_RESOLUTION
;
44 return b_priority
.IsHigherPriorityThan(a_priority
);
48 TreePriority tree_priority_
;
51 void CreateTilingSetRasterQueues(
52 const std::vector
<PictureLayerImpl
*>& layers
,
53 TreePriority tree_priority
,
54 ScopedPtrVector
<TilingSetRasterQueueAll
>* queues
) {
55 DCHECK(queues
->empty());
57 for (auto* layer
: layers
) {
58 if (!layer
->HasValidTilePriorities())
61 PictureLayerTilingSet
* tiling_set
= layer
->picture_layer_tiling_set();
62 bool prioritize_low_res
= tree_priority
== SMOOTHNESS_TAKES_PRIORITY
;
63 scoped_ptr
<TilingSetRasterQueueAll
> tiling_set_queue
= make_scoped_ptr(
64 new TilingSetRasterQueueAll(tiling_set
, prioritize_low_res
));
65 // Queues will only contain non empty tiling sets.
66 if (!tiling_set_queue
->IsEmpty())
67 queues
->push_back(tiling_set_queue
.Pass());
69 queues
->make_heap(RasterOrderComparator(tree_priority
));
74 RasterTilePriorityQueueAll::RasterTilePriorityQueueAll() {
77 RasterTilePriorityQueueAll::~RasterTilePriorityQueueAll() {
80 void RasterTilePriorityQueueAll::Build(
81 const std::vector
<PictureLayerImpl
*>& active_layers
,
82 const std::vector
<PictureLayerImpl
*>& pending_layers
,
83 TreePriority tree_priority
) {
84 tree_priority_
= tree_priority
;
86 CreateTilingSetRasterQueues(active_layers
, tree_priority_
, &active_queues_
);
87 CreateTilingSetRasterQueues(pending_layers
, tree_priority_
, &pending_queues_
);
90 bool RasterTilePriorityQueueAll::IsEmpty() const {
91 return active_queues_
.empty() && pending_queues_
.empty();
94 const PrioritizedTile
& RasterTilePriorityQueueAll::Top() const {
96 const ScopedPtrVector
<TilingSetRasterQueueAll
>& next_queues
= GetNextQueues();
97 return next_queues
.front()->Top();
100 void RasterTilePriorityQueueAll::Pop() {
103 ScopedPtrVector
<TilingSetRasterQueueAll
>& next_queues
= GetNextQueues();
104 next_queues
.pop_heap(RasterOrderComparator(tree_priority_
));
105 TilingSetRasterQueueAll
* queue
= next_queues
.back();
108 // Remove empty queues.
109 if (queue
->IsEmpty())
110 next_queues
.pop_back();
112 next_queues
.push_heap(RasterOrderComparator(tree_priority_
));
115 ScopedPtrVector
<TilingSetRasterQueueAll
>&
116 RasterTilePriorityQueueAll::GetNextQueues() {
117 return const_cast<ScopedPtrVector
<TilingSetRasterQueueAll
>&>(
118 static_cast<const RasterTilePriorityQueueAll
*>(this)->GetNextQueues());
121 const ScopedPtrVector
<TilingSetRasterQueueAll
>&
122 RasterTilePriorityQueueAll::GetNextQueues() const {
125 // If we only have one queue with tiles, return it.
126 if (active_queues_
.empty())
127 return pending_queues_
;
128 if (pending_queues_
.empty())
129 return active_queues_
;
131 const PrioritizedTile
& active_tile
= active_queues_
.front()->Top();
132 const PrioritizedTile
& pending_tile
= pending_queues_
.front()->Top();
134 const TilePriority
& active_priority
= active_tile
.priority();
135 const TilePriority
& pending_priority
= pending_tile
.priority();
137 switch (tree_priority_
) {
138 case SMOOTHNESS_TAKES_PRIORITY
: {
139 // If we're down to eventually bin tiles on the active tree and there
140 // is a pending tree, process the entire pending tree to allow tiles
141 // required for activation to be initialized when memory policy only
142 // allows prepaint. The eventually bin tiles on the active tree are
143 // lowest priority since that work is likely to be thrown away when
145 if (active_priority
.priority_bin
== TilePriority::EVENTUALLY
)
146 return pending_queues_
;
147 return active_queues_
;
149 case NEW_CONTENT_TAKES_PRIORITY
: {
150 // If we're down to soon bin tiles on the pending tree, process the
151 // active tree to allow tiles required for activation to be initialized
152 // when memory policy only allows prepaint. Note that active required for
153 // activation tiles might come from either now or soon bins.
154 if (pending_priority
.priority_bin
>= TilePriority::SOON
&&
155 active_priority
.priority_bin
<= TilePriority::SOON
) {
156 return active_queues_
;
158 return pending_queues_
;
160 case SAME_PRIORITY_FOR_BOTH_TREES
: {
161 if (active_priority
.IsHigherPriorityThan(pending_priority
))
162 return active_queues_
;
163 return pending_queues_
;
167 return active_queues_
;