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

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

Issue 674103004: [WIP] cc: Use reverse spiral iterator in tiling eviction. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase 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
« no previous file with comments | « cc/resources/picture_layer_tiling.h ('k') | cc/resources/picture_layer_tiling_perftest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 302 matching lines...) Expand 10 before | Expand all | Expand 10 after
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 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
588 float border = kSoonBorderDistanceInScreenPixels / content_to_screen_scale_; 554 float border = kSoonBorderDistanceInScreenPixels / content_to_screen_scale_;
589 soon_border_rect.Inset(-border, -border, -border, -border); 555 soon_border_rect.Inset(-border, -border, -border, -border);
590 556
591 // Update the tiling state. 557 // Update the tiling state.
592 SetLiveTilesRect(eventually_rect); 558 SetLiveTilesRect(eventually_rect);
593 559
594 last_impl_frame_time_in_seconds_ = current_frame_time_in_seconds; 560 last_impl_frame_time_in_seconds_ = current_frame_time_in_seconds;
595 last_viewport_in_layer_space_ = viewport_in_layer_space; 561 last_viewport_in_layer_space_ = viewport_in_layer_space;
596 last_visible_rect_in_content_space_ = visible_rect_in_content_space; 562 last_visible_rect_in_content_space_ = visible_rect_in_content_space;
597 563
598 eviction_tiles_cache_valid_ = false;
599
600 current_visible_rect_ = visible_rect_in_content_space; 564 current_visible_rect_ = visible_rect_in_content_space;
601 current_skewport_rect_ = skewport; 565 current_skewport_rect_ = skewport;
602 current_soon_border_rect_ = soon_border_rect; 566 current_soon_border_rect_ = soon_border_rect;
603 current_eventually_rect_ = eventually_rect; 567 current_eventually_rect_ = eventually_rect;
604 current_occlusion_in_layer_space_ = occlusion_in_layer_space; 568 current_occlusion_in_layer_space_ = occlusion_in_layer_space;
605 569
606 // Update has_*_tiles state. 570 // Update has_*_tiles state.
607 gfx::Rect tiling_rect(tiling_size()); 571 gfx::Rect tiling_rect(tiling_size());
608 572
609 has_visible_rect_tiles_ = tiling_rect.Intersects(current_visible_rect_); 573 has_visible_rect_tiles_ = tiling_rect.Intersects(current_visible_rect_);
(...skipping 382 matching lines...) Expand 10 before | Expand all | Expand 10 after
992 if (delta < event.distance) 956 if (delta < event.distance)
993 break; 957 break;
994 } 958 }
995 959
996 gfx::Rect result(origin_x, origin_y, width, height); 960 gfx::Rect result(origin_x, origin_y, width, height);
997 if (cache) 961 if (cache)
998 cache->previous_result = result; 962 cache->previous_result = result;
999 return result; 963 return result;
1000 } 964 }
1001 965
1002 void PictureLayerTiling::UpdateEvictionCacheIfNeeded(
1003 TreePriority tree_priority) {
1004 if (eviction_tiles_cache_valid_ &&
1005 eviction_cache_tree_priority_ == tree_priority)
1006 return;
1007
1008 eviction_tiles_now_.clear();
1009 eviction_tiles_now_and_required_for_activation_.clear();
1010 eviction_tiles_soon_.clear();
1011 eviction_tiles_soon_and_required_for_activation_.clear();
1012 eviction_tiles_eventually_.clear();
1013 eviction_tiles_eventually_and_required_for_activation_.clear();
1014
1015 for (TileMap::iterator it = tiles_.begin(); it != tiles_.end(); ++it) {
1016 Tile* tile = it->second.get();
1017 UpdateTileAndTwinPriority(tile);
1018 const TilePriority& priority =
1019 tile->priority_for_tree_priority(tree_priority);
1020 switch (priority.priority_bin) {
1021 case TilePriority::EVENTUALLY:
1022 if (tile->required_for_activation())
1023 eviction_tiles_eventually_and_required_for_activation_.push_back(
1024 tile);
1025 else
1026 eviction_tiles_eventually_.push_back(tile);
1027 break;
1028 case TilePriority::SOON:
1029 if (tile->required_for_activation())
1030 eviction_tiles_soon_and_required_for_activation_.push_back(tile);
1031 else
1032 eviction_tiles_soon_.push_back(tile);
1033 break;
1034 case TilePriority::NOW:
1035 if (tile->required_for_activation())
1036 eviction_tiles_now_and_required_for_activation_.push_back(tile);
1037 else
1038 eviction_tiles_now_.push_back(tile);
1039 break;
1040 }
1041 }
1042
1043 // TODO(vmpstr): Do this lazily. One option is to have a "sorted" flag that
1044 // can be updated for each of the queues.
1045 TileEvictionOrder sort_order(tree_priority);
1046 std::sort(eviction_tiles_now_.begin(), eviction_tiles_now_.end(), sort_order);
1047 std::sort(eviction_tiles_now_and_required_for_activation_.begin(),
1048 eviction_tiles_now_and_required_for_activation_.end(),
1049 sort_order);
1050 std::sort(
1051 eviction_tiles_soon_.begin(), eviction_tiles_soon_.end(), sort_order);
1052 std::sort(eviction_tiles_soon_and_required_for_activation_.begin(),
1053 eviction_tiles_soon_and_required_for_activation_.end(),
1054 sort_order);
1055 std::sort(eviction_tiles_eventually_.begin(),
1056 eviction_tiles_eventually_.end(),
1057 sort_order);
1058 std::sort(eviction_tiles_eventually_and_required_for_activation_.begin(),
1059 eviction_tiles_eventually_and_required_for_activation_.end(),
1060 sort_order);
1061
1062 eviction_tiles_cache_valid_ = true;
1063 eviction_cache_tree_priority_ = tree_priority;
1064 }
1065
1066 const std::vector<Tile*>* PictureLayerTiling::GetEvictionTiles(
1067 TreePriority tree_priority,
1068 EvictionCategory category) {
1069 UpdateEvictionCacheIfNeeded(tree_priority);
1070 switch (category) {
1071 case EVENTUALLY:
1072 return &eviction_tiles_eventually_;
1073 case EVENTUALLY_AND_REQUIRED_FOR_ACTIVATION:
1074 return &eviction_tiles_eventually_and_required_for_activation_;
1075 case SOON:
1076 return &eviction_tiles_soon_;
1077 case SOON_AND_REQUIRED_FOR_ACTIVATION:
1078 return &eviction_tiles_soon_and_required_for_activation_;
1079 case NOW:
1080 return &eviction_tiles_now_;
1081 case NOW_AND_REQUIRED_FOR_ACTIVATION:
1082 return &eviction_tiles_now_and_required_for_activation_;
1083 }
1084 NOTREACHED();
1085 return &eviction_tiles_eventually_;
1086 }
1087
1088 PictureLayerTiling::TilingRasterTileIterator::TilingRasterTileIterator() 966 PictureLayerTiling::TilingRasterTileIterator::TilingRasterTileIterator()
1089 : tiling_(NULL), current_tile_(NULL) {} 967 : tiling_(NULL), current_tile_(NULL) {}
1090 968
1091 PictureLayerTiling::TilingRasterTileIterator::TilingRasterTileIterator( 969 PictureLayerTiling::TilingRasterTileIterator::TilingRasterTileIterator(
1092 PictureLayerTiling* tiling) 970 PictureLayerTiling* tiling)
1093 : tiling_(tiling), phase_(VISIBLE_RECT), current_tile_(NULL) { 971 : tiling_(tiling), phase_(VISIBLE_RECT), current_tile_(NULL) {
1094 if (!tiling_->has_visible_rect_tiles_) { 972 if (!tiling_->has_visible_rect_tiles_) {
1095 AdvancePhase(); 973 AdvancePhase();
1096 return; 974 return;
1097 } 975 }
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
1211 } 1089 }
1212 current_tile_ = tiling_->TileAt(next_index.first, next_index.second); 1090 current_tile_ = tiling_->TileAt(next_index.first, next_index.second);
1213 } 1091 }
1214 1092
1215 if (current_tile_) 1093 if (current_tile_)
1216 tiling_->UpdateTileAndTwinPriority(current_tile_); 1094 tiling_->UpdateTileAndTwinPriority(current_tile_);
1217 return *this; 1095 return *this;
1218 } 1096 }
1219 1097
1220 PictureLayerTiling::TilingEvictionTileIterator::TilingEvictionTileIterator() 1098 PictureLayerTiling::TilingEvictionTileIterator::TilingEvictionTileIterator()
1221 : eviction_tiles_(NULL), current_eviction_tiles_index_(0u) { 1099 : tiling_(nullptr),
1100 tree_priority_(SAME_PRIORITY_FOR_BOTH_TREES),
1101 eviction_category_(EVENTUALLY),
1102 processing_soon_border_rect_(false),
1103 skip_shared_high_priority_tiles_(false),
1104 unoccluded_now_tiles_index_(0u),
1105 current_tile_(nullptr) {
1222 } 1106 }
1223 1107
1224 PictureLayerTiling::TilingEvictionTileIterator::TilingEvictionTileIterator( 1108 PictureLayerTiling::TilingEvictionTileIterator::TilingEvictionTileIterator(
1225 PictureLayerTiling* tiling, 1109 PictureLayerTiling* tiling,
1226 TreePriority tree_priority, 1110 TreePriority tree_priority,
1227 EvictionCategory category) 1111 EvictionCategory category,
1228 : eviction_tiles_(tiling->GetEvictionTiles(tree_priority, category)), 1112 bool skip_shared_high_priority_tiles)
1229 // Note: initializing to "0 - 1" works as overflow is well defined for 1113 : tiling_(tiling),
1230 // unsigned integers. 1114 tree_priority_(tree_priority),
1231 current_eviction_tiles_index_(static_cast<size_t>(0) - 1) { 1115 eviction_category_(category),
1232 DCHECK(eviction_tiles_); 1116 processing_soon_border_rect_(true),
1233 ++(*this); 1117 skip_shared_high_priority_tiles_(skip_shared_high_priority_tiles),
1118 unoccluded_now_tiles_index_(0),
1119 current_tile_(nullptr) {
1120 WhichTree tree = tiling_->client_->GetTree();
1121 if (tree == PENDING_TREE) {
1122 switch (eviction_category_) {
1123 case EVENTUALLY_AND_REQUIRED_FOR_ACTIVATION:
1124 case SOON_AND_REQUIRED_FOR_ACTIVATION:
1125 // Pending EVENTUALLY and SOON tiles are never required for activation.
1126 return;
1127 default:
1128 break;
1129 }
1130 } else {
1131 switch (eviction_category_) {
1132 case EVENTUALLY_AND_REQUIRED_FOR_ACTIVATION:
1133 case SOON_AND_REQUIRED_FOR_ACTIVATION:
1134 case NOW_AND_REQUIRED_FOR_ACTIVATION: {
1135 // Early out if there is no pending twin tiling.
1136 if (!skip_shared_high_priority_tiles_)
1137 return;
1138 const PictureLayerTiling* twin_tiling =
1139 tiling_->client_->GetPendingOrActiveTwinTiling(tiling_);
1140 if (!twin_tiling)
1141 return;
1142 // Early out if the pending twin tiling does not have NOW tiles.
1143 TilePriority::PriorityBin max_twin_tile_priority_bin =
1144 twin_tiling->client_->GetMaxTilePriorityBin();
1145 if (max_twin_tile_priority_bin > TilePriority::NOW)
1146 return;
1147 break;
1148 }
1149 default:
1150 break;
1151 }
1152 }
1153 TilePriority::PriorityBin max_tile_priority_bin =
1154 tiling_->client_->GetMaxTilePriorityBin();
1155 switch (eviction_category_) {
1156 case EVENTUALLY_AND_REQUIRED_FOR_ACTIVATION:
1157 case EVENTUALLY:
1158 if (tiling_->has_eventually_rect_tiles_) {
1159 if (max_tile_priority_bin < TilePriority::EVENTUALLY)
1160 spiral_iterator_ = TilingData::ReverseSpiralDifferenceIterator(
1161 &tiling_->tiling_data_, tiling_->current_eventually_rect_,
1162 tiling_->current_skewport_rect_,
1163 tiling_->current_soon_border_rect_);
1164 else
1165 spiral_iterator_ = TilingData::ReverseSpiralDifferenceIterator(
1166 &tiling_->tiling_data_, tiling_->current_eventually_rect_,
1167 gfx::Rect(), gfx::Rect());
1168 bool skipped_tiles = false;
1169 AdvanceEventually(&skipped_tiles);
1170 if (!current_tile_ && !skipped_tiles &&
1171 max_tile_priority_bin == TilePriority::EVENTUALLY)
1172 tiling_->has_eventually_rect_tiles_ = false;
1173 }
1174 break;
1175 case SOON_AND_REQUIRED_FOR_ACTIVATION:
1176 case SOON:
1177 if (max_tile_priority_bin <= TilePriority::SOON &&
1178 (tiling_->has_skewport_rect_tiles_ ||
1179 tiling_->has_soon_border_rect_tiles_)) {
1180 if (tiling_->has_soon_border_rect_tiles_)
1181 spiral_iterator_ = TilingData::ReverseSpiralDifferenceIterator(
1182 &tiling_->tiling_data_, tiling_->current_soon_border_rect_,
1183 tiling_->current_skewport_rect_, tiling_->current_visible_rect_);
1184 AdvanceSoon();
1185 }
1186 break;
1187 case NOW_AND_REQUIRED_FOR_ACTIVATION:
1188 case NOW:
1189 if (max_tile_priority_bin <= TilePriority::NOW &&
1190 tiling_->has_visible_rect_tiles_) {
1191 visible_iterator_ = TilingData::Iterator(&tiling_->tiling_data_,
1192 tiling_->current_visible_rect_,
1193 false /* include_borders */);
1194 AdvanceNow();
1195 }
1196 break;
1197 }
1198 }
1199
1200 void PictureLayerTiling::TilingEvictionTileIterator::AdvanceEventually(
1201 bool* skipped_tiles) {
1202 bool required_for_activation =
1203 eviction_category_ == EVENTUALLY_AND_REQUIRED_FOR_ACTIVATION;
1204 while (spiral_iterator_) {
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 (PrepareTileUnlessReturnedByTwin(tile) &&
1211 tile->required_for_activation() == required_for_activation) {
1212 current_tile_ = tile;
1213 return;
1214 }
1215 if (skipped_tiles)
1216 *skipped_tiles = true;
1217 }
1218
1219 current_tile_ = nullptr;
1220 }
1221
1222 void PictureLayerTiling::TilingEvictionTileIterator::AdvanceSoon() {
1223 bool required_for_activation =
1224 eviction_category_ == SOON_AND_REQUIRED_FOR_ACTIVATION;
1225 while (spiral_iterator_) {
1226 std::pair<int, int> next_index = spiral_iterator_.index();
1227 Tile* tile = tiling_->TileAt(next_index.first, next_index.second);
1228 ++spiral_iterator_;
1229 if (tile && tile->HasResources() && PrepareTileUnlessReturnedByTwin(tile) &&
1230 tile->required_for_activation() == required_for_activation) {
1231 current_tile_ = tile;
1232 return;
1233 }
1234 if (!spiral_iterator_ && processing_soon_border_rect_) {
1235 if (tiling_->has_skewport_rect_tiles_) {
1236 // Max tile priority bin should never be SOON so there is no need to
1237 // create a special case for the inclusion of the visible rect.
1238 DCHECK_EQ(tiling_->client_->GetMaxTilePriorityBin(), TilePriority::NOW);
1239 DCHECK_LT(tiling_->client_->GetMaxTilePriorityBin(),
1240 TilePriority::SOON);
1241 spiral_iterator_ = TilingData::ReverseSpiralDifferenceIterator(
1242 &tiling_->tiling_data_, tiling_->current_skewport_rect_,
1243 tiling_->current_visible_rect_, tiling_->current_visible_rect_);
1244 }
1245 processing_soon_border_rect_ = false;
1246 }
1247 }
1248
1249 current_tile_ = nullptr;
1250 }
1251
1252 void PictureLayerTiling::TilingEvictionTileIterator::AdvanceNow() {
1253 bool required_for_activation =
1254 eviction_category_ == NOW_AND_REQUIRED_FOR_ACTIVATION;
1255 if (visible_iterator_) {
1256 WhichTree tree = tiling_->client_->GetTree();
1257 bool skip_all_shared_tiles =
1258 skip_shared_high_priority_tiles_ &&
1259 tree_priority_ == (tree == ACTIVE_TREE ? NEW_CONTENT_TAKES_PRIORITY
1260 : SMOOTHNESS_TAKES_PRIORITY);
1261 while (visible_iterator_) {
1262 std::pair<int, int> next_index = visible_iterator_.index();
1263 Tile* tile = tiling_->TileAt(next_index.first, next_index.second);
1264 ++visible_iterator_;
1265 if (!tile || !tile->HasResources())
1266 continue;
1267 if (skip_all_shared_tiles && tile->is_shared())
1268 continue;
1269 if (tree == PENDING_TREE &&
1270 tiling_->IsTileRequiredForActivationIfVisible(tile) !=
1271 required_for_activation)
1272 continue;
1273 if (!tiling_->IsTileOccluded(tile)) {
1274 unoccluded_now_tiles_.push_back(tile);
1275 continue;
1276 }
1277 if (PrepareTileUnlessReturnedByTwin(tile) &&
1278 tile->required_for_activation() == required_for_activation) {
1279 current_tile_ = tile;
1280 return;
1281 }
1282 }
1283 }
1284
1285 while (unoccluded_now_tiles_index_ < unoccluded_now_tiles_.size()) {
1286 Tile* tile = unoccluded_now_tiles_[unoccluded_now_tiles_index_];
1287 ++unoccluded_now_tiles_index_;
1288 DCHECK(tile);
1289 if (!tile->HasResources())
1290 continue;
1291 if (PrepareTileUnlessReturnedByTwin(tile) &&
1292 tile->required_for_activation() == required_for_activation) {
1293 current_tile_ = tile;
1294 return;
1295 }
1296 }
1297
1298 current_tile_ = nullptr;
1299 }
1300
1301 bool PictureLayerTiling::TilingEvictionTileIterator::
1302 PrepareTileUnlessReturnedByTwin(Tile* tile) const {
1303 if (skip_shared_high_priority_tiles_ && tile->is_shared()) {
1304 WhichTree tree = tiling_->client_->GetTree();
1305 switch (tree_priority_) {
1306 case SMOOTHNESS_TAKES_PRIORITY:
1307 // The priority for tile priority of a shared tile will be the active
1308 // priority thus return shared tiles from the active tree.
1309 if (tree != ACTIVE_TREE)
1310 return false;
1311 break;
1312 case NEW_CONTENT_TAKES_PRIORITY:
1313 // The priority for tile priority of a shared tile will be the pending
1314 // priority thus return shared tiles from the pending tree.
1315 if (tree != PENDING_TREE)
1316 return false;
1317 break;
1318 case SAME_PRIORITY_FOR_BOTH_TREES: {
1319 // The priority for tile priority of a shared tile will be a combined
1320 // priority thus return shared tiles from a higher priority tree.
1321 tiling_->UpdateTileAndTwinPriority(tile);
1322 WhichTree other_tree = tree == ACTIVE_TREE ? PENDING_TREE : ACTIVE_TREE;
1323 const TilePriority& priority = tile->priority(tree);
1324 const TilePriority& other_priority = tile->priority(other_tree);
1325 if (priority.priority_bin != other_priority.priority_bin)
1326 return priority.priority_bin < other_priority.priority_bin;
1327 const bool occluded = tile->is_occluded(tree);
1328 const bool other_occluded = tile->is_occluded(other_tree);
1329 if (occluded != other_occluded)
1330 return !occluded;
1331 if (priority.distance_to_visible != other_priority.distance_to_visible)
1332 return priority.distance_to_visible <
1333 other_priority.distance_to_visible;
1334 return tree == ACTIVE_TREE;
1335 }
1336 default:
1337 NOTREACHED();
1338 }
1339 }
1340 tiling_->UpdateTileAndTwinPriority(tile);
1341 return true;
1234 } 1342 }
1235 1343
1236 PictureLayerTiling::TilingEvictionTileIterator::~TilingEvictionTileIterator() { 1344 PictureLayerTiling::TilingEvictionTileIterator::~TilingEvictionTileIterator() {
1237 } 1345 }
1238 1346
1239 PictureLayerTiling::TilingEvictionTileIterator::operator bool() const { 1347 PictureLayerTiling::TilingEvictionTileIterator::operator bool() const {
1240 return eviction_tiles_ && 1348 return !!current_tile_;
1241 current_eviction_tiles_index_ != eviction_tiles_->size();
1242 } 1349 }
1243 1350
1244 Tile* PictureLayerTiling::TilingEvictionTileIterator::operator*() { 1351 Tile* PictureLayerTiling::TilingEvictionTileIterator::operator*() {
1245 DCHECK(*this); 1352 DCHECK(*this);
1246 return (*eviction_tiles_)[current_eviction_tiles_index_]; 1353 return current_tile_;
1247 } 1354 }
1248 1355
1249 const Tile* PictureLayerTiling::TilingEvictionTileIterator::operator*() const { 1356 const Tile* PictureLayerTiling::TilingEvictionTileIterator::operator*() const {
1250 DCHECK(*this); 1357 DCHECK(*this);
1251 return (*eviction_tiles_)[current_eviction_tiles_index_]; 1358 return current_tile_;
1252 } 1359 }
1253 1360
1254 PictureLayerTiling::TilingEvictionTileIterator& 1361 PictureLayerTiling::TilingEvictionTileIterator&
1255 PictureLayerTiling::TilingEvictionTileIterator:: 1362 PictureLayerTiling::TilingEvictionTileIterator::
1256 operator++() { 1363 operator++() {
1257 DCHECK(*this); 1364 switch (eviction_category_) {
1258 do { 1365 case EVENTUALLY:
1259 ++current_eviction_tiles_index_; 1366 case EVENTUALLY_AND_REQUIRED_FOR_ACTIVATION:
1260 } while (current_eviction_tiles_index_ != eviction_tiles_->size() && 1367 AdvanceEventually(nullptr);
1261 !(*eviction_tiles_)[current_eviction_tiles_index_]->HasResources()); 1368 break;
1262 1369 case SOON:
1370 case SOON_AND_REQUIRED_FOR_ACTIVATION:
1371 AdvanceSoon();
1372 break;
1373 case NOW:
1374 case NOW_AND_REQUIRED_FOR_ACTIVATION:
1375 AdvanceNow();
1376 break;
1377 }
1263 return *this; 1378 return *this;
1264 } 1379 }
1265 1380
1266 } // namespace cc 1381 } // namespace cc
OLDNEW
« no previous file with comments | « cc/resources/picture_layer_tiling.h ('k') | cc/resources/picture_layer_tiling_perftest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698