| 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 |