| 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 |