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

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

Issue 812543002: Update from https://crrev.com/308331 (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Created 6 years 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 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
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
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
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
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
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
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
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