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/raster_source.h" | 19 #include "cc/resources/raster_source.h" |
18 #include "cc/resources/tile.h" | 20 #include "cc/resources/tile.h" |
19 #include "cc/resources/tile_priority.h" | 21 #include "cc/resources/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 gfx::Rect content_rect = |
270 gfx::ScaleToEnclosingRect(layer_rect, contents_scale_); | 272 gfx::ScaleToEnclosingRect(layer_rect, contents_scale_); |
271 // Consider tiles inside the live tiles rect even if only their border | 273 // Consider tiles inside the live tiles rect even if only their border |
272 // pixels intersect the invalidation. But don't consider tiles outside | 274 // pixels intersect the invalidation. But don't consider tiles outside |
273 // the live tiles rect with the same conditions, as they won't exist. | 275 // the live tiles rect with the same conditions, as they won't exist. |
274 int border_pixels = tiling_data_.border_texels(); | 276 int border_pixels = tiling_data_.border_texels(); |
275 content_rect.Inset(-border_pixels, -border_pixels); | 277 content_rect.Inset(-border_pixels, -border_pixels); |
276 // Avoid needless work by not bothering to invalidate where there aren't | 278 // Avoid needless work by not bothering to invalidate where there aren't |
277 // tiles. | 279 // tiles. |
278 content_rect.Intersect(expanded_live_tiles_rect); | 280 content_rect.Intersect(expanded_live_tiles_rect); |
279 if (content_rect.IsEmpty()) | 281 if (content_rect.IsEmpty()) |
280 continue; | 282 continue; |
281 // Since the content_rect includes border pixels already, don't include | 283 // Since the content_rect includes border pixels already, don't include |
282 // borders when iterating to avoid double counting them. | 284 // borders when iterating to avoid double counting them. |
283 bool include_borders = false; | 285 bool include_borders = false; |
284 for ( | 286 for ( |
285 TilingData::Iterator iter(&tiling_data_, content_rect, include_borders); | 287 TilingData::Iterator iter(&tiling_data_, content_rect, include_borders); |
286 iter; ++iter) { | 288 iter; ++iter) { |
287 if (RemoveTileAt(iter.index_x(), iter.index_y())) { | 289 // This also adds the TileMapKey to the map. |
288 if (recreate_tiles) | 290 remove_tiles[iter.index()].Union(content_rect); |
289 new_tile_keys.push_back(iter.index()); | |
290 } | |
291 } | 291 } |
292 } | 292 } |
293 | 293 |
294 for (const auto& key : new_tile_keys) | 294 for (const auto& pair : remove_tiles) { |
295 CreateTile(key.first, key.second); | 295 const TileMapKey& key = pair.first; |
296 const gfx::Rect& invalid_content_rect = pair.second; | |
297 Tile::Id old_id(0); | |
298 if (RemoveTileAt(key.first, key.second, &old_id) && recreate_tiles) { | |
299 if (Tile* tile = CreateTile(key.first, key.second)) | |
300 tile->SetInvalidated(invalid_content_rect, old_id); | |
301 } | |
302 } | |
296 } | 303 } |
297 | 304 |
298 bool PictureLayerTiling::ShouldCreateTileAt(int i, int j) const { | 305 bool PictureLayerTiling::ShouldCreateTileAt(int i, int j) const { |
299 // Active tree should always create a tile. The reason for this is that active | 306 // 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 | 307 // 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 | 308 // 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 | 309 // 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 | 310 // 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 | 311 // creating tiles that are different from the current active tree, which is |
305 // represented by the logic in the rest of the function. | 312 // 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_, | 490 texture_rect.Scale(dest_to_content_scale_, |
484 dest_to_content_scale_); | 491 dest_to_content_scale_); |
485 texture_rect.Intersect(gfx::Rect(tiling_->tiling_size())); | 492 texture_rect.Intersect(gfx::Rect(tiling_->tiling_size())); |
486 if (texture_rect.IsEmpty()) | 493 if (texture_rect.IsEmpty()) |
487 return texture_rect; | 494 return texture_rect; |
488 texture_rect.Offset(-tex_origin.OffsetFromOrigin()); | 495 texture_rect.Offset(-tex_origin.OffsetFromOrigin()); |
489 | 496 |
490 return texture_rect; | 497 return texture_rect; |
491 } | 498 } |
492 | 499 |
493 bool PictureLayerTiling::RemoveTileAt(int i, int j) { | 500 bool PictureLayerTiling::RemoveTileAt(int i, int j, Tile::Id* id) { |
vmpstr
2015/05/15 20:54:21
FWIW, now that you've changed Tile::id() to be > 0
| |
494 TileMap::iterator found = tiles_.find(TileMapKey(i, j)); | 501 TileMap::iterator found = tiles_.find(TileMapKey(i, j)); |
495 if (found == tiles_.end()) | 502 if (found == tiles_.end()) |
496 return false; | 503 return false; |
504 if (id) | |
505 *id = found->second->id(); | |
497 tiles_.erase(found); | 506 tiles_.erase(found); |
498 return true; | 507 return true; |
499 } | 508 } |
500 | 509 |
501 void PictureLayerTiling::Reset() { | 510 void PictureLayerTiling::Reset() { |
502 live_tiles_rect_ = gfx::Rect(); | 511 live_tiles_rect_ = gfx::Rect(); |
503 tiles_.clear(); | 512 tiles_.clear(); |
504 } | 513 } |
505 | 514 |
506 gfx::Rect PictureLayerTiling::ComputeSkewport( | 515 gfx::Rect PictureLayerTiling::ComputeSkewport( |
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
643 gfx::Rect(tiling_size()).Contains(new_live_tiles_rect)) | 652 gfx::Rect(tiling_size()).Contains(new_live_tiles_rect)) |
644 << "tiling_size: " << tiling_size().ToString() | 653 << "tiling_size: " << tiling_size().ToString() |
645 << " new_live_tiles_rect: " << new_live_tiles_rect.ToString(); | 654 << " new_live_tiles_rect: " << new_live_tiles_rect.ToString(); |
646 if (live_tiles_rect_ == new_live_tiles_rect) | 655 if (live_tiles_rect_ == new_live_tiles_rect) |
647 return; | 656 return; |
648 | 657 |
649 // Iterate to delete all tiles outside of our new live_tiles rect. | 658 // Iterate to delete all tiles outside of our new live_tiles rect. |
650 for (TilingData::DifferenceIterator iter(&tiling_data_, live_tiles_rect_, | 659 for (TilingData::DifferenceIterator iter(&tiling_data_, live_tiles_rect_, |
651 new_live_tiles_rect); | 660 new_live_tiles_rect); |
652 iter; ++iter) { | 661 iter; ++iter) { |
653 RemoveTileAt(iter.index_x(), iter.index_y()); | 662 RemoveTileAt(iter.index_x(), iter.index_y(), nullptr); |
654 } | 663 } |
655 | 664 |
656 // Iterate to allocate new tiles for all regions with newly exposed area. | 665 // Iterate to allocate new tiles for all regions with newly exposed area. |
657 for (TilingData::DifferenceIterator iter(&tiling_data_, new_live_tiles_rect, | 666 for (TilingData::DifferenceIterator iter(&tiling_data_, new_live_tiles_rect, |
658 live_tiles_rect_); | 667 live_tiles_rect_); |
659 iter; ++iter) { | 668 iter; ++iter) { |
660 TileMapKey key(iter.index()); | 669 TileMapKey key(iter.index()); |
661 if (ShouldCreateTileAt(key.first, key.second)) | 670 if (ShouldCreateTileAt(key.first, key.second)) |
662 CreateTile(key.first, key.second); | 671 CreateTile(key.first, key.second); |
663 } | 672 } |
(...skipping 407 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1071 break; | 1080 break; |
1072 } | 1081 } |
1073 | 1082 |
1074 gfx::Rect result(origin_x, origin_y, width, height); | 1083 gfx::Rect result(origin_x, origin_y, width, height); |
1075 if (cache) | 1084 if (cache) |
1076 cache->previous_result = result; | 1085 cache->previous_result = result; |
1077 return result; | 1086 return result; |
1078 } | 1087 } |
1079 | 1088 |
1080 } // namespace cc | 1089 } // namespace cc |
OLD | NEW |