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 |