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 <stddef.h> | 7 #include <stddef.h> |
8 | 8 |
9 #include <algorithm> | 9 #include <algorithm> |
10 #include <cmath> | 10 #include <cmath> |
11 #include <limits> | 11 #include <limits> |
12 #include <set> | 12 #include <set> |
13 | 13 |
14 #include "base/containers/hash_tables.h" | |
15 #include "base/containers/small_map.h" | 14 #include "base/containers/small_map.h" |
16 #include "base/logging.h" | 15 #include "base/logging.h" |
17 #include "base/numerics/safe_conversions.h" | 16 #include "base/numerics/safe_conversions.h" |
18 #include "base/trace_event/trace_event.h" | 17 #include "base/trace_event/trace_event.h" |
19 #include "base/trace_event/trace_event_argument.h" | 18 #include "base/trace_event/trace_event_argument.h" |
20 #include "cc/base/math_util.h" | 19 #include "cc/base/math_util.h" |
21 #include "cc/playback/display_list_raster_source.h" | 20 #include "cc/playback/display_list_raster_source.h" |
22 #include "cc/tiles/prioritized_tile.h" | 21 #include "cc/tiles/prioritized_tile.h" |
23 #include "cc/tiles/tile.h" | 22 #include "cc/tiles/tile.h" |
24 #include "cc/tiles/tile_priority.h" | 23 #include "cc/tiles/tile_priority.h" |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
110 const int j = info.tiling_j_index; | 109 const int j = info.tiling_j_index; |
111 TileMapKey key(i, j); | 110 TileMapKey key(i, j); |
112 DCHECK(tiles_.find(key) == tiles_.end()); | 111 DCHECK(tiles_.find(key) == tiles_.end()); |
113 | 112 |
114 if (!raster_source_->CoversRect(info.enclosing_layer_rect)) | 113 if (!raster_source_->CoversRect(info.enclosing_layer_rect)) |
115 return nullptr; | 114 return nullptr; |
116 | 115 |
117 all_tiles_done_ = false; | 116 all_tiles_done_ = false; |
118 ScopedTilePtr tile = client_->CreateTile(info); | 117 ScopedTilePtr tile = client_->CreateTile(info); |
119 Tile* raw_ptr = tile.get(); | 118 Tile* raw_ptr = tile.get(); |
120 tiles_.add(key, std::move(tile)); | 119 tiles_[key] = std::move(tile); |
121 return raw_ptr; | 120 return raw_ptr; |
122 } | 121 } |
123 | 122 |
124 void PictureLayerTiling::CreateMissingTilesInLiveTilesRect() { | 123 void PictureLayerTiling::CreateMissingTilesInLiveTilesRect() { |
125 const PictureLayerTiling* active_twin = | 124 const PictureLayerTiling* active_twin = |
126 tree_ == PENDING_TREE ? client_->GetPendingOrActiveTwinTiling(this) | 125 tree_ == PENDING_TREE ? client_->GetPendingOrActiveTwinTiling(this) |
127 : nullptr; | 126 : nullptr; |
128 const Region* invalidation = | 127 const Region* invalidation = |
129 active_twin ? client_->GetPendingInvalidation() : nullptr; | 128 active_twin ? client_->GetPendingInvalidation() : nullptr; |
130 | 129 |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
179 create_missing_tiles = true; | 178 create_missing_tiles = true; |
180 } else { | 179 } else { |
181 SetLiveTilesRect(pending_twin->live_tiles_rect()); | 180 SetLiveTilesRect(pending_twin->live_tiles_rect()); |
182 } | 181 } |
183 | 182 |
184 if (tiles_.empty()) { | 183 if (tiles_.empty()) { |
185 tiles_.swap(pending_twin->tiles_); | 184 tiles_.swap(pending_twin->tiles_); |
186 all_tiles_done_ = pending_twin->all_tiles_done_; | 185 all_tiles_done_ = pending_twin->all_tiles_done_; |
187 } else { | 186 } else { |
188 while (!pending_twin->tiles_.empty()) { | 187 while (!pending_twin->tiles_.empty()) { |
189 TileMapKey key = pending_twin->tiles_.begin()->first; | 188 auto pending_iter = pending_twin->tiles_.begin(); |
190 tiles_.set(key, pending_twin->tiles_.take_and_erase(key)); | 189 tiles_[pending_iter->first] = std::move(pending_iter->second); |
| 190 pending_twin->tiles_.erase(pending_iter); |
191 } | 191 } |
192 all_tiles_done_ &= pending_twin->all_tiles_done_; | 192 all_tiles_done_ &= pending_twin->all_tiles_done_; |
193 } | 193 } |
194 DCHECK(pending_twin->tiles_.empty()); | 194 DCHECK(pending_twin->tiles_.empty()); |
195 pending_twin->all_tiles_done_ = true; | 195 pending_twin->all_tiles_done_ = true; |
196 | 196 |
197 if (create_missing_tiles) | 197 if (create_missing_tiles) |
198 CreateMissingTilesInLiveTilesRect(); | 198 CreateMissingTilesInLiveTilesRect(); |
199 | 199 |
200 VerifyLiveTilesRect(false); | 200 VerifyLiveTilesRect(false); |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
289 DCHECK(tree_ != ACTIVE_TREE || !client_->GetPendingOrActiveTwinTiling(this)); | 289 DCHECK(tree_ != ACTIVE_TREE || !client_->GetPendingOrActiveTwinTiling(this)); |
290 RemoveTilesInRegion(layer_invalidation, true /* recreate tiles */); | 290 RemoveTilesInRegion(layer_invalidation, true /* recreate tiles */); |
291 } | 291 } |
292 | 292 |
293 void PictureLayerTiling::RemoveTilesInRegion(const Region& layer_invalidation, | 293 void PictureLayerTiling::RemoveTilesInRegion(const Region& layer_invalidation, |
294 bool recreate_tiles) { | 294 bool recreate_tiles) { |
295 // We only invalidate the active tiling when it's orphaned: it has no pending | 295 // We only invalidate the active tiling when it's orphaned: it has no pending |
296 // twin, so it's slated for removal in the future. | 296 // twin, so it's slated for removal in the future. |
297 if (live_tiles_rect_.IsEmpty()) | 297 if (live_tiles_rect_.IsEmpty()) |
298 return; | 298 return; |
299 // Pick 16 for the size of the SmallMap before it promotes to a hash_map. | 299 // Pick 16 for the size of the SmallMap before it promotes to a unordered_map. |
300 // 4x4 tiles should cover most small invalidations, and walking a vector of | 300 // 4x4 tiles should cover most small invalidations, and walking a vector of |
301 // 16 is fast enough. If an invalidation is huge we will fall back to a | 301 // 16 is fast enough. If an invalidation is huge we will fall back to a |
302 // hash_map instead of a vector in the SmallMap. | 302 // unordered_map instead of a vector in the SmallMap. |
303 base::SmallMap<base::hash_map<TileMapKey, gfx::Rect>, 16> remove_tiles; | 303 base::SmallMap<std::unordered_map<TileMapKey, gfx::Rect, TileMapKeyHash>, 16> |
| 304 remove_tiles; |
304 gfx::Rect expanded_live_tiles_rect = | 305 gfx::Rect expanded_live_tiles_rect = |
305 tiling_data_.ExpandRectToTileBounds(live_tiles_rect_); | 306 tiling_data_.ExpandRectToTileBounds(live_tiles_rect_); |
306 for (Region::Iterator iter(layer_invalidation); iter.has_rect(); | 307 for (Region::Iterator iter(layer_invalidation); iter.has_rect(); |
307 iter.next()) { | 308 iter.next()) { |
308 gfx::Rect layer_rect = iter.rect(); | 309 gfx::Rect layer_rect = iter.rect(); |
309 // The pixels which are invalid in content space. | 310 // The pixels which are invalid in content space. |
310 gfx::Rect invalid_content_rect = | 311 gfx::Rect invalid_content_rect = |
311 gfx::ScaleToEnclosingRect(layer_rect, contents_scale_); | 312 gfx::ScaleToEnclosingRect(layer_rect, contents_scale_); |
312 gfx::Rect coverage_content_rect = invalid_content_rect; | 313 gfx::Rect coverage_content_rect = invalid_content_rect; |
313 // Avoid needless work by not bothering to invalidate where there aren't | 314 // Avoid needless work by not bothering to invalidate where there aren't |
(...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
540 return texture_rect; | 541 return texture_rect; |
541 texture_rect.Offset(-tex_origin.OffsetFromOrigin()); | 542 texture_rect.Offset(-tex_origin.OffsetFromOrigin()); |
542 | 543 |
543 return texture_rect; | 544 return texture_rect; |
544 } | 545 } |
545 | 546 |
546 ScopedTilePtr PictureLayerTiling::TakeTileAt(int i, int j) { | 547 ScopedTilePtr PictureLayerTiling::TakeTileAt(int i, int j) { |
547 TileMap::iterator found = tiles_.find(TileMapKey(i, j)); | 548 TileMap::iterator found = tiles_.find(TileMapKey(i, j)); |
548 if (found == tiles_.end()) | 549 if (found == tiles_.end()) |
549 return nullptr; | 550 return nullptr; |
550 return tiles_.take_and_erase(found); | 551 ScopedTilePtr result = std::move(found->second); |
| 552 tiles_.erase(found); |
| 553 return result; |
551 } | 554 } |
552 | 555 |
553 bool PictureLayerTiling::RemoveTileAt(int i, int j) { | 556 bool PictureLayerTiling::RemoveTileAt(int i, int j) { |
554 TileMap::iterator found = tiles_.find(TileMapKey(i, j)); | 557 TileMap::iterator found = tiles_.find(TileMapKey(i, j)); |
555 if (found == tiles_.end()) | 558 if (found == tiles_.end()) |
556 return false; | 559 return false; |
557 tiles_.erase(found); | 560 tiles_.erase(found); |
558 return true; | 561 return true; |
559 } | 562 } |
560 | 563 |
(...skipping 366 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
927 | 930 |
928 return PrioritizedTile(tile, raster_source(), | 931 return PrioritizedTile(tile, raster_source(), |
929 ComputePriorityForTile(tile, priority_rect_type), | 932 ComputePriorityForTile(tile, priority_rect_type), |
930 IsTileOccluded(tile)); | 933 IsTileOccluded(tile)); |
931 } | 934 } |
932 | 935 |
933 std::map<const Tile*, PrioritizedTile> | 936 std::map<const Tile*, PrioritizedTile> |
934 PictureLayerTiling::UpdateAndGetAllPrioritizedTilesForTesting() const { | 937 PictureLayerTiling::UpdateAndGetAllPrioritizedTilesForTesting() const { |
935 std::map<const Tile*, PrioritizedTile> result; | 938 std::map<const Tile*, PrioritizedTile> result; |
936 for (const auto& key_tile_pair : tiles_) { | 939 for (const auto& key_tile_pair : tiles_) { |
937 Tile* tile = key_tile_pair.second; | 940 Tile* tile = key_tile_pair.second.get(); |
938 UpdateRequiredStatesOnTile(tile); | 941 UpdateRequiredStatesOnTile(tile); |
939 PrioritizedTile prioritized_tile = | 942 PrioritizedTile prioritized_tile = |
940 MakePrioritizedTile(tile, ComputePriorityRectTypeForTile(tile)); | 943 MakePrioritizedTile(tile, ComputePriorityRectTypeForTile(tile)); |
941 result.insert(std::make_pair(prioritized_tile.tile(), prioritized_tile)); | 944 result.insert(std::make_pair(prioritized_tile.tile(), prioritized_tile)); |
942 } | 945 } |
943 return result; | 946 return result; |
944 } | 947 } |
945 | 948 |
946 TilePriority PictureLayerTiling::ComputePriorityForTile( | 949 TilePriority PictureLayerTiling::ComputePriorityForTile( |
947 const Tile* tile, | 950 const Tile* tile, |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
998 if (current_soon_border_rect_.Intersects(tile_bounds)) | 1001 if (current_soon_border_rect_.Intersects(tile_bounds)) |
999 return SOON_BORDER_RECT; | 1002 return SOON_BORDER_RECT; |
1000 | 1003 |
1001 DCHECK(current_eventually_rect_.Intersects(tile_bounds)); | 1004 DCHECK(current_eventually_rect_.Intersects(tile_bounds)); |
1002 return EVENTUALLY_RECT; | 1005 return EVENTUALLY_RECT; |
1003 } | 1006 } |
1004 | 1007 |
1005 void PictureLayerTiling::GetAllPrioritizedTilesForTracing( | 1008 void PictureLayerTiling::GetAllPrioritizedTilesForTracing( |
1006 std::vector<PrioritizedTile>* prioritized_tiles) const { | 1009 std::vector<PrioritizedTile>* prioritized_tiles) const { |
1007 for (const auto& tile_pair : tiles_) { | 1010 for (const auto& tile_pair : tiles_) { |
1008 Tile* tile = tile_pair.second; | 1011 Tile* tile = tile_pair.second.get(); |
1009 prioritized_tiles->push_back( | 1012 prioritized_tiles->push_back( |
1010 MakePrioritizedTile(tile, ComputePriorityRectTypeForTile(tile))); | 1013 MakePrioritizedTile(tile, ComputePriorityRectTypeForTile(tile))); |
1011 } | 1014 } |
1012 } | 1015 } |
1013 | 1016 |
1014 void PictureLayerTiling::AsValueInto( | 1017 void PictureLayerTiling::AsValueInto( |
1015 base::trace_event::TracedValue* state) const { | 1018 base::trace_event::TracedValue* state) const { |
1016 state->SetInteger("num_tiles", base::saturated_cast<int>(tiles_.size())); | 1019 state->SetInteger("num_tiles", base::saturated_cast<int>(tiles_.size())); |
1017 state->SetDouble("content_scale", contents_scale_); | 1020 state->SetDouble("content_scale", contents_scale_); |
1018 MathUtil::AddToTracedValue("visible_rect", current_visible_rect_, state); | 1021 MathUtil::AddToTracedValue("visible_rect", current_visible_rect_, state); |
1019 MathUtil::AddToTracedValue("skewport_rect", current_skewport_rect_, state); | 1022 MathUtil::AddToTracedValue("skewport_rect", current_skewport_rect_, state); |
1020 MathUtil::AddToTracedValue("soon_rect", current_soon_border_rect_, state); | 1023 MathUtil::AddToTracedValue("soon_rect", current_soon_border_rect_, state); |
1021 MathUtil::AddToTracedValue("eventually_rect", current_eventually_rect_, | 1024 MathUtil::AddToTracedValue("eventually_rect", current_eventually_rect_, |
1022 state); | 1025 state); |
1023 MathUtil::AddToTracedValue("tiling_size", tiling_size(), state); | 1026 MathUtil::AddToTracedValue("tiling_size", tiling_size(), state); |
1024 } | 1027 } |
1025 | 1028 |
1026 size_t PictureLayerTiling::GPUMemoryUsageInBytes() const { | 1029 size_t PictureLayerTiling::GPUMemoryUsageInBytes() const { |
1027 size_t amount = 0; | 1030 size_t amount = 0; |
1028 for (TileMap::const_iterator it = tiles_.begin(); it != tiles_.end(); ++it) { | 1031 for (TileMap::const_iterator it = tiles_.begin(); it != tiles_.end(); ++it) { |
1029 const Tile* tile = it->second; | 1032 const Tile* tile = it->second.get(); |
1030 amount += tile->GPUMemoryUsageInBytes(); | 1033 amount += tile->GPUMemoryUsageInBytes(); |
1031 } | 1034 } |
1032 return amount; | 1035 return amount; |
1033 } | 1036 } |
1034 | 1037 |
1035 } // namespace cc | 1038 } // namespace cc |
OLD | NEW |