OLD | NEW |
---|---|
(Empty) | |
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 | |
3 // found in the LICENSE file. | |
4 | |
5 #include "cc/resources/eviction_tile_priority_queue.h" | |
6 | |
7 namespace cc { | |
8 | |
9 EvictionTilePriorityQueue::EvictionTilePriorityQueue() | |
10 : comparator_(SAME_PRIORITY_FOR_BOTH_TREES) { | |
11 } | |
12 | |
13 EvictionTilePriorityQueue::~EvictionTilePriorityQueue() { | |
14 } | |
15 | |
16 void EvictionTilePriorityQueue::Build( | |
17 const std::vector<PairedPictureLayer>& paired_layers, | |
18 TreePriority tree_priority) { | |
19 tree_priority_ = tree_priority; | |
20 comparator_ = EvictionOrderComparator(tree_priority_); | |
21 | |
22 paired_queues_.reserve(paired_layers.size()); | |
23 queue_heap_.reserve(paired_layers.size()); | |
reveman
2014/07/18 21:08:04
both these reserve calls can be removed after my s
vmpstr
2014/07/18 23:18:12
Done.
| |
24 for (std::vector<PairedPictureLayer>::const_iterator it = | |
25 paired_layers.begin(); | |
26 it != paired_layers.end(); | |
27 ++it) { | |
28 PairedPictureLayerQueue paired_queue; | |
29 if (it->active_layer) { | |
30 paired_queue.active_iterator = | |
31 PictureLayerImpl::LayerEvictionTileIterator(it->active_layer, | |
32 tree_priority_); | |
33 } | |
34 | |
35 if (it->pending_layer) { | |
36 paired_queue.pending_iterator = | |
37 PictureLayerImpl::LayerEvictionTileIterator(it->pending_layer, | |
38 tree_priority_); | |
39 } | |
40 | |
41 if (paired_queue.PeekTile(tree_priority_) != NULL) { | |
42 paired_queues_.push_back(paired_queue); | |
43 queue_heap_.push_back(&paired_queues_.back()); | |
44 } | |
reveman
2014/07/18 21:08:04
Can we remove this and if worthwhile add it in a f
vmpstr
2014/07/18 23:18:12
Done.
| |
45 } | |
46 | |
47 std::make_heap(queue_heap_.begin(), queue_heap_.end(), comparator_); | |
48 } | |
49 | |
50 void EvictionTilePriorityQueue::Reset() { | |
51 paired_queues_.clear(); | |
52 queue_heap_.clear(); | |
53 } | |
54 | |
55 void EvictionTilePriorityQueue::Pop() { | |
56 DCHECK(!IsEmpty()); | |
57 | |
58 std::pop_heap(queue_heap_.begin(), queue_heap_.end(), comparator_); | |
59 PairedPictureLayerQueue* paired_queue = queue_heap_.back(); | |
60 queue_heap_.pop_back(); | |
61 | |
62 paired_queue->PopTile(tree_priority_); | |
63 if (paired_queue->PeekTile(tree_priority_) != NULL) { | |
reveman
2014/07/18 21:08:04
remove this conditional and add it in a follow up
vmpstr
2014/07/18 23:18:12
Done.
| |
64 queue_heap_.push_back(paired_queue); | |
65 std::push_heap(queue_heap_.begin(), queue_heap_.end(), comparator_); | |
66 } | |
67 } | |
68 | |
69 bool EvictionTilePriorityQueue::IsEmpty() const { | |
70 return queue_heap_.empty(); | |
reveman
2014/07/18 21:08:04
With my other suggestions I think we need "|| !que
vmpstr
2014/07/18 23:18:12
Done.
| |
71 } | |
72 | |
73 Tile* EvictionTilePriorityQueue::Top() { | |
74 DCHECK(!IsEmpty()); | |
75 return queue_heap_.front()->PeekTile(tree_priority_); | |
76 } | |
77 | |
78 EvictionTilePriorityQueue::PairedPictureLayerQueue::PairedPictureLayerQueue() { | |
79 } | |
80 | |
81 EvictionTilePriorityQueue::PairedPictureLayerQueue::~PairedPictureLayerQueue() { | |
82 } | |
83 | |
84 Tile* EvictionTilePriorityQueue::PairedPictureLayerQueue::PeekTile( | |
85 TreePriority tree_priority) { | |
86 PictureLayerImpl::LayerEvictionTileIterator* next_iterator = | |
87 NextTileIterator(tree_priority); | |
88 if (!next_iterator) | |
89 return NULL; | |
90 | |
91 DCHECK(*next_iterator); | |
92 DCHECK(std::find(returned_shared_tiles.begin(), | |
93 returned_shared_tiles.end(), | |
94 **next_iterator) == returned_shared_tiles.end()); | |
95 return **next_iterator; | |
96 } | |
97 | |
98 void EvictionTilePriorityQueue::PairedPictureLayerQueue::PopTile( | |
99 TreePriority tree_priority) { | |
100 PictureLayerImpl::LayerEvictionTileIterator* next_iterator = | |
101 NextTileIterator(tree_priority); | |
102 DCHECK(next_iterator); | |
103 DCHECK(*next_iterator); | |
104 returned_shared_tiles.push_back(**next_iterator); | |
105 ++(*next_iterator); | |
106 | |
107 next_iterator = NextTileIterator(tree_priority); | |
108 while (next_iterator && | |
109 std::find(returned_shared_tiles.begin(), | |
110 returned_shared_tiles.end(), | |
111 **next_iterator) != returned_shared_tiles.end()) { | |
112 ++(*next_iterator); | |
113 next_iterator = NextTileIterator(tree_priority); | |
114 } | |
115 } | |
116 | |
117 PictureLayerImpl::LayerEvictionTileIterator* | |
118 EvictionTilePriorityQueue::PairedPictureLayerQueue::NextTileIterator( | |
119 TreePriority tree_priority) { | |
120 // If both iterators are out of tiles, return NULL. | |
121 if (!active_iterator && !pending_iterator) | |
122 return NULL; | |
123 | |
124 // If we only have one iterator with tiles, return it. | |
125 if (!active_iterator) | |
126 return &pending_iterator; | |
127 if (!pending_iterator) | |
128 return &active_iterator; | |
129 | |
130 Tile* active_tile = *active_iterator; | |
131 Tile* pending_tile = *pending_iterator; | |
132 if (active_tile == pending_tile) | |
133 return &active_iterator; | |
134 | |
135 const TilePriority& active_priority = | |
136 active_tile->priority_for_tree_priority(tree_priority); | |
137 const TilePriority& pending_priority = | |
138 pending_tile->priority_for_tree_priority(tree_priority); | |
139 | |
140 if (pending_priority.IsHigherPriorityThan(active_priority)) | |
141 return &active_iterator; | |
142 return &pending_iterator; | |
143 } | |
144 | |
145 EvictionTilePriorityQueue::EvictionOrderComparator::EvictionOrderComparator( | |
146 TreePriority tree_priority) | |
147 : tree_priority_(tree_priority) { | |
148 } | |
149 | |
150 bool EvictionTilePriorityQueue::EvictionOrderComparator::operator()( | |
151 PairedPictureLayerQueue* a, | |
152 PairedPictureLayerQueue* b) const { | |
153 PictureLayerImpl::LayerEvictionTileIterator* a_iterator = | |
154 a->NextTileIterator(tree_priority_); | |
155 DCHECK(a_iterator); | |
156 DCHECK(*a_iterator); | |
157 | |
158 PictureLayerImpl::LayerEvictionTileIterator* b_iterator = | |
159 b->NextTileIterator(tree_priority_); | |
160 DCHECK(b_iterator); | |
161 DCHECK(*b_iterator); | |
162 | |
163 Tile* a_tile = **a_iterator; | |
164 Tile* b_tile = **b_iterator; | |
165 | |
166 const TilePriority& a_priority = | |
167 a_tile->priority_for_tree_priority(tree_priority_); | |
168 const TilePriority& b_priority = | |
169 b_tile->priority_for_tree_priority(tree_priority_); | |
170 bool prioritize_low_res = tree_priority_ == SMOOTHNESS_TAKES_PRIORITY; | |
171 | |
172 // Now we have to return true iff b is lower priority than a. | |
173 | |
174 // If the priority bin differs, b is lower priority if it has the higher | |
175 // priority bin. | |
176 if (a_priority.priority_bin != b_priority.priority_bin) | |
177 return b_priority.priority_bin > a_priority.priority_bin; | |
178 | |
179 // Otherwise if the resolution differs, then the order will be determined by | |
180 // whether we prioritize low res or not. | |
181 // TODO(vmpstr): Remove this when TilePriority is no longer a member of Tile | |
182 // class but instead produced by the iterators. | |
183 if (b_priority.resolution != a_priority.resolution) { | |
184 // Non ideal resolution should be sorted higher than other resolutions. | |
185 if (a_priority.resolution == NON_IDEAL_RESOLUTION) | |
186 return false; | |
187 | |
188 if (b_priority.resolution == NON_IDEAL_RESOLUTION) | |
189 return true; | |
190 | |
191 if (prioritize_low_res) | |
192 return a_priority.resolution == LOW_RESOLUTION; | |
193 | |
194 return a_priority.resolution == HIGH_RESOLUTION; | |
195 } | |
196 | |
197 // Otherwise if the occlusion differs, b is lower priority if it is occluded. | |
198 bool a_is_occluded = a_tile->is_occluded_for_tree_priority(tree_priority_); | |
199 bool b_is_occluded = b_tile->is_occluded_for_tree_priority(tree_priority_); | |
200 if (a_is_occluded != b_is_occluded) | |
201 return b_is_occluded; | |
202 | |
203 // b is lower priorty if it is farther from visible. | |
204 return b_priority.distance_to_visible > a_priority.distance_to_visible; | |
205 } | |
206 | |
207 } // namespace cc | |
OLD | NEW |