Chromium Code Reviews| OLD | NEW |
|---|---|
| 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/tiles/picture_layer_tiling.h" | 5 #include "cc/tiles/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 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 95 float PictureLayerTiling::CalculateSoonBorderDistance( | 95 float PictureLayerTiling::CalculateSoonBorderDistance( |
| 96 const gfx::Rect& visible_rect_in_content_space, | 96 const gfx::Rect& visible_rect_in_content_space, |
| 97 float content_to_screen_scale) { | 97 float content_to_screen_scale) { |
| 98 float max_dimension = std::max(visible_rect_in_content_space.width(), | 98 float max_dimension = std::max(visible_rect_in_content_space.width(), |
| 99 visible_rect_in_content_space.height()); | 99 visible_rect_in_content_space.height()); |
| 100 return std::min( | 100 return std::min( |
| 101 kMaxSoonBorderDistanceInScreenPixels / content_to_screen_scale, | 101 kMaxSoonBorderDistanceInScreenPixels / content_to_screen_scale, |
| 102 max_dimension * kSoonBorderDistanceViewportPercentage); | 102 max_dimension * kSoonBorderDistanceViewportPercentage); |
| 103 } | 103 } |
| 104 | 104 |
| 105 Tile* PictureLayerTiling::CreateTile(int i, int j) { | 105 Tile* PictureLayerTiling::CreateTile(const Tile::CreateInfo& info) { |
| 106 const int i = info.tiling_i_index; | |
|
vmpstr
2015/08/28 21:04:17
While here and doing this, could you just use info
danakj
2015/08/31 21:12:12
As per offline convo.. nope. :D This is kinda weir
| |
| 107 const int j = info.tiling_j_index; | |
| 106 TileMapKey key(i, j); | 108 TileMapKey key(i, j); |
| 107 DCHECK(tiles_.find(key) == tiles_.end()); | 109 DCHECK(tiles_.find(key) == tiles_.end()); |
| 108 | 110 |
| 109 gfx::Rect paint_rect = tiling_data_.TileBoundsWithBorder(i, j); | 111 if (!raster_source_->CoversRect(info.enclosing_layer_rect)) |
| 110 gfx::Rect tile_rect = paint_rect; | |
| 111 tile_rect.set_size(tiling_data_.max_texture_size()); | |
| 112 | |
| 113 if (!raster_source_->CoversRect(tile_rect, contents_scale_)) | |
| 114 return nullptr; | 112 return nullptr; |
| 115 | 113 |
| 116 all_tiles_done_ = false; | 114 all_tiles_done_ = false; |
| 117 ScopedTilePtr tile = client_->CreateTile(contents_scale_, tile_rect); | 115 ScopedTilePtr tile = client_->CreateTile(info); |
| 118 Tile* raw_ptr = tile.get(); | 116 Tile* raw_ptr = tile.get(); |
| 119 tile->set_tiling_index(i, j); | |
| 120 tiles_.add(key, tile.Pass()); | 117 tiles_.add(key, tile.Pass()); |
| 121 return raw_ptr; | 118 return raw_ptr; |
| 122 } | 119 } |
| 123 | 120 |
| 124 void PictureLayerTiling::CreateMissingTilesInLiveTilesRect() { | 121 void PictureLayerTiling::CreateMissingTilesInLiveTilesRect() { |
| 125 const PictureLayerTiling* active_twin = | 122 const PictureLayerTiling* active_twin = |
| 126 tree_ == PENDING_TREE ? client_->GetPendingOrActiveTwinTiling(this) | 123 tree_ == PENDING_TREE ? client_->GetPendingOrActiveTwinTiling(this) |
| 127 : nullptr; | 124 : nullptr; |
| 128 const Region* invalidation = | 125 const Region* invalidation = |
| 129 active_twin ? client_->GetPendingInvalidation() : nullptr; | 126 active_twin ? client_->GetPendingInvalidation() : nullptr; |
| 130 | 127 |
| 131 bool include_borders = false; | 128 bool include_borders = false; |
| 132 for (TilingData::Iterator iter(&tiling_data_, live_tiles_rect_, | 129 for (TilingData::Iterator iter(&tiling_data_, live_tiles_rect_, |
| 133 include_borders); | 130 include_borders); |
| 134 iter; ++iter) { | 131 iter; ++iter) { |
| 135 TileMapKey key(iter.index()); | 132 TileMapKey key(iter.index()); |
| 136 TileMap::iterator find = tiles_.find(key); | 133 TileMap::iterator find = tiles_.find(key); |
| 137 if (find != tiles_.end()) | 134 if (find != tiles_.end()) |
| 138 continue; | 135 continue; |
| 139 | 136 |
| 140 if (ShouldCreateTileAt(key.index_x, key.index_y)) { | 137 Tile::CreateInfo info = CreateInfoForTile(key.index_x, key.index_y); |
|
vmpstr
2015/08/28 21:04:17
... Then don't expand key here, just pass a key.
| |
| 141 Tile* tile = CreateTile(key.index_x, key.index_y); | 138 if (ShouldCreateTileAt(info)) { |
| 139 Tile* tile = CreateTile(info); | |
| 142 | 140 |
| 143 // If this is the pending tree, then the active twin tiling may contain | 141 // If this is the pending tree, then the active twin tiling may contain |
| 144 // the previous content ID of these tiles. In that case, we need only | 142 // the previous content ID of these tiles. In that case, we need only |
| 145 // partially raster the tile content. | 143 // partially raster the tile content. |
| 146 if (tile && invalidation && TilingMatchesTileIndices(active_twin)) { | 144 if (tile && invalidation && TilingMatchesTileIndices(active_twin)) { |
| 147 if (const Tile* old_tile = | 145 if (const Tile* old_tile = |
| 148 active_twin->TileAt(key.index_x, key.index_y)) { | 146 active_twin->TileAt(key.index_x, key.index_y)) { |
| 149 gfx::Rect tile_rect = tile->content_rect(); | 147 gfx::Rect tile_rect = tile->content_rect(); |
| 150 gfx::Rect invalidated; | 148 gfx::Rect invalidated; |
| 151 for (Region::Iterator iter(*invalidation); iter.has_rect(); | 149 for (Region::Iterator iter(*invalidation); iter.has_rect(); |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 262 RemoveTileAt(i, j); | 260 RemoveTileAt(i, j); |
| 263 } | 261 } |
| 264 for (int i = before_left; i <= after_right; ++i) { | 262 for (int i = before_left; i <= after_right; ++i) { |
| 265 for (int j = after_bottom + 1; j <= before_bottom; ++j) | 263 for (int j = after_bottom + 1; j <= before_bottom; ++j) |
| 266 RemoveTileAt(i, j); | 264 RemoveTileAt(i, j); |
| 267 } | 265 } |
| 268 | 266 |
| 269 if (after_right > before_right) { | 267 if (after_right > before_right) { |
| 270 DCHECK_EQ(after_right, before_right + 1); | 268 DCHECK_EQ(after_right, before_right + 1); |
| 271 for (int j = before_top; j <= after_bottom; ++j) { | 269 for (int j = before_top; j <= after_bottom; ++j) { |
| 272 if (ShouldCreateTileAt(after_right, j)) | 270 Tile::CreateInfo info = CreateInfoForTile(after_right, j); |
| 273 CreateTile(after_right, j); | 271 if (ShouldCreateTileAt(info)) |
| 272 CreateTile(info); | |
| 274 } | 273 } |
| 275 } | 274 } |
| 276 if (after_bottom > before_bottom) { | 275 if (after_bottom > before_bottom) { |
| 277 DCHECK_EQ(after_bottom, before_bottom + 1); | 276 DCHECK_EQ(after_bottom, before_bottom + 1); |
| 278 for (int i = before_left; i <= before_right; ++i) { | 277 for (int i = before_left; i <= before_right; ++i) { |
| 279 if (ShouldCreateTileAt(i, after_bottom)) | 278 Tile::CreateInfo info = CreateInfoForTile(i, after_bottom); |
| 280 CreateTile(i, after_bottom); | 279 if (ShouldCreateTileAt(info)) |
| 280 CreateTile(info); | |
| 281 } | 281 } |
| 282 } | 282 } |
| 283 } | 283 } |
| 284 | 284 |
| 285 void PictureLayerTiling::Invalidate(const Region& layer_invalidation) { | 285 void PictureLayerTiling::Invalidate(const Region& layer_invalidation) { |
| 286 DCHECK_IMPLIES(tree_ == ACTIVE_TREE, | 286 DCHECK_IMPLIES(tree_ == ACTIVE_TREE, |
| 287 !client_->GetPendingOrActiveTwinTiling(this)); | 287 !client_->GetPendingOrActiveTwinTiling(this)); |
| 288 RemoveTilesInRegion(layer_invalidation, true /* recreate tiles */); | 288 RemoveTilesInRegion(layer_invalidation, true /* recreate tiles */); |
| 289 } | 289 } |
| 290 | 290 |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 330 } | 330 } |
| 331 | 331 |
| 332 for (const auto& pair : remove_tiles) { | 332 for (const auto& pair : remove_tiles) { |
| 333 const TileMapKey& key = pair.first; | 333 const TileMapKey& key = pair.first; |
| 334 const gfx::Rect& invalid_content_rect = pair.second; | 334 const gfx::Rect& invalid_content_rect = pair.second; |
| 335 // TODO(danakj): This old_tile will not exist if we are committing to a | 335 // TODO(danakj): This old_tile will not exist if we are committing to a |
| 336 // pending tree since there is no tile there to remove, which prevents | 336 // pending tree since there is no tile there to remove, which prevents |
| 337 // tiles from knowing the invalidation rect and content id. crbug.com/490847 | 337 // tiles from knowing the invalidation rect and content id. crbug.com/490847 |
| 338 ScopedTilePtr old_tile = TakeTileAt(key.index_x, key.index_y); | 338 ScopedTilePtr old_tile = TakeTileAt(key.index_x, key.index_y); |
| 339 if (recreate_tiles && old_tile) { | 339 if (recreate_tiles && old_tile) { |
| 340 if (Tile* tile = CreateTile(key.index_x, key.index_y)) | 340 Tile::CreateInfo info = CreateInfoForTile(key.index_x, key.index_y); |
| 341 if (Tile* tile = CreateTile(info)) | |
| 341 tile->SetInvalidated(invalid_content_rect, old_tile->id()); | 342 tile->SetInvalidated(invalid_content_rect, old_tile->id()); |
| 342 } | 343 } |
| 343 } | 344 } |
| 344 } | 345 } |
| 345 | 346 |
| 346 bool PictureLayerTiling::ShouldCreateTileAt(int i, int j) const { | 347 Tile::CreateInfo PictureLayerTiling::CreateInfoForTile(int i, int j) const { |
| 348 gfx::Rect tile_rect = tiling_data_.TileBoundsWithBorder(i, j); | |
|
vmpstr
2015/08/28 21:04:17
... And expand here? Wdyt?
| |
| 349 tile_rect.set_size(tiling_data_.max_texture_size()); | |
| 350 gfx::Rect enclosing_layer_rect = | |
| 351 gfx::ScaleToEnclosingRect(tile_rect, 1.f / contents_scale_); | |
| 352 return Tile::CreateInfo(i, j, enclosing_layer_rect, tile_rect, | |
| 353 contents_scale_); | |
| 354 } | |
| 355 | |
| 356 bool PictureLayerTiling::ShouldCreateTileAt( | |
| 357 const Tile::CreateInfo& info) const { | |
| 358 const int i = info.tiling_i_index; | |
| 359 const int j = info.tiling_j_index; | |
| 347 // Active tree should always create a tile. The reason for this is that active | 360 // Active tree should always create a tile. The reason for this is that active |
| 348 // tree represents content that we draw on screen, which means that whenever | 361 // tree represents content that we draw on screen, which means that whenever |
| 349 // we check whether a tile should exist somewhere, the answer is yes. This | 362 // we check whether a tile should exist somewhere, the answer is yes. This |
| 350 // doesn't mean it will actually be created (if raster source doesn't cover | 363 // doesn't mean it will actually be created (if raster source doesn't cover |
| 351 // the tile for instance). Pending tree, on the other hand, should only be | 364 // the tile for instance). Pending tree, on the other hand, should only be |
| 352 // creating tiles that are different from the current active tree, which is | 365 // creating tiles that are different from the current active tree, which is |
| 353 // represented by the logic in the rest of the function. | 366 // represented by the logic in the rest of the function. |
| 354 if (tree_ == ACTIVE_TREE) | 367 if (tree_ == ACTIVE_TREE) |
| 355 return true; | 368 return true; |
| 356 | 369 |
| 357 // If the pending tree has no active twin, then it needs to create all tiles. | 370 // If the pending tree has no active twin, then it needs to create all tiles. |
| 358 const PictureLayerTiling* active_twin = | 371 const PictureLayerTiling* active_twin = |
| 359 client_->GetPendingOrActiveTwinTiling(this); | 372 client_->GetPendingOrActiveTwinTiling(this); |
| 360 if (!active_twin) | 373 if (!active_twin) |
| 361 return true; | 374 return true; |
| 362 | 375 |
| 363 // Pending tree will override the entire active tree if indices don't match. | 376 // Pending tree will override the entire active tree if indices don't match. |
| 364 if (!TilingMatchesTileIndices(active_twin)) | 377 if (!TilingMatchesTileIndices(active_twin)) |
| 365 return true; | 378 return true; |
| 366 | 379 |
| 367 gfx::Rect paint_rect = tiling_data_.TileBoundsWithBorder(i, j); | |
| 368 gfx::Rect tile_rect = paint_rect; | |
| 369 tile_rect.set_size(tiling_data_.max_texture_size()); | |
| 370 | |
| 371 // If the active tree can't create a tile, because of its raster source, then | 380 // If the active tree can't create a tile, because of its raster source, then |
| 372 // the pending tree should create one. | 381 // the pending tree should create one. |
| 373 if (!active_twin->raster_source()->CoversRect(tile_rect, contents_scale())) | 382 if (!active_twin->raster_source()->CoversRect(info.enclosing_layer_rect)) |
| 374 return true; | 383 return true; |
| 375 | 384 |
| 376 const Region* layer_invalidation = client_->GetPendingInvalidation(); | 385 const Region* layer_invalidation = client_->GetPendingInvalidation(); |
| 377 gfx::Rect layer_rect = | |
| 378 gfx::ScaleToEnclosingRect(tile_rect, 1.f / contents_scale()); | |
| 379 | 386 |
| 380 // If this tile is invalidated, then the pending tree should create one. | 387 // If this tile is invalidated, then the pending tree should create one. |
| 381 if (layer_invalidation && layer_invalidation->Intersects(layer_rect)) | 388 if (layer_invalidation && |
| 389 layer_invalidation->Intersects(info.enclosing_layer_rect)) | |
| 382 return true; | 390 return true; |
| 383 | 391 |
| 384 // If the active tree doesn't have a tile here, but it's in the pending tree's | 392 // If the active tree doesn't have a tile here, but it's in the pending tree's |
| 385 // visible rect, then the pending tree should create a tile. This can happen | 393 // visible rect, then the pending tree should create a tile. This can happen |
| 386 // if the pending visible rect is outside of the active tree's live tiles | 394 // if the pending visible rect is outside of the active tree's live tiles |
| 387 // rect. In those situations, we need to block activation until we're ready to | 395 // rect. In those situations, we need to block activation until we're ready to |
| 388 // display content, which will have to come from the pending tree. | 396 // display content, which will have to come from the pending tree. |
| 389 if (!active_twin->TileAt(i, j) && current_visible_rect_.Intersects(tile_rect)) | 397 if (!active_twin->TileAt(i, j) && |
| 398 current_visible_rect_.Intersects(info.content_rect)) | |
| 390 return true; | 399 return true; |
| 391 | 400 |
| 392 // In all other cases, the pending tree doesn't need to create a tile. | 401 // In all other cases, the pending tree doesn't need to create a tile. |
| 393 return false; | 402 return false; |
| 394 } | 403 } |
| 395 | 404 |
| 396 bool PictureLayerTiling::TilingMatchesTileIndices( | 405 bool PictureLayerTiling::TilingMatchesTileIndices( |
| 397 const PictureLayerTiling* twin) const { | 406 const PictureLayerTiling* twin) const { |
| 398 return tiling_data_.max_texture_size() == | 407 return tiling_data_.max_texture_size() == |
| 399 twin->tiling_data_.max_texture_size(); | 408 twin->tiling_data_.max_texture_size(); |
| (...skipping 329 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 729 if (resolution_ == NON_IDEAL_RESOLUTION) { | 738 if (resolution_ == NON_IDEAL_RESOLUTION) { |
| 730 live_tiles_rect_.Intersect(new_live_tiles_rect); | 739 live_tiles_rect_.Intersect(new_live_tiles_rect); |
| 731 VerifyLiveTilesRect(false); | 740 VerifyLiveTilesRect(false); |
| 732 return; | 741 return; |
| 733 } | 742 } |
| 734 | 743 |
| 735 // Iterate to allocate new tiles for all regions with newly exposed area. | 744 // Iterate to allocate new tiles for all regions with newly exposed area. |
| 736 for (TilingData::DifferenceIterator iter(&tiling_data_, new_live_tiles_rect, | 745 for (TilingData::DifferenceIterator iter(&tiling_data_, new_live_tiles_rect, |
| 737 live_tiles_rect_); | 746 live_tiles_rect_); |
| 738 iter; ++iter) { | 747 iter; ++iter) { |
| 739 TileMapKey key(iter.index()); | 748 Tile::CreateInfo info = CreateInfoForTile(iter.index_x(), iter.index_y()); |
| 740 if (ShouldCreateTileAt(key.index_x, key.index_y)) | 749 if (ShouldCreateTileAt(info)) |
| 741 CreateTile(key.index_x, key.index_y); | 750 CreateTile(info); |
| 742 } | 751 } |
| 743 | 752 |
| 744 live_tiles_rect_ = new_live_tiles_rect; | 753 live_tiles_rect_ = new_live_tiles_rect; |
| 745 VerifyLiveTilesRect(false); | 754 VerifyLiveTilesRect(false); |
| 746 } | 755 } |
| 747 | 756 |
| 748 void PictureLayerTiling::VerifyLiveTilesRect(bool is_on_recycle_tree) const { | 757 void PictureLayerTiling::VerifyLiveTilesRect(bool is_on_recycle_tree) const { |
| 749 #if DCHECK_IS_ON() | 758 #if DCHECK_IS_ON() |
| 750 for (auto it = tiles_.begin(); it != tiles_.end(); ++it) { | 759 for (auto it = tiles_.begin(); it != tiles_.end(); ++it) { |
| 751 if (!it->second) | 760 if (!it->second) |
| (...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 882 void PictureLayerTiling::UpdateRequiredStatesOnTile(Tile* tile) const { | 891 void PictureLayerTiling::UpdateRequiredStatesOnTile(Tile* tile) const { |
| 883 DCHECK(tile); | 892 DCHECK(tile); |
| 884 tile->set_required_for_activation(IsTileRequiredForActivation(tile)); | 893 tile->set_required_for_activation(IsTileRequiredForActivation(tile)); |
| 885 tile->set_required_for_draw(IsTileRequiredForDraw(tile)); | 894 tile->set_required_for_draw(IsTileRequiredForDraw(tile)); |
| 886 } | 895 } |
| 887 | 896 |
| 888 PrioritizedTile PictureLayerTiling::MakePrioritizedTile( | 897 PrioritizedTile PictureLayerTiling::MakePrioritizedTile( |
| 889 Tile* tile, | 898 Tile* tile, |
| 890 PriorityRectType priority_rect_type) const { | 899 PriorityRectType priority_rect_type) const { |
| 891 DCHECK(tile); | 900 DCHECK(tile); |
| 892 DCHECK( | 901 DCHECK(raster_source()->CoversRect(tile->enclosing_layer_rect())) |
| 893 raster_source()->CoversRect(tile->content_rect(), tile->contents_scale())) | |
| 894 << "Recording rect: " | 902 << "Recording rect: " |
| 895 << gfx::ScaleToEnclosingRect(tile->content_rect(), | 903 << gfx::ScaleToEnclosingRect(tile->content_rect(), |
| 896 1.f / tile->contents_scale()).ToString(); | 904 1.f / tile->contents_scale()) |
| 905 .ToString(); | |
| 897 | 906 |
| 898 return PrioritizedTile(tile, raster_source(), | 907 return PrioritizedTile(tile, raster_source(), |
| 899 ComputePriorityForTile(tile, priority_rect_type), | 908 ComputePriorityForTile(tile, priority_rect_type), |
| 900 IsTileOccluded(tile)); | 909 IsTileOccluded(tile)); |
| 901 } | 910 } |
| 902 | 911 |
| 903 std::map<const Tile*, PrioritizedTile> | 912 std::map<const Tile*, PrioritizedTile> |
| 904 PictureLayerTiling::UpdateAndGetAllPrioritizedTilesForTesting() const { | 913 PictureLayerTiling::UpdateAndGetAllPrioritizedTilesForTesting() const { |
| 905 std::map<const Tile*, PrioritizedTile> result; | 914 std::map<const Tile*, PrioritizedTile> result; |
| 906 for (const auto& key_tile_pair : tiles_) { | 915 for (const auto& key_tile_pair : tiles_) { |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 996 size_t PictureLayerTiling::GPUMemoryUsageInBytes() const { | 1005 size_t PictureLayerTiling::GPUMemoryUsageInBytes() const { |
| 997 size_t amount = 0; | 1006 size_t amount = 0; |
| 998 for (TileMap::const_iterator it = tiles_.begin(); it != tiles_.end(); ++it) { | 1007 for (TileMap::const_iterator it = tiles_.begin(); it != tiles_.end(); ++it) { |
| 999 const Tile* tile = it->second; | 1008 const Tile* tile = it->second; |
| 1000 amount += tile->GPUMemoryUsageInBytes(); | 1009 amount += tile->GPUMemoryUsageInBytes(); |
| 1001 } | 1010 } |
| 1002 return amount; | 1011 return amount; |
| 1003 } | 1012 } |
| 1004 | 1013 |
| 1005 } // namespace cc | 1014 } // namespace cc |
| OLD | NEW |