Chromium Code Reviews| 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/resources/picture_layer_tiling.h" | 5 #include "cc/resources/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/resources/prioritized_tile.h" | 18 #include "cc/resources/prioritized_tile.h" |
| 17 #include "cc/resources/tile.h" | 19 #include "cc/resources/tile.h" |
| 18 #include "cc/resources/tile_priority.h" | 20 #include "cc/resources/tile_priority.h" |
| 19 #include "ui/gfx/geometry/point_conversions.h" | 21 #include "ui/gfx/geometry/point_conversions.h" |
| 20 #include "ui/gfx/geometry/rect_conversions.h" | 22 #include "ui/gfx/geometry/rect_conversions.h" |
| 21 #include "ui/gfx/geometry/safe_integer_conversions.h" | 23 #include "ui/gfx/geometry/safe_integer_conversions.h" |
| (...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 220 tiling_data_.TileXIndexFromSrcCoord(live_tiles_rect_.right() - 1); | 222 tiling_data_.TileXIndexFromSrcCoord(live_tiles_rect_.right() - 1); |
| 221 after_bottom = | 223 after_bottom = |
| 222 tiling_data_.TileYIndexFromSrcCoord(live_tiles_rect_.bottom() - 1); | 224 tiling_data_.TileYIndexFromSrcCoord(live_tiles_rect_.bottom() - 1); |
| 223 } | 225 } |
| 224 | 226 |
| 225 // There is no recycled twin since this is run on the pending tiling | 227 // There is no recycled twin since this is run on the pending tiling |
| 226 // during commit, and on the active tree during activate. | 228 // during commit, and on the active tree during activate. |
| 227 // Drop tiles outside the new layer bounds if the layer shrank. | 229 // Drop tiles outside the new layer bounds if the layer shrank. |
| 228 for (int i = after_right + 1; i <= before_right; ++i) { | 230 for (int i = after_right + 1; i <= before_right; ++i) { |
| 229 for (int j = before_top; j <= before_bottom; ++j) | 231 for (int j = before_top; j <= before_bottom; ++j) |
| 230 RemoveTileAt(i, j); | 232 RemoveTileAt(i, j, nullptr); |
| 231 } | 233 } |
| 232 for (int i = before_left; i <= after_right; ++i) { | 234 for (int i = before_left; i <= after_right; ++i) { |
| 233 for (int j = after_bottom + 1; j <= before_bottom; ++j) | 235 for (int j = after_bottom + 1; j <= before_bottom; ++j) |
| 234 RemoveTileAt(i, j); | 236 RemoveTileAt(i, j, nullptr); |
| 235 } | 237 } |
| 236 | 238 |
| 237 if (after_right > before_right) { | 239 if (after_right > before_right) { |
| 238 DCHECK_EQ(after_right, before_right + 1); | 240 DCHECK_EQ(after_right, before_right + 1); |
| 239 for (int j = before_top; j <= after_bottom; ++j) { | 241 for (int j = before_top; j <= after_bottom; ++j) { |
| 240 if (ShouldCreateTileAt(after_right, j)) | 242 if (ShouldCreateTileAt(after_right, j)) |
| 241 CreateTile(after_right, j); | 243 CreateTile(after_right, j); |
| 242 } | 244 } |
| 243 } | 245 } |
| 244 if (after_bottom > before_bottom) { | 246 if (after_bottom > before_bottom) { |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 255 !client_->GetPendingOrActiveTwinTiling(this)); | 257 !client_->GetPendingOrActiveTwinTiling(this)); |
| 256 RemoveTilesInRegion(layer_invalidation, true /* recreate tiles */); | 258 RemoveTilesInRegion(layer_invalidation, true /* recreate tiles */); |
| 257 } | 259 } |
| 258 | 260 |
| 259 void PictureLayerTiling::RemoveTilesInRegion(const Region& layer_invalidation, | 261 void PictureLayerTiling::RemoveTilesInRegion(const Region& layer_invalidation, |
| 260 bool recreate_tiles) { | 262 bool recreate_tiles) { |
| 261 // We only invalidate the active tiling when it's orphaned: it has no pending | 263 // We only invalidate the active tiling when it's orphaned: it has no pending |
| 262 // twin, so it's slated for removal in the future. | 264 // twin, so it's slated for removal in the future. |
| 263 if (live_tiles_rect_.IsEmpty()) | 265 if (live_tiles_rect_.IsEmpty()) |
| 264 return; | 266 return; |
| 265 std::vector<TileMapKey> new_tile_keys; | 267 struct RemoveTileData { |
| 268 gfx::Rect invalid_content_rect; | |
| 269 Tile::Id invalid_id; | |
| 270 }; | |
| 271 base::SmallMap<base::hash_map<TileMapKey, RemoveTileData>, 16> remove_tiles; | |
| 266 gfx::Rect expanded_live_tiles_rect = | 272 gfx::Rect expanded_live_tiles_rect = |
| 267 tiling_data_.ExpandRectIgnoringBordersToTileBounds(live_tiles_rect_); | 273 tiling_data_.ExpandRectIgnoringBordersToTileBounds(live_tiles_rect_); |
| 268 for (Region::Iterator iter(layer_invalidation); iter.has_rect(); | 274 for (Region::Iterator iter(layer_invalidation); iter.has_rect(); |
| 269 iter.next()) { | 275 iter.next()) { |
| 270 gfx::Rect layer_rect = iter.rect(); | 276 gfx::Rect layer_rect = iter.rect(); |
| 271 gfx::Rect content_rect = | 277 gfx::Rect content_rect = |
| 272 gfx::ScaleToEnclosingRect(layer_rect, contents_scale_); | 278 gfx::ScaleToEnclosingRect(layer_rect, contents_scale_); |
| 273 // Consider tiles inside the live tiles rect even if only their border | 279 // Consider tiles inside the live tiles rect even if only their border |
| 274 // pixels intersect the invalidation. But don't consider tiles outside | 280 // pixels intersect the invalidation. But don't consider tiles outside |
| 275 // the live tiles rect with the same conditions, as they won't exist. | 281 // the live tiles rect with the same conditions, as they won't exist. |
| 276 int border_pixels = tiling_data_.border_texels(); | 282 int border_pixels = tiling_data_.border_texels(); |
| 277 content_rect.Inset(-border_pixels, -border_pixels); | 283 content_rect.Inset(-border_pixels, -border_pixels); |
| 278 // Avoid needless work by not bothering to invalidate where there aren't | 284 // Avoid needless work by not bothering to invalidate where there aren't |
| 279 // tiles. | 285 // tiles. |
| 280 content_rect.Intersect(expanded_live_tiles_rect); | 286 content_rect.Intersect(expanded_live_tiles_rect); |
| 281 if (content_rect.IsEmpty()) | 287 if (content_rect.IsEmpty()) |
| 282 continue; | 288 continue; |
| 283 // Since the content_rect includes border pixels already, don't include | 289 // Since the content_rect includes border pixels already, don't include |
| 284 // borders when iterating to avoid double counting them. | 290 // borders when iterating to avoid double counting them. |
| 285 bool include_borders = false; | 291 bool include_borders = false; |
| 286 for ( | 292 for ( |
| 287 TilingData::Iterator iter(&tiling_data_, content_rect, include_borders); | 293 TilingData::Iterator iter(&tiling_data_, content_rect, include_borders); |
| 288 iter; ++iter) { | 294 iter; ++iter) { |
| 289 if (RemoveTileAt(iter.index_x(), iter.index_y())) { | 295 RemoveTileData& remove_tile_data = remove_tiles[iter.index()]; |
|
vmpstr
2015/05/14 22:28:27
At a first glance, this seems to be changing behav
danakj
2015/05/14 22:35:00
Ya you're very right and your suggestion is spot o
| |
| 290 if (recreate_tiles) | 296 remove_tile_data.invalid_content_rect.Union(content_rect); |
| 291 new_tile_keys.push_back(iter.index()); | 297 Tile::Id old_id; |
| 292 } | 298 if (RemoveTileAt(iter.index_x(), iter.index_y(), &old_id)) |
| 299 remove_tile_data.invalid_id = old_id; | |
| 293 } | 300 } |
| 294 } | 301 } |
| 295 | 302 |
| 296 for (const auto& key : new_tile_keys) | 303 for (const auto& pair : remove_tiles) { |
| 297 CreateTile(key.first, key.second); | 304 const TileMapKey& key = pair.first; |
| 305 const RemoveTileData& remove_tile_data = pair.second; | |
| 306 Tile* tile = CreateTile(key.first, key.second); | |
| 307 tile->SetInvalidatedRect(remove_tile_data.invalid_content_rect); | |
| 308 tile->SetInvalidatedId(remove_tile_data.invalid_id); | |
| 309 } | |
| 298 } | 310 } |
| 299 | 311 |
| 300 void PictureLayerTiling::SetRasterSourceOnTiles() { | 312 void PictureLayerTiling::SetRasterSourceOnTiles() { |
| 301 if (tree_ == PENDING_TREE) | 313 if (tree_ == PENDING_TREE) |
| 302 return; | 314 return; |
| 303 | 315 |
| 304 for (TileMap::value_type& tile_pair : tiles_) | 316 for (TileMap::value_type& tile_pair : tiles_) |
| 305 tile_pair.second->set_raster_source(raster_source_.get()); | 317 tile_pair.second->set_raster_source(raster_source_.get()); |
| 306 } | 318 } |
| 307 | 319 |
| (...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 493 texture_rect.Scale(dest_to_content_scale_, | 505 texture_rect.Scale(dest_to_content_scale_, |
| 494 dest_to_content_scale_); | 506 dest_to_content_scale_); |
| 495 texture_rect.Intersect(gfx::Rect(tiling_->tiling_size())); | 507 texture_rect.Intersect(gfx::Rect(tiling_->tiling_size())); |
| 496 if (texture_rect.IsEmpty()) | 508 if (texture_rect.IsEmpty()) |
| 497 return texture_rect; | 509 return texture_rect; |
| 498 texture_rect.Offset(-tex_origin.OffsetFromOrigin()); | 510 texture_rect.Offset(-tex_origin.OffsetFromOrigin()); |
| 499 | 511 |
| 500 return texture_rect; | 512 return texture_rect; |
| 501 } | 513 } |
| 502 | 514 |
| 503 bool PictureLayerTiling::RemoveTileAt(int i, int j) { | 515 bool PictureLayerTiling::RemoveTileAt(int i, int j, Tile::Id* id) { |
| 504 TileMap::iterator found = tiles_.find(TileMapKey(i, j)); | 516 TileMap::iterator found = tiles_.find(TileMapKey(i, j)); |
| 505 if (found == tiles_.end()) | 517 if (found == tiles_.end()) |
| 506 return false; | 518 return false; |
| 519 if (id) | |
| 520 *id = found->second->id(); | |
| 507 tiles_.erase(found); | 521 tiles_.erase(found); |
| 508 return true; | 522 return true; |
| 509 } | 523 } |
| 510 | 524 |
| 511 void PictureLayerTiling::Reset() { | 525 void PictureLayerTiling::Reset() { |
| 512 live_tiles_rect_ = gfx::Rect(); | 526 live_tiles_rect_ = gfx::Rect(); |
| 513 tiles_.clear(); | 527 tiles_.clear(); |
| 514 } | 528 } |
| 515 | 529 |
| 516 gfx::Rect PictureLayerTiling::ComputeSkewport( | 530 gfx::Rect PictureLayerTiling::ComputeSkewport( |
| (...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 654 gfx::Rect(tiling_size()).Contains(new_live_tiles_rect)) | 668 gfx::Rect(tiling_size()).Contains(new_live_tiles_rect)) |
| 655 << "tiling_size: " << tiling_size().ToString() | 669 << "tiling_size: " << tiling_size().ToString() |
| 656 << " new_live_tiles_rect: " << new_live_tiles_rect.ToString(); | 670 << " new_live_tiles_rect: " << new_live_tiles_rect.ToString(); |
| 657 if (live_tiles_rect_ == new_live_tiles_rect) | 671 if (live_tiles_rect_ == new_live_tiles_rect) |
| 658 return; | 672 return; |
| 659 | 673 |
| 660 // Iterate to delete all tiles outside of our new live_tiles rect. | 674 // Iterate to delete all tiles outside of our new live_tiles rect. |
| 661 for (TilingData::DifferenceIterator iter(&tiling_data_, live_tiles_rect_, | 675 for (TilingData::DifferenceIterator iter(&tiling_data_, live_tiles_rect_, |
| 662 new_live_tiles_rect); | 676 new_live_tiles_rect); |
| 663 iter; ++iter) { | 677 iter; ++iter) { |
| 664 RemoveTileAt(iter.index_x(), iter.index_y()); | 678 RemoveTileAt(iter.index_x(), iter.index_y(), nullptr); |
| 665 } | 679 } |
| 666 | 680 |
| 667 // Iterate to allocate new tiles for all regions with newly exposed area. | 681 // Iterate to allocate new tiles for all regions with newly exposed area. |
| 668 for (TilingData::DifferenceIterator iter(&tiling_data_, new_live_tiles_rect, | 682 for (TilingData::DifferenceIterator iter(&tiling_data_, new_live_tiles_rect, |
| 669 live_tiles_rect_); | 683 live_tiles_rect_); |
| 670 iter; ++iter) { | 684 iter; ++iter) { |
| 671 TileMapKey key(iter.index()); | 685 TileMapKey key(iter.index()); |
| 672 if (ShouldCreateTileAt(key.first, key.second)) | 686 if (ShouldCreateTileAt(key.first, key.second)) |
| 673 CreateTile(key.first, key.second); | 687 CreateTile(key.first, key.second); |
| 674 } | 688 } |
| (...skipping 378 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1053 break; | 1067 break; |
| 1054 } | 1068 } |
| 1055 | 1069 |
| 1056 gfx::Rect result(origin_x, origin_y, width, height); | 1070 gfx::Rect result(origin_x, origin_y, width, height); |
| 1057 if (cache) | 1071 if (cache) |
| 1058 cache->previous_result = result; | 1072 cache->previous_result = result; |
| 1059 return result; | 1073 return result; |
| 1060 } | 1074 } |
| 1061 | 1075 |
| 1062 } // namespace cc | 1076 } // namespace cc |
| OLD | NEW |