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/eviction_tile_priority_queue.h" | 5 #include "cc/resources/eviction_tile_priority_queue.h" |
6 | 6 |
7 namespace cc { | 7 namespace cc { |
8 | 8 |
9 namespace { | 9 namespace { |
10 | 10 |
11 class EvictionOrderComparator { | 11 class EvictionOrderComparator { |
12 public: | 12 public: |
13 explicit EvictionOrderComparator(TreePriority tree_priority) | 13 explicit EvictionOrderComparator(TreePriority tree_priority) |
14 : tree_priority_(tree_priority) {} | 14 : tree_priority_(tree_priority) {} |
15 | 15 |
16 bool operator()( | 16 bool operator()( |
17 const EvictionTilePriorityQueue::PairedTilingSetQueue* a, | 17 const EvictionTilePriorityQueue::PairedTilingSetQueue* a, |
18 const EvictionTilePriorityQueue::PairedTilingSetQueue* b) const { | 18 const EvictionTilePriorityQueue::PairedTilingSetQueue* b) const { |
19 // Note that in this function, we have to return true if and only if | 19 // Note that in this function, we have to return true if and only if |
20 // b is strictly lower priority than a. Note that for the sake of | 20 // b is strictly lower priority than a. Note that for the sake of |
21 // completeness, empty queue is considered to have lowest priority. | 21 // completeness, empty queue is considered to have lowest priority. |
22 if (a->IsEmpty() || b->IsEmpty()) | 22 if (a->IsEmpty() || b->IsEmpty()) |
23 return b->IsEmpty() < a->IsEmpty(); | 23 return b->IsEmpty() < a->IsEmpty(); |
24 | 24 |
25 WhichTree a_tree = a->NextTileIteratorTree(tree_priority_); | 25 WhichTree a_tree = a->NextTileIteratorTree(); |
26 const TilingSetEvictionQueue* a_queue = | 26 const TilingSetEvictionQueue* a_queue = |
27 a_tree == ACTIVE_TREE ? a->active_queue.get() : a->pending_queue.get(); | 27 a_tree == ACTIVE_TREE ? a->active_queue.get() : a->pending_queue.get(); |
28 | 28 |
29 WhichTree b_tree = b->NextTileIteratorTree(tree_priority_); | 29 WhichTree b_tree = b->NextTileIteratorTree(); |
30 const TilingSetEvictionQueue* b_queue = | 30 const TilingSetEvictionQueue* b_queue = |
31 b_tree == ACTIVE_TREE ? b->active_queue.get() : b->pending_queue.get(); | 31 b_tree == ACTIVE_TREE ? b->active_queue.get() : b->pending_queue.get(); |
32 | 32 |
33 const Tile* a_tile = a_queue->Top(); | 33 const Tile* a_tile = a_queue->Top(); |
34 const Tile* b_tile = b_queue->Top(); | 34 const Tile* b_tile = b_queue->Top(); |
35 | 35 |
36 const TilePriority& a_priority = | 36 const TilePriority& a_priority = a_tile->combined_priority(); |
37 a_tile->priority_for_tree_priority(tree_priority_); | 37 const TilePriority& b_priority = b_tile->combined_priority(); |
38 const TilePriority& b_priority = | |
39 b_tile->priority_for_tree_priority(tree_priority_); | |
40 bool prioritize_low_res = tree_priority_ == SMOOTHNESS_TAKES_PRIORITY; | 38 bool prioritize_low_res = tree_priority_ == SMOOTHNESS_TAKES_PRIORITY; |
41 | 39 |
42 // If the priority bin differs, b is lower priority if it has the higher | 40 // If the priority bin differs, b is lower priority if it has the higher |
43 // priority bin. | 41 // priority bin. |
44 if (a_priority.priority_bin != b_priority.priority_bin) | 42 if (a_priority.priority_bin != b_priority.priority_bin) |
45 return b_priority.priority_bin > a_priority.priority_bin; | 43 return b_priority.priority_bin > a_priority.priority_bin; |
46 | 44 |
47 // Otherwise if the resolution differs, then the order will be determined by | 45 // Otherwise if the resolution differs, then the order will be determined by |
48 // whether we prioritize low res or not. | 46 // whether we prioritize low res or not. |
49 // TODO(vmpstr): Remove this when TilePriority is no longer a member of Tile | 47 // TODO(vmpstr): Remove this when TilePriority is no longer a member of Tile |
50 // class but instead produced by the iterators. | 48 // class but instead produced by the iterators. |
51 if (b_priority.resolution != a_priority.resolution) { | 49 if (b_priority.resolution != a_priority.resolution) { |
52 // Non ideal resolution should be sorted higher than other resolutions. | 50 // Non ideal resolution should be sorted higher than other resolutions. |
53 if (a_priority.resolution == NON_IDEAL_RESOLUTION) | 51 if (a_priority.resolution == NON_IDEAL_RESOLUTION) |
54 return false; | 52 return false; |
55 | 53 |
56 if (b_priority.resolution == NON_IDEAL_RESOLUTION) | 54 if (b_priority.resolution == NON_IDEAL_RESOLUTION) |
57 return true; | 55 return true; |
58 | 56 |
59 if (prioritize_low_res) | 57 if (prioritize_low_res) |
60 return a_priority.resolution == LOW_RESOLUTION; | 58 return a_priority.resolution == LOW_RESOLUTION; |
61 return a_priority.resolution == HIGH_RESOLUTION; | 59 return a_priority.resolution == HIGH_RESOLUTION; |
62 } | 60 } |
63 | 61 |
64 // Otherwise if the occlusion differs, b is lower priority if it is | 62 // Otherwise if the occlusion differs, b is lower priority if it is |
65 // occluded. | 63 // occluded. |
66 bool a_is_occluded = a_tile->is_occluded_for_tree_priority(tree_priority_); | 64 bool a_is_occluded = a_tile->is_occluded_combined(); |
67 bool b_is_occluded = b_tile->is_occluded_for_tree_priority(tree_priority_); | 65 bool b_is_occluded = b_tile->is_occluded_combined(); |
68 if (a_is_occluded != b_is_occluded) | 66 if (a_is_occluded != b_is_occluded) |
69 return b_is_occluded; | 67 return b_is_occluded; |
70 | 68 |
71 // b is lower priorty if it is farther from visible. | 69 // b is lower priorty if it is farther from visible. |
72 return b_priority.distance_to_visible > a_priority.distance_to_visible; | 70 return b_priority.distance_to_visible > a_priority.distance_to_visible; |
73 } | 71 } |
74 | 72 |
75 private: | 73 private: |
76 TreePriority tree_priority_; | 74 TreePriority tree_priority_; |
77 }; | 75 }; |
(...skipping 21 matching lines...) Expand all Loading... |
99 | 97 |
100 paired_queues_.make_heap(EvictionOrderComparator(tree_priority_)); | 98 paired_queues_.make_heap(EvictionOrderComparator(tree_priority_)); |
101 } | 99 } |
102 | 100 |
103 bool EvictionTilePriorityQueue::IsEmpty() const { | 101 bool EvictionTilePriorityQueue::IsEmpty() const { |
104 return paired_queues_.empty() || paired_queues_.front()->IsEmpty(); | 102 return paired_queues_.empty() || paired_queues_.front()->IsEmpty(); |
105 } | 103 } |
106 | 104 |
107 Tile* EvictionTilePriorityQueue::Top() { | 105 Tile* EvictionTilePriorityQueue::Top() { |
108 DCHECK(!IsEmpty()); | 106 DCHECK(!IsEmpty()); |
109 return paired_queues_.front()->Top(tree_priority_); | 107 return paired_queues_.front()->Top(); |
110 } | 108 } |
111 | 109 |
112 void EvictionTilePriorityQueue::Pop() { | 110 void EvictionTilePriorityQueue::Pop() { |
113 DCHECK(!IsEmpty()); | 111 DCHECK(!IsEmpty()); |
114 | 112 |
115 paired_queues_.pop_heap(EvictionOrderComparator(tree_priority_)); | 113 paired_queues_.pop_heap(EvictionOrderComparator(tree_priority_)); |
116 PairedTilingSetQueue* paired_queue = paired_queues_.back(); | 114 PairedTilingSetQueue* paired_queue = paired_queues_.back(); |
117 paired_queue->Pop(tree_priority_); | 115 paired_queue->Pop(); |
118 paired_queues_.push_heap(EvictionOrderComparator(tree_priority_)); | 116 paired_queues_.push_heap(EvictionOrderComparator(tree_priority_)); |
119 } | 117 } |
120 | 118 |
121 EvictionTilePriorityQueue::PairedTilingSetQueue::PairedTilingSetQueue() { | 119 EvictionTilePriorityQueue::PairedTilingSetQueue::PairedTilingSetQueue() { |
122 } | 120 } |
123 | 121 |
124 EvictionTilePriorityQueue::PairedTilingSetQueue::PairedTilingSetQueue( | 122 EvictionTilePriorityQueue::PairedTilingSetQueue::PairedTilingSetQueue( |
125 const PictureLayerImpl::Pair& layer_pair, | 123 const PictureLayerImpl::Pair& layer_pair, |
126 TreePriority tree_priority) { | 124 TreePriority tree_priority) { |
127 bool skip_shared_out_of_order_tiles = layer_pair.active && layer_pair.pending; | 125 bool skip_shared_out_of_order_tiles = layer_pair.active && layer_pair.pending; |
(...skipping 10 matching lines...) Expand all Loading... |
138 } | 136 } |
139 | 137 |
140 EvictionTilePriorityQueue::PairedTilingSetQueue::~PairedTilingSetQueue() { | 138 EvictionTilePriorityQueue::PairedTilingSetQueue::~PairedTilingSetQueue() { |
141 } | 139 } |
142 | 140 |
143 bool EvictionTilePriorityQueue::PairedTilingSetQueue::IsEmpty() const { | 141 bool EvictionTilePriorityQueue::PairedTilingSetQueue::IsEmpty() const { |
144 return (!active_queue || active_queue->IsEmpty()) && | 142 return (!active_queue || active_queue->IsEmpty()) && |
145 (!pending_queue || pending_queue->IsEmpty()); | 143 (!pending_queue || pending_queue->IsEmpty()); |
146 } | 144 } |
147 | 145 |
148 Tile* EvictionTilePriorityQueue::PairedTilingSetQueue::Top( | 146 Tile* EvictionTilePriorityQueue::PairedTilingSetQueue::Top() { |
149 TreePriority tree_priority) { | |
150 DCHECK(!IsEmpty()); | 147 DCHECK(!IsEmpty()); |
151 | 148 |
152 WhichTree next_tree = NextTileIteratorTree(tree_priority); | 149 WhichTree next_tree = NextTileIteratorTree(); |
153 TilingSetEvictionQueue* next_queue = | 150 TilingSetEvictionQueue* next_queue = |
154 next_tree == ACTIVE_TREE ? active_queue.get() : pending_queue.get(); | 151 next_tree == ACTIVE_TREE ? active_queue.get() : pending_queue.get(); |
155 DCHECK(next_queue && !next_queue->IsEmpty()); | 152 DCHECK(next_queue && !next_queue->IsEmpty()); |
156 | 153 |
157 Tile* tile = next_queue->Top(); | 154 Tile* tile = next_queue->Top(); |
158 DCHECK(returned_tiles_for_debug.find(tile) == returned_tiles_for_debug.end()); | 155 DCHECK(returned_tiles_for_debug.find(tile) == returned_tiles_for_debug.end()); |
159 return tile; | 156 return tile; |
160 } | 157 } |
161 | 158 |
162 void EvictionTilePriorityQueue::PairedTilingSetQueue::Pop( | 159 void EvictionTilePriorityQueue::PairedTilingSetQueue::Pop() { |
163 TreePriority tree_priority) { | |
164 DCHECK(!IsEmpty()); | 160 DCHECK(!IsEmpty()); |
165 | 161 |
166 WhichTree next_tree = NextTileIteratorTree(tree_priority); | 162 WhichTree next_tree = NextTileIteratorTree(); |
167 TilingSetEvictionQueue* next_queue = | 163 TilingSetEvictionQueue* next_queue = |
168 next_tree == ACTIVE_TREE ? active_queue.get() : pending_queue.get(); | 164 next_tree == ACTIVE_TREE ? active_queue.get() : pending_queue.get(); |
169 DCHECK(next_queue && !next_queue->IsEmpty()); | 165 DCHECK(next_queue && !next_queue->IsEmpty()); |
170 DCHECK(returned_tiles_for_debug.insert(next_queue->Top()).second); | 166 DCHECK(returned_tiles_for_debug.insert(next_queue->Top()).second); |
171 next_queue->Pop(); | 167 next_queue->Pop(); |
172 | 168 |
173 // If not empty, use Top to DCHECK the next iterator. | 169 // If not empty, use Top to DCHECK the next iterator. |
174 DCHECK_IMPLIES(!IsEmpty(), Top(tree_priority)); | 170 DCHECK_IMPLIES(!IsEmpty(), Top()); |
175 } | 171 } |
176 | 172 |
177 WhichTree | 173 WhichTree |
178 EvictionTilePriorityQueue::PairedTilingSetQueue::NextTileIteratorTree( | 174 EvictionTilePriorityQueue::PairedTilingSetQueue::NextTileIteratorTree() const { |
179 TreePriority tree_priority) const { | |
180 DCHECK(!IsEmpty()); | 175 DCHECK(!IsEmpty()); |
181 | 176 |
182 // If we only have one iterator with tiles, return it. | 177 // If we only have one iterator with tiles, return it. |
183 if (!active_queue || active_queue->IsEmpty()) | 178 if (!active_queue || active_queue->IsEmpty()) |
184 return PENDING_TREE; | 179 return PENDING_TREE; |
185 if (!pending_queue || pending_queue->IsEmpty()) | 180 if (!pending_queue || pending_queue->IsEmpty()) |
186 return ACTIVE_TREE; | 181 return ACTIVE_TREE; |
187 | 182 |
188 const Tile* active_tile = active_queue->Top(); | 183 const Tile* active_tile = active_queue->Top(); |
189 const Tile* pending_tile = pending_queue->Top(); | 184 const Tile* pending_tile = pending_queue->Top(); |
190 | 185 |
191 // If tiles are the same, it doesn't matter which tree we return. | 186 // If tiles are the same, it doesn't matter which tree we return. |
192 if (active_tile == pending_tile) | 187 if (active_tile == pending_tile) |
193 return ACTIVE_TREE; | 188 return ACTIVE_TREE; |
194 | 189 |
195 const TilePriority& active_priority = | 190 const TilePriority& active_priority = active_tile->combined_priority(); |
196 active_tile->priority_for_tree_priority(tree_priority); | 191 const TilePriority& pending_priority = pending_tile->combined_priority(); |
197 const TilePriority& pending_priority = | |
198 pending_tile->priority_for_tree_priority(tree_priority); | |
199 | 192 |
200 // If the bins are the same and activation differs, then return the tree of | 193 // If the bins are the same and activation differs, then return the tree of |
201 // the tile not required for activation. | 194 // the tile not required for activation. |
202 if (active_priority.priority_bin == pending_priority.priority_bin && | 195 if (active_priority.priority_bin == pending_priority.priority_bin && |
203 active_tile->required_for_activation() != | 196 active_tile->required_for_activation() != |
204 pending_tile->required_for_activation()) { | 197 pending_tile->required_for_activation()) { |
205 return active_tile->required_for_activation() ? PENDING_TREE : ACTIVE_TREE; | 198 return active_tile->required_for_activation() ? PENDING_TREE : ACTIVE_TREE; |
206 } | 199 } |
207 | 200 |
208 // Return tile with a lower priority. | 201 // Return tile with a lower priority. |
209 if (pending_priority.IsHigherPriorityThan(active_priority)) | 202 if (pending_priority.IsHigherPriorityThan(active_priority)) |
210 return ACTIVE_TREE; | 203 return ACTIVE_TREE; |
211 return PENDING_TREE; | 204 return PENDING_TREE; |
212 } | 205 } |
213 | 206 |
214 } // namespace cc | 207 } // namespace cc |
OLD | NEW |