| 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> |
| 11 | 11 |
| 12 #include "base/containers/hash_tables.h" |
| 13 #include "base/containers/small_map.h" |
| 12 #include "base/logging.h" | 14 #include "base/logging.h" |
| 13 #include "base/trace_event/trace_event.h" | 15 #include "base/trace_event/trace_event.h" |
| 14 #include "base/trace_event/trace_event_argument.h" | 16 #include "base/trace_event/trace_event_argument.h" |
| 15 #include "cc/base/math_util.h" | 17 #include "cc/base/math_util.h" |
| 16 #include "cc/playback/raster_source.h" | 18 #include "cc/playback/raster_source.h" |
| 17 #include "cc/tiles/prioritized_tile.h" | 19 #include "cc/tiles/prioritized_tile.h" |
| 18 #include "cc/tiles/tile.h" | 20 #include "cc/tiles/tile.h" |
| 19 #include "cc/tiles/tile_priority.h" | 21 #include "cc/tiles/tile_priority.h" |
| 20 #include "ui/gfx/geometry/point_conversions.h" | 22 #include "ui/gfx/geometry/point_conversions.h" |
| 21 #include "ui/gfx/geometry/rect_conversions.h" | 23 #include "ui/gfx/geometry/rect_conversions.h" |
| (...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 258 !client_->GetPendingOrActiveTwinTiling(this)); | 260 !client_->GetPendingOrActiveTwinTiling(this)); |
| 259 RemoveTilesInRegion(layer_invalidation, true /* recreate tiles */); | 261 RemoveTilesInRegion(layer_invalidation, true /* recreate tiles */); |
| 260 } | 262 } |
| 261 | 263 |
| 262 void PictureLayerTiling::RemoveTilesInRegion(const Region& layer_invalidation, | 264 void PictureLayerTiling::RemoveTilesInRegion(const Region& layer_invalidation, |
| 263 bool recreate_tiles) { | 265 bool recreate_tiles) { |
| 264 // We only invalidate the active tiling when it's orphaned: it has no pending | 266 // We only invalidate the active tiling when it's orphaned: it has no pending |
| 265 // twin, so it's slated for removal in the future. | 267 // twin, so it's slated for removal in the future. |
| 266 if (live_tiles_rect_.IsEmpty()) | 268 if (live_tiles_rect_.IsEmpty()) |
| 267 return; | 269 return; |
| 268 std::vector<TileMapKey> new_tile_keys; | 270 // Pick 16 for the size of the SmallMap before it promotes to a hash_map. |
| 271 // 4x4 tiles should cover most small invalidations, and walking a vector of |
| 272 // 16 is fast enough. If an invalidation is huge we will fall back to a |
| 273 // hash_map instead of a vector in the SmallMap. |
| 274 base::SmallMap<base::hash_map<TileMapKey, gfx::Rect>, 16> remove_tiles; |
| 269 gfx::Rect expanded_live_tiles_rect = | 275 gfx::Rect expanded_live_tiles_rect = |
| 270 tiling_data_.ExpandRectIgnoringBordersToTileBounds(live_tiles_rect_); | 276 tiling_data_.ExpandRectIgnoringBordersToTileBounds(live_tiles_rect_); |
| 271 for (Region::Iterator iter(layer_invalidation); iter.has_rect(); | 277 for (Region::Iterator iter(layer_invalidation); iter.has_rect(); |
| 272 iter.next()) { | 278 iter.next()) { |
| 273 gfx::Rect layer_rect = iter.rect(); | 279 gfx::Rect layer_rect = iter.rect(); |
| 274 gfx::Rect content_rect = | 280 // The pixels which are invalid in content space. |
| 281 gfx::Rect invalid_content_rect = |
| 275 gfx::ScaleToEnclosingRect(layer_rect, contents_scale_); | 282 gfx::ScaleToEnclosingRect(layer_rect, contents_scale_); |
| 276 // Consider tiles inside the live tiles rect even if only their border | 283 // Consider tiles inside the live tiles rect even if only their border |
| 277 // pixels intersect the invalidation. But don't consider tiles outside | 284 // pixels intersect the invalidation. But don't consider tiles outside |
| 278 // the live tiles rect with the same conditions, as they won't exist. | 285 // the live tiles rect with the same conditions, as they won't exist. |
| 286 gfx::Rect coverage_content_rect = invalid_content_rect; |
| 279 int border_pixels = tiling_data_.border_texels(); | 287 int border_pixels = tiling_data_.border_texels(); |
| 280 content_rect.Inset(-border_pixels, -border_pixels); | 288 coverage_content_rect.Inset(-border_pixels, -border_pixels); |
| 281 // Avoid needless work by not bothering to invalidate where there aren't | 289 // Avoid needless work by not bothering to invalidate where there aren't |
| 282 // tiles. | 290 // tiles. |
| 283 content_rect.Intersect(expanded_live_tiles_rect); | 291 coverage_content_rect.Intersect(expanded_live_tiles_rect); |
| 284 if (content_rect.IsEmpty()) | 292 if (coverage_content_rect.IsEmpty()) |
| 285 continue; | 293 continue; |
| 286 // Since the content_rect includes border pixels already, don't include | 294 // Since the content_rect includes border pixels already, don't include |
| 287 // borders when iterating to avoid double counting them. | 295 // borders when iterating to avoid double counting them. |
| 288 bool include_borders = false; | 296 bool include_borders = false; |
| 289 for ( | 297 for (TilingData::Iterator iter(&tiling_data_, coverage_content_rect, |
| 290 TilingData::Iterator iter(&tiling_data_, content_rect, include_borders); | 298 include_borders); |
| 291 iter; ++iter) { | 299 iter; ++iter) { |
| 292 if (RemoveTileAt(iter.index_x(), iter.index_y())) { | 300 // This also adds the TileMapKey to the map. |
| 293 if (recreate_tiles) | 301 remove_tiles[TileMapKey(iter.index())].Union(invalid_content_rect); |
| 294 new_tile_keys.push_back(TileMapKey(iter.index())); | |
| 295 } | |
| 296 } | 302 } |
| 297 } | 303 } |
| 298 | 304 |
| 299 for (const auto& key : new_tile_keys) | 305 for (const auto& pair : remove_tiles) { |
| 300 CreateTile(key.index_x, key.index_y); | 306 const TileMapKey& key = pair.first; |
| 307 const gfx::Rect& invalid_content_rect = pair.second; |
| 308 // TODO(danakj): This old_tile will not exist if we are committing to a |
| 309 // pending tree since there is no tile there to remove, which prevents |
| 310 // tiles from knowing the invalidation rect and content id. crbug.com/490847 |
| 311 ScopedTilePtr old_tile = TakeTileAt(key.index_x, key.index_y); |
| 312 if (recreate_tiles && old_tile) { |
| 313 if (Tile* tile = CreateTile(key.index_x, key.index_y)) |
| 314 tile->SetInvalidated(invalid_content_rect, old_tile->id()); |
| 315 } |
| 316 } |
| 301 } | 317 } |
| 302 | 318 |
| 303 bool PictureLayerTiling::ShouldCreateTileAt(int i, int j) const { | 319 bool PictureLayerTiling::ShouldCreateTileAt(int i, int j) const { |
| 304 // Active tree should always create a tile. The reason for this is that active | 320 // Active tree should always create a tile. The reason for this is that active |
| 305 // tree represents content that we draw on screen, which means that whenever | 321 // tree represents content that we draw on screen, which means that whenever |
| 306 // we check whether a tile should exist somewhere, the answer is yes. This | 322 // we check whether a tile should exist somewhere, the answer is yes. This |
| 307 // doesn't mean it will actually be created (if raster source doesn't cover | 323 // doesn't mean it will actually be created (if raster source doesn't cover |
| 308 // the tile for instance). Pending tree, on the other hand, should only be | 324 // the tile for instance). Pending tree, on the other hand, should only be |
| 309 // creating tiles that are different from the current active tree, which is | 325 // creating tiles that are different from the current active tree, which is |
| 310 // represented by the logic in the rest of the function. | 326 // represented by the logic in the rest of the function. |
| (...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 488 texture_rect.Scale(dest_to_content_scale_, | 504 texture_rect.Scale(dest_to_content_scale_, |
| 489 dest_to_content_scale_); | 505 dest_to_content_scale_); |
| 490 texture_rect.Intersect(gfx::Rect(tiling_->tiling_size())); | 506 texture_rect.Intersect(gfx::Rect(tiling_->tiling_size())); |
| 491 if (texture_rect.IsEmpty()) | 507 if (texture_rect.IsEmpty()) |
| 492 return texture_rect; | 508 return texture_rect; |
| 493 texture_rect.Offset(-tex_origin.OffsetFromOrigin()); | 509 texture_rect.Offset(-tex_origin.OffsetFromOrigin()); |
| 494 | 510 |
| 495 return texture_rect; | 511 return texture_rect; |
| 496 } | 512 } |
| 497 | 513 |
| 514 ScopedTilePtr PictureLayerTiling::TakeTileAt(int i, int j) { |
| 515 TileMap::iterator found = tiles_.find(TileMapKey(i, j)); |
| 516 if (found == tiles_.end()) |
| 517 return nullptr; |
| 518 return tiles_.take_and_erase(found); |
| 519 } |
| 520 |
| 498 bool PictureLayerTiling::RemoveTileAt(int i, int j) { | 521 bool PictureLayerTiling::RemoveTileAt(int i, int j) { |
| 499 TileMap::iterator found = tiles_.find(TileMapKey(i, j)); | 522 TileMap::iterator found = tiles_.find(TileMapKey(i, j)); |
| 500 if (found == tiles_.end()) | 523 if (found == tiles_.end()) |
| 501 return false; | 524 return false; |
| 502 tiles_.erase(found); | 525 tiles_.erase(found); |
| 503 return true; | 526 return true; |
| 504 } | 527 } |
| 505 | 528 |
| 506 void PictureLayerTiling::Reset() { | 529 void PictureLayerTiling::Reset() { |
| 507 live_tiles_rect_ = gfx::Rect(); | 530 live_tiles_rect_ = gfx::Rect(); |
| (...skipping 572 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1080 break; | 1103 break; |
| 1081 } | 1104 } |
| 1082 | 1105 |
| 1083 gfx::Rect result(origin_x, origin_y, width, height); | 1106 gfx::Rect result(origin_x, origin_y, width, height); |
| 1084 if (cache) | 1107 if (cache) |
| 1085 cache->previous_result = result; | 1108 cache->previous_result = result; |
| 1086 return result; | 1109 return result; |
| 1087 } | 1110 } |
| 1088 | 1111 |
| 1089 } // namespace cc | 1112 } // namespace cc |
| OLD | NEW |