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 | 10 |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 46 return a_is_occluded; | 46 return a_is_occluded; |
| 47 | 47 |
| 48 // Or if a is farther away from visible. | 48 // Or if a is farther away from visible. |
| 49 return a_priority.distance_to_visible > b_priority.distance_to_visible; | 49 return a_priority.distance_to_visible > b_priority.distance_to_visible; |
| 50 } | 50 } |
| 51 | 51 |
| 52 private: | 52 private: |
| 53 TreePriority tree_priority_; | 53 TreePriority tree_priority_; |
| 54 }; | 54 }; |
| 55 | 55 |
| 56 void ReleaseTile(Tile* tile, WhichTree tree) { | |
| 57 // Reset priority as tile is ref-counted and might still be used | |
| 58 // even though we no longer hold a reference to it here anymore. | |
| 59 tile->SetPriority(tree, TilePriority()); | |
| 60 } | |
| 61 | |
| 62 } // namespace | 56 } // namespace |
| 63 | 57 |
| 64 scoped_ptr<PictureLayerTiling> PictureLayerTiling::Create( | 58 scoped_ptr<PictureLayerTiling> PictureLayerTiling::Create( |
| 65 float contents_scale, | 59 float contents_scale, |
| 66 const gfx::Size& layer_bounds, | 60 const gfx::Size& layer_bounds, |
| 67 PictureLayerTilingClient* client) { | 61 PictureLayerTilingClient* client) { |
| 68 return make_scoped_ptr(new PictureLayerTiling(contents_scale, | 62 return make_scoped_ptr(new PictureLayerTiling(contents_scale, |
| 69 layer_bounds, | 63 layer_bounds, |
| 70 client)); | 64 client)); |
| 71 } | 65 } |
| 72 | 66 |
| 73 PictureLayerTiling::PictureLayerTiling(float contents_scale, | 67 PictureLayerTiling::PictureLayerTiling(float contents_scale, |
| 74 const gfx::Size& layer_bounds, | 68 const gfx::Size& layer_bounds, |
| 75 PictureLayerTilingClient* client) | 69 PictureLayerTilingClient* client) |
| 76 : contents_scale_(contents_scale), | 70 : contents_scale_(contents_scale), |
| 77 layer_bounds_(layer_bounds), | 71 layer_bounds_(layer_bounds), |
| 78 resolution_(NON_IDEAL_RESOLUTION), | 72 resolution_(NON_IDEAL_RESOLUTION), |
| 79 client_(client), | 73 client_(client), |
| 80 tiling_data_(gfx::Size(), gfx::Size(), true), | 74 tiling_data_(gfx::Size(), gfx::Size(), true), |
| 81 last_impl_frame_time_in_seconds_(0.0), | 75 last_impl_frame_time_in_seconds_(0.0), |
| 76 content_to_screen_scale_(1.0f), | |
| 82 has_visible_rect_tiles_(false), | 77 has_visible_rect_tiles_(false), |
| 83 has_skewport_rect_tiles_(false), | 78 has_skewport_rect_tiles_(false), |
| 84 has_soon_border_rect_tiles_(false), | 79 has_soon_border_rect_tiles_(false), |
| 85 has_eventually_rect_tiles_(false), | 80 has_eventually_rect_tiles_(false), |
| 86 eviction_tiles_cache_valid_(false), | 81 eviction_tiles_cache_valid_(false), |
| 87 eviction_cache_tree_priority_(SAME_PRIORITY_FOR_BOTH_TREES) { | 82 eviction_cache_tree_priority_(SAME_PRIORITY_FOR_BOTH_TREES) { |
| 88 gfx::Size content_bounds = | 83 gfx::Size content_bounds = |
| 89 gfx::ToCeiledSize(gfx::ScaleSize(layer_bounds, contents_scale)); | 84 gfx::ToCeiledSize(gfx::ScaleSize(layer_bounds, contents_scale)); |
| 90 gfx::Size tile_size = client_->CalculateTileSize(content_bounds); | 85 gfx::Size tile_size = client_->CalculateTileSize(content_bounds); |
| 91 | 86 |
| 92 DCHECK(!gfx::ToFlooredSize( | 87 DCHECK(!gfx::ToFlooredSize( |
| 93 gfx::ScaleSize(layer_bounds, contents_scale)).IsEmpty()) << | 88 gfx::ScaleSize(layer_bounds, contents_scale)).IsEmpty()) << |
| 94 "Tiling created with scale too small as contents become empty." << | 89 "Tiling created with scale too small as contents become empty." << |
| 95 " Layer bounds: " << layer_bounds.ToString() << | 90 " Layer bounds: " << layer_bounds.ToString() << |
| 96 " Contents scale: " << contents_scale; | 91 " Contents scale: " << contents_scale; |
| 97 | 92 |
| 98 tiling_data_.SetTilingSize(content_bounds); | 93 tiling_data_.SetTilingSize(content_bounds); |
| 99 tiling_data_.SetMaxTextureSize(tile_size); | 94 tiling_data_.SetMaxTextureSize(tile_size); |
| 100 } | 95 } |
| 101 | 96 |
| 102 PictureLayerTiling::~PictureLayerTiling() { | 97 PictureLayerTiling::~PictureLayerTiling() { |
| 103 for (TileMap::const_iterator it = tiles_.begin(); it != tiles_.end(); ++it) | |
| 104 ReleaseTile(it->second.get(), client_->GetTree()); | |
| 105 } | 98 } |
| 106 | 99 |
| 107 void PictureLayerTiling::SetClient(PictureLayerTilingClient* client) { | 100 void PictureLayerTiling::SetClient(PictureLayerTilingClient* client) { |
| 108 client_ = client; | 101 client_ = client; |
| 109 } | 102 } |
| 110 | 103 |
| 111 Tile* PictureLayerTiling::CreateTile(int i, | 104 Tile* PictureLayerTiling::CreateTile(int i, |
| 112 int j, | 105 int j, |
| 113 const PictureLayerTiling* twin_tiling) { | 106 const PictureLayerTiling* twin_tiling) { |
| 114 TileMapKey key(i, j); | 107 TileMapKey key(i, j); |
| 115 DCHECK(tiles_.find(key) == tiles_.end()); | 108 DCHECK(tiles_.find(key) == tiles_.end()); |
| 116 | 109 |
| 117 gfx::Rect paint_rect = tiling_data_.TileBoundsWithBorder(i, j); | 110 gfx::Rect paint_rect = tiling_data_.TileBoundsWithBorder(i, j); |
| 118 gfx::Rect tile_rect = paint_rect; | 111 gfx::Rect tile_rect = paint_rect; |
| 119 tile_rect.set_size(tiling_data_.max_texture_size()); | 112 tile_rect.set_size(tiling_data_.max_texture_size()); |
| 120 | 113 |
| 121 // Check our twin for a valid tile. | 114 // Check our twin for a valid tile. |
| 122 if (twin_tiling && | 115 if (twin_tiling && |
| 123 tiling_data_.max_texture_size() == | 116 tiling_data_.max_texture_size() == |
| 124 twin_tiling->tiling_data_.max_texture_size()) { | 117 twin_tiling->tiling_data_.max_texture_size()) { |
| 125 if (Tile* candidate_tile = twin_tiling->TileAt(i, j)) { | 118 if (Tile* candidate_tile = twin_tiling->TileAt(i, j)) { |
| 126 gfx::Rect rect = | 119 gfx::Rect rect = |
| 127 gfx::ScaleToEnclosingRect(paint_rect, 1.0f / contents_scale_); | 120 gfx::ScaleToEnclosingRect(paint_rect, 1.0f / contents_scale_); |
| 128 if (!client_->GetInvalidation()->Intersects(rect)) { | 121 if (!client_->GetInvalidation()->Intersects(rect)) { |
| 122 DCHECK_EQ(i, candidate_tile->tiling_i_index()); | |
| 123 DCHECK_EQ(j, candidate_tile->tiling_j_index()); | |
| 129 tiles_[key] = candidate_tile; | 124 tiles_[key] = candidate_tile; |
| 130 return candidate_tile; | 125 return candidate_tile; |
| 131 } | 126 } |
| 132 } | 127 } |
| 133 } | 128 } |
| 134 | 129 |
| 135 // Create a new tile because our twin didn't have a valid one. | 130 // Create a new tile because our twin didn't have a valid one. |
| 136 scoped_refptr<Tile> tile = client_->CreateTile(this, tile_rect); | 131 scoped_refptr<Tile> tile = client_->CreateTile(this, tile_rect); |
| 137 if (tile.get()) | 132 if (tile.get()) { |
| 133 tile->set_tiling_index(i, j); | |
| 138 tiles_[key] = tile; | 134 tiles_[key] = tile; |
| 135 } | |
| 139 return tile.get(); | 136 return tile.get(); |
| 140 } | 137 } |
| 141 | 138 |
| 142 void PictureLayerTiling::CreateMissingTilesInLiveTilesRect() { | 139 void PictureLayerTiling::CreateMissingTilesInLiveTilesRect() { |
| 143 const PictureLayerTiling* twin_tiling = client_->GetTwinTiling(this); | 140 const PictureLayerTiling* twin_tiling = client_->GetTwinTiling(this); |
| 144 bool include_borders = true; | 141 bool include_borders = true; |
| 145 for (TilingData::Iterator iter( | 142 for (TilingData::Iterator iter( |
| 146 &tiling_data_, live_tiles_rect_, include_borders); | 143 &tiling_data_, live_tiles_rect_, include_borders); |
| 147 iter; | 144 iter; |
| 148 ++iter) { | 145 ++iter) { |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 216 bool include_borders = true; | 213 bool include_borders = true; |
| 217 for (TilingData::Iterator iter( | 214 for (TilingData::Iterator iter( |
| 218 &tiling_data_, content_rect, include_borders); | 215 &tiling_data_, content_rect, include_borders); |
| 219 iter; | 216 iter; |
| 220 ++iter) { | 217 ++iter) { |
| 221 TileMapKey key(iter.index()); | 218 TileMapKey key(iter.index()); |
| 222 TileMap::iterator find = tiles_.find(key); | 219 TileMap::iterator find = tiles_.find(key); |
| 223 if (find == tiles_.end()) | 220 if (find == tiles_.end()) |
| 224 continue; | 221 continue; |
| 225 | 222 |
| 226 ReleaseTile(find->second.get(), client_->GetTree()); | |
| 227 | |
| 228 tiles_.erase(find); | 223 tiles_.erase(find); |
| 229 new_tile_keys.push_back(key); | 224 new_tile_keys.push_back(key); |
| 230 } | 225 } |
| 231 } | 226 } |
| 232 | 227 |
| 233 if (recreate_invalidated_tiles && !new_tile_keys.empty()) { | 228 if (recreate_invalidated_tiles && !new_tile_keys.empty()) { |
| 234 for (size_t i = 0; i < new_tile_keys.size(); ++i) { | 229 for (size_t i = 0; i < new_tile_keys.size(); ++i) { |
| 235 // Don't try to share a tile with the twin layer, it's been invalidated so | 230 // Don't try to share a tile with the twin layer, it's been invalidated so |
| 236 // we have to make our own tile here. | 231 // we have to make our own tile here. |
| 237 const PictureLayerTiling* twin_tiling = NULL; | 232 const PictureLayerTiling* twin_tiling = NULL; |
| (...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 385 | 380 |
| 386 return texture_rect; | 381 return texture_rect; |
| 387 } | 382 } |
| 388 | 383 |
| 389 gfx::Size PictureLayerTiling::CoverageIterator::texture_size() const { | 384 gfx::Size PictureLayerTiling::CoverageIterator::texture_size() const { |
| 390 return tiling_->tiling_data_.max_texture_size(); | 385 return tiling_->tiling_data_.max_texture_size(); |
| 391 } | 386 } |
| 392 | 387 |
| 393 void PictureLayerTiling::Reset() { | 388 void PictureLayerTiling::Reset() { |
| 394 live_tiles_rect_ = gfx::Rect(); | 389 live_tiles_rect_ = gfx::Rect(); |
| 395 for (TileMap::const_iterator it = tiles_.begin(); it != tiles_.end(); ++it) | |
| 396 ReleaseTile(it->second.get(), client_->GetTree()); | |
| 397 tiles_.clear(); | 390 tiles_.clear(); |
| 398 } | 391 } |
| 399 | 392 |
| 400 gfx::Rect PictureLayerTiling::ComputeSkewport( | 393 gfx::Rect PictureLayerTiling::ComputeSkewport( |
| 401 double current_frame_time_in_seconds, | 394 double current_frame_time_in_seconds, |
| 402 const gfx::Rect& visible_rect_in_content_space) const { | 395 const gfx::Rect& visible_rect_in_content_space) const { |
| 403 gfx::Rect skewport = visible_rect_in_content_space; | 396 gfx::Rect skewport = visible_rect_in_content_space; |
| 404 if (last_impl_frame_time_in_seconds_ == 0.0) | 397 if (last_impl_frame_time_in_seconds_ == 0.0) |
| 405 return skewport; | 398 return skewport; |
| 406 | 399 |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 461 | 454 |
| 462 gfx::Rect visible_rect_in_content_space = | 455 gfx::Rect visible_rect_in_content_space = |
| 463 gfx::ScaleToEnclosingRect(visible_layer_rect, contents_scale_); | 456 gfx::ScaleToEnclosingRect(visible_layer_rect, contents_scale_); |
| 464 | 457 |
| 465 if (tiling_size().IsEmpty()) { | 458 if (tiling_size().IsEmpty()) { |
| 466 last_impl_frame_time_in_seconds_ = current_frame_time_in_seconds; | 459 last_impl_frame_time_in_seconds_ = current_frame_time_in_seconds; |
| 467 last_visible_rect_in_content_space_ = visible_rect_in_content_space; | 460 last_visible_rect_in_content_space_ = visible_rect_in_content_space; |
| 468 return; | 461 return; |
| 469 } | 462 } |
| 470 | 463 |
| 464 // Calculate the skewport. | |
| 465 gfx::Rect skewport = ComputeSkewport(current_frame_time_in_seconds, | |
| 466 visible_rect_in_content_space); | |
| 467 DCHECK(skewport.Contains(visible_rect_in_content_space)); | |
| 468 | |
| 469 // Calculate the eventually/live tiles rect. | |
| 471 size_t max_tiles_for_interest_area = client_->GetMaxTilesForInterestArea(); | 470 size_t max_tiles_for_interest_area = client_->GetMaxTilesForInterestArea(); |
| 472 | 471 |
| 473 gfx::Size tile_size = tiling_data_.max_texture_size(); | 472 gfx::Size tile_size = tiling_data_.max_texture_size(); |
| 474 int64 eventually_rect_area = | 473 int64 eventually_rect_area = |
| 475 max_tiles_for_interest_area * tile_size.width() * tile_size.height(); | 474 max_tiles_for_interest_area * tile_size.width() * tile_size.height(); |
| 476 | 475 |
| 477 gfx::Rect skewport = ComputeSkewport(current_frame_time_in_seconds, | |
| 478 visible_rect_in_content_space); | |
| 479 DCHECK(skewport.Contains(visible_rect_in_content_space)); | |
| 480 | |
| 481 gfx::Rect eventually_rect = | 476 gfx::Rect eventually_rect = |
| 482 ExpandRectEquallyToAreaBoundedBy(visible_rect_in_content_space, | 477 ExpandRectEquallyToAreaBoundedBy(visible_rect_in_content_space, |
| 483 eventually_rect_area, | 478 eventually_rect_area, |
| 484 gfx::Rect(tiling_size()), | 479 gfx::Rect(tiling_size()), |
| 485 &expansion_cache_); | 480 &expansion_cache_); |
| 486 | 481 |
| 487 DCHECK(eventually_rect.IsEmpty() || | 482 DCHECK(eventually_rect.IsEmpty() || |
| 488 gfx::Rect(tiling_size()).Contains(eventually_rect)) | 483 gfx::Rect(tiling_size()).Contains(eventually_rect)) |
| 489 << "tiling_size: " << tiling_size().ToString() | 484 << "tiling_size: " << tiling_size().ToString() |
| 490 << " eventually_rect: " << eventually_rect.ToString(); | 485 << " eventually_rect: " << eventually_rect.ToString(); |
| 491 | 486 |
| 487 // Calculate the soon border rect. | |
| 488 content_to_screen_scale_ = 1.0f / (contents_scale_ * ideal_contents_scale); | |
|
USE eero AT chromium.org
2014/08/19 08:40:20
This should be
content_to_screen_scale_ = ideal_
vmpstr
2014/08/19 18:04:33
Good point, I'll rebase.
| |
| 489 gfx::Rect soon_border_rect = visible_rect_in_content_space; | |
| 490 float border = kSoonBorderDistanceInScreenPixels / content_to_screen_scale_; | |
| 491 soon_border_rect.Inset(-border, -border, -border, -border); | |
| 492 | |
| 493 // Update the tiling state. | |
| 492 SetLiveTilesRect(eventually_rect); | 494 SetLiveTilesRect(eventually_rect); |
| 493 | 495 |
| 494 last_impl_frame_time_in_seconds_ = current_frame_time_in_seconds; | 496 last_impl_frame_time_in_seconds_ = current_frame_time_in_seconds; |
| 495 last_visible_rect_in_content_space_ = visible_rect_in_content_space; | 497 last_visible_rect_in_content_space_ = visible_rect_in_content_space; |
| 496 | 498 |
| 497 eviction_tiles_cache_valid_ = false; | 499 eviction_tiles_cache_valid_ = false; |
| 498 | 500 |
| 499 TilePriority now_priority(resolution_, TilePriority::NOW, 0); | |
| 500 float content_to_screen_scale = | |
| 501 1.0f / (contents_scale_ * ideal_contents_scale); | |
| 502 | |
| 503 // Assign now priority to all visible tiles. | |
| 504 bool include_borders = true; | |
| 505 has_visible_rect_tiles_ = false; | |
| 506 for (TilingData::Iterator iter( | |
| 507 &tiling_data_, visible_rect_in_content_space, include_borders); | |
| 508 iter; | |
| 509 ++iter) { | |
| 510 TileMap::iterator find = tiles_.find(iter.index()); | |
| 511 if (find == tiles_.end()) | |
| 512 continue; | |
| 513 has_visible_rect_tiles_ = true; | |
| 514 Tile* tile = find->second.get(); | |
| 515 | |
| 516 tile->SetPriority(tree, now_priority); | |
| 517 | |
| 518 // Set whether tile is occluded or not. | |
| 519 bool is_occluded = false; | |
| 520 if (occlusion_tracker) { | |
| 521 gfx::Rect tile_query_rect = ScaleToEnclosingRect( | |
| 522 IntersectRects(tile->content_rect(), visible_rect_in_content_space), | |
| 523 1.0f / contents_scale_); | |
| 524 // TODO(vmpstr): Remove render_target and draw_transform from the | |
| 525 // parameters so they can be hidden from the tiling. | |
| 526 is_occluded = occlusion_tracker->Occluded( | |
| 527 render_target, tile_query_rect, draw_transform); | |
| 528 } | |
| 529 tile->set_is_occluded(tree, is_occluded); | |
| 530 } | |
| 531 | |
| 532 // Assign soon priority to skewport tiles. | |
| 533 has_skewport_rect_tiles_ = false; | |
| 534 for (TilingData::DifferenceIterator iter( | |
| 535 &tiling_data_, skewport, visible_rect_in_content_space); | |
| 536 iter; | |
| 537 ++iter) { | |
| 538 TileMap::iterator find = tiles_.find(iter.index()); | |
| 539 if (find == tiles_.end()) | |
| 540 continue; | |
| 541 has_skewport_rect_tiles_ = true; | |
| 542 Tile* tile = find->second.get(); | |
| 543 | |
| 544 gfx::Rect tile_bounds = | |
| 545 tiling_data_.TileBounds(iter.index_x(), iter.index_y()); | |
| 546 | |
| 547 float distance_to_visible = | |
| 548 visible_rect_in_content_space.ManhattanInternalDistance(tile_bounds) * | |
| 549 content_to_screen_scale; | |
| 550 | |
| 551 TilePriority priority(resolution_, TilePriority::SOON, distance_to_visible); | |
| 552 tile->SetPriority(tree, priority); | |
| 553 } | |
| 554 | |
| 555 // Assign eventually priority to interest rect tiles. | |
| 556 has_eventually_rect_tiles_ = false; | |
| 557 for (TilingData::DifferenceIterator iter( | |
| 558 &tiling_data_, eventually_rect, skewport); | |
| 559 iter; | |
| 560 ++iter) { | |
| 561 TileMap::iterator find = tiles_.find(iter.index()); | |
| 562 if (find == tiles_.end()) | |
| 563 continue; | |
| 564 has_eventually_rect_tiles_ = true; | |
| 565 Tile* tile = find->second.get(); | |
| 566 | |
| 567 gfx::Rect tile_bounds = | |
| 568 tiling_data_.TileBounds(iter.index_x(), iter.index_y()); | |
| 569 | |
| 570 float distance_to_visible = | |
| 571 visible_rect_in_content_space.ManhattanInternalDistance(tile_bounds) * | |
| 572 content_to_screen_scale; | |
| 573 TilePriority priority( | |
| 574 resolution_, TilePriority::EVENTUALLY, distance_to_visible); | |
| 575 tile->SetPriority(tree, priority); | |
| 576 } | |
| 577 | |
| 578 // Upgrade the priority on border tiles to be SOON. | |
| 579 gfx::Rect soon_border_rect = visible_rect_in_content_space; | |
| 580 float border = kSoonBorderDistanceInScreenPixels / content_to_screen_scale; | |
| 581 soon_border_rect.Inset(-border, -border, -border, -border); | |
| 582 has_soon_border_rect_tiles_ = false; | |
| 583 for (TilingData::DifferenceIterator iter( | |
| 584 &tiling_data_, soon_border_rect, skewport); | |
| 585 iter; | |
| 586 ++iter) { | |
| 587 TileMap::iterator find = tiles_.find(iter.index()); | |
| 588 if (find == tiles_.end()) | |
| 589 continue; | |
| 590 has_soon_border_rect_tiles_ = true; | |
| 591 Tile* tile = find->second.get(); | |
| 592 | |
| 593 TilePriority priority(resolution_, | |
| 594 TilePriority::SOON, | |
| 595 tile->priority(tree).distance_to_visible); | |
| 596 tile->SetPriority(tree, priority); | |
| 597 } | |
| 598 | |
| 599 // Update iteration rects. | 501 // Update iteration rects. |
| 600 current_visible_rect_ = visible_rect_in_content_space; | 502 current_visible_rect_ = visible_rect_in_content_space; |
| 601 current_skewport_rect_ = skewport; | 503 current_skewport_rect_ = skewport; |
| 602 current_soon_border_rect_ = soon_border_rect; | 504 current_soon_border_rect_ = soon_border_rect; |
| 603 current_eventually_rect_ = eventually_rect; | 505 current_eventually_rect_ = eventually_rect; |
| 506 | |
| 507 // Update has_*_tiles state. | |
| 508 const gfx::Rect& tiling_rect = gfx::Rect(tiling_size()); | |
| 509 | |
| 510 has_visible_rect_tiles_ = tiling_rect.Intersects(current_visible_rect_); | |
| 511 has_skewport_rect_tiles_ = tiling_rect.Intersects(current_skewport_rect_); | |
| 512 has_soon_border_rect_tiles_ = | |
| 513 tiling_rect.Intersects(current_soon_border_rect_); | |
| 514 has_eventually_rect_tiles_ = tiling_rect.Intersects(current_eventually_rect_); | |
| 515 | |
| 516 // Update occlusion. | |
| 517 occlusion_set_.clear(); | |
| 518 if (occlusion_tracker) { | |
| 519 bool include_borders = true; | |
| 520 for (TilingData::Iterator iter( | |
| 521 &tiling_data_, visible_rect_in_content_space, include_borders); | |
| 522 iter; | |
| 523 ++iter) { | |
| 524 gfx::Rect paint_rect = | |
| 525 tiling_data_.TileBoundsWithBorder(iter.index_x(), iter.index_y()); | |
| 526 gfx::Rect tile_rect = paint_rect; | |
| 527 tile_rect.set_size(tiling_data_.max_texture_size()); | |
| 528 gfx::Rect tile_query_rect = ScaleToEnclosingRect( | |
| 529 IntersectRects(tile_rect, visible_rect_in_content_space), | |
| 530 1.0f / contents_scale_); | |
| 531 bool is_occluded = occlusion_tracker->Occluded( | |
| 532 render_target, tile_query_rect, draw_transform); | |
| 533 if (!is_occluded) | |
| 534 continue; | |
| 535 occlusion_set_.insert(iter.index()); | |
| 536 } | |
| 537 } | |
| 604 } | 538 } |
| 605 | 539 |
| 606 void PictureLayerTiling::SetLiveTilesRect( | 540 void PictureLayerTiling::SetLiveTilesRect( |
| 607 const gfx::Rect& new_live_tiles_rect) { | 541 const gfx::Rect& new_live_tiles_rect) { |
| 608 DCHECK(new_live_tiles_rect.IsEmpty() || | 542 DCHECK(new_live_tiles_rect.IsEmpty() || |
| 609 gfx::Rect(tiling_size()).Contains(new_live_tiles_rect)) | 543 gfx::Rect(tiling_size()).Contains(new_live_tiles_rect)) |
| 610 << "tiling_size: " << tiling_size().ToString() | 544 << "tiling_size: " << tiling_size().ToString() |
| 611 << " new_live_tiles_rect: " << new_live_tiles_rect.ToString(); | 545 << " new_live_tiles_rect: " << new_live_tiles_rect.ToString(); |
| 612 if (live_tiles_rect_ == new_live_tiles_rect) | 546 if (live_tiles_rect_ == new_live_tiles_rect) |
| 613 return; | 547 return; |
| 614 | 548 |
| 615 // Iterate to delete all tiles outside of our new live_tiles rect. | 549 // Iterate to delete all tiles outside of our new live_tiles rect. |
| 616 for (TilingData::DifferenceIterator iter(&tiling_data_, | 550 for (TilingData::DifferenceIterator iter(&tiling_data_, |
| 617 live_tiles_rect_, | 551 live_tiles_rect_, |
| 618 new_live_tiles_rect); | 552 new_live_tiles_rect); |
| 619 iter; | 553 iter; |
| 620 ++iter) { | 554 ++iter) { |
| 621 TileMapKey key(iter.index()); | 555 TileMapKey key(iter.index()); |
| 622 TileMap::iterator found = tiles_.find(key); | 556 TileMap::iterator found = tiles_.find(key); |
| 623 // If the tile was outside of the recorded region, it won't exist even | 557 // If the tile was outside of the recorded region, it won't exist even |
| 624 // though it was in the live rect. | 558 // though it was in the live rect. |
| 625 if (found != tiles_.end()) { | 559 if (found != tiles_.end()) |
| 626 ReleaseTile(found->second.get(), client_->GetTree()); | |
| 627 tiles_.erase(found); | 560 tiles_.erase(found); |
| 628 } | |
| 629 } | 561 } |
| 630 | 562 |
| 631 const PictureLayerTiling* twin_tiling = client_->GetTwinTiling(this); | 563 const PictureLayerTiling* twin_tiling = client_->GetTwinTiling(this); |
| 632 | 564 |
| 633 // Iterate to allocate new tiles for all regions with newly exposed area. | 565 // Iterate to allocate new tiles for all regions with newly exposed area. |
| 634 for (TilingData::DifferenceIterator iter(&tiling_data_, | 566 for (TilingData::DifferenceIterator iter(&tiling_data_, |
| 635 new_live_tiles_rect, | 567 new_live_tiles_rect, |
| 636 live_tiles_rect_); | 568 live_tiles_rect_); |
| 637 iter; | 569 iter; |
| 638 ++iter) { | 570 ++iter) { |
| 639 TileMapKey key(iter.index()); | 571 TileMapKey key(iter.index()); |
| 640 CreateTile(key.first, key.second, twin_tiling); | 572 CreateTile(key.first, key.second, twin_tiling); |
| 641 } | 573 } |
| 642 | 574 |
| 643 live_tiles_rect_ = new_live_tiles_rect; | 575 live_tiles_rect_ = new_live_tiles_rect; |
| 644 } | 576 } |
| 645 | 577 |
| 646 void PictureLayerTiling::DidBecomeRecycled() { | 578 bool PictureLayerTiling::IsTileOccluded(const Tile* tile) const { |
| 647 // DidBecomeActive below will set the active priority for tiles that are | 579 DCHECK(tile); |
| 648 // still in the tree. Calling this first on an active tiling that is becoming | 580 bool is_occluded = occlusion_set_.count(std::make_pair( |
| 649 // recycled takes care of tiles that are no longer in the active tree (eg. | 581 tile->tiling_i_index(), tile->tiling_j_index())) != 0; |
| 650 // due to a pending invalidation). | 582 return is_occluded; |
| 651 for (TileMap::const_iterator it = tiles_.begin(); it != tiles_.end(); ++it) { | |
| 652 it->second->SetPriority(ACTIVE_TREE, TilePriority()); | |
| 653 } | |
| 654 } | 583 } |
| 655 | 584 |
| 656 void PictureLayerTiling::DidBecomeActive() { | 585 bool PictureLayerTiling::IsTileRequiredForActivation(const Tile* tile) const { |
| 657 PicturePileImpl* active_pile = client_->GetPile(); | 586 if (resolution_ != HIGH_RESOLUTION) |
| 658 for (TileMap::const_iterator it = tiles_.begin(); it != tiles_.end(); ++it) { | 587 return false; |
| 659 it->second->SetPriority(ACTIVE_TREE, it->second->priority(PENDING_TREE)); | |
| 660 it->second->SetPriority(PENDING_TREE, TilePriority()); | |
| 661 | 588 |
| 662 // Tile holds a ref onto a picture pile. If the tile never gets invalidated | 589 WhichTree tree = client_->GetTree(); |
| 663 // and recreated, then that picture pile ref could exist indefinitely. To | 590 if (tree != PENDING_TREE) |
| 664 // prevent this, ask the client to update the pile to its own ref. This | 591 return false; |
| 665 // will cause PicturePileImpls and their clones to get deleted once the | 592 |
| 666 // corresponding PictureLayerImpl and any in flight raster jobs go out of | 593 if (IsTileOccluded(tile)) |
| 667 // scope. | 594 return false; |
| 668 it->second->set_picture_pile(active_pile); | 595 |
| 596 if (client_->RequiresHighResToDraw()) | |
| 597 return true; | |
| 598 | |
| 599 const PictureLayerTiling* twin_tiling = client_->GetTwinTiling(this); | |
| 600 if (!twin_tiling) | |
| 601 return true; | |
| 602 | |
| 603 if (twin_tiling->layer_bounds() != layer_bounds()) | |
| 604 return true; | |
| 605 | |
| 606 if (twin_tiling->current_visible_rect_ != current_visible_rect_) | |
| 607 return true; | |
| 608 | |
| 609 Tile* twin_tile = | |
| 610 twin_tiling->TileAt(tile->tiling_i_index(), tile->tiling_j_index()); | |
|
danakj
2014/08/18 19:29:13
:( We do this every time we want to see if we can
vmpstr
2014/08/18 19:49:52
I'll do this in a separate patch.
| |
| 611 if (!twin_tile || twin_tile == tile) | |
| 612 return false; | |
| 613 | |
| 614 return true; | |
| 615 } | |
| 616 | |
| 617 void PictureLayerTiling::UpdateTileAndTwinPriority(Tile* tile) const { | |
| 618 const PictureLayerTiling* twin_tiling = client_->GetTwinTiling(this); | |
| 619 if (twin_tiling) | |
| 620 twin_tiling->UpdateTilePriority(tile); | |
| 621 UpdateTilePriority(tile); | |
| 622 } | |
| 623 | |
| 624 void PictureLayerTiling::UpdateTilePriority(Tile* tile) const { | |
| 625 WhichTree tree = client_->GetTree(); | |
| 626 | |
| 627 if (tree == PENDING_TREE) | |
| 628 tile->set_required_for_activation(false); | |
| 629 tile->set_is_occluded(tree, false); | |
| 630 | |
| 631 if (TileAt(tile->tiling_i_index(), tile->tiling_j_index()) != tile) { | |
| 632 tile->SetPriority(tree, TilePriority()); | |
| 633 return; | |
| 669 } | 634 } |
| 635 | |
| 636 gfx::Rect tile_bounds = tiling_data_.TileBoundsWithBorder( | |
| 637 tile->tiling_i_index(), tile->tiling_j_index()); | |
| 638 | |
| 639 if (current_visible_rect_.Intersects(tile_bounds)) { | |
| 640 tile->SetPriority(tree, TilePriority(resolution_, TilePriority::NOW, 0)); | |
| 641 if (tree == PENDING_TREE) | |
| 642 tile->set_required_for_activation(IsTileRequiredForActivation(tile)); | |
| 643 tile->set_is_occluded(tree, IsTileOccluded(tile)); | |
| 644 return; | |
| 645 } | |
| 646 | |
| 647 float distance_to_visible = | |
| 648 current_visible_rect_.ManhattanInternalDistance(tile_bounds) * | |
| 649 content_to_screen_scale_; | |
| 650 | |
| 651 if (current_soon_border_rect_.Intersects(tile_bounds) || | |
| 652 current_skewport_rect_.Intersects(tile_bounds)) { | |
| 653 tile->SetPriority( | |
| 654 tree, | |
| 655 TilePriority(resolution_, TilePriority::SOON, distance_to_visible)); | |
| 656 return; | |
| 657 } | |
| 658 | |
| 659 tile->SetPriority( | |
| 660 tree, | |
| 661 TilePriority(resolution_, TilePriority::EVENTUALLY, distance_to_visible)); | |
| 670 } | 662 } |
| 671 | 663 |
| 672 void PictureLayerTiling::AsValueInto(base::debug::TracedValue* state) const { | 664 void PictureLayerTiling::AsValueInto(base::debug::TracedValue* state) const { |
| 673 state->SetInteger("num_tiles", tiles_.size()); | 665 state->SetInteger("num_tiles", tiles_.size()); |
| 674 state->SetDouble("content_scale", contents_scale_); | 666 state->SetDouble("content_scale", contents_scale_); |
| 675 state->BeginDictionary("tiling_size"); | 667 state->BeginDictionary("tiling_size"); |
| 676 MathUtil::AddToTracedValue(tiling_size(), state); | 668 MathUtil::AddToTracedValue(tiling_size(), state); |
| 677 state->EndDictionary(); | 669 state->EndDictionary(); |
| 678 } | 670 } |
| 679 | 671 |
| (...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 842 return; | 834 return; |
| 843 | 835 |
| 844 eviction_tiles_now_.clear(); | 836 eviction_tiles_now_.clear(); |
| 845 eviction_tiles_now_and_rfa_.clear(); | 837 eviction_tiles_now_and_rfa_.clear(); |
| 846 eviction_tiles_soon_.clear(); | 838 eviction_tiles_soon_.clear(); |
| 847 eviction_tiles_soon_and_rfa_.clear(); | 839 eviction_tiles_soon_and_rfa_.clear(); |
| 848 eviction_tiles_eventually_.clear(); | 840 eviction_tiles_eventually_.clear(); |
| 849 eviction_tiles_eventually_and_rfa_.clear(); | 841 eviction_tiles_eventually_and_rfa_.clear(); |
| 850 | 842 |
| 851 for (TileMap::iterator it = tiles_.begin(); it != tiles_.end(); ++it) { | 843 for (TileMap::iterator it = tiles_.begin(); it != tiles_.end(); ++it) { |
| 852 // TODO(vmpstr): This should update the priority if UpdateTilePriorities | |
| 853 // changes not to do this. | |
| 854 Tile* tile = it->second; | 844 Tile* tile = it->second; |
| 845 UpdateTileAndTwinPriority(tile); | |
| 855 const TilePriority& priority = | 846 const TilePriority& priority = |
| 856 tile->priority_for_tree_priority(tree_priority); | 847 tile->priority_for_tree_priority(tree_priority); |
| 857 switch (priority.priority_bin) { | 848 switch (priority.priority_bin) { |
| 858 case TilePriority::EVENTUALLY: | 849 case TilePriority::EVENTUALLY: |
| 859 if (tile->required_for_activation()) | 850 if (tile->required_for_activation()) |
| 860 eviction_tiles_eventually_and_rfa_.push_back(tile); | 851 eviction_tiles_eventually_and_rfa_.push_back(tile); |
| 861 else | 852 else |
| 862 eviction_tiles_eventually_.push_back(tile); | 853 eviction_tiles_eventually_.push_back(tile); |
| 863 break; | 854 break; |
| 864 case TilePriority::SOON: | 855 case TilePriority::SOON: |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 936 visible_iterator_ = TilingData::Iterator(&tiling_->tiling_data_, | 927 visible_iterator_ = TilingData::Iterator(&tiling_->tiling_data_, |
| 937 tiling_->current_visible_rect_, | 928 tiling_->current_visible_rect_, |
| 938 true /* include_borders */); | 929 true /* include_borders */); |
| 939 if (!visible_iterator_) { | 930 if (!visible_iterator_) { |
| 940 AdvancePhase(); | 931 AdvancePhase(); |
| 941 return; | 932 return; |
| 942 } | 933 } |
| 943 | 934 |
| 944 current_tile_ = | 935 current_tile_ = |
| 945 tiling_->TileAt(visible_iterator_.index_x(), visible_iterator_.index_y()); | 936 tiling_->TileAt(visible_iterator_.index_x(), visible_iterator_.index_y()); |
| 946 if (!current_tile_ || !TileNeedsRaster(current_tile_)) | 937 if (!current_tile_ || !TileNeedsRaster(current_tile_)) { |
| 947 ++(*this); | 938 ++(*this); |
| 939 return; | |
| 940 } | |
| 941 tiling_->UpdateTileAndTwinPriority(current_tile_); | |
| 948 } | 942 } |
| 949 | 943 |
| 950 PictureLayerTiling::TilingRasterTileIterator::~TilingRasterTileIterator() {} | 944 PictureLayerTiling::TilingRasterTileIterator::~TilingRasterTileIterator() {} |
| 951 | 945 |
| 952 void PictureLayerTiling::TilingRasterTileIterator::AdvancePhase() { | 946 void PictureLayerTiling::TilingRasterTileIterator::AdvancePhase() { |
| 953 DCHECK_LT(phase_, EVENTUALLY_RECT); | 947 DCHECK_LT(phase_, EVENTUALLY_RECT); |
| 954 | 948 |
| 955 do { | 949 do { |
| 956 phase_ = static_cast<Phase>(phase_ + 1); | 950 phase_ = static_cast<Phase>(phase_ + 1); |
| 957 switch (phase_) { | 951 switch (phase_) { |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 998 if (current_tile_ && TileNeedsRaster(current_tile_)) | 992 if (current_tile_ && TileNeedsRaster(current_tile_)) |
| 999 break; | 993 break; |
| 1000 ++spiral_iterator_; | 994 ++spiral_iterator_; |
| 1001 } | 995 } |
| 1002 | 996 |
| 1003 if (!spiral_iterator_ && phase_ == EVENTUALLY_RECT) { | 997 if (!spiral_iterator_ && phase_ == EVENTUALLY_RECT) { |
| 1004 current_tile_ = NULL; | 998 current_tile_ = NULL; |
| 1005 break; | 999 break; |
| 1006 } | 1000 } |
| 1007 } while (!spiral_iterator_); | 1001 } while (!spiral_iterator_); |
| 1002 | |
| 1003 if (current_tile_) | |
| 1004 tiling_->UpdateTileAndTwinPriority(current_tile_); | |
| 1008 } | 1005 } |
| 1009 | 1006 |
| 1010 PictureLayerTiling::TilingRasterTileIterator& | 1007 PictureLayerTiling::TilingRasterTileIterator& |
| 1011 PictureLayerTiling::TilingRasterTileIterator:: | 1008 PictureLayerTiling::TilingRasterTileIterator:: |
| 1012 operator++() { | 1009 operator++() { |
| 1013 current_tile_ = NULL; | 1010 current_tile_ = NULL; |
| 1014 while (!current_tile_ || !TileNeedsRaster(current_tile_)) { | 1011 while (!current_tile_ || !TileNeedsRaster(current_tile_)) { |
| 1015 std::pair<int, int> next_index; | 1012 std::pair<int, int> next_index; |
| 1016 switch (phase_) { | 1013 switch (phase_) { |
| 1017 case VISIBLE_RECT: | 1014 case VISIBLE_RECT: |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 1035 ++spiral_iterator_; | 1032 ++spiral_iterator_; |
| 1036 if (!spiral_iterator_) { | 1033 if (!spiral_iterator_) { |
| 1037 current_tile_ = NULL; | 1034 current_tile_ = NULL; |
| 1038 return *this; | 1035 return *this; |
| 1039 } | 1036 } |
| 1040 next_index = spiral_iterator_.index(); | 1037 next_index = spiral_iterator_.index(); |
| 1041 break; | 1038 break; |
| 1042 } | 1039 } |
| 1043 current_tile_ = tiling_->TileAt(next_index.first, next_index.second); | 1040 current_tile_ = tiling_->TileAt(next_index.first, next_index.second); |
| 1044 } | 1041 } |
| 1042 | |
| 1043 if (current_tile_) | |
| 1044 tiling_->UpdateTileAndTwinPriority(current_tile_); | |
| 1045 return *this; | 1045 return *this; |
| 1046 } | 1046 } |
| 1047 | 1047 |
| 1048 PictureLayerTiling::TilingEvictionTileIterator::TilingEvictionTileIterator() | 1048 PictureLayerTiling::TilingEvictionTileIterator::TilingEvictionTileIterator() |
| 1049 : eviction_tiles_(NULL), current_eviction_tiles_index_(0u) { | 1049 : eviction_tiles_(NULL), current_eviction_tiles_index_(0u) { |
| 1050 } | 1050 } |
| 1051 | 1051 |
| 1052 PictureLayerTiling::TilingEvictionTileIterator::TilingEvictionTileIterator( | 1052 PictureLayerTiling::TilingEvictionTileIterator::TilingEvictionTileIterator( |
| 1053 PictureLayerTiling* tiling, | 1053 PictureLayerTiling* tiling, |
| 1054 TreePriority tree_priority, | 1054 TreePriority tree_priority, |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 1085 DCHECK(*this); | 1085 DCHECK(*this); |
| 1086 do { | 1086 do { |
| 1087 ++current_eviction_tiles_index_; | 1087 ++current_eviction_tiles_index_; |
| 1088 } while (current_eviction_tiles_index_ != eviction_tiles_->size() && | 1088 } while (current_eviction_tiles_index_ != eviction_tiles_->size() && |
| 1089 !(*eviction_tiles_)[current_eviction_tiles_index_]->HasResources()); | 1089 !(*eviction_tiles_)[current_eviction_tiles_index_]->HasResources()); |
| 1090 | 1090 |
| 1091 return *this; | 1091 return *this; |
| 1092 } | 1092 } |
| 1093 | 1093 |
| 1094 } // namespace cc | 1094 } // namespace cc |
| OLD | NEW |