| Index: cc/layers/picture_layer_impl.cc
|
| diff --git a/cc/layers/picture_layer_impl.cc b/cc/layers/picture_layer_impl.cc
|
| index 54cfac88b32ec722abac90809ad0c5c9486e7731..392450a32942284cf6315b74e1e4b43faf2836ac 100644
|
| --- a/cc/layers/picture_layer_impl.cc
|
| +++ b/cc/layers/picture_layer_impl.cc
|
| @@ -63,9 +63,13 @@ PictureLayerImpl::Pair::Pair(PictureLayerImpl* active_layer,
|
| PictureLayerImpl::Pair::~Pair() {
|
| }
|
|
|
| -PictureLayerImpl::PictureLayerImpl(LayerTreeImpl* tree_impl, int id)
|
| +PictureLayerImpl::PictureLayerImpl(LayerTreeImpl* tree_impl,
|
| + int id,
|
| + bool is_mask)
|
| : LayerImpl(tree_impl, id),
|
| twin_layer_(nullptr),
|
| + tilings_(CreatePictureLayerTilingSet()),
|
| + // TODO(danakj): Can this be null to start?
|
| raster_source_(PicturePileImpl::Create()),
|
| ideal_page_scale_(0.f),
|
| ideal_device_scale_(0.f),
|
| @@ -81,7 +85,8 @@ PictureLayerImpl::PictureLayerImpl(LayerTreeImpl* tree_impl, int id)
|
| needs_post_commit_initialization_(true),
|
| should_update_tile_priorities_(false),
|
| only_used_low_res_last_append_quads_(false),
|
| - is_mask_(false) {
|
| + is_mask_(is_mask),
|
| + nearest_neighbor_(false) {
|
| layer_tree_impl()->RegisterPictureLayerImpl(this);
|
| }
|
|
|
| @@ -95,8 +100,10 @@ scoped_ptr<TilingSetEvictionQueue> PictureLayerImpl::CreateEvictionQueue(
|
| TreePriority tree_priority) {
|
| if (!tilings_)
|
| return make_scoped_ptr(new TilingSetEvictionQueue());
|
| - return make_scoped_ptr(
|
| - new TilingSetEvictionQueue(tilings_.get(), tree_priority));
|
| + bool skip_shared_out_of_order_tiles =
|
| + GetPendingOrActiveTwinLayer() != nullptr;
|
| + return make_scoped_ptr(new TilingSetEvictionQueue(
|
| + tilings_.get(), tree_priority, skip_shared_out_of_order_tiles));
|
| }
|
|
|
| scoped_ptr<TilingSetRasterQueue> PictureLayerImpl::CreateRasterQueue(
|
| @@ -113,7 +120,7 @@ const char* PictureLayerImpl::LayerTypeAsString() const {
|
|
|
| scoped_ptr<LayerImpl> PictureLayerImpl::CreateLayerImpl(
|
| LayerTreeImpl* tree_impl) {
|
| - return PictureLayerImpl::Create(tree_impl, id());
|
| + return PictureLayerImpl::Create(tree_impl, id(), is_mask_);
|
| }
|
|
|
| void PictureLayerImpl::PushPropertiesTo(LayerImpl* base_layer) {
|
| @@ -121,6 +128,7 @@ void PictureLayerImpl::PushPropertiesTo(LayerImpl* base_layer) {
|
| // a descendant of an opacity 0 layer).
|
| DoPostCommitInitializationIfNeeded();
|
| PictureLayerImpl* layer_impl = static_cast<PictureLayerImpl*>(base_layer);
|
| + DCHECK_EQ(layer_impl->is_mask_, is_mask_);
|
|
|
| LayerImpl::PushPropertiesTo(base_layer);
|
|
|
| @@ -134,54 +142,39 @@ void PictureLayerImpl::PushPropertiesTo(LayerImpl* base_layer) {
|
| twin_layer_ = layer_impl;
|
| layer_impl->twin_layer_ = this;
|
|
|
| - layer_impl->set_is_mask(is_mask_);
|
| - layer_impl->UpdateRasterSource(raster_source_);
|
| + layer_impl->SetNearestNeighbor(nearest_neighbor_);
|
|
|
| + // Solid color layers have no tilings.
|
| DCHECK_IMPLIES(raster_source_->IsSolidColor(), tilings_->num_tilings() == 0);
|
| - // Tilings would be expensive to push, so we swap.
|
| - layer_impl->tilings_.swap(tilings_);
|
| - layer_impl->tilings_->SetClient(layer_impl);
|
| - if (tilings_)
|
| - tilings_->SetClient(this);
|
| + // The pending tree should only have a high res (and possibly low res) tiling.
|
| + DCHECK_LE(tilings_->num_tilings(),
|
| + layer_tree_impl()->create_low_res_tiling() ? 2u : 1u);
|
|
|
| - // Ensure that the recycle tree doesn't have any unshared tiles.
|
| - if (tilings_ && raster_source_->IsSolidColor())
|
| - tilings_->RemoveAllTilings();
|
| + layer_impl->UpdateRasterSource(raster_source_, &invalidation_,
|
| + tilings_.get());
|
| + DCHECK(invalidation_.IsEmpty());
|
|
|
| - // Remove invalidated tiles from what will become a recycle tree.
|
| - if (tilings_)
|
| - tilings_->RemoveTilesInRegion(invalidation_);
|
| + // After syncing a solid color layer, the active layer has no tilings.
|
| + DCHECK_IMPLIES(raster_source_->IsSolidColor(),
|
| + layer_impl->tilings_->num_tilings() == 0);
|
|
|
| layer_impl->raster_page_scale_ = raster_page_scale_;
|
| layer_impl->raster_device_scale_ = raster_device_scale_;
|
| layer_impl->raster_source_scale_ = raster_source_scale_;
|
| layer_impl->raster_contents_scale_ = raster_contents_scale_;
|
| layer_impl->low_res_raster_contents_scale_ = low_res_raster_contents_scale_;
|
| - layer_impl->needs_post_commit_initialization_ = false;
|
|
|
| - // The invalidation on this soon-to-be-recycled layer must be cleared to
|
| - // mirror clearing the invalidation in PictureLayer's version of this function
|
| - // in case push properties is skipped.
|
| - layer_impl->invalidation_.Swap(&invalidation_);
|
| - invalidation_.Clear();
|
| + layer_impl->SanityCheckTilingState();
|
| +
|
| + layer_impl->needs_post_commit_initialization_ = false;
|
| needs_post_commit_initialization_ = true;
|
|
|
| // We always need to push properties.
|
| // See http://crbug.com/303943
|
| + // TODO(danakj): Stop always pushing properties since we don't swap tilings.
|
| needs_push_properties_ = true;
|
| }
|
|
|
| -void PictureLayerImpl::UpdateRasterSource(
|
| - scoped_refptr<RasterSource> raster_source) {
|
| - bool could_have_tilings = CanHaveTilings();
|
| - raster_source_.swap(raster_source);
|
| -
|
| - // Need to call UpdateTiles again if CanHaveTilings changed.
|
| - if (could_have_tilings != CanHaveTilings()) {
|
| - layer_tree_impl()->set_needs_update_draw_properties();
|
| - }
|
| -}
|
| -
|
| void PictureLayerImpl::AppendQuads(RenderPass* render_pass,
|
| const Occlusion& occlusion_in_content_space,
|
| AppendQuadsData* append_quads_data) {
|
| @@ -251,8 +244,9 @@ void PictureLayerImpl::AppendQuads(RenderPass* render_pass,
|
| PictureDrawQuad* quad =
|
| render_pass->CreateAndAppendDrawQuad<PictureDrawQuad>();
|
| quad->SetNew(shared_quad_state, geometry_rect, opaque_rect,
|
| - visible_geometry_rect, texture_rect, texture_size, RGBA_8888,
|
| - quad_content_rect, max_contents_scale, raster_source_);
|
| + visible_geometry_rect, texture_rect, texture_size,
|
| + nearest_neighbor_, RGBA_8888, quad_content_rect,
|
| + max_contents_scale, raster_source_);
|
| return;
|
| }
|
|
|
| @@ -364,7 +358,8 @@ void PictureLayerImpl::AppendQuads(RenderPass* render_pass,
|
| draw_info.get_resource_id(),
|
| texture_rect,
|
| iter.texture_size(),
|
| - draw_info.contents_swizzled());
|
| + draw_info.contents_swizzled(),
|
| + nearest_neighbor_);
|
| has_draw_quad = true;
|
| break;
|
| }
|
| @@ -386,8 +381,8 @@ void PictureLayerImpl::AppendQuads(RenderPass* render_pass,
|
| render_pass->CreateAndAppendDrawQuad<PictureDrawQuad>();
|
| quad->SetNew(shared_quad_state, geometry_rect, opaque_rect,
|
| visible_geometry_rect, texture_rect, iter.texture_size(),
|
| - format, iter->content_rect(), iter->contents_scale(),
|
| - raster_source_);
|
| + nearest_neighbor_, format, iter->content_rect(),
|
| + iter->contents_scale(), raster_source_);
|
| has_draw_quad = true;
|
| break;
|
| }
|
| @@ -485,8 +480,6 @@ void PictureLayerImpl::UpdateTiles(const Occlusion& occlusion_in_content_space,
|
|
|
| UpdateIdealScales();
|
|
|
| - DCHECK_IMPLIES(tilings_->num_tilings() == 0, raster_contents_scale_ == 0.f)
|
| - << "A layer with no tilings shouldn't have valid raster scales";
|
| if (!raster_contents_scale_ || ShouldAdjustRasterScale()) {
|
| RecalculateRasterScales();
|
| AddTilingsForRasterScale();
|
| @@ -581,6 +574,44 @@ PictureLayerImpl* PictureLayerImpl::GetRecycledTwinLayer() const {
|
| return twin_layer_;
|
| }
|
|
|
| +void PictureLayerImpl::UpdateRasterSource(
|
| + scoped_refptr<RasterSource> raster_source,
|
| + Region* new_invalidation,
|
| + const PictureLayerTilingSet* pending_set) {
|
| + // The bounds and the pile size may differ if the pile wasn't updated (ie.
|
| + // PictureLayer::Update didn't happen). In that case the pile will be empty.
|
| + DCHECK_IMPLIES(!raster_source->GetSize().IsEmpty(),
|
| + bounds() == raster_source->GetSize())
|
| + << " bounds " << bounds().ToString() << " pile "
|
| + << raster_source->GetSize().ToString();
|
| +
|
| + bool could_have_tilings = CanHaveTilings();
|
| + raster_source_.swap(raster_source);
|
| +
|
| + // The |new_invalidation| must be cleared before updating tilings since they
|
| + // access the invalidation through the PictureLayerTilingClient interface.
|
| + invalidation_.Clear();
|
| + invalidation_.Swap(new_invalidation);
|
| +
|
| + bool can_have_tilings = CanHaveTilings();
|
| +
|
| + // Need to call UpdateTiles again if CanHaveTilings changed.
|
| + if (could_have_tilings != can_have_tilings)
|
| + layer_tree_impl()->set_needs_update_draw_properties();
|
| +
|
| + if (!can_have_tilings) {
|
| + RemoveAllTilings();
|
| + return;
|
| + }
|
| +
|
| + // We could do this after doing UpdateTiles, which would avoid doing this for
|
| + // tilings that are going to disappear on the pending tree (if scale changed).
|
| + // But that would also be more complicated, so we just do it here for now.
|
| + tilings_->UpdateTilingsToCurrentRasterSource(
|
| + raster_source_.get(), pending_set, raster_source_->GetSize(),
|
| + invalidation_, MinimumContentsScale());
|
| +}
|
| +
|
| void PictureLayerImpl::NotifyTileStateChanged(const Tile* tile) {
|
| if (layer_tree_impl()->IsActiveTree()) {
|
| gfx::RectF layer_damage_rect =
|
| @@ -600,9 +631,10 @@ void PictureLayerImpl::DidBeginTracing() {
|
| }
|
|
|
| void PictureLayerImpl::ReleaseResources() {
|
| + // Recreate tilings with new settings, since some of those might change when
|
| + // we release resources. If tilings_ is null, then leave it as null.
|
| if (tilings_)
|
| - RemoveAllTilings();
|
| -
|
| + tilings_ = CreatePictureLayerTilingSet();
|
| ResetRasterScale();
|
|
|
| // To avoid an edge case after lost context where the tree is up to date but
|
| @@ -637,6 +669,8 @@ scoped_refptr<Tile> PictureLayerImpl::CreateTile(PictureLayerTiling* tiling,
|
| const Region* PictureLayerImpl::GetPendingInvalidation() {
|
| if (layer_tree_impl()->IsPendingTree())
|
| return &invalidation_;
|
| + if (layer_tree_impl()->IsRecycleTree())
|
| + return nullptr;
|
| DCHECK(layer_tree_impl()->IsActiveTree());
|
| if (PictureLayerImpl* twin_layer = GetPendingOrActiveTwinLayer())
|
| return &twin_layer->invalidation_;
|
| @@ -648,9 +682,6 @@ const PictureLayerTiling* PictureLayerImpl::GetPendingOrActiveTwinTiling(
|
| 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_->FindTilingWithScale(tiling->contents_scale());
|
| }
|
|
|
| @@ -668,22 +699,6 @@ TilePriority::PriorityBin PictureLayerImpl::GetMaxTilePriorityBin() const {
|
| return TilePriority::NOW;
|
| }
|
|
|
| -size_t PictureLayerImpl::GetMaxTilesForInterestArea() const {
|
| - return layer_tree_impl()->settings().max_tiles_for_interest_area;
|
| -}
|
| -
|
| -float PictureLayerImpl::GetSkewportTargetTimeInSeconds() const {
|
| - return layer_tree_impl()->use_gpu_rasterization()
|
| - ? 0.f
|
| - : layer_tree_impl()->settings().skewport_target_time_in_seconds;
|
| -}
|
| -
|
| -int PictureLayerImpl::GetSkewportExtrapolationLimitInContentPixels() const {
|
| - return layer_tree_impl()
|
| - ->settings()
|
| - .skewport_extrapolation_limit_in_content_pixels;
|
| -}
|
| -
|
| bool PictureLayerImpl::RequiresHighResToDraw() const {
|
| return layer_tree_impl()->RequiresHighResToDraw();
|
| }
|
| @@ -765,69 +780,15 @@ gfx::Size PictureLayerImpl::CalculateTileSize(
|
| return gfx::Size(tile_width, tile_height);
|
| }
|
|
|
| -void PictureLayerImpl::SyncFromActiveLayer(const PictureLayerImpl* other) {
|
| - DCHECK(!other->needs_post_commit_initialization_);
|
| - DCHECK(other->tilings_);
|
| -
|
| - if (!DrawsContent()) {
|
| - RemoveAllTilings();
|
| - return;
|
| - }
|
| -
|
| - raster_page_scale_ = other->raster_page_scale_;
|
| - raster_device_scale_ = other->raster_device_scale_;
|
| - raster_source_scale_ = other->raster_source_scale_;
|
| - raster_contents_scale_ = other->raster_contents_scale_;
|
| - low_res_raster_contents_scale_ = other->low_res_raster_contents_scale_;
|
| -
|
| - bool synced_high_res_tiling = false;
|
| - if (CanHaveTilings()) {
|
| - synced_high_res_tiling = tilings_->SyncTilings(
|
| - *other->tilings_, raster_source_->GetSize(), invalidation_,
|
| - MinimumContentsScale(), raster_source_.get());
|
| - } else {
|
| - RemoveAllTilings();
|
| - }
|
| -
|
| - // If our MinimumContentsScale has changed to prevent the twin's high res
|
| - // tiling from being synced, we should reset the raster scale and let it be
|
| - // recalculated (1) again. This can happen if our bounds shrink to the point
|
| - // where min contents scale grows.
|
| - // (1) - TODO(vmpstr) Instead of hoping that this will be recalculated, we
|
| - // should refactor this code a little bit and actually recalculate this.
|
| - // However, this is a larger undertaking, so this will work for now.
|
| - if (!synced_high_res_tiling)
|
| - ResetRasterScale();
|
| - else
|
| - SanityCheckTilingState();
|
| -}
|
| -
|
| -void PictureLayerImpl::SyncTiling(
|
| - const PictureLayerTiling* tiling) {
|
| - if (!tilings_)
|
| - return;
|
| - if (!CanHaveTilingWithScale(tiling->contents_scale()))
|
| - return;
|
| - tilings_->AddTiling(tiling->contents_scale(), raster_source_->GetSize());
|
| -
|
| - // If this tree needs update draw properties, then the tiling will
|
| - // get updated prior to drawing or activation. If this tree does not
|
| - // need update draw properties, then its transforms are up to date and
|
| - // we can create tiles for this tiling immediately.
|
| - if (!layer_tree_impl()->needs_update_draw_properties() &&
|
| - should_update_tile_priorities_) {
|
| - // TODO(danakj): Add a DCHECK() that we are not using occlusion tracking
|
| - // when we stop using the pending tree in the browser compositor. If we want
|
| - // to support occlusion tracking here, we need to dirty the draw properties
|
| - // or save occlusion as a draw property.
|
| - UpdateTilePriorities(Occlusion());
|
| - }
|
| -}
|
| -
|
| void PictureLayerImpl::GetContentsResourceId(
|
| ResourceProvider::ResourceId* resource_id,
|
| gfx::Size* resource_size) const {
|
| - DCHECK_EQ(bounds().ToString(), raster_source_->GetSize().ToString());
|
| + // The bounds and the pile size may differ if the pile wasn't updated (ie.
|
| + // PictureLayer::Update didn't happen). In that case the pile will be empty.
|
| + DCHECK_IMPLIES(!raster_source_->GetSize().IsEmpty(),
|
| + bounds() == raster_source_->GetSize())
|
| + << " bounds " << bounds().ToString() << " pile "
|
| + << raster_source_->GetSize().ToString();
|
| gfx::Rect content_rect(bounds());
|
| PictureLayerTilingSet::CoverageIterator iter(
|
| tilings_.get(), 1.f, content_rect, ideal_contents_scale_);
|
| @@ -854,21 +815,18 @@ void PictureLayerImpl::GetContentsResourceId(
|
| *resource_size = iter.texture_size();
|
| }
|
|
|
| +void PictureLayerImpl::SetNearestNeighbor(bool nearest_neighbor) {
|
| + if (nearest_neighbor_ == nearest_neighbor)
|
| + return;
|
| +
|
| + nearest_neighbor_ = nearest_neighbor;
|
| + NoteLayerPropertyChanged();
|
| +}
|
| +
|
| void PictureLayerImpl::DoPostCommitInitialization() {
|
| + // TODO(danakj): Remove this.
|
| DCHECK(needs_post_commit_initialization_);
|
| DCHECK(layer_tree_impl()->IsPendingTree());
|
| -
|
| - if (!tilings_)
|
| - tilings_ = PictureLayerTilingSet::Create(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);
|
| - }
|
| -
|
| needs_post_commit_initialization_ = false;
|
| }
|
|
|
| @@ -881,9 +839,6 @@ PictureLayerTiling* PictureLayerImpl::AddTiling(float contents_scale) {
|
|
|
| DCHECK(raster_source_->HasRecordings());
|
|
|
| - if (PictureLayerImpl* twin_layer = GetPendingOrActiveTwinLayer())
|
| - twin_layer->SyncTiling(tiling);
|
| -
|
| return tiling;
|
| }
|
|
|
| @@ -929,6 +884,12 @@ void PictureLayerImpl::AddTilingsForRasterScale() {
|
| // Make sure we always have one high-res (even if high == low).
|
| high_res->set_resolution(HIGH_RESOLUTION);
|
|
|
| + if (layer_tree_impl()->IsPendingTree()) {
|
| + // On the pending tree, drop any tilings that are non-ideal since we don't
|
| + // need them to activate anyway.
|
| + tilings_->RemoveNonIdealTilings();
|
| + }
|
| +
|
| SanityCheckTilingState();
|
| }
|
|
|
| @@ -1113,9 +1074,6 @@ void PictureLayerImpl::CleanUpTilingsOnActiveLayer(
|
| layer_tree_impl()->create_low_res_tiling(), twin_set,
|
| recycled_twin_set);
|
|
|
| - if (twin_set && twin_set->num_tilings() == 0)
|
| - twin->ResetRasterScale();
|
| -
|
| if (recycled_twin_set && recycled_twin_set->num_tilings() == 0)
|
| recycled_twin->ResetRasterScale();
|
|
|
| @@ -1158,6 +1116,8 @@ bool PictureLayerImpl::CanHaveTilings() const {
|
| return false;
|
| if (!raster_source_->HasRecordings())
|
| return false;
|
| + // If the |raster_source_| has a recording it should have non-empty bounds.
|
| + DCHECK(!raster_source_->GetSize().IsEmpty());
|
| return true;
|
| }
|
|
|
| @@ -1196,6 +1156,17 @@ float PictureLayerImpl::MaximumTilingContentsScale() const {
|
| return std::max(max_contents_scale, MinimumContentsScale());
|
| }
|
|
|
| +scoped_ptr<PictureLayerTilingSet>
|
| +PictureLayerImpl::CreatePictureLayerTilingSet() {
|
| + const LayerTreeSettings& settings = layer_tree_impl()->settings();
|
| + return PictureLayerTilingSet::Create(
|
| + this, settings.max_tiles_for_interest_area,
|
| + layer_tree_impl()->use_gpu_rasterization()
|
| + ? 0.f
|
| + : settings.skewport_target_time_in_seconds,
|
| + settings.skewport_extrapolation_limit_in_content_pixels);
|
| +}
|
| +
|
| void PictureLayerImpl::UpdateIdealScales() {
|
| DCHECK(CanHaveTilings());
|
|
|
|
|