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/debug/trace_event.h" | 12 #include "base/debug/trace_event.h" |
| 13 #include "base/debug/trace_event_argument.h" | 13 #include "base/debug/trace_event_argument.h" |
| 14 #include "base/logging.h" | 14 #include "base/logging.h" |
| 15 #include "cc/base/math_util.h" | 15 #include "cc/base/math_util.h" |
| 16 #include "cc/resources/tile.h" | 16 #include "cc/resources/tile.h" |
| 17 #include "cc/resources/tile_priority.h" | 17 #include "cc/resources/tile_priority.h" |
| 18 #include "ui/gfx/geometry/point_conversions.h" | 18 #include "ui/gfx/geometry/point_conversions.h" |
| 19 #include "ui/gfx/geometry/rect_conversions.h" | 19 #include "ui/gfx/geometry/rect_conversions.h" |
| 20 #include "ui/gfx/geometry/safe_integer_conversions.h" | 20 #include "ui/gfx/geometry/safe_integer_conversions.h" |
| 21 #include "ui/gfx/geometry/size_conversions.h" | 21 #include "ui/gfx/geometry/size_conversions.h" |
| 22 | 22 |
| 23 namespace cc { | 23 namespace cc { |
| 24 namespace { | 24 namespace { |
| 25 | 25 |
| 26 const float kSoonBorderDistanceInScreenPixels = 312.f; | 26 const float kSoonBorderDistanceInScreenPixels = 312.f; |
| 27 | 27 |
| 28 class TileEvictionOrder { | |
| 29 public: | |
| 30 explicit TileEvictionOrder(TreePriority tree_priority) | |
| 31 : tree_priority_(tree_priority) {} | |
| 32 ~TileEvictionOrder() {} | |
| 33 | |
| 34 bool operator()(const Tile* a, const Tile* b) { | |
| 35 const TilePriority& a_priority = | |
| 36 a->priority_for_tree_priority(tree_priority_); | |
| 37 const TilePriority& b_priority = | |
| 38 b->priority_for_tree_priority(tree_priority_); | |
| 39 | |
| 40 DCHECK(a_priority.priority_bin == b_priority.priority_bin); | |
| 41 DCHECK(a->required_for_activation() == b->required_for_activation()); | |
| 42 | |
| 43 // Or if a is occluded and b is unoccluded. | |
| 44 bool a_is_occluded = a->is_occluded_for_tree_priority(tree_priority_); | |
| 45 bool b_is_occluded = b->is_occluded_for_tree_priority(tree_priority_); | |
| 46 if (a_is_occluded != b_is_occluded) | |
| 47 return a_is_occluded; | |
| 48 | |
| 49 // Or if a is farther away from visible. | |
| 50 return a_priority.distance_to_visible > b_priority.distance_to_visible; | |
| 51 } | |
| 52 | |
| 53 private: | |
| 54 TreePriority tree_priority_; | |
| 55 }; | |
| 56 | |
| 57 } // namespace | 28 } // namespace |
| 58 | 29 |
| 59 scoped_ptr<PictureLayerTiling> PictureLayerTiling::Create( | 30 scoped_ptr<PictureLayerTiling> PictureLayerTiling::Create( |
| 60 float contents_scale, | 31 float contents_scale, |
| 61 const gfx::Size& layer_bounds, | 32 const gfx::Size& layer_bounds, |
| 62 PictureLayerTilingClient* client) { | 33 PictureLayerTilingClient* client) { |
| 63 return make_scoped_ptr(new PictureLayerTiling(contents_scale, | 34 return make_scoped_ptr(new PictureLayerTiling(contents_scale, |
| 64 layer_bounds, | 35 layer_bounds, |
| 65 client)); | 36 client)); |
| 66 } | 37 } |
| 67 | 38 |
| 68 PictureLayerTiling::PictureLayerTiling(float contents_scale, | 39 PictureLayerTiling::PictureLayerTiling(float contents_scale, |
| 69 const gfx::Size& layer_bounds, | 40 const gfx::Size& layer_bounds, |
| 70 PictureLayerTilingClient* client) | 41 PictureLayerTilingClient* client) |
| 71 : contents_scale_(contents_scale), | 42 : contents_scale_(contents_scale), |
| 72 layer_bounds_(layer_bounds), | 43 layer_bounds_(layer_bounds), |
| 73 resolution_(NON_IDEAL_RESOLUTION), | 44 resolution_(NON_IDEAL_RESOLUTION), |
| 74 client_(client), | 45 client_(client), |
| 75 tiling_data_(gfx::Size(), gfx::Size(), kBorderTexels), | 46 tiling_data_(gfx::Size(), gfx::Size(), kBorderTexels), |
| 76 last_impl_frame_time_in_seconds_(0.0), | 47 last_impl_frame_time_in_seconds_(0.0), |
| 77 content_to_screen_scale_(0.f), | 48 content_to_screen_scale_(0.f), |
| 78 can_require_tiles_for_activation_(false), | 49 can_require_tiles_for_activation_(false), |
| 79 has_visible_rect_tiles_(false), | 50 has_visible_rect_tiles_(false), |
| 80 has_skewport_rect_tiles_(false), | 51 has_skewport_rect_tiles_(false), |
| 81 has_soon_border_rect_tiles_(false), | 52 has_soon_border_rect_tiles_(false), |
| 82 has_eventually_rect_tiles_(false), | 53 has_eventually_rect_tiles_(false) { |
| 83 eviction_tiles_cache_valid_(false), | |
| 84 eviction_cache_tree_priority_(SAME_PRIORITY_FOR_BOTH_TREES) { | |
| 85 gfx::Size content_bounds = | 54 gfx::Size content_bounds = |
| 86 gfx::ToCeiledSize(gfx::ScaleSize(layer_bounds, contents_scale)); | 55 gfx::ToCeiledSize(gfx::ScaleSize(layer_bounds, contents_scale)); |
| 87 gfx::Size tile_size = client_->CalculateTileSize(content_bounds); | 56 gfx::Size tile_size = client_->CalculateTileSize(content_bounds); |
| 88 if (tile_size.IsEmpty()) { | 57 if (tile_size.IsEmpty()) { |
| 89 layer_bounds_ = gfx::Size(); | 58 layer_bounds_ = gfx::Size(); |
| 90 content_bounds = gfx::Size(); | 59 content_bounds = gfx::Size(); |
| 91 } | 60 } |
| 92 | 61 |
| 93 DCHECK(!gfx::ToFlooredSize( | 62 DCHECK(!gfx::ToFlooredSize( |
| 94 gfx::ScaleSize(layer_bounds, contents_scale)).IsEmpty()) << | 63 gfx::ScaleSize(layer_bounds, contents_scale)).IsEmpty()) << |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 138 } | 107 } |
| 139 } | 108 } |
| 140 | 109 |
| 141 // Create a new tile because our twin didn't have a valid one. | 110 // Create a new tile because our twin didn't have a valid one. |
| 142 scoped_refptr<Tile> tile = client_->CreateTile(this, tile_rect); | 111 scoped_refptr<Tile> tile = client_->CreateTile(this, tile_rect); |
| 143 if (tile.get()) { | 112 if (tile.get()) { |
| 144 DCHECK(!tile->is_shared()); | 113 DCHECK(!tile->is_shared()); |
| 145 tile->set_tiling_index(i, j); | 114 tile->set_tiling_index(i, j); |
| 146 tiles_[key] = tile; | 115 tiles_[key] = tile; |
| 147 } | 116 } |
| 148 eviction_tiles_cache_valid_ = false; | |
| 149 return tile.get(); | 117 return tile.get(); |
| 150 } | 118 } |
| 151 | 119 |
| 152 void PictureLayerTiling::CreateMissingTilesInLiveTilesRect() { | 120 void PictureLayerTiling::CreateMissingTilesInLiveTilesRect() { |
| 153 const PictureLayerTiling* twin_tiling = | 121 const PictureLayerTiling* twin_tiling = |
| 154 client_->GetPendingOrActiveTwinTiling(this); | 122 client_->GetPendingOrActiveTwinTiling(this); |
| 155 bool include_borders = false; | 123 bool include_borders = false; |
| 156 for (TilingData::Iterator iter( | 124 for (TilingData::Iterator iter( |
| 157 &tiling_data_, live_tiles_rect_, include_borders); | 125 &tiling_data_, live_tiles_rect_, include_borders); |
| 158 iter; | 126 iter; |
| (...skipping 302 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 461 } | 429 } |
| 462 | 430 |
| 463 bool PictureLayerTiling::RemoveTileAt(int i, | 431 bool PictureLayerTiling::RemoveTileAt(int i, |
| 464 int j, | 432 int j, |
| 465 PictureLayerTiling* recycled_twin) { | 433 PictureLayerTiling* recycled_twin) { |
| 466 TileMap::iterator found = tiles_.find(TileMapKey(i, j)); | 434 TileMap::iterator found = tiles_.find(TileMapKey(i, j)); |
| 467 if (found == tiles_.end()) | 435 if (found == tiles_.end()) |
| 468 return false; | 436 return false; |
| 469 found->second->set_shared(false); | 437 found->second->set_shared(false); |
| 470 tiles_.erase(found); | 438 tiles_.erase(found); |
| 471 eviction_tiles_cache_valid_ = false; | |
| 472 if (recycled_twin) { | 439 if (recycled_twin) { |
| 473 // Recycled twin does not also have a recycled twin, so pass NULL. | 440 // Recycled twin does not also have a recycled twin, so pass NULL. |
| 474 recycled_twin->RemoveTileAt(i, j, NULL); | 441 recycled_twin->RemoveTileAt(i, j, NULL); |
| 475 } | 442 } |
| 476 return true; | 443 return true; |
| 477 } | 444 } |
| 478 | 445 |
| 479 void PictureLayerTiling::Reset() { | 446 void PictureLayerTiling::Reset() { |
| 480 live_tiles_rect_ = gfx::Rect(); | 447 live_tiles_rect_ = gfx::Rect(); |
| 481 PictureLayerTiling* recycled_twin = client_->GetRecycledTwinTiling(this); | 448 PictureLayerTiling* recycled_twin = client_->GetRecycledTwinTiling(this); |
| 482 for (TileMap::const_iterator it = tiles_.begin(); it != tiles_.end(); ++it) { | 449 for (TileMap::const_iterator it = tiles_.begin(); it != tiles_.end(); ++it) { |
| 483 it->second->set_shared(false); | 450 it->second->set_shared(false); |
| 484 if (recycled_twin) | 451 if (recycled_twin) |
| 485 recycled_twin->RemoveTileAt(it->first.first, it->first.second, NULL); | 452 recycled_twin->RemoveTileAt(it->first.first, it->first.second, NULL); |
| 486 } | 453 } |
| 487 tiles_.clear(); | 454 tiles_.clear(); |
| 488 eviction_tiles_cache_valid_ = false; | |
| 489 } | 455 } |
| 490 | 456 |
| 491 gfx::Rect PictureLayerTiling::ComputeSkewport( | 457 gfx::Rect PictureLayerTiling::ComputeSkewport( |
| 492 double current_frame_time_in_seconds, | 458 double current_frame_time_in_seconds, |
| 493 const gfx::Rect& visible_rect_in_content_space) const { | 459 const gfx::Rect& visible_rect_in_content_space) const { |
| 494 gfx::Rect skewport = visible_rect_in_content_space; | 460 gfx::Rect skewport = visible_rect_in_content_space; |
| 495 if (last_impl_frame_time_in_seconds_ == 0.0) | 461 if (last_impl_frame_time_in_seconds_ == 0.0) |
| 496 return skewport; | 462 return skewport; |
| 497 | 463 |
| 498 double time_delta = | 464 double time_delta = |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 587 float border = kSoonBorderDistanceInScreenPixels / content_to_screen_scale_; | 553 float border = kSoonBorderDistanceInScreenPixels / content_to_screen_scale_; |
| 588 soon_border_rect.Inset(-border, -border, -border, -border); | 554 soon_border_rect.Inset(-border, -border, -border, -border); |
| 589 | 555 |
| 590 // Update the tiling state. | 556 // Update the tiling state. |
| 591 SetLiveTilesRect(eventually_rect); | 557 SetLiveTilesRect(eventually_rect); |
| 592 | 558 |
| 593 last_impl_frame_time_in_seconds_ = current_frame_time_in_seconds; | 559 last_impl_frame_time_in_seconds_ = current_frame_time_in_seconds; |
| 594 last_viewport_in_layer_space_ = viewport_in_layer_space; | 560 last_viewport_in_layer_space_ = viewport_in_layer_space; |
| 595 last_visible_rect_in_content_space_ = visible_rect_in_content_space; | 561 last_visible_rect_in_content_space_ = visible_rect_in_content_space; |
| 596 | 562 |
| 597 eviction_tiles_cache_valid_ = false; | |
| 598 | |
| 599 current_visible_rect_ = visible_rect_in_content_space; | 563 current_visible_rect_ = visible_rect_in_content_space; |
| 600 current_skewport_rect_ = skewport; | 564 current_skewport_rect_ = skewport; |
| 601 current_soon_border_rect_ = soon_border_rect; | 565 current_soon_border_rect_ = soon_border_rect; |
| 602 current_eventually_rect_ = eventually_rect; | 566 current_eventually_rect_ = eventually_rect; |
| 603 current_occlusion_in_layer_space_ = occlusion_in_layer_space; | 567 current_occlusion_in_layer_space_ = occlusion_in_layer_space; |
| 604 | 568 |
| 605 // Update has_*_tiles state. | 569 // Update has_*_tiles state. |
| 606 gfx::Rect tiling_rect(tiling_size()); | 570 gfx::Rect tiling_rect(tiling_size()); |
| 607 | 571 |
| 608 has_visible_rect_tiles_ = tiling_rect.Intersects(current_visible_rect_); | 572 has_visible_rect_tiles_ = tiling_rect.Intersects(current_visible_rect_); |
| (...skipping 382 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 991 if (delta < event.distance) | 955 if (delta < event.distance) |
| 992 break; | 956 break; |
| 993 } | 957 } |
| 994 | 958 |
| 995 gfx::Rect result(origin_x, origin_y, width, height); | 959 gfx::Rect result(origin_x, origin_y, width, height); |
| 996 if (cache) | 960 if (cache) |
| 997 cache->previous_result = result; | 961 cache->previous_result = result; |
| 998 return result; | 962 return result; |
| 999 } | 963 } |
| 1000 | 964 |
| 1001 void PictureLayerTiling::UpdateEvictionCacheIfNeeded( | |
| 1002 TreePriority tree_priority) { | |
| 1003 if (eviction_tiles_cache_valid_ && | |
| 1004 eviction_cache_tree_priority_ == tree_priority) | |
| 1005 return; | |
| 1006 | |
| 1007 eviction_tiles_now_.clear(); | |
| 1008 eviction_tiles_now_and_required_for_activation_.clear(); | |
| 1009 eviction_tiles_soon_.clear(); | |
| 1010 eviction_tiles_soon_and_required_for_activation_.clear(); | |
| 1011 eviction_tiles_eventually_.clear(); | |
| 1012 eviction_tiles_eventually_and_required_for_activation_.clear(); | |
| 1013 | |
| 1014 for (TileMap::iterator it = tiles_.begin(); it != tiles_.end(); ++it) { | |
| 1015 Tile* tile = it->second.get(); | |
| 1016 UpdateTileAndTwinPriority(tile); | |
| 1017 const TilePriority& priority = | |
| 1018 tile->priority_for_tree_priority(tree_priority); | |
| 1019 switch (priority.priority_bin) { | |
| 1020 case TilePriority::EVENTUALLY: | |
| 1021 if (tile->required_for_activation()) | |
| 1022 eviction_tiles_eventually_and_required_for_activation_.push_back( | |
| 1023 tile); | |
| 1024 else | |
| 1025 eviction_tiles_eventually_.push_back(tile); | |
| 1026 break; | |
| 1027 case TilePriority::SOON: | |
| 1028 if (tile->required_for_activation()) | |
| 1029 eviction_tiles_soon_and_required_for_activation_.push_back(tile); | |
| 1030 else | |
| 1031 eviction_tiles_soon_.push_back(tile); | |
| 1032 break; | |
| 1033 case TilePriority::NOW: | |
| 1034 if (tile->required_for_activation()) | |
| 1035 eviction_tiles_now_and_required_for_activation_.push_back(tile); | |
| 1036 else | |
| 1037 eviction_tiles_now_.push_back(tile); | |
| 1038 break; | |
| 1039 } | |
| 1040 } | |
| 1041 | |
| 1042 // TODO(vmpstr): Do this lazily. One option is to have a "sorted" flag that | |
| 1043 // can be updated for each of the queues. | |
| 1044 TileEvictionOrder sort_order(tree_priority); | |
| 1045 std::sort(eviction_tiles_now_.begin(), eviction_tiles_now_.end(), sort_order); | |
| 1046 std::sort(eviction_tiles_now_and_required_for_activation_.begin(), | |
| 1047 eviction_tiles_now_and_required_for_activation_.end(), | |
| 1048 sort_order); | |
| 1049 std::sort( | |
| 1050 eviction_tiles_soon_.begin(), eviction_tiles_soon_.end(), sort_order); | |
| 1051 std::sort(eviction_tiles_soon_and_required_for_activation_.begin(), | |
| 1052 eviction_tiles_soon_and_required_for_activation_.end(), | |
| 1053 sort_order); | |
| 1054 std::sort(eviction_tiles_eventually_.begin(), | |
| 1055 eviction_tiles_eventually_.end(), | |
| 1056 sort_order); | |
| 1057 std::sort(eviction_tiles_eventually_and_required_for_activation_.begin(), | |
| 1058 eviction_tiles_eventually_and_required_for_activation_.end(), | |
| 1059 sort_order); | |
| 1060 | |
| 1061 eviction_tiles_cache_valid_ = true; | |
| 1062 eviction_cache_tree_priority_ = tree_priority; | |
| 1063 } | |
| 1064 | |
| 1065 const std::vector<Tile*>* PictureLayerTiling::GetEvictionTiles( | |
| 1066 TreePriority tree_priority, | |
| 1067 EvictionCategory category) { | |
| 1068 UpdateEvictionCacheIfNeeded(tree_priority); | |
| 1069 switch (category) { | |
| 1070 case EVENTUALLY: | |
| 1071 return &eviction_tiles_eventually_; | |
| 1072 case EVENTUALLY_AND_REQUIRED_FOR_ACTIVATION: | |
| 1073 return &eviction_tiles_eventually_and_required_for_activation_; | |
| 1074 case SOON: | |
| 1075 return &eviction_tiles_soon_; | |
| 1076 case SOON_AND_REQUIRED_FOR_ACTIVATION: | |
| 1077 return &eviction_tiles_soon_and_required_for_activation_; | |
| 1078 case NOW: | |
| 1079 return &eviction_tiles_now_; | |
| 1080 case NOW_AND_REQUIRED_FOR_ACTIVATION: | |
| 1081 return &eviction_tiles_now_and_required_for_activation_; | |
| 1082 } | |
| 1083 NOTREACHED(); | |
| 1084 return &eviction_tiles_eventually_; | |
| 1085 } | |
| 1086 | |
| 1087 PictureLayerTiling::TilingRasterTileIterator::TilingRasterTileIterator() | 965 PictureLayerTiling::TilingRasterTileIterator::TilingRasterTileIterator() |
| 1088 : tiling_(NULL), current_tile_(NULL) {} | 966 : tiling_(NULL), current_tile_(NULL) {} |
| 1089 | 967 |
| 1090 PictureLayerTiling::TilingRasterTileIterator::TilingRasterTileIterator( | 968 PictureLayerTiling::TilingRasterTileIterator::TilingRasterTileIterator( |
| 1091 PictureLayerTiling* tiling) | 969 PictureLayerTiling* tiling) |
| 1092 : tiling_(tiling), phase_(VISIBLE_RECT), current_tile_(NULL) { | 970 : tiling_(tiling), phase_(VISIBLE_RECT), current_tile_(NULL) { |
| 1093 if (!tiling_->has_visible_rect_tiles_) { | 971 if (!tiling_->has_visible_rect_tiles_) { |
| 1094 AdvancePhase(); | 972 AdvancePhase(); |
| 1095 return; | 973 return; |
| 1096 } | 974 } |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1210 } | 1088 } |
| 1211 current_tile_ = tiling_->TileAt(next_index.first, next_index.second); | 1089 current_tile_ = tiling_->TileAt(next_index.first, next_index.second); |
| 1212 } | 1090 } |
| 1213 | 1091 |
| 1214 if (current_tile_) | 1092 if (current_tile_) |
| 1215 tiling_->UpdateTileAndTwinPriority(current_tile_); | 1093 tiling_->UpdateTileAndTwinPriority(current_tile_); |
| 1216 return *this; | 1094 return *this; |
| 1217 } | 1095 } |
| 1218 | 1096 |
| 1219 PictureLayerTiling::TilingEvictionTileIterator::TilingEvictionTileIterator() | 1097 PictureLayerTiling::TilingEvictionTileIterator::TilingEvictionTileIterator() |
| 1220 : eviction_tiles_(NULL), current_eviction_tiles_index_(0u) { | 1098 : tiling_(nullptr), |
| 1099 tree_priority_(SAME_PRIORITY_FOR_BOTH_TREES), | |
| 1100 eviction_category_(EVENTUALLY), | |
| 1101 processing_soon_border_rect_(false), | |
| 1102 skip_shared_out_of_order_tiles_(false), | |
| 1103 unoccluded_now_tiles_index_(0u), | |
| 1104 current_tile_(nullptr) { | |
| 1221 } | 1105 } |
| 1222 | 1106 |
| 1223 PictureLayerTiling::TilingEvictionTileIterator::TilingEvictionTileIterator( | 1107 PictureLayerTiling::TilingEvictionTileIterator::TilingEvictionTileIterator( |
| 1224 PictureLayerTiling* tiling, | 1108 PictureLayerTiling* tiling, |
| 1225 TreePriority tree_priority, | 1109 TreePriority tree_priority, |
| 1226 EvictionCategory category) | 1110 EvictionCategory category, |
| 1227 : eviction_tiles_(tiling->GetEvictionTiles(tree_priority, category)), | 1111 bool skip_shared_out_of_order_tiles) |
| 1228 // Note: initializing to "0 - 1" works as overflow is well defined for | 1112 : tiling_(tiling), |
| 1229 // unsigned integers. | 1113 tree_priority_(tree_priority), |
| 1230 current_eviction_tiles_index_(static_cast<size_t>(0) - 1) { | 1114 eviction_category_(category), |
| 1231 DCHECK(eviction_tiles_); | 1115 processing_soon_border_rect_(true), |
| 1232 ++(*this); | 1116 skip_shared_out_of_order_tiles_(skip_shared_out_of_order_tiles), |
| 1117 unoccluded_now_tiles_index_(0u), | |
| 1118 current_tile_(nullptr) { | |
| 1119 TilePriority::PriorityBin max_tile_priority_bin = | |
| 1120 tiling_->client_->GetMaxTilePriorityBin(); | |
|
vmpstr
2014/11/19 16:47:58
I'm not sure if this check matters here. The order
USE eero AT chromium.org
2014/11/20 14:54:38
[...]
| |
| 1121 switch (eviction_category_) { | |
| 1122 case EVENTUALLY: | |
| 1123 case EVENTUALLY_AND_REQUIRED_FOR_ACTIVATION: | |
| 1124 if (tiling_->has_eventually_rect_tiles_) { | |
| 1125 if (max_tile_priority_bin < TilePriority::EVENTUALLY) | |
| 1126 spiral_iterator_ = TilingData::ReverseSpiralDifferenceIterator( | |
| 1127 &tiling_->tiling_data_, tiling_->current_eventually_rect_, | |
| 1128 tiling_->current_skewport_rect_, | |
| 1129 tiling_->current_soon_border_rect_); | |
| 1130 else | |
| 1131 spiral_iterator_ = TilingData::ReverseSpiralDifferenceIterator( | |
| 1132 &tiling_->tiling_data_, tiling_->current_eventually_rect_, | |
| 1133 gfx::Rect(), gfx::Rect()); | |
| 1134 AdvanceEventually(); | |
| 1135 } | |
| 1136 break; | |
| 1137 case SOON: | |
| 1138 case SOON_AND_REQUIRED_FOR_ACTIVATION: | |
|
vmpstr
2014/11/19 16:47:58
Doing both SOON and SOON_AND_RFA would return doub
USE eero AT chromium.org
2014/11/20 14:54:38
No. SOON returns only tiles which are not required
| |
| 1139 if (max_tile_priority_bin <= TilePriority::SOON && | |
| 1140 (tiling_->has_skewport_rect_tiles_ || | |
| 1141 tiling_->has_soon_border_rect_tiles_)) { | |
| 1142 if (tiling_->has_soon_border_rect_tiles_) | |
| 1143 spiral_iterator_ = TilingData::ReverseSpiralDifferenceIterator( | |
| 1144 &tiling_->tiling_data_, tiling_->current_soon_border_rect_, | |
| 1145 tiling_->current_skewport_rect_, tiling_->current_visible_rect_); | |
| 1146 AdvanceSoon(); | |
| 1147 } | |
| 1148 break; | |
| 1149 case NOW: | |
| 1150 case NOW_AND_REQUIRED_FOR_ACTIVATION: | |
| 1151 if (max_tile_priority_bin <= TilePriority::NOW && | |
| 1152 tiling_->has_visible_rect_tiles_) { | |
| 1153 visible_iterator_ = TilingData::Iterator(&tiling_->tiling_data_, | |
| 1154 tiling_->current_visible_rect_, | |
| 1155 false /* include_borders */); | |
| 1156 AdvanceNow(); | |
| 1157 } | |
| 1158 break; | |
| 1159 } | |
| 1233 } | 1160 } |
| 1234 | 1161 |
| 1235 PictureLayerTiling::TilingEvictionTileIterator::~TilingEvictionTileIterator() { | 1162 PictureLayerTiling::TilingEvictionTileIterator::~TilingEvictionTileIterator() { |
| 1236 } | 1163 } |
| 1237 | 1164 |
| 1165 void PictureLayerTiling::TilingEvictionTileIterator::AdvanceEventually() { | |
| 1166 bool required_for_activation = | |
| 1167 eviction_category_ == EVENTUALLY_AND_REQUIRED_FOR_ACTIVATION; | |
| 1168 | |
| 1169 while (spiral_iterator_) { | |
| 1170 std::pair<int, int> next_index = spiral_iterator_.index(); | |
| 1171 Tile* tile = tiling_->TileAt(next_index.first, next_index.second); | |
| 1172 ++spiral_iterator_; | |
| 1173 if (!tile || !tile->HasResources()) | |
| 1174 continue; | |
| 1175 if (PreparseTileUnlessReturningShouldBeDoneByTwin(tile) && | |
| 1176 tile->required_for_activation() == required_for_activation) { | |
| 1177 current_tile_ = tile; | |
| 1178 return; | |
| 1179 } | |
| 1180 } | |
| 1181 | |
| 1182 current_tile_ = nullptr; | |
| 1183 } | |
| 1184 | |
| 1185 void PictureLayerTiling::TilingEvictionTileIterator::AdvanceSoon() { | |
| 1186 bool required_for_activation = | |
| 1187 eviction_category_ == SOON_AND_REQUIRED_FOR_ACTIVATION; | |
| 1188 | |
| 1189 for (;;) { | |
| 1190 if (!spiral_iterator_) { | |
| 1191 if (!processing_soon_border_rect_) | |
| 1192 break; | |
| 1193 // Max tile priority bin should never be SOON so there is no need to | |
| 1194 // handle that case (to return visible tiles as SOON tiles). | |
| 1195 DCHECK_LT(tiling_->client_->GetMaxTilePriorityBin(), TilePriority::SOON); | |
| 1196 processing_soon_border_rect_ = false; | |
| 1197 if (tiling_->has_skewport_rect_tiles_) { | |
| 1198 spiral_iterator_ = TilingData::ReverseSpiralDifferenceIterator( | |
| 1199 &tiling_->tiling_data_, tiling_->current_skewport_rect_, | |
| 1200 tiling_->current_visible_rect_, tiling_->current_visible_rect_); | |
| 1201 } | |
| 1202 if (!spiral_iterator_) | |
| 1203 break; | |
| 1204 } | |
| 1205 std::pair<int, int> next_index = spiral_iterator_.index(); | |
| 1206 Tile* tile = tiling_->TileAt(next_index.first, next_index.second); | |
| 1207 ++spiral_iterator_; | |
| 1208 if (!tile || !tile->HasResources()) | |
| 1209 continue; | |
| 1210 if (PreparseTileUnlessReturningShouldBeDoneByTwin(tile) && | |
| 1211 tile->required_for_activation() == required_for_activation) { | |
| 1212 current_tile_ = tile; | |
| 1213 return; | |
| 1214 } | |
| 1215 } | |
| 1216 | |
| 1217 current_tile_ = nullptr; | |
| 1218 } | |
| 1219 | |
| 1220 void PictureLayerTiling::TilingEvictionTileIterator::AdvanceNow() { | |
| 1221 bool required_for_activation = | |
| 1222 eviction_category_ == NOW_AND_REQUIRED_FOR_ACTIVATION; | |
| 1223 | |
| 1224 if (visible_iterator_) { | |
| 1225 WhichTree tree = tiling_->client_->GetTree(); | |
| 1226 bool skip_all_shared_tiles = | |
| 1227 skip_shared_out_of_order_tiles_ && | |
| 1228 tree_priority_ == (tree == ACTIVE_TREE ? NEW_CONTENT_TAKES_PRIORITY | |
| 1229 : SMOOTHNESS_TAKES_PRIORITY); | |
| 1230 do { | |
| 1231 std::pair<int, int> next_index = visible_iterator_.index(); | |
| 1232 Tile* tile = tiling_->TileAt(next_index.first, next_index.second); | |
| 1233 ++visible_iterator_; | |
| 1234 if (!tile || !tile->HasResources()) | |
| 1235 continue; | |
| 1236 if (skip_all_shared_tiles && tile->is_shared()) | |
| 1237 continue; | |
| 1238 if (tree == PENDING_TREE && | |
| 1239 tiling_->IsTileRequiredForActivationIfVisible(tile) != | |
| 1240 required_for_activation) | |
| 1241 continue; | |
| 1242 if (!tiling_->IsTileOccluded(tile)) { | |
| 1243 unoccluded_now_tiles_.push_back(tile); | |
| 1244 continue; | |
| 1245 } | |
| 1246 if (PreparseTileUnlessReturningShouldBeDoneByTwin(tile) && | |
| 1247 tile->required_for_activation() == required_for_activation) { | |
| 1248 current_tile_ = tile; | |
| 1249 return; | |
| 1250 } | |
| 1251 } while (visible_iterator_); | |
| 1252 } | |
| 1253 | |
| 1254 while (unoccluded_now_tiles_index_ < unoccluded_now_tiles_.size()) { | |
| 1255 Tile* tile = unoccluded_now_tiles_[unoccluded_now_tiles_index_]; | |
| 1256 ++unoccluded_now_tiles_index_; | |
| 1257 DCHECK(tile); | |
| 1258 if (!tile->HasResources()) | |
| 1259 continue; | |
| 1260 if (PreparseTileUnlessReturningShouldBeDoneByTwin(tile) && | |
| 1261 tile->required_for_activation() == required_for_activation) { | |
| 1262 current_tile_ = tile; | |
| 1263 return; | |
| 1264 } | |
| 1265 } | |
| 1266 | |
| 1267 current_tile_ = nullptr; | |
| 1268 } | |
| 1269 | |
| 1270 bool PictureLayerTiling::TilingEvictionTileIterator:: | |
| 1271 PreparseTileUnlessReturningShouldBeDoneByTwin(Tile* tile) const { | |
|
vmpstr
2014/11/19 16:47:58
This is named a bit awkwardly. It feels like it's
USE eero AT chromium.org
2014/11/20 14:54:38
Yes, and avoids calling costly UpdateTileAndTwinPr
| |
| 1272 if (skip_shared_out_of_order_tiles_ && tile->is_shared()) { | |
| 1273 WhichTree tree = tiling_->client_->GetTree(); | |
| 1274 switch (tree_priority_) { | |
| 1275 case SMOOTHNESS_TAKES_PRIORITY: | |
| 1276 // The priority for tile priority of a shared tile will be the active | |
| 1277 // priority thus return shared tiles from the active tree. | |
| 1278 if (tree != ACTIVE_TREE) | |
| 1279 return false; | |
| 1280 break; | |
| 1281 case NEW_CONTENT_TAKES_PRIORITY: | |
| 1282 // The priority for tile priority of a shared tile will be the pending | |
| 1283 // priority thus return shared tiles from the pending tree. | |
| 1284 if (tree != PENDING_TREE) | |
| 1285 return false; | |
| 1286 break; | |
| 1287 case SAME_PRIORITY_FOR_BOTH_TREES: { | |
| 1288 // The priority for tile priority of a shared tile will be a combined | |
| 1289 // priority thus return shared tiles from a higher priority tree. | |
| 1290 tiling_->UpdateTileAndTwinPriority(tile); | |
| 1291 WhichTree other_tree = tree == ACTIVE_TREE ? PENDING_TREE : ACTIVE_TREE; | |
| 1292 const TilePriority& priority = tile->priority(tree); | |
| 1293 const TilePriority& other_priority = tile->priority(other_tree); | |
| 1294 if (priority.priority_bin != other_priority.priority_bin) | |
| 1295 return priority.priority_bin < other_priority.priority_bin; | |
| 1296 const bool occluded = tile->is_occluded(tree); | |
| 1297 const bool other_occluded = tile->is_occluded(other_tree); | |
| 1298 if (occluded != other_occluded) | |
| 1299 return !occluded; | |
| 1300 if (priority.distance_to_visible != other_priority.distance_to_visible) | |
| 1301 return priority.distance_to_visible < | |
| 1302 other_priority.distance_to_visible; | |
| 1303 // If priorities are the same, it does not matter which tree returns | |
| 1304 // the tile. Let's pick the active tree. | |
| 1305 return tree == ACTIVE_TREE; | |
| 1306 } | |
| 1307 default: | |
| 1308 NOTREACHED(); | |
| 1309 } | |
| 1310 } | |
| 1311 tiling_->UpdateTileAndTwinPriority(tile); | |
| 1312 return true; | |
| 1313 } | |
| 1314 | |
| 1238 PictureLayerTiling::TilingEvictionTileIterator::operator bool() const { | 1315 PictureLayerTiling::TilingEvictionTileIterator::operator bool() const { |
| 1239 return eviction_tiles_ && | 1316 return !!current_tile_; |
| 1240 current_eviction_tiles_index_ != eviction_tiles_->size(); | |
| 1241 } | 1317 } |
| 1242 | 1318 |
| 1243 Tile* PictureLayerTiling::TilingEvictionTileIterator::operator*() { | 1319 Tile* PictureLayerTiling::TilingEvictionTileIterator::operator*() { |
| 1244 DCHECK(*this); | 1320 DCHECK(*this); |
| 1245 return (*eviction_tiles_)[current_eviction_tiles_index_]; | 1321 return current_tile_; |
| 1246 } | 1322 } |
| 1247 | 1323 |
| 1248 const Tile* PictureLayerTiling::TilingEvictionTileIterator::operator*() const { | 1324 const Tile* PictureLayerTiling::TilingEvictionTileIterator::operator*() const { |
| 1249 DCHECK(*this); | 1325 DCHECK(*this); |
| 1250 return (*eviction_tiles_)[current_eviction_tiles_index_]; | 1326 return current_tile_; |
| 1251 } | 1327 } |
| 1252 | 1328 |
| 1253 PictureLayerTiling::TilingEvictionTileIterator& | 1329 PictureLayerTiling::TilingEvictionTileIterator& |
| 1254 PictureLayerTiling::TilingEvictionTileIterator:: | 1330 PictureLayerTiling::TilingEvictionTileIterator:: |
| 1255 operator++() { | 1331 operator++() { |
| 1256 DCHECK(*this); | 1332 DCHECK(*this); |
| 1257 do { | 1333 switch (eviction_category_) { |
| 1258 ++current_eviction_tiles_index_; | 1334 case EVENTUALLY: |
| 1259 } while (current_eviction_tiles_index_ != eviction_tiles_->size() && | 1335 case EVENTUALLY_AND_REQUIRED_FOR_ACTIVATION: |
| 1260 !(*eviction_tiles_)[current_eviction_tiles_index_]->HasResources()); | 1336 AdvanceEventually(); |
| 1261 | 1337 break; |
| 1338 case SOON: | |
| 1339 case SOON_AND_REQUIRED_FOR_ACTIVATION: | |
| 1340 AdvanceSoon(); | |
| 1341 break; | |
| 1342 case NOW: | |
| 1343 case NOW_AND_REQUIRED_FOR_ACTIVATION: | |
| 1344 AdvanceNow(); | |
| 1345 break; | |
| 1346 } | |
| 1262 return *this; | 1347 return *this; |
| 1263 } | 1348 } |
| 1264 | 1349 |
| 1265 } // namespace cc | 1350 } // namespace cc |
| OLD | NEW |