| 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 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 218 tiling_data_.TileXIndexFromSrcCoord(live_tiles_rect_.right() - 1); | 220 tiling_data_.TileXIndexFromSrcCoord(live_tiles_rect_.right() - 1); |
| 219 after_bottom = | 221 after_bottom = |
| 220 tiling_data_.TileYIndexFromSrcCoord(live_tiles_rect_.bottom() - 1); | 222 tiling_data_.TileYIndexFromSrcCoord(live_tiles_rect_.bottom() - 1); |
| 221 } | 223 } |
| 222 | 224 |
| 223 // There is no recycled twin since this is run on the pending tiling | 225 // There is no recycled twin since this is run on the pending tiling |
| 224 // during commit, and on the active tree during activate. | 226 // during commit, and on the active tree during activate. |
| 225 // Drop tiles outside the new layer bounds if the layer shrank. | 227 // Drop tiles outside the new layer bounds if the layer shrank. |
| 226 for (int i = after_right + 1; i <= before_right; ++i) { | 228 for (int i = after_right + 1; i <= before_right; ++i) { |
| 227 for (int j = before_top; j <= before_bottom; ++j) | 229 for (int j = before_top; j <= before_bottom; ++j) |
| 228 RemoveTileAt(i, j); | 230 RemoveTileAt(i, j, nullptr); |
| 229 } | 231 } |
| 230 for (int i = before_left; i <= after_right; ++i) { | 232 for (int i = before_left; i <= after_right; ++i) { |
| 231 for (int j = after_bottom + 1; j <= before_bottom; ++j) | 233 for (int j = after_bottom + 1; j <= before_bottom; ++j) |
| 232 RemoveTileAt(i, j); | 234 RemoveTileAt(i, j, nullptr); |
| 233 } | 235 } |
| 234 | 236 |
| 235 if (after_right > before_right) { | 237 if (after_right > before_right) { |
| 236 DCHECK_EQ(after_right, before_right + 1); | 238 DCHECK_EQ(after_right, before_right + 1); |
| 237 for (int j = before_top; j <= after_bottom; ++j) { | 239 for (int j = before_top; j <= after_bottom; ++j) { |
| 238 if (ShouldCreateTileAt(after_right, j)) | 240 if (ShouldCreateTileAt(after_right, j)) |
| 239 CreateTile(after_right, j); | 241 CreateTile(after_right, j); |
| 240 } | 242 } |
| 241 } | 243 } |
| 242 if (after_bottom > before_bottom) { | 244 if (after_bottom > before_bottom) { |
| (...skipping 10 matching lines...) Expand all Loading... |
| 253 !client_->GetPendingOrActiveTwinTiling(this)); | 255 !client_->GetPendingOrActiveTwinTiling(this)); |
| 254 RemoveTilesInRegion(layer_invalidation, true /* recreate tiles */); | 256 RemoveTilesInRegion(layer_invalidation, true /* recreate tiles */); |
| 255 } | 257 } |
| 256 | 258 |
| 257 void PictureLayerTiling::RemoveTilesInRegion(const Region& layer_invalidation, | 259 void PictureLayerTiling::RemoveTilesInRegion(const Region& layer_invalidation, |
| 258 bool recreate_tiles) { | 260 bool recreate_tiles) { |
| 259 // We only invalidate the active tiling when it's orphaned: it has no pending | 261 // We only invalidate the active tiling when it's orphaned: it has no pending |
| 260 // twin, so it's slated for removal in the future. | 262 // twin, so it's slated for removal in the future. |
| 261 if (live_tiles_rect_.IsEmpty()) | 263 if (live_tiles_rect_.IsEmpty()) |
| 262 return; | 264 return; |
| 263 std::vector<TileMapKey> new_tile_keys; | 265 base::SmallMap<base::hash_map<TileMapKey, gfx::Rect>, 16> remove_tiles; |
| 264 gfx::Rect expanded_live_tiles_rect = | 266 gfx::Rect expanded_live_tiles_rect = |
| 265 tiling_data_.ExpandRectIgnoringBordersToTileBounds(live_tiles_rect_); | 267 tiling_data_.ExpandRectIgnoringBordersToTileBounds(live_tiles_rect_); |
| 266 for (Region::Iterator iter(layer_invalidation); iter.has_rect(); | 268 for (Region::Iterator iter(layer_invalidation); iter.has_rect(); |
| 267 iter.next()) { | 269 iter.next()) { |
| 268 gfx::Rect layer_rect = iter.rect(); | 270 gfx::Rect layer_rect = iter.rect(); |
| 269 gfx::Rect content_rect = | 271 // The pixels which are invalid in content space. |
| 272 gfx::Rect invalid_content_rect = |
| 270 gfx::ScaleToEnclosingRect(layer_rect, contents_scale_); | 273 gfx::ScaleToEnclosingRect(layer_rect, contents_scale_); |
| 271 // Consider tiles inside the live tiles rect even if only their border | 274 // Consider tiles inside the live tiles rect even if only their border |
| 272 // pixels intersect the invalidation. But don't consider tiles outside | 275 // pixels intersect the invalidation. But don't consider tiles outside |
| 273 // the live tiles rect with the same conditions, as they won't exist. | 276 // the live tiles rect with the same conditions, as they won't exist. |
| 277 gfx::Rect coverage_content_rect = invalid_content_rect; |
| 274 int border_pixels = tiling_data_.border_texels(); | 278 int border_pixels = tiling_data_.border_texels(); |
| 275 content_rect.Inset(-border_pixels, -border_pixels); | 279 coverage_content_rect.Inset(-border_pixels, -border_pixels); |
| 276 // Avoid needless work by not bothering to invalidate where there aren't | 280 // Avoid needless work by not bothering to invalidate where there aren't |
| 277 // tiles. | 281 // tiles. |
| 278 content_rect.Intersect(expanded_live_tiles_rect); | 282 coverage_content_rect.Intersect(expanded_live_tiles_rect); |
| 279 if (content_rect.IsEmpty()) | 283 if (coverage_content_rect.IsEmpty()) |
| 280 continue; | 284 continue; |
| 281 // Since the content_rect includes border pixels already, don't include | 285 // Since the content_rect includes border pixels already, don't include |
| 282 // borders when iterating to avoid double counting them. | 286 // borders when iterating to avoid double counting them. |
| 283 bool include_borders = false; | 287 bool include_borders = false; |
| 284 for ( | 288 for (TilingData::Iterator iter(&tiling_data_, coverage_content_rect, |
| 285 TilingData::Iterator iter(&tiling_data_, content_rect, include_borders); | 289 include_borders); |
| 286 iter; ++iter) { | 290 iter; ++iter) { |
| 287 if (RemoveTileAt(iter.index_x(), iter.index_y())) { | 291 // This also adds the TileMapKey to the map. |
| 288 if (recreate_tiles) | 292 remove_tiles[TileMapKey(iter.index())].Union(invalid_content_rect); |
| 289 new_tile_keys.push_back(TileMapKey(iter.index())); | |
| 290 } | |
| 291 } | 293 } |
| 292 } | 294 } |
| 293 | 295 |
| 294 for (const auto& key : new_tile_keys) | 296 for (const auto& pair : remove_tiles) { |
| 295 CreateTile(key.index_x, key.index_y); | 297 const TileMapKey& key = pair.first; |
| 298 const gfx::Rect& invalid_content_rect = pair.second; |
| 299 Tile::Id old_id(0); |
| 300 // TODO(danakj): This |old_id| will be empty if we are committing to a |
| 301 // pending tree since there is no tile there to remove. crbug.com/490847 |
| 302 if (RemoveTileAt(key.index_x, key.index_y, &old_id) && recreate_tiles) { |
| 303 if (Tile* tile = CreateTile(key.index_x, key.index_y)) |
| 304 tile->SetInvalidated(invalid_content_rect, old_id); |
| 305 } |
| 306 } |
| 296 } | 307 } |
| 297 | 308 |
| 298 bool PictureLayerTiling::ShouldCreateTileAt(int i, int j) const { | 309 bool PictureLayerTiling::ShouldCreateTileAt(int i, int j) const { |
| 299 // Active tree should always create a tile. The reason for this is that active | 310 // Active tree should always create a tile. The reason for this is that active |
| 300 // tree represents content that we draw on screen, which means that whenever | 311 // tree represents content that we draw on screen, which means that whenever |
| 301 // we check whether a tile should exist somewhere, the answer is yes. This | 312 // we check whether a tile should exist somewhere, the answer is yes. This |
| 302 // doesn't mean it will actually be created (if raster source doesn't cover | 313 // doesn't mean it will actually be created (if raster source doesn't cover |
| 303 // the tile for instance). Pending tree, on the other hand, should only be | 314 // the tile for instance). Pending tree, on the other hand, should only be |
| 304 // creating tiles that are different from the current active tree, which is | 315 // creating tiles that are different from the current active tree, which is |
| 305 // represented by the logic in the rest of the function. | 316 // represented by the logic in the rest of the function. |
| (...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 483 texture_rect.Scale(dest_to_content_scale_, | 494 texture_rect.Scale(dest_to_content_scale_, |
| 484 dest_to_content_scale_); | 495 dest_to_content_scale_); |
| 485 texture_rect.Intersect(gfx::Rect(tiling_->tiling_size())); | 496 texture_rect.Intersect(gfx::Rect(tiling_->tiling_size())); |
| 486 if (texture_rect.IsEmpty()) | 497 if (texture_rect.IsEmpty()) |
| 487 return texture_rect; | 498 return texture_rect; |
| 488 texture_rect.Offset(-tex_origin.OffsetFromOrigin()); | 499 texture_rect.Offset(-tex_origin.OffsetFromOrigin()); |
| 489 | 500 |
| 490 return texture_rect; | 501 return texture_rect; |
| 491 } | 502 } |
| 492 | 503 |
| 493 bool PictureLayerTiling::RemoveTileAt(int i, int j) { | 504 bool PictureLayerTiling::RemoveTileAt(int i, int j, Tile::Id* id) { |
| 494 TileMap::iterator found = tiles_.find(TileMapKey(i, j)); | 505 TileMap::iterator found = tiles_.find(TileMapKey(i, j)); |
| 495 if (found == tiles_.end()) | 506 if (found == tiles_.end()) |
| 496 return false; | 507 return false; |
| 508 if (id) |
| 509 *id = found->second->id(); |
| 497 tiles_.erase(found); | 510 tiles_.erase(found); |
| 498 return true; | 511 return true; |
| 499 } | 512 } |
| 500 | 513 |
| 501 void PictureLayerTiling::Reset() { | 514 void PictureLayerTiling::Reset() { |
| 502 live_tiles_rect_ = gfx::Rect(); | 515 live_tiles_rect_ = gfx::Rect(); |
| 503 tiles_.clear(); | 516 tiles_.clear(); |
| 504 } | 517 } |
| 505 | 518 |
| 506 gfx::Rect PictureLayerTiling::ComputeSkewport( | 519 gfx::Rect PictureLayerTiling::ComputeSkewport( |
| (...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 650 gfx::Rect(tiling_size()).Contains(new_live_tiles_rect)) | 663 gfx::Rect(tiling_size()).Contains(new_live_tiles_rect)) |
| 651 << "tiling_size: " << tiling_size().ToString() | 664 << "tiling_size: " << tiling_size().ToString() |
| 652 << " new_live_tiles_rect: " << new_live_tiles_rect.ToString(); | 665 << " new_live_tiles_rect: " << new_live_tiles_rect.ToString(); |
| 653 if (live_tiles_rect_ == new_live_tiles_rect) | 666 if (live_tiles_rect_ == new_live_tiles_rect) |
| 654 return; | 667 return; |
| 655 | 668 |
| 656 // Iterate to delete all tiles outside of our new live_tiles rect. | 669 // Iterate to delete all tiles outside of our new live_tiles rect. |
| 657 for (TilingData::DifferenceIterator iter(&tiling_data_, live_tiles_rect_, | 670 for (TilingData::DifferenceIterator iter(&tiling_data_, live_tiles_rect_, |
| 658 new_live_tiles_rect); | 671 new_live_tiles_rect); |
| 659 iter; ++iter) { | 672 iter; ++iter) { |
| 660 RemoveTileAt(iter.index_x(), iter.index_y()); | 673 RemoveTileAt(iter.index_x(), iter.index_y(), nullptr); |
| 661 } | 674 } |
| 662 | 675 |
| 663 // Iterate to allocate new tiles for all regions with newly exposed area. | 676 // Iterate to allocate new tiles for all regions with newly exposed area. |
| 664 for (TilingData::DifferenceIterator iter(&tiling_data_, new_live_tiles_rect, | 677 for (TilingData::DifferenceIterator iter(&tiling_data_, new_live_tiles_rect, |
| 665 live_tiles_rect_); | 678 live_tiles_rect_); |
| 666 iter; ++iter) { | 679 iter; ++iter) { |
| 667 TileMapKey key(iter.index()); | 680 TileMapKey key(iter.index()); |
| 668 if (ShouldCreateTileAt(key.index_x, key.index_y)) | 681 if (ShouldCreateTileAt(key.index_x, key.index_y)) |
| 669 CreateTile(key.index_x, key.index_y); | 682 CreateTile(key.index_x, key.index_y); |
| 670 } | 683 } |
| (...skipping 407 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1078 break; | 1091 break; |
| 1079 } | 1092 } |
| 1080 | 1093 |
| 1081 gfx::Rect result(origin_x, origin_y, width, height); | 1094 gfx::Rect result(origin_x, origin_y, width, height); |
| 1082 if (cache) | 1095 if (cache) |
| 1083 cache->previous_result = result; | 1096 cache->previous_result = result; |
| 1084 return result; | 1097 return result; |
| 1085 } | 1098 } |
| 1086 | 1099 |
| 1087 } // namespace cc | 1100 } // namespace cc |
| OLD | NEW |