Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(128)

Side by Side Diff: cc/resources/picture_layer_tiling.cc

Issue 793693003: Tile Compression (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « cc/resources/picture_layer_tiling.h ('k') | cc/resources/picture_layer_tiling_perftest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 The Chromium Authors. All rights reserved. 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 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/picture_layer_tiling.h" 5 #include "cc/resources/picture_layer_tiling.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <cmath> 8 #include <cmath>
9 #include <limits> 9 #include <limits>
10 #include <set> 10 #include <set>
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
49 // Or if a is farther away from visible. 49 // Or if a is farther away from visible.
50 return a_priority.distance_to_visible > b_priority.distance_to_visible; 50 return a_priority.distance_to_visible > b_priority.distance_to_visible;
51 } 51 }
52 52
53 private: 53 private:
54 TreePriority tree_priority_; 54 TreePriority tree_priority_;
55 }; 55 };
56 56
57 } // namespace 57 } // namespace
58 58
59 const int
60 PictureLayerTiling::TileInvalidationState::kFrequentInvalidationThreshold =
61 2;
62
63 PictureLayerTiling::TileInvalidationState::TileInvalidationState()
64 : frame_count_(0) {
65 }
66
67 void PictureLayerTiling::TileInvalidationState::Invalidate(
68 base::TimeTicks current_frame_time) {
69 if (current_frame_time == last_frame_time_)
70 return;
71
72 // Check the time intervals between consecutive invalidations:
73 // - If the intervals are shorter than kIntervalMin for a number of
74 // consecutive invalidations, it's a "frequently invalidated" tile.
75 // - If the interval between two invalidations is longer than kIntervalMax,
76 // it's not a "frequently invalidated" tile anymore.
77 base::TimeDelta time_since = current_frame_time - last_frame_time_;
78 const base::TimeDelta kIntervalMin = base::TimeDelta::FromMilliseconds(700);
79 const base::TimeDelta kIntervalMax = base::TimeDelta::FromMilliseconds(2000);
80 const base::TimeDelta interval =
81 FrequentlyInvalidated() ? kIntervalMax : kIntervalMin;
82 frame_count_ =
83 time_since < interval
84 ? std::min(frame_count_ + 1, kFrequentInvalidationThreshold)
85 : 0;
86 last_frame_time_ = current_frame_time;
87 }
88
89 bool PictureLayerTiling::TileInvalidationState::FrequentlyInvalidated() const {
90 return frame_count_ >= kFrequentInvalidationThreshold;
91 }
92
59 scoped_ptr<PictureLayerTiling> PictureLayerTiling::Create( 93 scoped_ptr<PictureLayerTiling> PictureLayerTiling::Create(
60 float contents_scale, 94 float contents_scale,
61 const gfx::Size& layer_bounds, 95 const gfx::Size& layer_bounds,
62 PictureLayerTilingClient* client) { 96 PictureLayerTilingClient* client) {
63 return make_scoped_ptr(new PictureLayerTiling(contents_scale, 97 return make_scoped_ptr(new PictureLayerTiling(contents_scale,
64 layer_bounds, 98 layer_bounds,
65 client)); 99 client));
66 } 100 }
67 101
68 PictureLayerTiling::PictureLayerTiling(float contents_scale, 102 PictureLayerTiling::PictureLayerTiling(float contents_scale,
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
131 DCHECK(!candidate_tile->is_shared()); 165 DCHECK(!candidate_tile->is_shared());
132 DCHECK_EQ(i, candidate_tile->tiling_i_index()); 166 DCHECK_EQ(i, candidate_tile->tiling_i_index());
133 DCHECK_EQ(j, candidate_tile->tiling_j_index()); 167 DCHECK_EQ(j, candidate_tile->tiling_j_index());
134 candidate_tile->set_shared(true); 168 candidate_tile->set_shared(true);
135 tiles_[key] = candidate_tile; 169 tiles_[key] = candidate_tile;
136 return candidate_tile; 170 return candidate_tile;
137 } 171 }
138 } 172 }
139 } 173 }
140 174
175 int flags = 0;
176 auto found = tile_invalidation_states_.find(key);
177 if (found != tile_invalidation_states_.end()) {
178 if (found->second.FrequentlyInvalidated())
179 flags |= Tile::FREQUENTLY_INVALIDATED;
180 }
181
141 // Create a new tile because our twin didn't have a valid one. 182 // Create a new tile because our twin didn't have a valid one.
142 scoped_refptr<Tile> tile = client_->CreateTile(this, tile_rect); 183 scoped_refptr<Tile> tile = client_->CreateTile(this, tile_rect, flags);
143 if (tile.get()) { 184 if (tile.get()) {
144 DCHECK(!tile->is_shared()); 185 DCHECK(!tile->is_shared());
145 tile->set_tiling_index(i, j); 186 tile->set_tiling_index(i, j);
146 tiles_[key] = tile; 187 tiles_[key] = tile;
147 } 188 }
148 eviction_tiles_cache_valid_ = false; 189 eviction_tiles_cache_valid_ = false;
149 return tile.get(); 190 return tile.get();
150 } 191 }
151 192
152 void PictureLayerTiling::CreateMissingTilesInLiveTilesRect() { 193 void PictureLayerTiling::CreateMissingTilesInLiveTilesRect() {
(...skipping 10 matching lines...) Expand all
163 continue; 204 continue;
164 CreateTile(key.first, key.second, twin_tiling); 205 CreateTile(key.first, key.second, twin_tiling);
165 } 206 }
166 207
167 VerifyLiveTilesRect(); 208 VerifyLiveTilesRect();
168 } 209 }
169 210
170 void PictureLayerTiling::UpdateTilesToCurrentRasterSource( 211 void PictureLayerTiling::UpdateTilesToCurrentRasterSource(
171 RasterSource* raster_source, 212 RasterSource* raster_source,
172 const Region& layer_invalidation, 213 const Region& layer_invalidation,
173 const gfx::Size& new_layer_bounds) { 214 const gfx::Size& new_layer_bounds,
215 base::TimeTicks frame_time) {
174 DCHECK(!new_layer_bounds.IsEmpty()); 216 DCHECK(!new_layer_bounds.IsEmpty());
175 217
176 gfx::Size content_bounds = 218 gfx::Size content_bounds =
177 gfx::ToCeiledSize(gfx::ScaleSize(new_layer_bounds, contents_scale_)); 219 gfx::ToCeiledSize(gfx::ScaleSize(new_layer_bounds, contents_scale_));
178 gfx::Size tile_size = client_->CalculateTileSize(content_bounds); 220 gfx::Size tile_size = client_->CalculateTileSize(content_bounds);
179 221
180 if (new_layer_bounds != layer_bounds_) { 222 if (new_layer_bounds != layer_bounds_) {
181 if (tile_size.IsEmpty()) { 223 if (tile_size.IsEmpty()) {
182 layer_bounds_ = gfx::Size(); 224 layer_bounds_ = gfx::Size();
183 content_bounds = gfx::Size(); 225 content_bounds = gfx::Size();
(...skipping 27 matching lines...) Expand all
211 } 253 }
212 254
213 // There is no recycled twin since this is run on the pending tiling. 255 // There is no recycled twin since this is run on the pending tiling.
214 PictureLayerTiling* recycled_twin = NULL; 256 PictureLayerTiling* recycled_twin = NULL;
215 DCHECK_EQ(recycled_twin, client_->GetRecycledTwinTiling(this)); 257 DCHECK_EQ(recycled_twin, client_->GetRecycledTwinTiling(this));
216 DCHECK_EQ(PENDING_TREE, client_->GetTree()); 258 DCHECK_EQ(PENDING_TREE, client_->GetTree());
217 259
218 // Drop tiles outside the new layer bounds if the layer shrank. 260 // Drop tiles outside the new layer bounds if the layer shrank.
219 for (int i = after_right + 1; i <= before_right; ++i) { 261 for (int i = after_right + 1; i <= before_right; ++i) {
220 for (int j = before_top; j <= before_bottom; ++j) 262 for (int j = before_top; j <= before_bottom; ++j)
221 RemoveTileAt(i, j, recycled_twin); 263 RemoveTileAt(i, j, recycled_twin, true);
222 } 264 }
223 for (int i = before_left; i <= after_right; ++i) { 265 for (int i = before_left; i <= after_right; ++i) {
224 for (int j = after_bottom + 1; j <= before_bottom; ++j) 266 for (int j = after_bottom + 1; j <= before_bottom; ++j)
225 RemoveTileAt(i, j, recycled_twin); 267 RemoveTileAt(i, j, recycled_twin, true);
226 } 268 }
227 269
228 // If the layer grew, the live_tiles_rect_ is not changed, but a new row 270 // If the layer grew, the live_tiles_rect_ is not changed, but a new row
229 // and/or column of tiles may now exist inside the same live_tiles_rect_. 271 // and/or column of tiles may now exist inside the same live_tiles_rect_.
230 const PictureLayerTiling* twin_tiling = 272 const PictureLayerTiling* twin_tiling =
231 client_->GetPendingOrActiveTwinTiling(this); 273 client_->GetPendingOrActiveTwinTiling(this);
232 if (after_right > before_right) { 274 if (after_right > before_right) {
233 DCHECK_EQ(after_right, before_right + 1); 275 DCHECK_EQ(after_right, before_right + 1);
234 for (int j = before_top; j <= after_bottom; ++j) 276 for (int j = before_top; j <= after_bottom; ++j)
235 CreateTile(after_right, j, twin_tiling); 277 CreateTile(after_right, j, twin_tiling);
236 } 278 }
237 if (after_bottom > before_bottom) { 279 if (after_bottom > before_bottom) {
238 DCHECK_EQ(after_bottom, before_bottom + 1); 280 DCHECK_EQ(after_bottom, before_bottom + 1);
239 for (int i = before_left; i <= before_right; ++i) 281 for (int i = before_left; i <= before_right; ++i)
240 CreateTile(i, after_bottom, twin_tiling); 282 CreateTile(i, after_bottom, twin_tiling);
241 } 283 }
242 } 284 }
243 285
244 if (tile_size != tiling_data_.max_texture_size()) { 286 if (tile_size != tiling_data_.max_texture_size()) {
245 tiling_data_.SetMaxTextureSize(tile_size); 287 tiling_data_.SetMaxTextureSize(tile_size);
246 // When the tile size changes, the TilingData positions no longer work 288 // When the tile size changes, the TilingData positions no longer work
247 // as valid keys to the TileMap, so just drop all tiles. 289 // as valid keys to the TileMap, so just drop all tiles.
248 Reset(); 290 Reset();
249 } else { 291 } else {
250 Invalidate(layer_invalidation); 292 Invalidate(layer_invalidation, frame_time);
251 } 293 }
252 294
253 for (TileMap::const_iterator it = tiles_.begin(); it != tiles_.end(); ++it) 295 for (TileMap::const_iterator it = tiles_.begin(); it != tiles_.end(); ++it)
254 it->second->set_raster_source(raster_source); 296 it->second->set_raster_source(raster_source);
255 VerifyLiveTilesRect(); 297 VerifyLiveTilesRect();
256 } 298 }
257 299
258 void PictureLayerTiling::RemoveTilesInRegion(const Region& layer_region) { 300 void PictureLayerTiling::RemoveTilesInRegion(const Region& layer_region) {
259 bool recreate_invalidated_tiles = false; 301 bool recreate_invalidated_tiles = false;
260 DoInvalidate(layer_region, recreate_invalidated_tiles); 302 DoInvalidate(layer_region, recreate_invalidated_tiles, base::TimeTicks());
261 } 303 }
262 304
263 void PictureLayerTiling::Invalidate(const Region& layer_region) { 305 void PictureLayerTiling::Invalidate(const Region& layer_region,
306 base::TimeTicks frame_time) {
264 bool recreate_invalidated_tiles = true; 307 bool recreate_invalidated_tiles = true;
265 DoInvalidate(layer_region, recreate_invalidated_tiles); 308 DoInvalidate(layer_region, recreate_invalidated_tiles, frame_time);
266 } 309 }
267 310
268 void PictureLayerTiling::DoInvalidate(const Region& layer_region, 311 void PictureLayerTiling::DoInvalidate(const Region& layer_region,
269 bool recreate_invalidated_tiles) { 312 bool recreate_invalidated_tiles,
313 base::TimeTicks frame_time) {
314 bool update_invalidation_states = frame_time != base::TimeTicks();
270 std::vector<TileMapKey> new_tile_keys; 315 std::vector<TileMapKey> new_tile_keys;
271 gfx::Rect expanded_live_tiles_rect = 316 gfx::Rect expanded_live_tiles_rect =
272 tiling_data_.ExpandRectIgnoringBordersToTileBounds(live_tiles_rect_); 317 tiling_data_.ExpandRectIgnoringBordersToTileBounds(live_tiles_rect_);
273 for (Region::Iterator iter(layer_region); iter.has_rect(); iter.next()) { 318 for (Region::Iterator iter(layer_region); iter.has_rect(); iter.next()) {
274 gfx::Rect layer_rect = iter.rect(); 319 gfx::Rect layer_rect = iter.rect();
275 gfx::Rect content_rect = 320 gfx::Rect content_rect =
276 gfx::ScaleToEnclosingRect(layer_rect, contents_scale_); 321 gfx::ScaleToEnclosingRect(layer_rect, contents_scale_);
277 // Consider tiles inside the live tiles rect even if only their border 322 // Consider tiles inside the live tiles rect even if only their border
278 // pixels intersect the invalidation. But don't consider tiles outside 323 // pixels intersect the invalidation. But don't consider tiles outside
279 // the live tiles rect with the same conditions, as they won't exist. 324 // the live tiles rect with the same conditions, as they won't exist.
280 int border_pixels = tiling_data_.border_texels(); 325 int border_pixels = tiling_data_.border_texels();
281 content_rect.Inset(-border_pixels, -border_pixels); 326 content_rect.Inset(-border_pixels, -border_pixels);
282 // Avoid needless work by not bothering to invalidate where there aren't 327 // Avoid needless work by not bothering to invalidate where there aren't
283 // tiles. 328 // tiles.
284 content_rect.Intersect(expanded_live_tiles_rect); 329 content_rect.Intersect(expanded_live_tiles_rect);
285 if (content_rect.IsEmpty()) 330 if (content_rect.IsEmpty())
286 continue; 331 continue;
287 // Since the content_rect includes border pixels already, don't include 332 // Since the content_rect includes border pixels already, don't include
288 // borders when iterating to avoid double counting them. 333 // borders when iterating to avoid double counting them.
289 bool include_borders = false; 334 bool include_borders = false;
290 for (TilingData::Iterator iter( 335 for (TilingData::Iterator iter(
291 &tiling_data_, content_rect, include_borders); 336 &tiling_data_, content_rect, include_borders);
292 iter; 337 iter;
293 ++iter) { 338 ++iter) {
339 if (update_invalidation_states)
340 tile_invalidation_states_[iter.index()].Invalidate(frame_time);
341
294 // There is no recycled twin since this is run on the pending tiling. 342 // There is no recycled twin since this is run on the pending tiling.
295 PictureLayerTiling* recycled_twin = NULL; 343 PictureLayerTiling* recycled_twin = NULL;
296 DCHECK_EQ(recycled_twin, client_->GetRecycledTwinTiling(this)); 344 DCHECK_EQ(recycled_twin, client_->GetRecycledTwinTiling(this));
297 DCHECK_EQ(PENDING_TREE, client_->GetTree()); 345 DCHECK_EQ(PENDING_TREE, client_->GetTree());
298 if (RemoveTileAt(iter.index_x(), iter.index_y(), recycled_twin)) 346 if (RemoveTileAt(iter.index_x(), iter.index_y(), recycled_twin, false))
299 new_tile_keys.push_back(iter.index()); 347 new_tile_keys.push_back(iter.index());
300 } 348 }
301 } 349 }
302 350
303 if (recreate_invalidated_tiles && !new_tile_keys.empty()) { 351 if (recreate_invalidated_tiles && !new_tile_keys.empty()) {
304 for (size_t i = 0; i < new_tile_keys.size(); ++i) { 352 for (size_t i = 0; i < new_tile_keys.size(); ++i) {
305 // Don't try to share a tile with the twin layer, it's been invalidated so 353 // Don't try to share a tile with the twin layer, it's been invalidated so
306 // we have to make our own tile here. 354 // we have to make our own tile here.
307 const PictureLayerTiling* twin_tiling = NULL; 355 const PictureLayerTiling* twin_tiling = NULL;
308 CreateTile(new_tile_keys[i].first, new_tile_keys[i].second, twin_tiling); 356 CreateTile(new_tile_keys[i].first, new_tile_keys[i].second, twin_tiling);
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
455 503
456 return texture_rect; 504 return texture_rect;
457 } 505 }
458 506
459 gfx::Size PictureLayerTiling::CoverageIterator::texture_size() const { 507 gfx::Size PictureLayerTiling::CoverageIterator::texture_size() const {
460 return tiling_->tiling_data_.max_texture_size(); 508 return tiling_->tiling_data_.max_texture_size();
461 } 509 }
462 510
463 bool PictureLayerTiling::RemoveTileAt(int i, 511 bool PictureLayerTiling::RemoveTileAt(int i,
464 int j, 512 int j,
465 PictureLayerTiling* recycled_twin) { 513 PictureLayerTiling* recycled_twin,
514 bool remove_invalidation_state) {
466 TileMap::iterator found = tiles_.find(TileMapKey(i, j)); 515 TileMap::iterator found = tiles_.find(TileMapKey(i, j));
467 if (found == tiles_.end()) 516 if (found == tiles_.end())
468 return false; 517 return false;
469 found->second->set_shared(false); 518 found->second->set_shared(false);
470 tiles_.erase(found); 519 tiles_.erase(found);
471 eviction_tiles_cache_valid_ = false; 520 eviction_tiles_cache_valid_ = false;
521
522 if (remove_invalidation_state) {
523 auto found = tile_invalidation_states_.find(TileMapKey(i, j));
524 if (found != tile_invalidation_states_.end())
525 tile_invalidation_states_.erase(found);
526 }
527
472 if (recycled_twin) { 528 if (recycled_twin) {
473 // Recycled twin does not also have a recycled twin, so pass NULL. 529 // Recycled twin does not also have a recycled twin, so pass NULL.
474 recycled_twin->RemoveTileAt(i, j, NULL); 530 recycled_twin->RemoveTileAt(i, j, NULL, remove_invalidation_state);
475 } 531 }
476 return true; 532 return true;
477 } 533 }
478 534
479 void PictureLayerTiling::Reset() { 535 void PictureLayerTiling::Reset() {
480 live_tiles_rect_ = gfx::Rect(); 536 live_tiles_rect_ = gfx::Rect();
481 PictureLayerTiling* recycled_twin = client_->GetRecycledTwinTiling(this); 537 PictureLayerTiling* recycled_twin = client_->GetRecycledTwinTiling(this);
482 for (TileMap::const_iterator it = tiles_.begin(); it != tiles_.end(); ++it) { 538 for (TileMap::const_iterator it = tiles_.begin(); it != tiles_.end(); ++it) {
483 it->second->set_shared(false); 539 it->second->set_shared(false);
484 if (recycled_twin) 540 if (recycled_twin) {
485 recycled_twin->RemoveTileAt(it->first.first, it->first.second, NULL); 541 recycled_twin->RemoveTileAt(it->first.first, it->first.second, NULL,
542 true);
543 }
486 } 544 }
487 tiles_.clear(); 545 tiles_.clear();
546 tile_invalidation_states_.clear();
488 eviction_tiles_cache_valid_ = false; 547 eviction_tiles_cache_valid_ = false;
489 } 548 }
490 549
491 gfx::Rect PictureLayerTiling::ComputeSkewport( 550 gfx::Rect PictureLayerTiling::ComputeSkewport(
492 double current_frame_time_in_seconds, 551 double current_frame_time_in_seconds,
493 const gfx::Rect& visible_rect_in_content_space) const { 552 const gfx::Rect& visible_rect_in_content_space) const {
494 gfx::Rect skewport = visible_rect_in_content_space; 553 gfx::Rect skewport = visible_rect_in_content_space;
495 if (last_impl_frame_time_in_seconds_ == 0.0) 554 if (last_impl_frame_time_in_seconds_ == 0.0)
496 return skewport; 555 return skewport;
497 556
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
621 if (live_tiles_rect_ == new_live_tiles_rect) 680 if (live_tiles_rect_ == new_live_tiles_rect)
622 return; 681 return;
623 682
624 // Iterate to delete all tiles outside of our new live_tiles rect. 683 // Iterate to delete all tiles outside of our new live_tiles rect.
625 PictureLayerTiling* recycled_twin = client_->GetRecycledTwinTiling(this); 684 PictureLayerTiling* recycled_twin = client_->GetRecycledTwinTiling(this);
626 for (TilingData::DifferenceIterator iter(&tiling_data_, 685 for (TilingData::DifferenceIterator iter(&tiling_data_,
627 live_tiles_rect_, 686 live_tiles_rect_,
628 new_live_tiles_rect); 687 new_live_tiles_rect);
629 iter; 688 iter;
630 ++iter) { 689 ++iter) {
631 RemoveTileAt(iter.index_x(), iter.index_y(), recycled_twin); 690 RemoveTileAt(iter.index_x(), iter.index_y(), recycled_twin, true);
632 } 691 }
633 692
634 const PictureLayerTiling* twin_tiling = 693 const PictureLayerTiling* twin_tiling =
635 client_->GetPendingOrActiveTwinTiling(this); 694 client_->GetPendingOrActiveTwinTiling(this);
636 695
637 // Iterate to allocate new tiles for all regions with newly exposed area. 696 // Iterate to allocate new tiles for all regions with newly exposed area.
638 for (TilingData::DifferenceIterator iter(&tiling_data_, 697 for (TilingData::DifferenceIterator iter(&tiling_data_,
639 new_live_tiles_rect, 698 new_live_tiles_rect,
640 live_tiles_rect_); 699 live_tiles_rect_);
641 iter; 700 iter;
(...skipping 568 matching lines...) Expand 10 before | Expand all | Expand 10 after
1210 } 1269 }
1211 current_tile_ = tiling_->TileAt(next_index.first, next_index.second); 1270 current_tile_ = tiling_->TileAt(next_index.first, next_index.second);
1212 } 1271 }
1213 1272
1214 if (current_tile_) 1273 if (current_tile_)
1215 tiling_->UpdateTileAndTwinPriority(current_tile_); 1274 tiling_->UpdateTileAndTwinPriority(current_tile_);
1216 return *this; 1275 return *this;
1217 } 1276 }
1218 1277
1219 } // namespace cc 1278 } // namespace cc
OLDNEW
« no previous file with comments | « cc/resources/picture_layer_tiling.h ('k') | cc/resources/picture_layer_tiling_perftest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698