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 367 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
462 } | 431 } |
463 | 432 |
464 bool PictureLayerTiling::RemoveTileAt(int i, | 433 bool PictureLayerTiling::RemoveTileAt(int i, |
465 int j, | 434 int j, |
466 PictureLayerTiling* recycled_twin) { | 435 PictureLayerTiling* recycled_twin) { |
467 TileMap::iterator found = tiles_.find(TileMapKey(i, j)); | 436 TileMap::iterator found = tiles_.find(TileMapKey(i, j)); |
468 if (found == tiles_.end()) | 437 if (found == tiles_.end()) |
469 return false; | 438 return false; |
470 found->second->set_shared(false); | 439 found->second->set_shared(false); |
471 tiles_.erase(found); | 440 tiles_.erase(found); |
472 eviction_tiles_cache_valid_ = false; | |
473 if (recycled_twin) { | 441 if (recycled_twin) { |
474 // Recycled twin does not also have a recycled twin, so pass NULL. | 442 // Recycled twin does not also have a recycled twin, so pass NULL. |
475 recycled_twin->RemoveTileAt(i, j, NULL); | 443 recycled_twin->RemoveTileAt(i, j, NULL); |
476 } | 444 } |
477 return true; | 445 return true; |
478 } | 446 } |
479 | 447 |
480 void PictureLayerTiling::Reset() { | 448 void PictureLayerTiling::Reset() { |
481 live_tiles_rect_ = gfx::Rect(); | 449 live_tiles_rect_ = gfx::Rect(); |
482 PictureLayerTiling* recycled_twin = client_->GetRecycledTwinTiling(this); | 450 PictureLayerTiling* recycled_twin = client_->GetRecycledTwinTiling(this); |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
588 float border = kSoonBorderDistanceInScreenPixels / content_to_screen_scale_; | 556 float border = kSoonBorderDistanceInScreenPixels / content_to_screen_scale_; |
589 soon_border_rect.Inset(-border, -border, -border, -border); | 557 soon_border_rect.Inset(-border, -border, -border, -border); |
590 | 558 |
591 // Update the tiling state. | 559 // Update the tiling state. |
592 SetLiveTilesRect(eventually_rect); | 560 SetLiveTilesRect(eventually_rect); |
593 | 561 |
594 last_impl_frame_time_in_seconds_ = current_frame_time_in_seconds; | 562 last_impl_frame_time_in_seconds_ = current_frame_time_in_seconds; |
595 last_viewport_in_layer_space_ = viewport_in_layer_space; | 563 last_viewport_in_layer_space_ = viewport_in_layer_space; |
596 last_visible_rect_in_content_space_ = visible_rect_in_content_space; | 564 last_visible_rect_in_content_space_ = visible_rect_in_content_space; |
597 | 565 |
598 eviction_tiles_cache_valid_ = false; | |
599 | |
600 current_visible_rect_ = visible_rect_in_content_space; | 566 current_visible_rect_ = visible_rect_in_content_space; |
601 current_skewport_rect_ = skewport; | 567 current_skewport_rect_ = skewport; |
602 current_soon_border_rect_ = soon_border_rect; | 568 current_soon_border_rect_ = soon_border_rect; |
603 current_eventually_rect_ = eventually_rect; | 569 current_eventually_rect_ = eventually_rect; |
604 current_occlusion_in_layer_space_ = occlusion_in_layer_space; | 570 current_occlusion_in_layer_space_ = occlusion_in_layer_space; |
605 | 571 |
606 // Update has_*_tiles state. | 572 // Update has_*_tiles state. |
607 gfx::Rect tiling_rect(tiling_size()); | 573 gfx::Rect tiling_rect(tiling_size()); |
608 | 574 |
609 has_visible_rect_tiles_ = tiling_rect.Intersects(current_visible_rect_); | 575 has_visible_rect_tiles_ = tiling_rect.Intersects(current_visible_rect_); |
(...skipping 357 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
967 if (delta < event.distance) | 933 if (delta < event.distance) |
968 break; | 934 break; |
969 } | 935 } |
970 | 936 |
971 gfx::Rect result(origin_x, origin_y, width, height); | 937 gfx::Rect result(origin_x, origin_y, width, height); |
972 if (cache) | 938 if (cache) |
973 cache->previous_result = result; | 939 cache->previous_result = result; |
974 return result; | 940 return result; |
975 } | 941 } |
976 | 942 |
977 void PictureLayerTiling::UpdateEvictionCacheIfNeeded( | |
978 TreePriority tree_priority) { | |
979 if (eviction_tiles_cache_valid_ && | |
980 eviction_cache_tree_priority_ == tree_priority) | |
981 return; | |
982 | |
983 eviction_tiles_now_.clear(); | |
984 eviction_tiles_now_and_required_for_activation_.clear(); | |
985 eviction_tiles_soon_.clear(); | |
986 eviction_tiles_soon_and_required_for_activation_.clear(); | |
987 eviction_tiles_eventually_.clear(); | |
988 eviction_tiles_eventually_and_required_for_activation_.clear(); | |
989 | |
990 for (TileMap::iterator it = tiles_.begin(); it != tiles_.end(); ++it) { | |
991 Tile* tile = it->second.get(); | |
992 UpdateTileAndTwinPriority(tile); | |
993 const TilePriority& priority = | |
994 tile->priority_for_tree_priority(tree_priority); | |
995 switch (priority.priority_bin) { | |
996 case TilePriority::EVENTUALLY: | |
997 if (tile->required_for_activation()) | |
998 eviction_tiles_eventually_and_required_for_activation_.push_back( | |
999 tile); | |
1000 else | |
1001 eviction_tiles_eventually_.push_back(tile); | |
1002 break; | |
1003 case TilePriority::SOON: | |
1004 if (tile->required_for_activation()) | |
1005 eviction_tiles_soon_and_required_for_activation_.push_back(tile); | |
1006 else | |
1007 eviction_tiles_soon_.push_back(tile); | |
1008 break; | |
1009 case TilePriority::NOW: | |
1010 if (tile->required_for_activation()) | |
1011 eviction_tiles_now_and_required_for_activation_.push_back(tile); | |
1012 else | |
1013 eviction_tiles_now_.push_back(tile); | |
1014 break; | |
1015 } | |
1016 } | |
1017 | |
1018 // TODO(vmpstr): Do this lazily. One option is to have a "sorted" flag that | |
1019 // can be updated for each of the queues. | |
1020 TileEvictionOrder sort_order(tree_priority); | |
1021 std::sort(eviction_tiles_now_.begin(), eviction_tiles_now_.end(), sort_order); | |
1022 std::sort(eviction_tiles_now_and_required_for_activation_.begin(), | |
1023 eviction_tiles_now_and_required_for_activation_.end(), | |
1024 sort_order); | |
1025 std::sort( | |
1026 eviction_tiles_soon_.begin(), eviction_tiles_soon_.end(), sort_order); | |
1027 std::sort(eviction_tiles_soon_and_required_for_activation_.begin(), | |
1028 eviction_tiles_soon_and_required_for_activation_.end(), | |
1029 sort_order); | |
1030 std::sort(eviction_tiles_eventually_.begin(), | |
1031 eviction_tiles_eventually_.end(), | |
1032 sort_order); | |
1033 std::sort(eviction_tiles_eventually_and_required_for_activation_.begin(), | |
1034 eviction_tiles_eventually_and_required_for_activation_.end(), | |
1035 sort_order); | |
1036 | |
1037 eviction_tiles_cache_valid_ = true; | |
1038 eviction_cache_tree_priority_ = tree_priority; | |
1039 } | |
1040 | |
1041 const std::vector<Tile*>* PictureLayerTiling::GetEvictionTiles( | |
1042 TreePriority tree_priority, | |
1043 EvictionCategory category) { | |
1044 UpdateEvictionCacheIfNeeded(tree_priority); | |
1045 switch (category) { | |
1046 case EVENTUALLY: | |
1047 return &eviction_tiles_eventually_; | |
1048 case EVENTUALLY_AND_REQUIRED_FOR_ACTIVATION: | |
1049 return &eviction_tiles_eventually_and_required_for_activation_; | |
1050 case SOON: | |
1051 return &eviction_tiles_soon_; | |
1052 case SOON_AND_REQUIRED_FOR_ACTIVATION: | |
1053 return &eviction_tiles_soon_and_required_for_activation_; | |
1054 case NOW: | |
1055 return &eviction_tiles_now_; | |
1056 case NOW_AND_REQUIRED_FOR_ACTIVATION: | |
1057 return &eviction_tiles_now_and_required_for_activation_; | |
1058 } | |
1059 NOTREACHED(); | |
1060 return &eviction_tiles_eventually_; | |
1061 } | |
1062 | |
1063 PictureLayerTiling::TilingRasterTileIterator::TilingRasterTileIterator() | 943 PictureLayerTiling::TilingRasterTileIterator::TilingRasterTileIterator() |
1064 : tiling_(NULL), current_tile_(NULL) {} | 944 : tiling_(NULL), current_tile_(NULL) {} |
1065 | 945 |
1066 PictureLayerTiling::TilingRasterTileIterator::TilingRasterTileIterator( | 946 PictureLayerTiling::TilingRasterTileIterator::TilingRasterTileIterator( |
1067 PictureLayerTiling* tiling) | 947 PictureLayerTiling* tiling) |
1068 : tiling_(tiling), phase_(VISIBLE_RECT), current_tile_(NULL) { | 948 : tiling_(tiling), phase_(VISIBLE_RECT), current_tile_(NULL) { |
1069 if (!tiling_->has_visible_rect_tiles_) { | 949 if (!tiling_->has_visible_rect_tiles_) { |
1070 AdvancePhase(); | 950 AdvancePhase(); |
1071 return; | 951 return; |
1072 } | 952 } |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1186 } | 1066 } |
1187 current_tile_ = tiling_->TileAt(next_index.first, next_index.second); | 1067 current_tile_ = tiling_->TileAt(next_index.first, next_index.second); |
1188 } | 1068 } |
1189 | 1069 |
1190 if (current_tile_) | 1070 if (current_tile_) |
1191 tiling_->UpdateTileAndTwinPriority(current_tile_); | 1071 tiling_->UpdateTileAndTwinPriority(current_tile_); |
1192 return *this; | 1072 return *this; |
1193 } | 1073 } |
1194 | 1074 |
1195 PictureLayerTiling::TilingEvictionTileIterator::TilingEvictionTileIterator() | 1075 PictureLayerTiling::TilingEvictionTileIterator::TilingEvictionTileIterator() |
1196 : eviction_tiles_(NULL), current_eviction_tiles_index_(0u) { | 1076 : tiling_(nullptr), |
| 1077 eviction_category_(EVENTUALLY), |
| 1078 processing_occluded_now_tiles_(false), |
| 1079 processing_soon_border_rect_(false), |
| 1080 unoccluded_now_tiles_index_(0u), |
| 1081 current_tile_(nullptr) { |
1197 } | 1082 } |
1198 | 1083 |
1199 PictureLayerTiling::TilingEvictionTileIterator::TilingEvictionTileIterator( | 1084 PictureLayerTiling::TilingEvictionTileIterator::TilingEvictionTileIterator( |
1200 PictureLayerTiling* tiling, | 1085 PictureLayerTiling* tiling, |
1201 TreePriority tree_priority, | |
1202 EvictionCategory category) | 1086 EvictionCategory category) |
1203 : eviction_tiles_(tiling->GetEvictionTiles(tree_priority, category)), | 1087 : tiling_(tiling), |
1204 // Note: initializing to "0 - 1" works as overflow is well defined for | 1088 eviction_category_(category), |
1205 // unsigned integers. | 1089 processing_occluded_now_tiles_(true), |
1206 current_eviction_tiles_index_(static_cast<size_t>(0) - 1) { | 1090 processing_soon_border_rect_(true), |
1207 DCHECK(eviction_tiles_); | 1091 unoccluded_now_tiles_index_(0), |
1208 ++(*this); | 1092 current_tile_(nullptr) { |
| 1093 switch (category) { |
| 1094 case EVENTUALLY: |
| 1095 if (tiling_->has_eventually_rect_tiles_) { |
| 1096 spiral_iterator_ = TilingData::ReverseSpiralDifferenceIterator( |
| 1097 &tiling_->tiling_data_, |
| 1098 tiling_->current_eventually_rect_, |
| 1099 tiling_->current_skewport_rect_, |
| 1100 tiling_->current_soon_border_rect_); |
| 1101 } |
| 1102 AdvanceEventually(true); |
| 1103 break; |
| 1104 case SOON: |
| 1105 if (tiling_->has_soon_border_rect_tiles_) { |
| 1106 spiral_iterator_ = TilingData::ReverseSpiralDifferenceIterator( |
| 1107 &tiling_->tiling_data_, |
| 1108 tiling_->current_soon_border_rect_, |
| 1109 tiling_->current_skewport_rect_, |
| 1110 tiling_->current_visible_rect_); |
| 1111 } |
| 1112 AdvanceSoon(true); |
| 1113 break; |
| 1114 case NOW: |
| 1115 case NOW_AND_REQUIRED_FOR_ACTIVATION: |
| 1116 if (tiling_->has_visible_rect_tiles_) { |
| 1117 visible_iterator_ = TilingData::Iterator(&tiling_->tiling_data_, |
| 1118 tiling_->current_visible_rect_, |
| 1119 false /* include_borders */); |
| 1120 } |
| 1121 AdvanceNow(true); |
| 1122 break; |
| 1123 } |
| 1124 } |
| 1125 |
| 1126 void PictureLayerTiling::TilingEvictionTileIterator::AdvanceEventually( |
| 1127 bool first_run) { |
| 1128 if (!first_run) |
| 1129 ++spiral_iterator_; |
| 1130 |
| 1131 current_tile_ = nullptr; |
| 1132 while (spiral_iterator_) { |
| 1133 std::pair<int, int> next_index = spiral_iterator_.index(); |
| 1134 Tile* tile = tiling_->TileAt(next_index.first, next_index.second); |
| 1135 |
| 1136 // If a tile has resources, then it is a valid tile to return. |
| 1137 if (tile && tile->HasResources()) { |
| 1138 current_tile_ = tile; |
| 1139 break; |
| 1140 } |
| 1141 ++spiral_iterator_; |
| 1142 } |
| 1143 |
| 1144 if (current_tile_) |
| 1145 tiling_->UpdateTileAndTwinPriority(current_tile_); |
| 1146 } |
| 1147 |
| 1148 void PictureLayerTiling::TilingEvictionTileIterator::AdvanceSoon( |
| 1149 bool first_run) { |
| 1150 if (!first_run) |
| 1151 ++spiral_iterator_; |
| 1152 |
| 1153 // For the soon rect, we process both the soon border rect and |
| 1154 // the skewport rect. |
| 1155 current_tile_ = nullptr; |
| 1156 while (spiral_iterator_) { |
| 1157 std::pair<int, int> next_index = spiral_iterator_.index(); |
| 1158 Tile* tile = tiling_->TileAt(next_index.first, next_index.second); |
| 1159 |
| 1160 // If the tile has resources, we can return it. |
| 1161 if (tile && tile->HasResources()) { |
| 1162 current_tile_ = tile; |
| 1163 break; |
| 1164 } |
| 1165 ++spiral_iterator_; |
| 1166 |
| 1167 // If we ran out of tiles, but we were processing the soon border rect, then |
| 1168 // rebuild the iterator to iterate over skewport. |
| 1169 if (!spiral_iterator_ && processing_soon_border_rect_) { |
| 1170 if (tiling_->has_skewport_rect_tiles_) { |
| 1171 spiral_iterator_ = TilingData::ReverseSpiralDifferenceIterator( |
| 1172 &tiling_->tiling_data_, |
| 1173 tiling_->current_skewport_rect_, |
| 1174 tiling_->current_visible_rect_, |
| 1175 tiling_->current_visible_rect_); |
| 1176 } |
| 1177 processing_soon_border_rect_ = false; |
| 1178 } |
| 1179 } |
| 1180 |
| 1181 if (current_tile_) |
| 1182 tiling_->UpdateTileAndTwinPriority(current_tile_); |
| 1183 } |
| 1184 |
| 1185 void PictureLayerTiling::TilingEvictionTileIterator::AdvanceNow( |
| 1186 bool first_run) { |
| 1187 if (!first_run) { |
| 1188 if (processing_occluded_now_tiles_) |
| 1189 ++visible_iterator_; |
| 1190 else |
| 1191 ++unoccluded_now_tiles_index_; |
| 1192 } |
| 1193 |
| 1194 // For NOW bin, we process the visible rect, returning occluded tiles first, |
| 1195 // followed by unoccluded tiles. |
| 1196 current_tile_ = nullptr; |
| 1197 while (visible_iterator_ || |
| 1198 (unoccluded_now_tiles_index_ < unoccluded_now_tiles_.size())) { |
| 1199 if (!visible_iterator_) |
| 1200 processing_occluded_now_tiles_ = false; |
| 1201 |
| 1202 if (processing_occluded_now_tiles_) { |
| 1203 std::pair<int, int> next_index = visible_iterator_.index(); |
| 1204 Tile* tile = tiling_->TileAt(next_index.first, next_index.second); |
| 1205 |
| 1206 // If the tile doesn't have resources, then we won't return it now or |
| 1207 // during the occluded tile iteration. |
| 1208 if (!tile || !tile->HasResources()) { |
| 1209 ++visible_iterator_; |
| 1210 continue; |
| 1211 } |
| 1212 |
| 1213 bool tile_required_for_activation = false; |
| 1214 if (tiling_->client_->GetTree() == PENDING_TREE) |
| 1215 tile_required_for_activation = |
| 1216 tiling_->IsTileRequiredForActivation(tile); |
| 1217 |
| 1218 // Skip the tile if it doesn't match the requested activation criteria. |
| 1219 if ((eviction_category_ == NOW_AND_REQUIRED_FOR_ACTIVATION && |
| 1220 !tile_required_for_activation) || |
| 1221 (eviction_category_ == NOW && tile_required_for_activation)) { |
| 1222 ++visible_iterator_; |
| 1223 continue; |
| 1224 } |
| 1225 |
| 1226 // If the tile is not occluded, then save it temporarily for iteration |
| 1227 // later (in this pass, we're returning only occluded tiles). |
| 1228 if (!tiling_->IsTileOccluded(tile)) { |
| 1229 unoccluded_now_tiles_.push_back(tile); |
| 1230 ++visible_iterator_; |
| 1231 continue; |
| 1232 } |
| 1233 |
| 1234 // All of the above checks passed, so the tile is good to return now. |
| 1235 current_tile_ = tile; |
| 1236 break; |
| 1237 } |
| 1238 |
| 1239 // If we fall through here, that means we're iterating unoccluded tiles, |
| 1240 // which we already saved in |unoccluded_now_tiles_|. So, we can just |
| 1241 // iterate the vector. |
| 1242 Tile* tile = unoccluded_now_tiles_[unoccluded_now_tiles_index_]; |
| 1243 DCHECK(tile); |
| 1244 if (!tile->HasResources()) { |
| 1245 ++unoccluded_now_tiles_index_; |
| 1246 continue; |
| 1247 } |
| 1248 |
| 1249 current_tile_ = tile; |
| 1250 break; |
| 1251 } |
| 1252 |
| 1253 if (current_tile_) |
| 1254 tiling_->UpdateTileAndTwinPriority(current_tile_); |
1209 } | 1255 } |
1210 | 1256 |
1211 PictureLayerTiling::TilingEvictionTileIterator::~TilingEvictionTileIterator() { | 1257 PictureLayerTiling::TilingEvictionTileIterator::~TilingEvictionTileIterator() { |
1212 } | 1258 } |
1213 | 1259 |
1214 PictureLayerTiling::TilingEvictionTileIterator::operator bool() const { | 1260 PictureLayerTiling::TilingEvictionTileIterator::operator bool() const { |
1215 return eviction_tiles_ && | 1261 return !!current_tile_; |
1216 current_eviction_tiles_index_ != eviction_tiles_->size(); | |
1217 } | 1262 } |
1218 | 1263 |
1219 Tile* PictureLayerTiling::TilingEvictionTileIterator::operator*() { | 1264 Tile* PictureLayerTiling::TilingEvictionTileIterator::operator*() { |
1220 DCHECK(*this); | 1265 DCHECK(*this); |
1221 return (*eviction_tiles_)[current_eviction_tiles_index_]; | 1266 return current_tile_; |
1222 } | 1267 } |
1223 | 1268 |
1224 const Tile* PictureLayerTiling::TilingEvictionTileIterator::operator*() const { | 1269 const Tile* PictureLayerTiling::TilingEvictionTileIterator::operator*() const { |
1225 DCHECK(*this); | 1270 DCHECK(*this); |
1226 return (*eviction_tiles_)[current_eviction_tiles_index_]; | 1271 return current_tile_; |
1227 } | 1272 } |
1228 | 1273 |
1229 PictureLayerTiling::TilingEvictionTileIterator& | 1274 PictureLayerTiling::TilingEvictionTileIterator& |
1230 PictureLayerTiling::TilingEvictionTileIterator:: | 1275 PictureLayerTiling::TilingEvictionTileIterator:: |
1231 operator++() { | 1276 operator++() { |
1232 DCHECK(*this); | 1277 switch (eviction_category_) { |
1233 do { | 1278 case EVENTUALLY: |
1234 ++current_eviction_tiles_index_; | 1279 AdvanceEventually(false); |
1235 } while (current_eviction_tiles_index_ != eviction_tiles_->size() && | 1280 break; |
1236 !(*eviction_tiles_)[current_eviction_tiles_index_]->HasResources()); | 1281 case SOON: |
1237 | 1282 AdvanceSoon(false); |
| 1283 break; |
| 1284 case NOW: |
| 1285 case NOW_AND_REQUIRED_FOR_ACTIVATION: |
| 1286 AdvanceNow(false); |
| 1287 break; |
| 1288 } |
1238 return *this; | 1289 return *this; |
1239 } | 1290 } |
1240 | 1291 |
1241 } // namespace cc | 1292 } // namespace cc |
OLD | NEW |