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> |
(...skipping 11 matching lines...) Expand all Loading... |
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 } // namespace | 28 } // namespace |
29 | 29 |
30 scoped_ptr<PictureLayerTiling> PictureLayerTiling::Create( | 30 scoped_ptr<PictureLayerTiling> PictureLayerTiling::Create( |
31 float contents_scale, | 31 float contents_scale, |
32 const gfx::Size& layer_bounds, | 32 scoped_refptr<RasterSource> raster_source, |
33 PictureLayerTilingClient* client, | 33 PictureLayerTilingClient* client, |
34 size_t max_tiles_for_interest_area, | 34 size_t max_tiles_for_interest_area, |
35 float skewport_target_time_in_seconds, | 35 float skewport_target_time_in_seconds, |
36 int skewport_extrapolation_limit_in_content_pixels) { | 36 int skewport_extrapolation_limit_in_content_pixels) { |
37 return make_scoped_ptr(new PictureLayerTiling( | 37 return make_scoped_ptr(new PictureLayerTiling( |
38 contents_scale, layer_bounds, client, max_tiles_for_interest_area, | 38 contents_scale, raster_source, client, max_tiles_for_interest_area, |
39 skewport_target_time_in_seconds, | 39 skewport_target_time_in_seconds, |
40 skewport_extrapolation_limit_in_content_pixels)); | 40 skewport_extrapolation_limit_in_content_pixels)); |
41 } | 41 } |
42 | 42 |
43 PictureLayerTiling::PictureLayerTiling( | 43 PictureLayerTiling::PictureLayerTiling( |
44 float contents_scale, | 44 float contents_scale, |
45 const gfx::Size& layer_bounds, | 45 scoped_refptr<RasterSource> raster_source, |
46 PictureLayerTilingClient* client, | 46 PictureLayerTilingClient* client, |
47 size_t max_tiles_for_interest_area, | 47 size_t max_tiles_for_interest_area, |
48 float skewport_target_time_in_seconds, | 48 float skewport_target_time_in_seconds, |
49 int skewport_extrapolation_limit_in_content_pixels) | 49 int skewport_extrapolation_limit_in_content_pixels) |
50 : max_tiles_for_interest_area_(max_tiles_for_interest_area), | 50 : max_tiles_for_interest_area_(max_tiles_for_interest_area), |
51 skewport_target_time_in_seconds_(skewport_target_time_in_seconds), | 51 skewport_target_time_in_seconds_(skewport_target_time_in_seconds), |
52 skewport_extrapolation_limit_in_content_pixels_( | 52 skewport_extrapolation_limit_in_content_pixels_( |
53 skewport_extrapolation_limit_in_content_pixels), | 53 skewport_extrapolation_limit_in_content_pixels), |
54 contents_scale_(contents_scale), | 54 contents_scale_(contents_scale), |
55 client_(client), | 55 client_(client), |
56 layer_bounds_(layer_bounds), | 56 raster_source_(raster_source), |
57 resolution_(NON_IDEAL_RESOLUTION), | 57 resolution_(NON_IDEAL_RESOLUTION), |
58 tiling_data_(gfx::Size(), gfx::Size(), kBorderTexels), | 58 tiling_data_(gfx::Size(), gfx::Size(), kBorderTexels), |
59 last_impl_frame_time_in_seconds_(0.0), | 59 last_impl_frame_time_in_seconds_(0.0), |
60 can_require_tiles_for_activation_(false), | 60 can_require_tiles_for_activation_(false), |
61 current_content_to_screen_scale_(0.f), | 61 current_content_to_screen_scale_(0.f), |
62 has_visible_rect_tiles_(false), | 62 has_visible_rect_tiles_(false), |
63 has_skewport_rect_tiles_(false), | 63 has_skewport_rect_tiles_(false), |
64 has_soon_border_rect_tiles_(false), | 64 has_soon_border_rect_tiles_(false), |
65 has_eventually_rect_tiles_(false) { | 65 has_eventually_rect_tiles_(false) { |
66 gfx::Size content_bounds = | 66 DCHECK(!raster_source->IsSolidColor()); |
67 gfx::ToCeiledSize(gfx::ScaleSize(layer_bounds, contents_scale)); | 67 gfx::Size content_bounds = gfx::ToCeiledSize( |
| 68 gfx::ScaleSize(raster_source_->GetSize(), contents_scale)); |
68 gfx::Size tile_size = client_->CalculateTileSize(content_bounds); | 69 gfx::Size tile_size = client_->CalculateTileSize(content_bounds); |
69 | 70 |
70 DCHECK(!gfx::ToFlooredSize( | 71 DCHECK(!gfx::ToFlooredSize(gfx::ScaleSize(raster_source_->GetSize(), |
71 gfx::ScaleSize(layer_bounds, contents_scale)).IsEmpty()) << | 72 contents_scale)).IsEmpty()) |
72 "Tiling created with scale too small as contents become empty." << | 73 << "Tiling created with scale too small as contents become empty." |
73 " Layer bounds: " << layer_bounds.ToString() << | 74 << " Layer bounds: " << raster_source_->GetSize().ToString() |
74 " Contents scale: " << contents_scale; | 75 << " Contents scale: " << contents_scale; |
75 | 76 |
76 tiling_data_.SetTilingSize(content_bounds); | 77 tiling_data_.SetTilingSize(content_bounds); |
77 tiling_data_.SetMaxTextureSize(tile_size); | 78 tiling_data_.SetMaxTextureSize(tile_size); |
78 } | 79 } |
79 | 80 |
80 PictureLayerTiling::~PictureLayerTiling() { | 81 PictureLayerTiling::~PictureLayerTiling() { |
81 for (TileMap::const_iterator it = tiles_.begin(); it != tiles_.end(); ++it) | 82 for (TileMap::const_iterator it = tiles_.begin(); it != tiles_.end(); ++it) |
82 it->second->set_shared(false); | 83 it->second->set_shared(false); |
83 } | 84 } |
84 | 85 |
(...skipping 23 matching lines...) Expand all Loading... |
108 DCHECK(!candidate_tile->is_shared()); | 109 DCHECK(!candidate_tile->is_shared()); |
109 DCHECK_EQ(i, candidate_tile->tiling_i_index()); | 110 DCHECK_EQ(i, candidate_tile->tiling_i_index()); |
110 DCHECK_EQ(j, candidate_tile->tiling_j_index()); | 111 DCHECK_EQ(j, candidate_tile->tiling_j_index()); |
111 candidate_tile->set_shared(true); | 112 candidate_tile->set_shared(true); |
112 tiles_[key] = candidate_tile; | 113 tiles_[key] = candidate_tile; |
113 return candidate_tile; | 114 return candidate_tile; |
114 } | 115 } |
115 } | 116 } |
116 } | 117 } |
117 | 118 |
| 119 if (!raster_source_->CoversRect(tile_rect, contents_scale_)) |
| 120 return nullptr; |
| 121 |
118 // 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. |
119 scoped_refptr<Tile> tile = client_->CreateTile(this, tile_rect); | 123 scoped_refptr<Tile> tile = client_->CreateTile(contents_scale_, tile_rect); |
120 if (tile.get()) { | 124 DCHECK(!tile->is_shared()); |
121 DCHECK(!tile->is_shared()); | 125 tile->set_tiling_index(i, j); |
122 tile->set_tiling_index(i, j); | 126 tiles_[key] = tile; |
123 tiles_[key] = tile; | |
124 | 127 |
125 if (recycled_twin) { | 128 if (recycled_twin) { |
126 DCHECK(recycled_twin->tiles_.find(key) == recycled_twin->tiles_.end()); | 129 DCHECK(recycled_twin->tiles_.find(key) == recycled_twin->tiles_.end()); |
127 // Do what recycled_twin->CreateTile() would do. | 130 // Do what recycled_twin->CreateTile() would do. |
128 tile->set_shared(true); | 131 tile->set_shared(true); |
129 recycled_twin->tiles_[key] = tile; | 132 recycled_twin->tiles_[key] = tile; |
130 } | |
131 } | 133 } |
132 return tile.get(); | 134 return tile.get(); |
133 } | 135 } |
134 | 136 |
135 void PictureLayerTiling::CreateMissingTilesInLiveTilesRect() { | 137 void PictureLayerTiling::CreateMissingTilesInLiveTilesRect() { |
136 const PictureLayerTiling* twin_tiling = | 138 const PictureLayerTiling* twin_tiling = |
137 client_->GetPendingOrActiveTwinTiling(this); | 139 client_->GetPendingOrActiveTwinTiling(this); |
138 // There is no recycled twin during commit from the main thread which is when | 140 // There is no recycled twin during commit from the main thread which is when |
139 // this occurs. | 141 // this occurs. |
140 PictureLayerTiling* null_recycled_twin = nullptr; | 142 PictureLayerTiling* null_recycled_twin = nullptr; |
(...skipping 10 matching lines...) Expand all Loading... |
151 CreateTile(key.first, key.second, twin_tiling, null_recycled_twin); | 153 CreateTile(key.first, key.second, twin_tiling, null_recycled_twin); |
152 } | 154 } |
153 | 155 |
154 VerifyLiveTilesRect(false); | 156 VerifyLiveTilesRect(false); |
155 } | 157 } |
156 | 158 |
157 void PictureLayerTiling::CloneTilesAndPropertiesFrom( | 159 void PictureLayerTiling::CloneTilesAndPropertiesFrom( |
158 const PictureLayerTiling& twin_tiling) { | 160 const PictureLayerTiling& twin_tiling) { |
159 DCHECK_EQ(&twin_tiling, client_->GetPendingOrActiveTwinTiling(this)); | 161 DCHECK_EQ(&twin_tiling, client_->GetPendingOrActiveTwinTiling(this)); |
160 | 162 |
161 Resize(twin_tiling.layer_bounds_); | 163 SetRasterSourceAndResize(twin_tiling.raster_source_); |
162 DCHECK_EQ(twin_tiling.contents_scale_, contents_scale_); | 164 DCHECK_EQ(twin_tiling.contents_scale_, contents_scale_); |
163 DCHECK_EQ(twin_tiling.layer_bounds().ToString(), layer_bounds().ToString()); | 165 DCHECK_EQ(twin_tiling.raster_source_, raster_source_); |
164 DCHECK_EQ(twin_tiling.tile_size().ToString(), tile_size().ToString()); | 166 DCHECK_EQ(twin_tiling.tile_size().ToString(), tile_size().ToString()); |
165 | 167 |
166 resolution_ = twin_tiling.resolution_; | 168 resolution_ = twin_tiling.resolution_; |
167 | 169 |
168 SetLiveTilesRect(twin_tiling.live_tiles_rect()); | 170 SetLiveTilesRect(twin_tiling.live_tiles_rect()); |
169 | 171 |
170 // Recreate unshared tiles. | 172 // Recreate unshared tiles. |
171 std::vector<TileMapKey> to_remove; | 173 std::vector<TileMapKey> to_remove; |
172 for (const auto& tile_map_pair : tiles_) { | 174 for (const auto& tile_map_pair : tiles_) { |
173 TileMapKey key = tile_map_pair.first; | 175 TileMapKey key = tile_map_pair.first; |
(...skipping 26 matching lines...) Expand all Loading... |
200 #endif | 202 #endif |
201 | 203 |
202 UpdateTilePriorityRects(twin_tiling.current_content_to_screen_scale_, | 204 UpdateTilePriorityRects(twin_tiling.current_content_to_screen_scale_, |
203 twin_tiling.current_visible_rect_, | 205 twin_tiling.current_visible_rect_, |
204 twin_tiling.current_skewport_rect_, | 206 twin_tiling.current_skewport_rect_, |
205 twin_tiling.current_soon_border_rect_, | 207 twin_tiling.current_soon_border_rect_, |
206 twin_tiling.current_eventually_rect_, | 208 twin_tiling.current_eventually_rect_, |
207 twin_tiling.current_occlusion_in_layer_space_); | 209 twin_tiling.current_occlusion_in_layer_space_); |
208 } | 210 } |
209 | 211 |
210 void PictureLayerTiling::Resize(const gfx::Size& new_layer_bounds) { | 212 void PictureLayerTiling::SetRasterSourceAndResize( |
211 gfx::Size layer_bounds = new_layer_bounds; | 213 scoped_refptr<RasterSource> raster_source) { |
| 214 DCHECK(!raster_source->IsSolidColor()); |
| 215 gfx::Size old_layer_bounds = raster_source_->GetSize(); |
| 216 raster_source_.swap(raster_source); |
| 217 gfx::Size new_layer_bounds = raster_source_->GetSize(); |
212 gfx::Size content_bounds = | 218 gfx::Size content_bounds = |
213 gfx::ToCeiledSize(gfx::ScaleSize(new_layer_bounds, contents_scale_)); | 219 gfx::ToCeiledSize(gfx::ScaleSize(new_layer_bounds, contents_scale_)); |
214 gfx::Size tile_size = client_->CalculateTileSize(content_bounds); | 220 gfx::Size tile_size = client_->CalculateTileSize(content_bounds); |
215 | 221 |
216 // The layer bounds are only allowed to be empty when the tile size is empty. | |
217 // Otherwise we should not have such a tiling in the first place. | |
218 DCHECK_IMPLIES(!tile_size.IsEmpty(), !layer_bounds_.IsEmpty()); | |
219 | |
220 bool resized = layer_bounds != layer_bounds_; | |
221 layer_bounds_ = layer_bounds; | |
222 | |
223 if (tile_size != tiling_data_.max_texture_size()) { | 222 if (tile_size != tiling_data_.max_texture_size()) { |
224 tiling_data_.SetTilingSize(content_bounds); | 223 tiling_data_.SetTilingSize(content_bounds); |
225 tiling_data_.SetMaxTextureSize(tile_size); | 224 tiling_data_.SetMaxTextureSize(tile_size); |
226 // When the tile size changes, the TilingData positions no longer work | 225 // When the tile size changes, the TilingData positions no longer work |
227 // as valid keys to the TileMap, so just drop all tiles and clear the live | 226 // as valid keys to the TileMap, so just drop all tiles and clear the live |
228 // tiles rect. | 227 // tiles rect. |
229 Reset(); | 228 Reset(); |
230 return; | 229 return; |
231 } | 230 } |
232 | 231 |
233 if (!resized) | 232 if (old_layer_bounds == new_layer_bounds) |
234 return; | 233 return; |
235 | 234 |
236 // The SetLiveTilesRect() method would drop tiles outside the new bounds, | 235 // The SetLiveTilesRect() method would drop tiles outside the new bounds, |
237 // but may do so incorrectly if resizing the tiling causes the number of | 236 // but may do so incorrectly if resizing the tiling causes the number of |
238 // tiles in the tiling_data_ to change. | 237 // tiles in the tiling_data_ to change. |
239 gfx::Rect content_rect(content_bounds); | 238 gfx::Rect content_rect(content_bounds); |
240 int before_left = tiling_data_.TileXIndexFromSrcCoord(live_tiles_rect_.x()); | 239 int before_left = tiling_data_.TileXIndexFromSrcCoord(live_tiles_rect_.x()); |
241 int before_top = tiling_data_.TileYIndexFromSrcCoord(live_tiles_rect_.y()); | 240 int before_top = tiling_data_.TileYIndexFromSrcCoord(live_tiles_rect_.y()); |
242 int before_right = | 241 int before_right = |
243 tiling_data_.TileXIndexFromSrcCoord(live_tiles_rect_.right() - 1); | 242 tiling_data_.TileXIndexFromSrcCoord(live_tiles_rect_.right() - 1); |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
334 const PictureLayerTiling* null_twin_tiling = nullptr; | 333 const PictureLayerTiling* null_twin_tiling = nullptr; |
335 PictureLayerTiling* null_recycled_twin = nullptr; | 334 PictureLayerTiling* null_recycled_twin = nullptr; |
336 DCHECK_EQ(null_recycled_twin, client_->GetRecycledTwinTiling(this)); | 335 DCHECK_EQ(null_recycled_twin, client_->GetRecycledTwinTiling(this)); |
337 for (size_t i = 0; i < new_tile_keys.size(); ++i) { | 336 for (size_t i = 0; i < new_tile_keys.size(); ++i) { |
338 CreateTile(new_tile_keys[i].first, new_tile_keys[i].second, | 337 CreateTile(new_tile_keys[i].first, new_tile_keys[i].second, |
339 null_twin_tiling, null_recycled_twin); | 338 null_twin_tiling, null_recycled_twin); |
340 } | 339 } |
341 } | 340 } |
342 } | 341 } |
343 | 342 |
344 void PictureLayerTiling::SetRasterSource( | 343 void PictureLayerTiling::SetRasterSourceOnTiles() { |
345 scoped_refptr<RasterSource> raster_source) { | |
346 // Shared (ie. non-invalidated) tiles on the pending tree are updated to use | 344 // Shared (ie. non-invalidated) tiles on the pending tree are updated to use |
347 // the new raster source. When this raster source is activated, the raster | 345 // the new raster source. When this raster source is activated, the raster |
348 // source will remain valid for shared tiles in the active tree. | 346 // source will remain valid for shared tiles in the active tree. |
349 for (TileMap::const_iterator it = tiles_.begin(); it != tiles_.end(); ++it) | 347 for (TileMap::const_iterator it = tiles_.begin(); it != tiles_.end(); ++it) |
350 it->second->set_raster_source(raster_source); | 348 it->second->set_raster_source(raster_source_); |
351 VerifyLiveTilesRect(false); | 349 VerifyLiveTilesRect(false); |
352 } | 350 } |
353 | 351 |
354 PictureLayerTiling::CoverageIterator::CoverageIterator() | 352 PictureLayerTiling::CoverageIterator::CoverageIterator() |
355 : tiling_(NULL), | 353 : tiling_(NULL), |
356 current_tile_(NULL), | 354 current_tile_(NULL), |
357 tile_i_(0), | 355 tile_i_(0), |
358 tile_j_(0), | 356 tile_j_(0), |
359 left_(0), | 357 left_(0), |
360 top_(0), | 358 top_(0), |
(...skipping 403 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
764 return false; | 762 return false; |
765 | 763 |
766 if (client_->RequiresHighResToDraw()) | 764 if (client_->RequiresHighResToDraw()) |
767 return true; | 765 return true; |
768 | 766 |
769 const PictureLayerTiling* twin_tiling = | 767 const PictureLayerTiling* twin_tiling = |
770 client_->GetPendingOrActiveTwinTiling(this); | 768 client_->GetPendingOrActiveTwinTiling(this); |
771 if (!twin_tiling) | 769 if (!twin_tiling) |
772 return true; | 770 return true; |
773 | 771 |
774 if (twin_tiling->layer_bounds() != layer_bounds()) | 772 if (twin_tiling->raster_source()->GetSize() != raster_source()->GetSize()) |
775 return true; | 773 return true; |
776 | 774 |
777 if (twin_tiling->current_visible_rect_ != current_visible_rect_) | 775 if (twin_tiling->current_visible_rect_ != current_visible_rect_) |
778 return true; | 776 return true; |
779 | 777 |
780 Tile* twin_tile = | 778 Tile* twin_tile = |
781 twin_tiling->TileAt(tile->tiling_i_index(), tile->tiling_j_index()); | 779 twin_tiling->TileAt(tile->tiling_i_index(), tile->tiling_j_index()); |
782 // If twin tile is missing, it might not have a recording, so we don't need | 780 // If twin tile is missing, it might not have a recording, so we don't need |
783 // this tile to be required for activation. | 781 // this tile to be required for activation. |
784 if (!twin_tile) | 782 if (!twin_tile) |
(...skipping 387 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1172 } | 1170 } |
1173 current_tile_ = tiling_->TileAt(next_index.first, next_index.second); | 1171 current_tile_ = tiling_->TileAt(next_index.first, next_index.second); |
1174 } | 1172 } |
1175 | 1173 |
1176 if (current_tile_) | 1174 if (current_tile_) |
1177 tiling_->UpdateTileAndTwinPriority(current_tile_); | 1175 tiling_->UpdateTileAndTwinPriority(current_tile_); |
1178 return *this; | 1176 return *this; |
1179 } | 1177 } |
1180 | 1178 |
1181 } // namespace cc | 1179 } // namespace cc |
OLD | NEW |