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