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 size_t max_tiles_for_interest_area, |
64 layer_bounds, | 35 float skewport_target_time_in_seconds, |
65 client)); | 36 int skewport_extrapolation_limit_in_content_pixels) { |
| 37 return make_scoped_ptr(new PictureLayerTiling( |
| 38 contents_scale, layer_bounds, client, max_tiles_for_interest_area, |
| 39 skewport_target_time_in_seconds, |
| 40 skewport_extrapolation_limit_in_content_pixels)); |
66 } | 41 } |
67 | 42 |
68 PictureLayerTiling::PictureLayerTiling(float contents_scale, | 43 PictureLayerTiling::PictureLayerTiling( |
69 const gfx::Size& layer_bounds, | 44 float contents_scale, |
70 PictureLayerTilingClient* client) | 45 const gfx::Size& layer_bounds, |
71 : contents_scale_(contents_scale), | 46 PictureLayerTilingClient* client, |
| 47 size_t max_tiles_for_interest_area, |
| 48 float skewport_target_time_in_seconds, |
| 49 int skewport_extrapolation_limit_in_content_pixels) |
| 50 : max_tiles_for_interest_area_(max_tiles_for_interest_area), |
| 51 skewport_target_time_in_seconds_(skewport_target_time_in_seconds), |
| 52 skewport_extrapolation_limit_in_content_pixels_( |
| 53 skewport_extrapolation_limit_in_content_pixels), |
| 54 contents_scale_(contents_scale), |
72 layer_bounds_(layer_bounds), | 55 layer_bounds_(layer_bounds), |
73 resolution_(NON_IDEAL_RESOLUTION), | 56 resolution_(NON_IDEAL_RESOLUTION), |
74 client_(client), | 57 client_(client), |
75 tiling_data_(gfx::Size(), gfx::Size(), kBorderTexels), | 58 tiling_data_(gfx::Size(), gfx::Size(), kBorderTexels), |
76 last_impl_frame_time_in_seconds_(0.0), | 59 last_impl_frame_time_in_seconds_(0.0), |
77 content_to_screen_scale_(0.f), | |
78 can_require_tiles_for_activation_(false), | 60 can_require_tiles_for_activation_(false), |
| 61 current_content_to_screen_scale_(0.f), |
79 has_visible_rect_tiles_(false), | 62 has_visible_rect_tiles_(false), |
80 has_skewport_rect_tiles_(false), | 63 has_skewport_rect_tiles_(false), |
81 has_soon_border_rect_tiles_(false), | 64 has_soon_border_rect_tiles_(false), |
82 has_eventually_rect_tiles_(false), | 65 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 = | 66 gfx::Size content_bounds = |
86 gfx::ToCeiledSize(gfx::ScaleSize(layer_bounds, contents_scale)); | 67 gfx::ToCeiledSize(gfx::ScaleSize(layer_bounds, contents_scale)); |
87 gfx::Size tile_size = client_->CalculateTileSize(content_bounds); | 68 gfx::Size tile_size = client_->CalculateTileSize(content_bounds); |
88 if (tile_size.IsEmpty()) { | 69 if (tile_size.IsEmpty()) { |
89 layer_bounds_ = gfx::Size(); | 70 layer_bounds_ = gfx::Size(); |
90 content_bounds = gfx::Size(); | 71 content_bounds = gfx::Size(); |
91 } | 72 } |
92 | 73 |
93 DCHECK(!gfx::ToFlooredSize( | 74 DCHECK(!gfx::ToFlooredSize( |
94 gfx::ScaleSize(layer_bounds, contents_scale)).IsEmpty()) << | 75 gfx::ScaleSize(layer_bounds, contents_scale)).IsEmpty()) << |
95 "Tiling created with scale too small as contents become empty." << | 76 "Tiling created with scale too small as contents become empty." << |
96 " Layer bounds: " << layer_bounds.ToString() << | 77 " Layer bounds: " << layer_bounds.ToString() << |
97 " Contents scale: " << contents_scale; | 78 " Contents scale: " << contents_scale; |
98 | 79 |
99 tiling_data_.SetTilingSize(content_bounds); | 80 tiling_data_.SetTilingSize(content_bounds); |
100 tiling_data_.SetMaxTextureSize(tile_size); | 81 tiling_data_.SetMaxTextureSize(tile_size); |
101 } | 82 } |
102 | 83 |
103 PictureLayerTiling::~PictureLayerTiling() { | 84 PictureLayerTiling::~PictureLayerTiling() { |
104 for (TileMap::const_iterator it = tiles_.begin(); it != tiles_.end(); ++it) | 85 for (TileMap::const_iterator it = tiles_.begin(); it != tiles_.end(); ++it) |
105 it->second->set_shared(false); | 86 it->second->set_shared(false); |
106 } | 87 } |
107 | 88 |
108 void PictureLayerTiling::SetClient(PictureLayerTilingClient* client) { | |
109 client_ = client; | |
110 } | |
111 | |
112 Tile* PictureLayerTiling::CreateTile(int i, | 89 Tile* PictureLayerTiling::CreateTile(int i, |
113 int j, | 90 int j, |
114 const PictureLayerTiling* twin_tiling) { | 91 const PictureLayerTiling* twin_tiling, |
| 92 PictureLayerTiling* recycled_twin) { |
| 93 // Can't have both a (pending or active) twin and a recycled twin tiling. |
| 94 DCHECK_IMPLIES(twin_tiling, !recycled_twin); |
| 95 DCHECK_IMPLIES(recycled_twin, !twin_tiling); |
115 TileMapKey key(i, j); | 96 TileMapKey key(i, j); |
116 DCHECK(tiles_.find(key) == tiles_.end()); | 97 DCHECK(tiles_.find(key) == tiles_.end()); |
117 | 98 |
118 gfx::Rect paint_rect = tiling_data_.TileBoundsWithBorder(i, j); | 99 gfx::Rect paint_rect = tiling_data_.TileBoundsWithBorder(i, j); |
119 gfx::Rect tile_rect = paint_rect; | 100 gfx::Rect tile_rect = paint_rect; |
120 tile_rect.set_size(tiling_data_.max_texture_size()); | 101 tile_rect.set_size(tiling_data_.max_texture_size()); |
121 | 102 |
122 // Check our twin for a valid tile. | 103 // Check our twin for a valid tile. |
123 if (twin_tiling && | 104 if (twin_tiling && |
124 tiling_data_.max_texture_size() == | 105 tiling_data_.max_texture_size() == |
(...skipping 12 matching lines...) Expand all Loading... |
137 } | 118 } |
138 } | 119 } |
139 } | 120 } |
140 | 121 |
141 // Create a new tile because our twin didn't have a valid one. | 122 // Create a new tile because our twin didn't have a valid one. |
142 scoped_refptr<Tile> tile = client_->CreateTile(this, tile_rect); | 123 scoped_refptr<Tile> tile = client_->CreateTile(this, tile_rect); |
143 if (tile.get()) { | 124 if (tile.get()) { |
144 DCHECK(!tile->is_shared()); | 125 DCHECK(!tile->is_shared()); |
145 tile->set_tiling_index(i, j); | 126 tile->set_tiling_index(i, j); |
146 tiles_[key] = tile; | 127 tiles_[key] = tile; |
| 128 |
| 129 if (recycled_twin) { |
| 130 DCHECK(recycled_twin->tiles_.find(key) == recycled_twin->tiles_.end()); |
| 131 // Do what recycled_twin->CreateTile() would do. |
| 132 tile->set_shared(true); |
| 133 recycled_twin->tiles_[key] = tile; |
| 134 } |
147 } | 135 } |
148 eviction_tiles_cache_valid_ = false; | |
149 return tile.get(); | 136 return tile.get(); |
150 } | 137 } |
151 | 138 |
152 void PictureLayerTiling::CreateMissingTilesInLiveTilesRect() { | 139 void PictureLayerTiling::CreateMissingTilesInLiveTilesRect() { |
153 const PictureLayerTiling* twin_tiling = | 140 const PictureLayerTiling* twin_tiling = |
154 client_->GetPendingOrActiveTwinTiling(this); | 141 client_->GetPendingOrActiveTwinTiling(this); |
| 142 // There is no recycled twin during commit from the main thread which is when |
| 143 // this occurs. |
| 144 PictureLayerTiling* null_recycled_twin = nullptr; |
| 145 DCHECK_EQ(null_recycled_twin, client_->GetRecycledTwinTiling(this)); |
155 bool include_borders = false; | 146 bool include_borders = false; |
156 for (TilingData::Iterator iter( | 147 for (TilingData::Iterator iter( |
157 &tiling_data_, live_tiles_rect_, include_borders); | 148 &tiling_data_, live_tiles_rect_, include_borders); |
158 iter; | 149 iter; |
159 ++iter) { | 150 ++iter) { |
160 TileMapKey key = iter.index(); | 151 TileMapKey key = iter.index(); |
161 TileMap::iterator find = tiles_.find(key); | 152 TileMap::iterator find = tiles_.find(key); |
162 if (find != tiles_.end()) | 153 if (find != tiles_.end()) |
163 continue; | 154 continue; |
164 CreateTile(key.first, key.second, twin_tiling); | 155 CreateTile(key.first, key.second, twin_tiling, null_recycled_twin); |
165 } | 156 } |
166 | 157 |
167 VerifyLiveTilesRect(); | 158 VerifyLiveTilesRect(false); |
168 } | 159 } |
169 | 160 |
170 void PictureLayerTiling::UpdateTilesToCurrentRasterSource( | 161 void PictureLayerTiling::CloneTilesAndPropertiesFrom( |
171 RasterSource* raster_source, | 162 const PictureLayerTiling& twin_tiling) { |
172 const Region& layer_invalidation, | 163 DCHECK_EQ(&twin_tiling, client_->GetPendingOrActiveTwinTiling(this)); |
173 const gfx::Size& new_layer_bounds) { | |
174 DCHECK(!new_layer_bounds.IsEmpty()); | |
175 | 164 |
| 165 Resize(twin_tiling.layer_bounds_); |
| 166 DCHECK_EQ(twin_tiling.contents_scale_, contents_scale_); |
| 167 DCHECK_EQ(twin_tiling.layer_bounds().ToString(), layer_bounds().ToString()); |
| 168 DCHECK_EQ(twin_tiling.tile_size().ToString(), tile_size().ToString()); |
| 169 |
| 170 resolution_ = twin_tiling.resolution_; |
| 171 |
| 172 SetLiveTilesRect(twin_tiling.live_tiles_rect()); |
| 173 |
| 174 // Recreate unshared tiles. |
| 175 std::vector<TileMapKey> to_remove; |
| 176 for (const auto& tile_map_pair : tiles_) { |
| 177 TileMapKey key = tile_map_pair.first; |
| 178 Tile* tile = tile_map_pair.second.get(); |
| 179 if (!tile->is_shared()) |
| 180 to_remove.push_back(key); |
| 181 } |
| 182 // The recycled twin does not exist since there is a pending twin (which is |
| 183 // |twin_tiling|). |
| 184 PictureLayerTiling* null_recycled_twin = nullptr; |
| 185 DCHECK_EQ(null_recycled_twin, client_->GetRecycledTwinTiling(this)); |
| 186 for (const auto& key : to_remove) { |
| 187 RemoveTileAt(key.first, key.second, null_recycled_twin); |
| 188 CreateTile(key.first, key.second, &twin_tiling, null_recycled_twin); |
| 189 } |
| 190 |
| 191 // Create any missing tiles from the |twin_tiling|. |
| 192 for (const auto& tile_map_pair : twin_tiling.tiles_) { |
| 193 TileMapKey key = tile_map_pair.first; |
| 194 Tile* tile = tile_map_pair.second.get(); |
| 195 if (!tile->is_shared()) |
| 196 CreateTile(key.first, key.second, &twin_tiling, null_recycled_twin); |
| 197 } |
| 198 |
| 199 DCHECK_EQ(twin_tiling.tiles_.size(), tiles_.size()); |
| 200 #if DCHECK_IS_ON |
| 201 for (const auto& tile_map_pair : tiles_) |
| 202 DCHECK(tile_map_pair.second->is_shared()); |
| 203 VerifyLiveTilesRect(false); |
| 204 #endif |
| 205 |
| 206 UpdateTilePriorityRects(twin_tiling.current_content_to_screen_scale_, |
| 207 twin_tiling.current_visible_rect_, |
| 208 twin_tiling.current_skewport_rect_, |
| 209 twin_tiling.current_soon_border_rect_, |
| 210 twin_tiling.current_eventually_rect_, |
| 211 twin_tiling.current_occlusion_in_layer_space_); |
| 212 } |
| 213 |
| 214 void PictureLayerTiling::Resize(const gfx::Size& new_layer_bounds) { |
| 215 gfx::Size layer_bounds = new_layer_bounds; |
176 gfx::Size content_bounds = | 216 gfx::Size content_bounds = |
177 gfx::ToCeiledSize(gfx::ScaleSize(new_layer_bounds, contents_scale_)); | 217 gfx::ToCeiledSize(gfx::ScaleSize(new_layer_bounds, contents_scale_)); |
178 gfx::Size tile_size = client_->CalculateTileSize(content_bounds); | 218 gfx::Size tile_size = client_->CalculateTileSize(content_bounds); |
179 | 219 |
180 if (new_layer_bounds != layer_bounds_) { | 220 if (tile_size.IsEmpty()) { |
181 if (tile_size.IsEmpty()) { | 221 layer_bounds = gfx::Size(); |
182 layer_bounds_ = gfx::Size(); | 222 content_bounds = gfx::Size(); |
183 content_bounds = gfx::Size(); | |
184 } else { | |
185 layer_bounds_ = new_layer_bounds; | |
186 } | |
187 | |
188 // The SetLiveTilesRect() method would drop tiles outside the new bounds, | |
189 // but may do so incorrectly if resizing the tiling causes the number of | |
190 // tiles in the tiling_data_ to change. | |
191 gfx::Rect content_rect(content_bounds); | |
192 int before_left = tiling_data_.TileXIndexFromSrcCoord(live_tiles_rect_.x()); | |
193 int before_top = tiling_data_.TileYIndexFromSrcCoord(live_tiles_rect_.y()); | |
194 int before_right = | |
195 tiling_data_.TileXIndexFromSrcCoord(live_tiles_rect_.right() - 1); | |
196 int before_bottom = | |
197 tiling_data_.TileYIndexFromSrcCoord(live_tiles_rect_.bottom() - 1); | |
198 | |
199 // The live_tiles_rect_ is clamped to stay within the tiling size as we | |
200 // change it. | |
201 live_tiles_rect_.Intersect(content_rect); | |
202 tiling_data_.SetTilingSize(content_bounds); | |
203 | |
204 int after_right = -1; | |
205 int after_bottom = -1; | |
206 if (!live_tiles_rect_.IsEmpty()) { | |
207 after_right = | |
208 tiling_data_.TileXIndexFromSrcCoord(live_tiles_rect_.right() - 1); | |
209 after_bottom = | |
210 tiling_data_.TileYIndexFromSrcCoord(live_tiles_rect_.bottom() - 1); | |
211 } | |
212 | |
213 // There is no recycled twin since this is run on the pending tiling. | |
214 PictureLayerTiling* recycled_twin = NULL; | |
215 DCHECK_EQ(recycled_twin, client_->GetRecycledTwinTiling(this)); | |
216 DCHECK_EQ(PENDING_TREE, client_->GetTree()); | |
217 | |
218 // Drop tiles outside the new layer bounds if the layer shrank. | |
219 for (int i = after_right + 1; i <= before_right; ++i) { | |
220 for (int j = before_top; j <= before_bottom; ++j) | |
221 RemoveTileAt(i, j, recycled_twin); | |
222 } | |
223 for (int i = before_left; i <= after_right; ++i) { | |
224 for (int j = after_bottom + 1; j <= before_bottom; ++j) | |
225 RemoveTileAt(i, j, recycled_twin); | |
226 } | |
227 | |
228 // If the layer grew, the live_tiles_rect_ is not changed, but a new row | |
229 // and/or column of tiles may now exist inside the same live_tiles_rect_. | |
230 const PictureLayerTiling* twin_tiling = | |
231 client_->GetPendingOrActiveTwinTiling(this); | |
232 if (after_right > before_right) { | |
233 DCHECK_EQ(after_right, before_right + 1); | |
234 for (int j = before_top; j <= after_bottom; ++j) | |
235 CreateTile(after_right, j, twin_tiling); | |
236 } | |
237 if (after_bottom > before_bottom) { | |
238 DCHECK_EQ(after_bottom, before_bottom + 1); | |
239 for (int i = before_left; i <= before_right; ++i) | |
240 CreateTile(i, after_bottom, twin_tiling); | |
241 } | |
242 } | 223 } |
243 | 224 |
| 225 // The layer bounds are only allowed to be empty when the tile size is empty. |
| 226 // Otherwise we should not have such a tiling in the first place. |
| 227 DCHECK_IMPLIES(!tile_size.IsEmpty(), !layer_bounds_.IsEmpty()); |
| 228 |
| 229 bool resized = layer_bounds != layer_bounds_; |
| 230 layer_bounds_ = layer_bounds; |
| 231 |
244 if (tile_size != tiling_data_.max_texture_size()) { | 232 if (tile_size != tiling_data_.max_texture_size()) { |
| 233 tiling_data_.SetTilingSize(content_bounds); |
245 tiling_data_.SetMaxTextureSize(tile_size); | 234 tiling_data_.SetMaxTextureSize(tile_size); |
246 // When the tile size changes, the TilingData positions no longer work | 235 // When the tile size changes, the TilingData positions no longer work |
247 // as valid keys to the TileMap, so just drop all tiles. | 236 // as valid keys to the TileMap, so just drop all tiles and clear the live |
| 237 // tiles rect. |
248 Reset(); | 238 Reset(); |
249 } else { | 239 return; |
250 Invalidate(layer_invalidation); | |
251 } | 240 } |
252 | 241 |
253 for (TileMap::const_iterator it = tiles_.begin(); it != tiles_.end(); ++it) | 242 if (!resized) |
254 it->second->set_raster_source(raster_source); | 243 return; |
255 VerifyLiveTilesRect(); | 244 |
| 245 // The SetLiveTilesRect() method would drop tiles outside the new bounds, |
| 246 // but may do so incorrectly if resizing the tiling causes the number of |
| 247 // tiles in the tiling_data_ to change. |
| 248 gfx::Rect content_rect(content_bounds); |
| 249 int before_left = tiling_data_.TileXIndexFromSrcCoord(live_tiles_rect_.x()); |
| 250 int before_top = tiling_data_.TileYIndexFromSrcCoord(live_tiles_rect_.y()); |
| 251 int before_right = |
| 252 tiling_data_.TileXIndexFromSrcCoord(live_tiles_rect_.right() - 1); |
| 253 int before_bottom = |
| 254 tiling_data_.TileYIndexFromSrcCoord(live_tiles_rect_.bottom() - 1); |
| 255 |
| 256 // The live_tiles_rect_ is clamped to stay within the tiling size as we |
| 257 // change it. |
| 258 live_tiles_rect_.Intersect(content_rect); |
| 259 tiling_data_.SetTilingSize(content_bounds); |
| 260 |
| 261 int after_right = -1; |
| 262 int after_bottom = -1; |
| 263 if (!live_tiles_rect_.IsEmpty()) { |
| 264 after_right = |
| 265 tiling_data_.TileXIndexFromSrcCoord(live_tiles_rect_.right() - 1); |
| 266 after_bottom = |
| 267 tiling_data_.TileYIndexFromSrcCoord(live_tiles_rect_.bottom() - 1); |
| 268 } |
| 269 |
| 270 // There is no recycled twin since this is run on the pending tiling |
| 271 // during commit, and on the active tree during activate. |
| 272 PictureLayerTiling* null_recycled_twin = nullptr; |
| 273 DCHECK_EQ(null_recycled_twin, client_->GetRecycledTwinTiling(this)); |
| 274 |
| 275 // Drop tiles outside the new layer bounds if the layer shrank. |
| 276 for (int i = after_right + 1; i <= before_right; ++i) { |
| 277 for (int j = before_top; j <= before_bottom; ++j) |
| 278 RemoveTileAt(i, j, null_recycled_twin); |
| 279 } |
| 280 for (int i = before_left; i <= after_right; ++i) { |
| 281 for (int j = after_bottom + 1; j <= before_bottom; ++j) |
| 282 RemoveTileAt(i, j, null_recycled_twin); |
| 283 } |
| 284 |
| 285 // If the layer grew, the live_tiles_rect_ is not changed, but a new row |
| 286 // and/or column of tiles may now exist inside the same live_tiles_rect_. |
| 287 const PictureLayerTiling* twin_tiling = |
| 288 client_->GetPendingOrActiveTwinTiling(this); |
| 289 if (after_right > before_right) { |
| 290 DCHECK_EQ(after_right, before_right + 1); |
| 291 for (int j = before_top; j <= after_bottom; ++j) |
| 292 CreateTile(after_right, j, twin_tiling, null_recycled_twin); |
| 293 } |
| 294 if (after_bottom > before_bottom) { |
| 295 DCHECK_EQ(after_bottom, before_bottom + 1); |
| 296 for (int i = before_left; i <= before_right; ++i) |
| 297 CreateTile(i, after_bottom, twin_tiling, null_recycled_twin); |
| 298 } |
256 } | 299 } |
257 | 300 |
258 void PictureLayerTiling::RemoveTilesInRegion(const Region& layer_region) { | 301 void PictureLayerTiling::Invalidate(const Region& layer_invalidation) { |
259 bool recreate_invalidated_tiles = false; | 302 if (live_tiles_rect_.IsEmpty()) |
260 DoInvalidate(layer_region, recreate_invalidated_tiles); | 303 return; |
261 } | |
262 | |
263 void PictureLayerTiling::Invalidate(const Region& layer_region) { | |
264 bool recreate_invalidated_tiles = true; | |
265 DoInvalidate(layer_region, recreate_invalidated_tiles); | |
266 } | |
267 | |
268 void PictureLayerTiling::DoInvalidate(const Region& layer_region, | |
269 bool recreate_invalidated_tiles) { | |
270 std::vector<TileMapKey> new_tile_keys; | 304 std::vector<TileMapKey> new_tile_keys; |
271 gfx::Rect expanded_live_tiles_rect = | 305 gfx::Rect expanded_live_tiles_rect = |
272 tiling_data_.ExpandRectIgnoringBordersToTileBounds(live_tiles_rect_); | 306 tiling_data_.ExpandRectIgnoringBordersToTileBounds(live_tiles_rect_); |
273 for (Region::Iterator iter(layer_region); iter.has_rect(); iter.next()) { | 307 for (Region::Iterator iter(layer_invalidation); iter.has_rect(); |
| 308 iter.next()) { |
274 gfx::Rect layer_rect = iter.rect(); | 309 gfx::Rect layer_rect = iter.rect(); |
275 gfx::Rect content_rect = | 310 gfx::Rect content_rect = |
276 gfx::ScaleToEnclosingRect(layer_rect, contents_scale_); | 311 gfx::ScaleToEnclosingRect(layer_rect, contents_scale_); |
277 // Consider tiles inside the live tiles rect even if only their border | 312 // Consider tiles inside the live tiles rect even if only their border |
278 // pixels intersect the invalidation. But don't consider tiles outside | 313 // pixels intersect the invalidation. But don't consider tiles outside |
279 // the live tiles rect with the same conditions, as they won't exist. | 314 // the live tiles rect with the same conditions, as they won't exist. |
280 int border_pixels = tiling_data_.border_texels(); | 315 int border_pixels = tiling_data_.border_texels(); |
281 content_rect.Inset(-border_pixels, -border_pixels); | 316 content_rect.Inset(-border_pixels, -border_pixels); |
282 // Avoid needless work by not bothering to invalidate where there aren't | 317 // Avoid needless work by not bothering to invalidate where there aren't |
283 // tiles. | 318 // tiles. |
284 content_rect.Intersect(expanded_live_tiles_rect); | 319 content_rect.Intersect(expanded_live_tiles_rect); |
285 if (content_rect.IsEmpty()) | 320 if (content_rect.IsEmpty()) |
286 continue; | 321 continue; |
287 // Since the content_rect includes border pixels already, don't include | 322 // Since the content_rect includes border pixels already, don't include |
288 // borders when iterating to avoid double counting them. | 323 // borders when iterating to avoid double counting them. |
289 bool include_borders = false; | 324 bool include_borders = false; |
290 for (TilingData::Iterator iter( | 325 for (TilingData::Iterator iter( |
291 &tiling_data_, content_rect, include_borders); | 326 &tiling_data_, content_rect, include_borders); |
292 iter; | 327 iter; |
293 ++iter) { | 328 ++iter) { |
294 // There is no recycled twin since this is run on the pending tiling. | 329 // There is no recycled twin for the pending tree during commit, or for |
295 PictureLayerTiling* recycled_twin = NULL; | 330 // the active tree during activation. |
296 DCHECK_EQ(recycled_twin, client_->GetRecycledTwinTiling(this)); | 331 PictureLayerTiling* null_recycled_twin = nullptr; |
297 DCHECK_EQ(PENDING_TREE, client_->GetTree()); | 332 DCHECK_EQ(null_recycled_twin, client_->GetRecycledTwinTiling(this)); |
298 if (RemoveTileAt(iter.index_x(), iter.index_y(), recycled_twin)) | 333 if (RemoveTileAt(iter.index_x(), iter.index_y(), null_recycled_twin)) |
299 new_tile_keys.push_back(iter.index()); | 334 new_tile_keys.push_back(iter.index()); |
300 } | 335 } |
301 } | 336 } |
302 | 337 |
303 if (recreate_invalidated_tiles && !new_tile_keys.empty()) { | 338 if (!new_tile_keys.empty()) { |
| 339 // During commit from the main thread, invalidations can never be shared |
| 340 // with the active tree since the active tree has different content there. |
| 341 // And when invalidating an active-tree tiling, it means there was no |
| 342 // pending tiling to clone from. |
| 343 const PictureLayerTiling* null_twin_tiling = nullptr; |
| 344 PictureLayerTiling* null_recycled_twin = nullptr; |
| 345 DCHECK_EQ(null_recycled_twin, client_->GetRecycledTwinTiling(this)); |
304 for (size_t i = 0; i < new_tile_keys.size(); ++i) { | 346 for (size_t i = 0; i < new_tile_keys.size(); ++i) { |
305 // Don't try to share a tile with the twin layer, it's been invalidated so | 347 CreateTile(new_tile_keys[i].first, new_tile_keys[i].second, |
306 // we have to make our own tile here. | 348 null_twin_tiling, null_recycled_twin); |
307 const PictureLayerTiling* twin_tiling = NULL; | |
308 CreateTile(new_tile_keys[i].first, new_tile_keys[i].second, twin_tiling); | |
309 } | 349 } |
310 } | 350 } |
311 } | 351 } |
312 | 352 |
| 353 void PictureLayerTiling::SetRasterSource( |
| 354 scoped_refptr<RasterSource> raster_source) { |
| 355 // Shared (ie. non-invalidated) tiles on the pending tree are updated to use |
| 356 // the new raster source. When this raster source is activated, the raster |
| 357 // source will remain valid for shared tiles in the active tree. |
| 358 for (TileMap::const_iterator it = tiles_.begin(); it != tiles_.end(); ++it) |
| 359 it->second->set_raster_source(raster_source); |
| 360 VerifyLiveTilesRect(false); |
| 361 } |
| 362 |
313 PictureLayerTiling::CoverageIterator::CoverageIterator() | 363 PictureLayerTiling::CoverageIterator::CoverageIterator() |
314 : tiling_(NULL), | 364 : tiling_(NULL), |
315 current_tile_(NULL), | 365 current_tile_(NULL), |
316 tile_i_(0), | 366 tile_i_(0), |
317 tile_j_(0), | 367 tile_j_(0), |
318 left_(0), | 368 left_(0), |
319 top_(0), | 369 top_(0), |
320 right_(-1), | 370 right_(-1), |
321 bottom_(-1) { | 371 bottom_(-1) { |
322 } | 372 } |
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
461 } | 511 } |
462 | 512 |
463 bool PictureLayerTiling::RemoveTileAt(int i, | 513 bool PictureLayerTiling::RemoveTileAt(int i, |
464 int j, | 514 int j, |
465 PictureLayerTiling* recycled_twin) { | 515 PictureLayerTiling* recycled_twin) { |
466 TileMap::iterator found = tiles_.find(TileMapKey(i, j)); | 516 TileMap::iterator found = tiles_.find(TileMapKey(i, j)); |
467 if (found == tiles_.end()) | 517 if (found == tiles_.end()) |
468 return false; | 518 return false; |
469 found->second->set_shared(false); | 519 found->second->set_shared(false); |
470 tiles_.erase(found); | 520 tiles_.erase(found); |
471 eviction_tiles_cache_valid_ = false; | |
472 if (recycled_twin) { | 521 if (recycled_twin) { |
473 // Recycled twin does not also have a recycled twin, so pass NULL. | 522 // Recycled twin does not also have a recycled twin, so pass null. |
474 recycled_twin->RemoveTileAt(i, j, NULL); | 523 recycled_twin->RemoveTileAt(i, j, nullptr); |
475 } | 524 } |
476 return true; | 525 return true; |
477 } | 526 } |
478 | 527 |
479 void PictureLayerTiling::Reset() { | 528 void PictureLayerTiling::Reset() { |
480 live_tiles_rect_ = gfx::Rect(); | 529 live_tiles_rect_ = gfx::Rect(); |
481 PictureLayerTiling* recycled_twin = client_->GetRecycledTwinTiling(this); | 530 PictureLayerTiling* recycled_twin = client_->GetRecycledTwinTiling(this); |
482 for (TileMap::const_iterator it = tiles_.begin(); it != tiles_.end(); ++it) { | 531 for (TileMap::const_iterator it = tiles_.begin(); it != tiles_.end(); ++it) { |
483 it->second->set_shared(false); | 532 it->second->set_shared(false); |
484 if (recycled_twin) | 533 if (recycled_twin) |
485 recycled_twin->RemoveTileAt(it->first.first, it->first.second, NULL); | 534 recycled_twin->RemoveTileAt(it->first.first, it->first.second, nullptr); |
486 } | 535 } |
487 tiles_.clear(); | 536 tiles_.clear(); |
488 eviction_tiles_cache_valid_ = false; | |
489 } | 537 } |
490 | 538 |
491 gfx::Rect PictureLayerTiling::ComputeSkewport( | 539 gfx::Rect PictureLayerTiling::ComputeSkewport( |
492 double current_frame_time_in_seconds, | 540 double current_frame_time_in_seconds, |
493 const gfx::Rect& visible_rect_in_content_space) const { | 541 const gfx::Rect& visible_rect_in_content_space) const { |
494 gfx::Rect skewport = visible_rect_in_content_space; | 542 gfx::Rect skewport = visible_rect_in_content_space; |
495 if (last_impl_frame_time_in_seconds_ == 0.0) | 543 if (last_impl_frame_time_in_seconds_ == 0.0) |
496 return skewport; | 544 return skewport; |
497 | 545 |
498 double time_delta = | 546 double time_delta = |
499 current_frame_time_in_seconds - last_impl_frame_time_in_seconds_; | 547 current_frame_time_in_seconds - last_impl_frame_time_in_seconds_; |
500 if (time_delta == 0.0) | 548 if (time_delta == 0.0) |
501 return skewport; | 549 return skewport; |
502 | 550 |
503 float skewport_target_time_in_seconds = | |
504 client_->GetSkewportTargetTimeInSeconds(); | |
505 double extrapolation_multiplier = | 551 double extrapolation_multiplier = |
506 skewport_target_time_in_seconds / time_delta; | 552 skewport_target_time_in_seconds_ / time_delta; |
507 | 553 |
508 int old_x = last_visible_rect_in_content_space_.x(); | 554 int old_x = last_visible_rect_in_content_space_.x(); |
509 int old_y = last_visible_rect_in_content_space_.y(); | 555 int old_y = last_visible_rect_in_content_space_.y(); |
510 int old_right = last_visible_rect_in_content_space_.right(); | 556 int old_right = last_visible_rect_in_content_space_.right(); |
511 int old_bottom = last_visible_rect_in_content_space_.bottom(); | 557 int old_bottom = last_visible_rect_in_content_space_.bottom(); |
512 | 558 |
513 int new_x = visible_rect_in_content_space.x(); | 559 int new_x = visible_rect_in_content_space.x(); |
514 int new_y = visible_rect_in_content_space.y(); | 560 int new_y = visible_rect_in_content_space.y(); |
515 int new_right = visible_rect_in_content_space.right(); | 561 int new_right = visible_rect_in_content_space.right(); |
516 int new_bottom = visible_rect_in_content_space.bottom(); | 562 int new_bottom = visible_rect_in_content_space.bottom(); |
517 | 563 |
518 int skewport_limit = client_->GetSkewportExtrapolationLimitInContentPixels(); | 564 // Compute the maximum skewport based on |
519 | 565 // |skewport_extrapolation_limit_in_content_pixels_|. |
520 // Compute the maximum skewport based on |skewport_limit|. | |
521 gfx::Rect max_skewport = skewport; | 566 gfx::Rect max_skewport = skewport; |
522 max_skewport.Inset( | 567 max_skewport.Inset(-skewport_extrapolation_limit_in_content_pixels_, |
523 -skewport_limit, -skewport_limit, -skewport_limit, -skewport_limit); | 568 -skewport_extrapolation_limit_in_content_pixels_); |
524 | 569 |
525 // Inset the skewport by the needed adjustment. | 570 // Inset the skewport by the needed adjustment. |
526 skewport.Inset(extrapolation_multiplier * (new_x - old_x), | 571 skewport.Inset(extrapolation_multiplier * (new_x - old_x), |
527 extrapolation_multiplier * (new_y - old_y), | 572 extrapolation_multiplier * (new_y - old_y), |
528 extrapolation_multiplier * (old_right - new_right), | 573 extrapolation_multiplier * (old_right - new_right), |
529 extrapolation_multiplier * (old_bottom - new_bottom)); | 574 extrapolation_multiplier * (old_bottom - new_bottom)); |
530 | 575 |
531 // Clip the skewport to |max_skewport|. | 576 // Clip the skewport to |max_skewport|. |
532 skewport.Intersect(max_skewport); | 577 skewport.Intersect(max_skewport); |
533 | 578 |
(...skipping 23 matching lines...) Expand all Loading... |
557 last_visible_rect_in_content_space_ = visible_rect_in_content_space; | 602 last_visible_rect_in_content_space_ = visible_rect_in_content_space; |
558 return; | 603 return; |
559 } | 604 } |
560 | 605 |
561 // Calculate the skewport. | 606 // Calculate the skewport. |
562 gfx::Rect skewport = ComputeSkewport(current_frame_time_in_seconds, | 607 gfx::Rect skewport = ComputeSkewport(current_frame_time_in_seconds, |
563 visible_rect_in_content_space); | 608 visible_rect_in_content_space); |
564 DCHECK(skewport.Contains(visible_rect_in_content_space)); | 609 DCHECK(skewport.Contains(visible_rect_in_content_space)); |
565 | 610 |
566 // Calculate the eventually/live tiles rect. | 611 // Calculate the eventually/live tiles rect. |
567 size_t max_tiles_for_interest_area = client_->GetMaxTilesForInterestArea(); | |
568 | |
569 gfx::Size tile_size = tiling_data_.max_texture_size(); | 612 gfx::Size tile_size = tiling_data_.max_texture_size(); |
570 int64 eventually_rect_area = | 613 int64 eventually_rect_area = |
571 max_tiles_for_interest_area * tile_size.width() * tile_size.height(); | 614 max_tiles_for_interest_area_ * tile_size.width() * tile_size.height(); |
572 | 615 |
573 gfx::Rect eventually_rect = | 616 gfx::Rect eventually_rect = |
574 ExpandRectEquallyToAreaBoundedBy(visible_rect_in_content_space, | 617 ExpandRectEquallyToAreaBoundedBy(visible_rect_in_content_space, |
575 eventually_rect_area, | 618 eventually_rect_area, |
576 gfx::Rect(tiling_size()), | 619 gfx::Rect(tiling_size()), |
577 &expansion_cache_); | 620 &expansion_cache_); |
578 | 621 |
579 DCHECK(eventually_rect.IsEmpty() || | 622 DCHECK(eventually_rect.IsEmpty() || |
580 gfx::Rect(tiling_size()).Contains(eventually_rect)) | 623 gfx::Rect(tiling_size()).Contains(eventually_rect)) |
581 << "tiling_size: " << tiling_size().ToString() | 624 << "tiling_size: " << tiling_size().ToString() |
582 << " eventually_rect: " << eventually_rect.ToString(); | 625 << " eventually_rect: " << eventually_rect.ToString(); |
583 | 626 |
584 // Calculate the soon border rect. | 627 // Calculate the soon border rect. |
585 content_to_screen_scale_ = ideal_contents_scale / contents_scale_; | 628 float content_to_screen_scale = ideal_contents_scale / contents_scale_; |
586 gfx::Rect soon_border_rect = visible_rect_in_content_space; | 629 gfx::Rect soon_border_rect = visible_rect_in_content_space; |
587 float border = kSoonBorderDistanceInScreenPixels / content_to_screen_scale_; | 630 float border = kSoonBorderDistanceInScreenPixels / content_to_screen_scale; |
588 soon_border_rect.Inset(-border, -border, -border, -border); | 631 soon_border_rect.Inset(-border, -border, -border, -border); |
589 | 632 |
590 // Update the tiling state. | |
591 SetLiveTilesRect(eventually_rect); | |
592 | |
593 last_impl_frame_time_in_seconds_ = current_frame_time_in_seconds; | 633 last_impl_frame_time_in_seconds_ = current_frame_time_in_seconds; |
594 last_viewport_in_layer_space_ = viewport_in_layer_space; | 634 last_viewport_in_layer_space_ = viewport_in_layer_space; |
595 last_visible_rect_in_content_space_ = visible_rect_in_content_space; | 635 last_visible_rect_in_content_space_ = visible_rect_in_content_space; |
596 | 636 |
597 eviction_tiles_cache_valid_ = false; | 637 SetLiveTilesRect(eventually_rect); |
| 638 UpdateTilePriorityRects( |
| 639 content_to_screen_scale, visible_rect_in_content_space, skewport, |
| 640 soon_border_rect, eventually_rect, occlusion_in_layer_space); |
| 641 } |
598 | 642 |
| 643 void PictureLayerTiling::UpdateTilePriorityRects( |
| 644 float content_to_screen_scale, |
| 645 const gfx::Rect& visible_rect_in_content_space, |
| 646 const gfx::Rect& skewport, |
| 647 const gfx::Rect& soon_border_rect, |
| 648 const gfx::Rect& eventually_rect, |
| 649 const Occlusion& occlusion_in_layer_space) { |
599 current_visible_rect_ = visible_rect_in_content_space; | 650 current_visible_rect_ = visible_rect_in_content_space; |
600 current_skewport_rect_ = skewport; | 651 current_skewport_rect_ = skewport; |
601 current_soon_border_rect_ = soon_border_rect; | 652 current_soon_border_rect_ = soon_border_rect; |
602 current_eventually_rect_ = eventually_rect; | 653 current_eventually_rect_ = eventually_rect; |
603 current_occlusion_in_layer_space_ = occlusion_in_layer_space; | 654 current_occlusion_in_layer_space_ = occlusion_in_layer_space; |
| 655 current_content_to_screen_scale_ = content_to_screen_scale; |
604 | 656 |
605 // Update has_*_tiles state. | |
606 gfx::Rect tiling_rect(tiling_size()); | 657 gfx::Rect tiling_rect(tiling_size()); |
607 | |
608 has_visible_rect_tiles_ = tiling_rect.Intersects(current_visible_rect_); | 658 has_visible_rect_tiles_ = tiling_rect.Intersects(current_visible_rect_); |
609 has_skewport_rect_tiles_ = tiling_rect.Intersects(current_skewport_rect_); | 659 has_skewport_rect_tiles_ = tiling_rect.Intersects(current_skewport_rect_); |
610 has_soon_border_rect_tiles_ = | 660 has_soon_border_rect_tiles_ = |
611 tiling_rect.Intersects(current_soon_border_rect_); | 661 tiling_rect.Intersects(current_soon_border_rect_); |
612 has_eventually_rect_tiles_ = tiling_rect.Intersects(current_eventually_rect_); | 662 has_eventually_rect_tiles_ = tiling_rect.Intersects(current_eventually_rect_); |
613 } | 663 } |
614 | 664 |
615 void PictureLayerTiling::SetLiveTilesRect( | 665 void PictureLayerTiling::SetLiveTilesRect( |
616 const gfx::Rect& new_live_tiles_rect) { | 666 const gfx::Rect& new_live_tiles_rect) { |
617 DCHECK(new_live_tiles_rect.IsEmpty() || | 667 DCHECK(new_live_tiles_rect.IsEmpty() || |
618 gfx::Rect(tiling_size()).Contains(new_live_tiles_rect)) | 668 gfx::Rect(tiling_size()).Contains(new_live_tiles_rect)) |
619 << "tiling_size: " << tiling_size().ToString() | 669 << "tiling_size: " << tiling_size().ToString() |
620 << " new_live_tiles_rect: " << new_live_tiles_rect.ToString(); | 670 << " new_live_tiles_rect: " << new_live_tiles_rect.ToString(); |
621 if (live_tiles_rect_ == new_live_tiles_rect) | 671 if (live_tiles_rect_ == new_live_tiles_rect) |
622 return; | 672 return; |
623 | 673 |
| 674 PictureLayerTiling* recycled_twin = client_->GetRecycledTwinTiling(this); |
| 675 |
624 // Iterate to delete all tiles outside of our new live_tiles rect. | 676 // Iterate to delete all tiles outside of our new live_tiles rect. |
625 PictureLayerTiling* recycled_twin = client_->GetRecycledTwinTiling(this); | |
626 for (TilingData::DifferenceIterator iter(&tiling_data_, | 677 for (TilingData::DifferenceIterator iter(&tiling_data_, |
627 live_tiles_rect_, | 678 live_tiles_rect_, |
628 new_live_tiles_rect); | 679 new_live_tiles_rect); |
629 iter; | 680 iter; |
630 ++iter) { | 681 ++iter) { |
631 RemoveTileAt(iter.index_x(), iter.index_y(), recycled_twin); | 682 RemoveTileAt(iter.index_x(), iter.index_y(), recycled_twin); |
632 } | 683 } |
633 | 684 |
634 const PictureLayerTiling* twin_tiling = | 685 const PictureLayerTiling* twin_tiling = |
635 client_->GetPendingOrActiveTwinTiling(this); | 686 client_->GetPendingOrActiveTwinTiling(this); |
636 | 687 |
637 // Iterate to allocate new tiles for all regions with newly exposed area. | 688 // Iterate to allocate new tiles for all regions with newly exposed area. |
638 for (TilingData::DifferenceIterator iter(&tiling_data_, | 689 for (TilingData::DifferenceIterator iter(&tiling_data_, |
639 new_live_tiles_rect, | 690 new_live_tiles_rect, |
640 live_tiles_rect_); | 691 live_tiles_rect_); |
641 iter; | 692 iter; |
642 ++iter) { | 693 ++iter) { |
643 TileMapKey key(iter.index()); | 694 TileMapKey key(iter.index()); |
644 CreateTile(key.first, key.second, twin_tiling); | 695 CreateTile(key.first, key.second, twin_tiling, recycled_twin); |
645 } | 696 } |
646 | 697 |
647 live_tiles_rect_ = new_live_tiles_rect; | 698 live_tiles_rect_ = new_live_tiles_rect; |
648 VerifyLiveTilesRect(); | 699 VerifyLiveTilesRect(false); |
| 700 if (recycled_twin) { |
| 701 recycled_twin->live_tiles_rect_ = live_tiles_rect_; |
| 702 recycled_twin->VerifyLiveTilesRect(true); |
| 703 } |
649 } | 704 } |
650 | 705 |
651 void PictureLayerTiling::VerifyLiveTilesRect() { | 706 void PictureLayerTiling::VerifyLiveTilesRect(bool is_on_recycle_tree) const { |
652 #if DCHECK_IS_ON | 707 #if DCHECK_IS_ON |
653 for (TileMap::iterator it = tiles_.begin(); it != tiles_.end(); ++it) { | 708 for (auto it = tiles_.begin(); it != tiles_.end(); ++it) { |
654 if (!it->second.get()) | 709 if (!it->second.get()) |
655 continue; | 710 continue; |
656 DCHECK(it->first.first < tiling_data_.num_tiles_x()) | 711 DCHECK(it->first.first < tiling_data_.num_tiles_x()) |
657 << this << " " << it->first.first << "," << it->first.second | 712 << this << " " << it->first.first << "," << it->first.second |
658 << " num_tiles_x " << tiling_data_.num_tiles_x() << " live_tiles_rect " | 713 << " num_tiles_x " << tiling_data_.num_tiles_x() << " live_tiles_rect " |
659 << live_tiles_rect_.ToString(); | 714 << live_tiles_rect_.ToString(); |
660 DCHECK(it->first.second < tiling_data_.num_tiles_y()) | 715 DCHECK(it->first.second < tiling_data_.num_tiles_y()) |
661 << this << " " << it->first.first << "," << it->first.second | 716 << this << " " << it->first.first << "," << it->first.second |
662 << " num_tiles_y " << tiling_data_.num_tiles_y() << " live_tiles_rect " | 717 << " num_tiles_y " << tiling_data_.num_tiles_y() << " live_tiles_rect " |
663 << live_tiles_rect_.ToString(); | 718 << live_tiles_rect_.ToString(); |
664 DCHECK(tiling_data_.TileBounds(it->first.first, it->first.second) | 719 DCHECK(tiling_data_.TileBounds(it->first.first, it->first.second) |
665 .Intersects(live_tiles_rect_)) | 720 .Intersects(live_tiles_rect_)) |
666 << this << " " << it->first.first << "," << it->first.second | 721 << this << " " << it->first.first << "," << it->first.second |
667 << " tile bounds " | 722 << " tile bounds " |
668 << tiling_data_.TileBounds(it->first.first, it->first.second).ToString() | 723 << tiling_data_.TileBounds(it->first.first, it->first.second).ToString() |
669 << " live_tiles_rect " << live_tiles_rect_.ToString(); | 724 << " live_tiles_rect " << live_tiles_rect_.ToString(); |
| 725 DCHECK_IMPLIES(is_on_recycle_tree, it->second->is_shared()); |
670 } | 726 } |
671 #endif | 727 #endif |
672 } | 728 } |
673 | 729 |
674 bool PictureLayerTiling::IsTileOccluded(const Tile* tile) const { | 730 bool PictureLayerTiling::IsTileOccluded(const Tile* tile) const { |
675 DCHECK(tile); | 731 DCHECK(tile); |
676 | 732 |
677 if (!current_occlusion_in_layer_space_.HasOcclusion()) | 733 if (!current_occlusion_in_layer_space_.HasOcclusion()) |
678 return false; | 734 return false; |
679 | 735 |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
798 tile->set_is_occluded(tree, IsTileOccluded(tile)); | 854 tile->set_is_occluded(tree, IsTileOccluded(tile)); |
799 return; | 855 return; |
800 } | 856 } |
801 | 857 |
802 if (tree == PENDING_TREE) | 858 if (tree == PENDING_TREE) |
803 tile->set_required_for_activation(false); | 859 tile->set_required_for_activation(false); |
804 else | 860 else |
805 tile->set_required_for_draw(false); | 861 tile->set_required_for_draw(false); |
806 tile->set_is_occluded(tree, false); | 862 tile->set_is_occluded(tree, false); |
807 | 863 |
808 DCHECK_GT(content_to_screen_scale_, 0.f); | 864 DCHECK_GT(current_content_to_screen_scale_, 0.f); |
809 float distance_to_visible = | 865 float distance_to_visible = |
810 current_visible_rect_.ManhattanInternalDistance(tile_bounds) * | 866 current_visible_rect_.ManhattanInternalDistance(tile_bounds) * |
811 content_to_screen_scale_; | 867 current_content_to_screen_scale_; |
812 | 868 |
813 if (max_tile_priority_bin <= TilePriority::SOON && | 869 if (max_tile_priority_bin <= TilePriority::SOON && |
814 (current_soon_border_rect_.Intersects(tile_bounds) || | 870 (current_soon_border_rect_.Intersects(tile_bounds) || |
815 current_skewport_rect_.Intersects(tile_bounds))) { | 871 current_skewport_rect_.Intersects(tile_bounds))) { |
816 tile->SetPriority( | 872 tile->SetPriority( |
817 tree, | 873 tree, |
818 TilePriority(resolution_, TilePriority::SOON, distance_to_visible)); | 874 TilePriority(resolution_, TilePriority::SOON, distance_to_visible)); |
819 return; | 875 return; |
820 } | 876 } |
821 | 877 |
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
991 if (delta < event.distance) | 1047 if (delta < event.distance) |
992 break; | 1048 break; |
993 } | 1049 } |
994 | 1050 |
995 gfx::Rect result(origin_x, origin_y, width, height); | 1051 gfx::Rect result(origin_x, origin_y, width, height); |
996 if (cache) | 1052 if (cache) |
997 cache->previous_result = result; | 1053 cache->previous_result = result; |
998 return result; | 1054 return result; |
999 } | 1055 } |
1000 | 1056 |
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() | 1057 PictureLayerTiling::TilingRasterTileIterator::TilingRasterTileIterator() |
1088 : tiling_(NULL), current_tile_(NULL) {} | 1058 : tiling_(NULL), current_tile_(NULL) {} |
1089 | 1059 |
1090 PictureLayerTiling::TilingRasterTileIterator::TilingRasterTileIterator( | 1060 PictureLayerTiling::TilingRasterTileIterator::TilingRasterTileIterator( |
1091 PictureLayerTiling* tiling) | 1061 PictureLayerTiling* tiling) |
1092 : tiling_(tiling), phase_(VISIBLE_RECT), current_tile_(NULL) { | 1062 : tiling_(tiling), phase_(VISIBLE_RECT), current_tile_(NULL) { |
1093 if (!tiling_->has_visible_rect_tiles_) { | 1063 if (!tiling_->has_visible_rect_tiles_) { |
1094 AdvancePhase(); | 1064 AdvancePhase(); |
1095 return; | 1065 return; |
1096 } | 1066 } |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1210 } | 1180 } |
1211 current_tile_ = tiling_->TileAt(next_index.first, next_index.second); | 1181 current_tile_ = tiling_->TileAt(next_index.first, next_index.second); |
1212 } | 1182 } |
1213 | 1183 |
1214 if (current_tile_) | 1184 if (current_tile_) |
1215 tiling_->UpdateTileAndTwinPriority(current_tile_); | 1185 tiling_->UpdateTileAndTwinPriority(current_tile_); |
1216 return *this; | 1186 return *this; |
1217 } | 1187 } |
1218 | 1188 |
1219 } // namespace cc | 1189 } // namespace cc |
OLD | NEW |