| Index: cc/layers/picture_layer_impl.cc
|
| diff --git a/cc/layers/picture_layer_impl.cc b/cc/layers/picture_layer_impl.cc
|
| index e51821fbc92a7d2b8f13536998b41210f141003d..7fd7730be24e32de49cf1a87552ea33e8858320f 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_;
|
|
|
| @@ -155,6 +162,11 @@ void PictureLayerImpl::AppendQuads(RenderPass* render_pass,
|
| const Occlusion& occlusion_in_content_space,
|
| AppendQuadsData* append_quads_data) {
|
| DCHECK(!needs_post_commit_initialization_);
|
| + // The bounds and the pile size may differ if the pile wasn't updated (ie.
|
| + // PictureLayer::Update didn't happen). But that should never be the case if
|
| + // the layer is part of the visible frame, which is why we're appending quads
|
| + // in the first place
|
| + DCHECK_EQ(bounds().ToString(), pile_->tiling_size().ToString());
|
|
|
| SharedQuadState* shared_quad_state =
|
| render_pass->CreateAndAppendSharedQuadState();
|
| @@ -163,7 +175,7 @@ void PictureLayerImpl::AppendQuads(RenderPass* render_pass,
|
| PopulateSharedQuadState(shared_quad_state);
|
|
|
| AppendDebugBorderQuad(
|
| - render_pass, content_bounds(), shared_quad_state, append_quads_data);
|
| + render_pass, bounds(), shared_quad_state, append_quads_data);
|
|
|
| SolidColorLayerImpl::AppendSolidQuads(render_pass,
|
| occlusion_in_content_space,
|
| @@ -179,7 +191,7 @@ void PictureLayerImpl::AppendQuads(RenderPass* render_pass,
|
| scaled_draw_transform.Scale(SK_MScalar1 / max_contents_scale,
|
| SK_MScalar1 / max_contents_scale);
|
| gfx::Size scaled_content_bounds =
|
| - gfx::ToCeiledSize(gfx::ScaleSize(content_bounds(), max_contents_scale));
|
| + gfx::ToCeiledSize(gfx::ScaleSize(bounds(), max_contents_scale));
|
| gfx::Rect scaled_visible_content_rect =
|
| gfx::ScaleToEnclosingRect(visible_content_rect(), max_contents_scale);
|
| scaled_visible_content_rect.Intersect(gfx::Rect(scaled_content_bounds));
|
| @@ -561,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) {
|
| @@ -628,19 +646,28 @@ scoped_refptr<Tile> PictureLayerImpl::CreateTile(PictureLayerTiling* tiling,
|
| flags);
|
| }
|
|
|
| -PicturePileImpl* PictureLayerImpl::GetPile() {
|
| +RasterSource* PictureLayerImpl::GetRasterSource() {
|
| return pile_.get();
|
| }
|
|
|
| -const Region* PictureLayerImpl::GetInvalidation() {
|
| - return &invalidation_;
|
| +const Region* PictureLayerImpl::GetPendingInvalidation() {
|
| + if (layer_tree_impl()->IsPendingTree())
|
| + return &invalidation_;
|
| + DCHECK(layer_tree_impl()->IsActiveTree());
|
| + 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;
|
| + // TODO(danakj): Remove this when no longer swapping tilings.
|
| + if (!twin_layer->tilings_)
|
| return nullptr;
|
| - return twin_layer_->tilings_->TilingAtScale(tiling->contents_scale());
|
| + return twin_layer->tilings_->TilingAtScale(tiling->contents_scale());
|
| }
|
|
|
| PictureLayerTiling* PictureLayerImpl::GetRecycledTwinTiling(
|
| @@ -770,8 +797,10 @@ void PictureLayerImpl::SyncFromActiveLayer(const PictureLayerImpl* other) {
|
|
|
| bool synced_high_res_tiling = false;
|
| if (CanHaveTilings()) {
|
| - synced_high_res_tiling = tilings_->SyncTilings(
|
| - *other->tilings_, bounds(), invalidation_, MinimumContentsScale());
|
| + synced_high_res_tiling = tilings_->SyncTilings(*other->tilings_,
|
| + pile_->tiling_size(),
|
| + invalidation_,
|
| + MinimumContentsScale());
|
| } else {
|
| RemoveAllTilings();
|
| }
|
| @@ -791,9 +820,11 @@ 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(), bounds());
|
| + tilings_->AddTiling(tiling->contents_scale(), pile_->tiling_size());
|
|
|
| // If this tree needs update draw properties, then the tiling will
|
| // get updated prior to drawing or activation. If this tree does not
|
| @@ -812,6 +843,7 @@ void PictureLayerImpl::SyncTiling(
|
| void PictureLayerImpl::GetContentsResourceId(
|
| ResourceProvider::ResourceId* resource_id,
|
| gfx::Size* resource_size) const {
|
| + DCHECK_EQ(bounds().ToString(), pile_->tiling_size().ToString());
|
| gfx::Rect content_rect(bounds());
|
| PictureLayerTilingSet::CoverageIterator iter(
|
| tilings_.get(), 1.f, content_rect, ideal_contents_scale_);
|
| @@ -845,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;
|
| @@ -864,12 +892,13 @@ PictureLayerTiling* PictureLayerImpl::AddTiling(float contents_scale) {
|
| DCHECK(CanHaveTilingWithScale(contents_scale)) <<
|
| "contents_scale: " << contents_scale;
|
|
|
| - PictureLayerTiling* tiling = tilings_->AddTiling(contents_scale, bounds());
|
| + PictureLayerTiling* tiling =
|
| + tilings_->AddTiling(contents_scale, pile_->tiling_size());
|
|
|
| DCHECK(pile_->HasRecordings());
|
|
|
| - if (twin_layer_)
|
| - twin_layer_->SyncTiling(tiling);
|
| + if (PictureLayerImpl* twin_layer = GetPendingOrActiveTwinLayer())
|
| + twin_layer->SyncTiling(tiling);
|
|
|
| return tiling;
|
| }
|
| @@ -1067,8 +1096,8 @@ void PictureLayerImpl::RecalculateRasterScales() {
|
| // See crbug.com/422341.
|
| float maximum_scale = draw_properties().maximum_animation_contents_scale;
|
| if (maximum_scale) {
|
| - gfx::Size bounds_at_maximum_scale =
|
| - gfx::ToCeiledSize(gfx::ScaleSize(bounds(), maximum_scale));
|
| + gfx::Size bounds_at_maximum_scale = gfx::ToCeiledSize(
|
| + gfx::ScaleSize(pile_->tiling_size(), maximum_scale));
|
| if (bounds_at_maximum_scale.GetArea() <=
|
| layer_tree_impl()->device_viewport_size().GetArea())
|
| can_raster_at_maximum_scale = true;
|
| @@ -1084,11 +1113,11 @@ void PictureLayerImpl::RecalculateRasterScales() {
|
|
|
| // If this layer would create zero or one tiles at this content scale,
|
| // don't create a low res tiling.
|
| - gfx::Size content_bounds =
|
| - gfx::ToCeiledSize(gfx::ScaleSize(bounds(), raster_contents_scale_));
|
| - gfx::Size tile_size = CalculateTileSize(content_bounds);
|
| - bool tile_covers_bounds = tile_size.width() >= content_bounds.width() &&
|
| - tile_size.height() >= content_bounds.height();
|
| + gfx::Size raster_bounds = gfx::ToCeiledSize(
|
| + gfx::ScaleSize(pile_->tiling_size(), raster_contents_scale_));
|
| + gfx::Size tile_size = CalculateTileSize(raster_bounds);
|
| + bool tile_covers_bounds = tile_size.width() >= raster_bounds.width() &&
|
| + tile_size.height() >= raster_bounds.height();
|
| if (tile_size.IsEmpty() || tile_covers_bounds) {
|
| low_res_raster_contents_scale_ = raster_contents_scale_;
|
| return;
|
| @@ -1113,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,
|
| @@ -1122,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();
|
| + }
|
| }
|
| }
|
|
|
| @@ -1160,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)
|
| @@ -1185,7 +1219,8 @@ float PictureLayerImpl::MinimumContentsScale() const {
|
| // then it will end up having less than one pixel of content in that
|
| // dimension. Bump the minimum contents scale up in this case to prevent
|
| // this from happening.
|
| - int min_dimension = std::min(bounds().width(), bounds().height());
|
| + int min_dimension =
|
| + std::min(pile_->tiling_size().width(), pile_->tiling_size().height());
|
| if (!min_dimension)
|
| return setting_min;
|
|
|
| @@ -1318,10 +1353,11 @@ void PictureLayerImpl::AsValueInto(base::debug::TracedValue* state) const {
|
| state->EndArray();
|
|
|
| state->BeginArray("coverage_tiles");
|
| - for (PictureLayerTilingSet::CoverageIterator iter(tilings_.get(),
|
| - 1.f,
|
| - gfx::Rect(content_bounds()),
|
| - ideal_contents_scale_);
|
| + for (PictureLayerTilingSet::CoverageIterator iter(
|
| + tilings_.get(),
|
| + 1.f,
|
| + gfx::Rect(pile_->tiling_size()),
|
| + ideal_contents_scale_);
|
| iter;
|
| ++iter) {
|
| state->BeginDictionary();
|
|
|