OLD | NEW |
| (Empty) |
1 // Copyright 2012 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/picture_layer_tiling_set.h" | |
6 | |
7 namespace cc { | |
8 | |
9 namespace { | |
10 | |
11 class LargestToSmallestScaleFunctor { | |
12 public: | |
13 bool operator() (PictureLayerTiling* left, PictureLayerTiling* right) { | |
14 return left->contents_scale() > right->contents_scale(); | |
15 } | |
16 }; | |
17 | |
18 } // namespace | |
19 | |
20 | |
21 PictureLayerTilingSet::PictureLayerTilingSet( | |
22 PictureLayerTilingClient * client) | |
23 : client_(client) { | |
24 } | |
25 | |
26 PictureLayerTilingSet::~PictureLayerTilingSet() { | |
27 } | |
28 | |
29 void PictureLayerTilingSet::SetClient(PictureLayerTilingClient* client) { | |
30 client_ = client; | |
31 for (size_t i = 0; i < tilings_.size(); ++i) | |
32 tilings_[i]->SetClient(client_); | |
33 } | |
34 | |
35 void PictureLayerTilingSet::CloneAll( | |
36 const PictureLayerTilingSet& other, | |
37 const Region& invalidation, | |
38 float minimum_contents_scale) { | |
39 tilings_.clear(); | |
40 tilings_.reserve(other.tilings_.size()); | |
41 for (size_t i = 0; i < other.tilings_.size(); ++i) { | |
42 if (other.tilings_[i]->contents_scale() < minimum_contents_scale) | |
43 continue; | |
44 Clone(other.tilings_[i], invalidation); | |
45 } | |
46 } | |
47 | |
48 void PictureLayerTilingSet::Clone( | |
49 const PictureLayerTiling* tiling, | |
50 const Region& invalidation) { | |
51 | |
52 for (size_t i = 0; i < tilings_.size(); ++i) | |
53 DCHECK_NE(tilings_[i]->contents_scale(), tiling->contents_scale()); | |
54 | |
55 tilings_.push_back(tiling->Clone()); | |
56 gfx::Size size = tilings_.back()->layer_bounds(); | |
57 tilings_.back()->SetClient(client_); | |
58 tilings_.back()->Invalidate(invalidation); | |
59 // Intentionally use this set's layer bounds, as it may have changed. | |
60 tilings_.back()->SetLayerBounds(layer_bounds_); | |
61 | |
62 tilings_.sort(LargestToSmallestScaleFunctor()); | |
63 } | |
64 | |
65 void PictureLayerTilingSet::SetLayerBounds(gfx::Size layer_bounds) { | |
66 if (layer_bounds_ == layer_bounds) | |
67 return; | |
68 layer_bounds_ = layer_bounds; | |
69 for (size_t i = 0; i < tilings_.size(); ++i) | |
70 tilings_[i]->SetLayerBounds(layer_bounds); | |
71 } | |
72 | |
73 gfx::Size PictureLayerTilingSet::LayerBounds() const { | |
74 return layer_bounds_; | |
75 } | |
76 | |
77 PictureLayerTiling* PictureLayerTilingSet::AddTiling(float contents_scale) { | |
78 tilings_.push_back(PictureLayerTiling::Create(contents_scale)); | |
79 PictureLayerTiling* appended = tilings_.back(); | |
80 appended->SetClient(client_); | |
81 appended->SetLayerBounds(layer_bounds_); | |
82 | |
83 tilings_.sort(LargestToSmallestScaleFunctor()); | |
84 return appended; | |
85 } | |
86 | |
87 void PictureLayerTilingSet::RemoveAllTilings() { | |
88 tilings_.clear(); | |
89 } | |
90 | |
91 void PictureLayerTilingSet::Remove(PictureLayerTiling* tiling) { | |
92 ScopedPtrVector<PictureLayerTiling>::iterator iter = | |
93 std::find(tilings_.begin(), tilings_.end(), tiling); | |
94 if (iter == tilings_.end()) | |
95 return; | |
96 tilings_.erase(iter); | |
97 } | |
98 | |
99 void PictureLayerTilingSet::RemoveAllTiles() { | |
100 for (size_t i = 0; i < tilings_.size(); ++i) | |
101 tilings_[i]->Reset(); | |
102 } | |
103 | |
104 void PictureLayerTilingSet::CreateTilesFromLayerRect(gfx::Rect layer_rect) { | |
105 for (size_t i = 0; i < tilings_.size(); ++i) | |
106 tilings_[i]->CreateTilesFromLayerRect(layer_rect); | |
107 } | |
108 | |
109 PictureLayerTilingSet::Iterator::Iterator( | |
110 const PictureLayerTilingSet* set, | |
111 float contents_scale, | |
112 gfx::Rect content_rect, | |
113 float ideal_contents_scale, | |
114 PictureLayerTiling::LayerDeviceAlignment layerDeviceAlignment) | |
115 : set_(set), | |
116 contents_scale_(contents_scale), | |
117 ideal_contents_scale_(ideal_contents_scale), | |
118 layer_device_alignment_(layerDeviceAlignment), | |
119 current_tiling_(-1) { | |
120 missing_region_.Union(content_rect); | |
121 | |
122 for (ideal_tiling_ = 0; | |
123 static_cast<size_t>(ideal_tiling_) < set_->tilings_.size(); | |
124 ++ideal_tiling_) { | |
125 PictureLayerTiling* tiling = set_->tilings_[ideal_tiling_]; | |
126 if (tiling->contents_scale() < ideal_contents_scale_) { | |
127 if (ideal_tiling_ > 0) | |
128 ideal_tiling_--; | |
129 break; | |
130 } | |
131 } | |
132 | |
133 if (ideal_tiling_ == set_->tilings_.size() && ideal_tiling_ > 0) | |
134 ideal_tiling_--; | |
135 | |
136 ++(*this); | |
137 } | |
138 | |
139 PictureLayerTilingSet::Iterator::~Iterator() { | |
140 } | |
141 | |
142 gfx::Rect PictureLayerTilingSet::Iterator::geometry_rect() const { | |
143 if (!tiling_iter_) { | |
144 if (!region_iter_.has_rect()) | |
145 return gfx::Rect(); | |
146 return region_iter_.rect(); | |
147 } | |
148 return tiling_iter_.geometry_rect(); | |
149 } | |
150 | |
151 gfx::RectF PictureLayerTilingSet::Iterator::texture_rect() const { | |
152 if (!tiling_iter_) | |
153 return gfx::RectF(); | |
154 return tiling_iter_.texture_rect(); | |
155 } | |
156 | |
157 gfx::Size PictureLayerTilingSet::Iterator::texture_size() const { | |
158 if (!tiling_iter_) | |
159 return gfx::Size(); | |
160 return tiling_iter_.texture_size(); | |
161 } | |
162 | |
163 Tile* PictureLayerTilingSet::Iterator::operator->() const { | |
164 if (!tiling_iter_) | |
165 return NULL; | |
166 return *tiling_iter_; | |
167 } | |
168 | |
169 Tile* PictureLayerTilingSet::Iterator::operator*() const { | |
170 if (!tiling_iter_) | |
171 return NULL; | |
172 return *tiling_iter_; | |
173 } | |
174 | |
175 PictureLayerTiling* PictureLayerTilingSet::Iterator::CurrentTiling() { | |
176 if (current_tiling_ < 0) | |
177 return NULL; | |
178 if (static_cast<size_t>(current_tiling_) >= set_->tilings_.size()) | |
179 return NULL; | |
180 return set_->tilings_[current_tiling_]; | |
181 } | |
182 | |
183 int PictureLayerTilingSet::Iterator::NextTiling() const { | |
184 // Order returned by this method is: | |
185 // 1. Ideal tiling index | |
186 // 2. Tiling index < Ideal in decreasing order (higher res than ideal) | |
187 // 3. Tiling index > Ideal in increasing order (lower res than ideal) | |
188 // 4. Tiling index > tilings.size() (invalid index) | |
189 if (current_tiling_ < 0) | |
190 return ideal_tiling_; | |
191 else if (current_tiling_ > ideal_tiling_) | |
192 return current_tiling_ + 1; | |
193 else if (current_tiling_) | |
194 return current_tiling_ - 1; | |
195 else | |
196 return ideal_tiling_ + 1; | |
197 } | |
198 | |
199 PictureLayerTilingSet::Iterator& PictureLayerTilingSet::Iterator::operator++() { | |
200 bool first_time = current_tiling_ < 0; | |
201 | |
202 if (!*this && !first_time) | |
203 return *this; | |
204 | |
205 if (tiling_iter_) | |
206 ++tiling_iter_; | |
207 | |
208 // Loop until we find a valid place to stop. | |
209 while (true) { | |
210 while (tiling_iter_ && | |
211 (!*tiling_iter_ || !tiling_iter_->drawing_info().IsReadyToDraw())) { | |
212 missing_region_.Union(tiling_iter_.geometry_rect()); | |
213 ++tiling_iter_; | |
214 } | |
215 if (tiling_iter_) | |
216 return *this; | |
217 | |
218 // If the set of current rects for this tiling is done, go to the next | |
219 // tiling and set up to iterate through all of the remaining holes. | |
220 // This will also happen the first time through the loop. | |
221 if (!region_iter_.has_rect()) { | |
222 current_tiling_ = NextTiling(); | |
223 current_region_.Swap(missing_region_); | |
224 missing_region_.Clear(); | |
225 region_iter_ = Region::Iterator(current_region_); | |
226 | |
227 // All done and all filled. | |
228 if (!region_iter_.has_rect()) { | |
229 current_tiling_ = set_->tilings_.size(); | |
230 return *this; | |
231 } | |
232 | |
233 // No more valid tiles, return this checkerboard rect. | |
234 if (current_tiling_ >= static_cast<int>(set_->tilings_.size())) | |
235 return *this; | |
236 } | |
237 | |
238 // Pop a rect off. If there are no more tilings, then these will be | |
239 // treated as geometry with null tiles that the caller can checkerboard. | |
240 gfx::Rect last_rect = region_iter_.rect(); | |
241 region_iter_.next(); | |
242 | |
243 // Done, found next checkerboard rect to return. | |
244 if (current_tiling_ >= static_cast<int>(set_->tilings_.size())) | |
245 return *this; | |
246 | |
247 // Construct a new iterator for the next tiling, but we need to loop | |
248 // again until we get to a valid one. | |
249 tiling_iter_ = PictureLayerTiling::Iterator( | |
250 set_->tilings_[current_tiling_], | |
251 contents_scale_, | |
252 last_rect, | |
253 layer_device_alignment_); | |
254 } | |
255 | |
256 return *this; | |
257 } | |
258 | |
259 PictureLayerTilingSet::Iterator::operator bool() const { | |
260 return current_tiling_ < static_cast<int>(set_->tilings_.size()) || | |
261 region_iter_.has_rect(); | |
262 } | |
263 | |
264 void PictureLayerTilingSet::UpdateTilePriorities( | |
265 WhichTree tree, | |
266 gfx::Size device_viewport, | |
267 gfx::Rect viewport_in_content_space, | |
268 gfx::Size last_layer_bounds, | |
269 gfx::Size current_layer_bounds, | |
270 float last_layer_contents_scale, | |
271 float current_layer_contents_scale, | |
272 const gfx::Transform& last_screen_transform, | |
273 const gfx::Transform& current_screen_transform, | |
274 int current_source_frame_number, | |
275 double current_frame_time, | |
276 bool store_screen_space_quads_on_tiles) { | |
277 gfx::RectF viewport_in_layer_space = gfx::ScaleRect( | |
278 viewport_in_content_space, | |
279 1.f / current_layer_contents_scale, | |
280 1.f / current_layer_contents_scale); | |
281 | |
282 for (size_t i = 0; i < tilings_.size(); ++i) { | |
283 tilings_[i]->UpdateTilePriorities( | |
284 tree, | |
285 device_viewport, | |
286 viewport_in_layer_space, | |
287 last_layer_bounds, | |
288 current_layer_bounds, | |
289 last_layer_contents_scale, | |
290 current_layer_contents_scale, | |
291 last_screen_transform, | |
292 current_screen_transform, | |
293 current_source_frame_number, | |
294 current_frame_time, | |
295 store_screen_space_quads_on_tiles); | |
296 } | |
297 } | |
298 | |
299 void PictureLayerTilingSet::DidBecomeActive() { | |
300 for (size_t i = 0; i < tilings_.size(); ++i) | |
301 tilings_[i]->DidBecomeActive(); | |
302 } | |
303 | |
304 scoped_ptr<base::Value> PictureLayerTilingSet::AsValue() const { | |
305 scoped_ptr<base::ListValue> state(new base::ListValue()); | |
306 for (size_t i = 0; i < tilings_.size(); ++i) | |
307 state->Append(tilings_[i]->AsValue().release()); | |
308 return state.PassAs<base::Value>(); | |
309 } | |
310 | |
311 } // namespace cc | |
OLD | NEW |