| Index: cc/layers/picture_layer_impl.cc
|
| diff --git a/cc/layers/picture_layer_impl.cc b/cc/layers/picture_layer_impl.cc
|
| index 965a6129e66322a4bfb7bf04694d19eca580e46b..aacabde2c4effca2dc505f9ea303f6231d84ad1c 100644
|
| --- a/cc/layers/picture_layer_impl.cc
|
| +++ b/cc/layers/picture_layer_impl.cc
|
| @@ -90,6 +90,8 @@ PictureLayerImpl::PictureLayerImpl(LayerTreeImpl* tree_impl, int id)
|
| }
|
|
|
| PictureLayerImpl::~PictureLayerImpl() {
|
| + if (twin_layer_)
|
| + twin_layer_->twin_layer_ = nullptr;
|
| layer_tree_impl()->UnregisterPictureLayerImpl(this);
|
| }
|
|
|
| @@ -110,10 +112,15 @@ void PictureLayerImpl::PushPropertiesTo(LayerImpl* base_layer) {
|
|
|
| LayerImpl::PushPropertiesTo(base_layer);
|
|
|
| - // When the pending tree pushes to the active tree, the pending twin
|
| - // becomes recycled.
|
| - layer_impl->twin_layer_ = nullptr;
|
| - twin_layer_ = nullptr;
|
| + // Twin relationships should never change once established.
|
| + DCHECK_IMPLIES(twin_layer_, twin_layer_ == layer_impl);
|
| + DCHECK_IMPLIES(twin_layer_, layer_impl->twin_layer_ == this);
|
| + // The twin relationship does not need to exist before the first
|
| + // PushPropertiesTo from pending to active layer since before that the active
|
| + // layer can not have a pile or tilings, it has only been created and inserted
|
| + // into the tree at that point.
|
| + twin_layer_ = layer_impl;
|
| + layer_impl->twin_layer_ = this;
|
|
|
| layer_impl->pile_ = pile_;
|
|
|
| @@ -566,10 +573,16 @@ gfx::Rect PictureLayerImpl::GetViewportForTilePriorityInContentSpace() const {
|
| return visible_rect_in_content_space;
|
| }
|
|
|
| -PictureLayerImpl* PictureLayerImpl::GetRecycledTwinLayer() {
|
| - // TODO(vmpstr): Maintain recycled twin as a member. crbug.com/407418
|
| - return static_cast<PictureLayerImpl*>(
|
| - layer_tree_impl()->FindRecycleTreeLayerById(id()));
|
| +PictureLayerImpl* PictureLayerImpl::GetPendingOrActiveTwinLayer() const {
|
| + if (!twin_layer_ || !twin_layer_->IsOnActiveOrPendingTree())
|
| + return nullptr;
|
| + return twin_layer_;
|
| +}
|
| +
|
| +PictureLayerImpl* PictureLayerImpl::GetRecycledTwinLayer() const {
|
| + if (!twin_layer_ || twin_layer_->IsOnActiveOrPendingTree())
|
| + return nullptr;
|
| + return twin_layer_;
|
| }
|
|
|
| void PictureLayerImpl::NotifyTileStateChanged(const Tile* tile) {
|
| @@ -641,16 +654,20 @@ const Region* PictureLayerImpl::GetPendingInvalidation() {
|
| if (layer_tree_impl()->IsPendingTree())
|
| return &invalidation_;
|
| DCHECK(layer_tree_impl()->IsActiveTree());
|
| - if (PictureLayerImpl* twin_layer = GetTwinLayer())
|
| + if (PictureLayerImpl* twin_layer = GetPendingOrActiveTwinLayer())
|
| return &twin_layer->invalidation_;
|
| return nullptr;
|
| }
|
|
|
| -const PictureLayerTiling* PictureLayerImpl::GetTwinTiling(
|
| +const PictureLayerTiling* PictureLayerImpl::GetPendingOrActiveTwinTiling(
|
| const PictureLayerTiling* tiling) const {
|
| - if (!twin_layer_)
|
| + PictureLayerImpl* twin_layer = GetPendingOrActiveTwinLayer();
|
| + if (!twin_layer)
|
| return nullptr;
|
| - return twin_layer_->tilings_->TilingAtScale(tiling->contents_scale());
|
| + // TODO(danakj): Remove this when no longer swapping tilings.
|
| + if (!twin_layer->tilings_)
|
| + return nullptr;
|
| + return twin_layer->tilings_->TilingAtScale(tiling->contents_scale());
|
| }
|
|
|
| PictureLayerTiling* PictureLayerImpl::GetRecycledTwinTiling(
|
| @@ -803,6 +820,8 @@ void PictureLayerImpl::SyncFromActiveLayer(const PictureLayerImpl* other) {
|
|
|
| void PictureLayerImpl::SyncTiling(
|
| const PictureLayerTiling* tiling) {
|
| + if (!tilings_)
|
| + return;
|
| if (!CanHaveTilingWithScale(tiling->contents_scale()))
|
| return;
|
| tilings_->AddTiling(tiling->contents_scale(), pile_->tiling_size());
|
| @@ -858,16 +877,12 @@ void PictureLayerImpl::DoPostCommitInitialization() {
|
| if (!tilings_)
|
| tilings_ = make_scoped_ptr(new PictureLayerTilingSet(this));
|
|
|
| - DCHECK(!twin_layer_);
|
| - twin_layer_ = static_cast<PictureLayerImpl*>(
|
| - layer_tree_impl()->FindActiveTreeLayerById(id()));
|
| - if (twin_layer_) {
|
| - DCHECK(!twin_layer_->twin_layer_);
|
| - twin_layer_->twin_layer_ = this;
|
| + PictureLayerImpl* twin_layer = GetPendingOrActiveTwinLayer();
|
| + if (twin_layer) {
|
| // If the twin has never been pushed to, do not sync from it.
|
| // This can happen if this function is called during activation.
|
| - if (!twin_layer_->needs_post_commit_initialization_)
|
| - SyncFromActiveLayer(twin_layer_);
|
| + if (!twin_layer->needs_post_commit_initialization_)
|
| + SyncFromActiveLayer(twin_layer);
|
| }
|
|
|
| needs_post_commit_initialization_ = false;
|
| @@ -882,8 +897,8 @@ PictureLayerTiling* PictureLayerImpl::AddTiling(float contents_scale) {
|
|
|
| DCHECK(pile_->HasRecordings());
|
|
|
| - if (twin_layer_)
|
| - twin_layer_->SyncTiling(tiling);
|
| + if (PictureLayerImpl* twin_layer = GetPendingOrActiveTwinLayer())
|
| + twin_layer->SyncTiling(tiling);
|
|
|
| return tiling;
|
| }
|
| @@ -1127,7 +1142,7 @@ void PictureLayerImpl::CleanUpTilingsOnActiveLayer(
|
| raster_contents_scale_, ideal_contents_scale_);
|
| float twin_low_res_scale = 0.f;
|
|
|
| - PictureLayerImpl* twin = twin_layer_;
|
| + PictureLayerImpl* twin = GetPendingOrActiveTwinLayer();
|
| if (twin && twin->CanHaveTilings()) {
|
| min_acceptable_high_res_scale = std::min(
|
| min_acceptable_high_res_scale,
|
| @@ -1136,10 +1151,14 @@ void PictureLayerImpl::CleanUpTilingsOnActiveLayer(
|
| max_acceptable_high_res_scale,
|
| std::max(twin->raster_contents_scale_, twin->ideal_contents_scale_));
|
|
|
| - for (size_t i = 0; i < twin->tilings_->num_tilings(); ++i) {
|
| - PictureLayerTiling* tiling = twin->tilings_->tiling_at(i);
|
| - if (tiling->resolution() == LOW_RESOLUTION)
|
| - twin_low_res_scale = tiling->contents_scale();
|
| + // TODO(danakj): Remove the tilings_ check when we create them in the
|
| + // constructor.
|
| + if (twin->tilings_) {
|
| + for (size_t i = 0; i < twin->tilings_->num_tilings(); ++i) {
|
| + PictureLayerTiling* tiling = twin->tilings_->tiling_at(i);
|
| + if (tiling->resolution() == LOW_RESOLUTION)
|
| + twin_low_res_scale = tiling->contents_scale();
|
| + }
|
| }
|
| }
|
|
|
| @@ -1174,7 +1193,8 @@ void PictureLayerImpl::CleanUpTilingsOnActiveLayer(
|
| PictureLayerImpl* recycled_twin = GetRecycledTwinLayer();
|
| // Remove tilings on this tree and the twin tree.
|
| for (size_t i = 0; i < to_remove.size(); ++i) {
|
| - const PictureLayerTiling* twin_tiling = GetTwinTiling(to_remove[i]);
|
| + const PictureLayerTiling* twin_tiling =
|
| + GetPendingOrActiveTwinTiling(to_remove[i]);
|
| // Only remove tilings from the twin layer if they have
|
| // NON_IDEAL_RESOLUTION.
|
| if (twin_tiling && twin_tiling->resolution() == NON_IDEAL_RESOLUTION)
|
|
|