Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1433)

Side by Side Diff: cc/resources/picture_layer_tiling.cc

Issue 644313002: cc: Use reverse spiral iterator in tiling eviction. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698