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

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

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

Powered by Google App Engine
This is Rietveld 408576698