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

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

Issue 1318733006: cc: Do the math for a tile's content rect in layer space once. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 3 months 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
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/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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « cc/tiles/picture_layer_tiling.h ('k') | cc/tiles/tile.h » ('j') | cc/tiles/tile.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698