diff options
-rw-r--r-- | cc/layers/picture_layer.cc | 5 | ||||
-rw-r--r-- | cc/layers/picture_layer_impl.cc | 40 | ||||
-rw-r--r-- | cc/layers/picture_layer_impl.h | 5 | ||||
-rw-r--r-- | cc/layers/picture_layer_impl_unittest.cc | 62 | ||||
-rw-r--r-- | cc/resources/picture_layer_tiling.cc | 24 | ||||
-rw-r--r-- | cc/resources/picture_pile_base.cc | 6 | ||||
-rw-r--r-- | cc/resources/picture_pile_base.h | 4 | ||||
-rw-r--r-- | cc/trees/layer_tree_impl.cc | 6 | ||||
-rw-r--r-- | cc/trees/layer_tree_impl.h | 1 |
9 files changed, 101 insertions, 52 deletions
diff --git a/cc/layers/picture_layer.cc b/cc/layers/picture_layer.cc index 8b8558c..4207aa2 100644 --- a/cc/layers/picture_layer.cc +++ b/cc/layers/picture_layer.cc @@ -21,7 +21,6 @@ PictureLayer::PictureLayer(ContentLayerClient* client) : client_(client), pile_(make_scoped_refptr(new PicturePile())), instrumentation_object_tracker_(id()), - is_mask_(false), update_source_frame_number_(-1), can_use_lcd_text_last_frame_(can_use_lcd_text()) { } @@ -50,8 +49,6 @@ void PictureLayer::PushPropertiesTo(LayerImpl* base_layer) { DCHECK_EQ(layer_impl->bounds().ToString(), pile_->tiling_size().ToString()); } - layer_impl->SetIsMask(is_mask_); - // Unlike other properties, invalidation must always be set on layer_impl. // See PictureLayerImpl::PushPropertiesTo for more details. layer_impl->invalidation_.Clear(); @@ -149,7 +146,7 @@ bool PictureLayer::Update(ResourceUpdateQueue* queue, } void PictureLayer::SetIsMask(bool is_mask) { - is_mask_ = is_mask; + pile_->set_is_mask(is_mask); } Picture::RecordingMode PictureLayer::RecordingMode() const { diff --git a/cc/layers/picture_layer_impl.cc b/cc/layers/picture_layer_impl.cc index e7512a5..cb8141b 100644 --- a/cc/layers/picture_layer_impl.cc +++ b/cc/layers/picture_layer_impl.cc @@ -62,7 +62,6 @@ PictureLayerImpl::PictureLayerImpl(LayerTreeImpl* tree_impl, int id) : LayerImpl(tree_impl, id), twin_layer_(NULL), pile_(PicturePileImpl::Create()), - is_mask_(false), ideal_page_scale_(0.f), ideal_device_scale_(0.f), ideal_source_scale_(0.f), @@ -114,7 +113,6 @@ void PictureLayerImpl::PushPropertiesTo(LayerImpl* base_layer) { layer_impl->twin_layer_ = NULL; twin_layer_ = NULL; - layer_impl->SetIsMask(is_mask_); layer_impl->pile_ = pile_; // Tilings would be expensive to push, so we swap. @@ -590,7 +588,7 @@ scoped_refptr<Tile> PictureLayerImpl::CreateTile(PictureLayerTiling* tiling, // memory savings that we can get. Note that we don't handle solid color // masks, so we shouldn't bother analyzing those. // Bugs: crbug.com/397198, crbug.com/396908 - if (!is_mask_) + if (!pile_->is_mask()) flags = Tile::USE_PICTURE_ANALYSIS; return layer_tree_impl()->tile_manager()->CreateTile( @@ -649,16 +647,18 @@ int PictureLayerImpl::GetSkewportExtrapolationLimitInContentPixels() const { gfx::Size PictureLayerImpl::CalculateTileSize( const gfx::Size& content_bounds) const { - if (is_mask_) { - int max_size = layer_tree_impl()->MaxTextureSize(); - return gfx::Size( - std::min(max_size, content_bounds.width()), - std::min(max_size, content_bounds.height())); - } - int max_texture_size = layer_tree_impl()->resource_provider()->max_texture_size(); + if (pile_->is_mask()) { + // Masks are not tiled, so if we can't cover the whole mask with one tile, + // don't make any tiles at all. Returning an empty size signals this. + if (content_bounds.width() > max_texture_size || + content_bounds.height() > max_texture_size) + return gfx::Size(); + return content_bounds; + } + gfx::Size default_tile_size = layer_tree_impl()->settings().default_tile_size; if (layer_tree_impl()->use_gpu_rasterization()) { // TODO(ernstm) crbug.com/365877: We need a unified way to override the @@ -760,14 +760,6 @@ void PictureLayerImpl::SyncTiling( } } -void PictureLayerImpl::SetIsMask(bool is_mask) { - if (is_mask_ == is_mask) - return; - is_mask_ = is_mask; - if (tilings_) - tilings_->RemoveAllTiles(); -} - ResourceProvider::ResourceId PictureLayerImpl::ContentsResourceId() const { gfx::Rect content_rect(content_bounds()); float scale = MaximumTilingContentsScale(); @@ -779,8 +771,9 @@ ResourceProvider::ResourceId PictureLayerImpl::ContentsResourceId() const { return 0; // Masks only supported if they fit on exactly one tile. - if (iter.geometry_rect() != content_rect) - return 0; + DCHECK(iter.geometry_rect() == content_rect) + << "iter rect " << iter.geometry_rect().ToString() << " content rect " + << content_rect.ToString(); const ManagedTileState::TileVersion& tile_version = iter->GetTileVersionForDrawing(); @@ -1196,13 +1189,14 @@ void PictureLayerImpl::RecalculateRasterScales() { } } - // If this layer would only create one tile at this content scale, + // 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); - if (tile_size.width() >= content_bounds.width() && - tile_size.height() >= content_bounds.height()) { + bool tile_covers_bounds = tile_size.width() >= content_bounds.width() && + tile_size.height() >= content_bounds.height(); + if (tile_size.IsEmpty() || tile_covers_bounds) { low_res_raster_contents_scale_ = raster_contents_scale_; return; } diff --git a/cc/layers/picture_layer_impl.h b/cc/layers/picture_layer_impl.h index 47d881d..47e74ae 100644 --- a/cc/layers/picture_layer_impl.h +++ b/cc/layers/picture_layer_impl.h @@ -135,8 +135,7 @@ class CC_EXPORT PictureLayerImpl // PushPropertiesTo active tree => pending tree. void SyncTiling(const PictureLayerTiling* tiling); - // Mask-related functions - void SetIsMask(bool is_mask); + // Mask-related functions. virtual ResourceProvider::ResourceId ContentsResourceId() const OVERRIDE; virtual size_t GPUMemoryUsageInBytes() const OVERRIDE; @@ -205,8 +204,6 @@ class CC_EXPORT PictureLayerImpl scoped_refptr<PicturePileImpl> pile_; Region invalidation_; - bool is_mask_; - float ideal_page_scale_; float ideal_device_scale_; float ideal_source_scale_; diff --git a/cc/layers/picture_layer_impl_unittest.cc b/cc/layers/picture_layer_impl_unittest.cc index ba6c6bb..bd6a8f7 100644 --- a/cc/layers/picture_layer_impl_unittest.cc +++ b/cc/layers/picture_layer_impl_unittest.cc @@ -109,8 +109,6 @@ class PictureLayerImplTest : public testing::Test { SetupPendingTree(active_pile); ActivateTree(); SetupPendingTree(pending_pile); - host_impl_.pending_tree()->SetPageScaleFactorAndLimits(1.f, 0.25f, 100.f); - host_impl_.active_tree()->SetPageScaleFactorAndLimits(1.f, 0.25f, 100.f); } void CreateHighLowResAndSetAllTilesVisible() { @@ -134,6 +132,7 @@ class PictureLayerImplTest : public testing::Test { void SetupPendingTree(scoped_refptr<PicturePileImpl> pile) { host_impl_.CreatePendingTree(); + host_impl_.pending_tree()->SetPageScaleFactorAndLimits(1.f, 0.25f, 100.f); LayerTreeImpl* pending_tree = host_impl_.pending_tree(); // Clear recycled tree. pending_tree->DetachLayerTree(); @@ -1044,6 +1043,12 @@ TEST_F(PictureLayerImplTest, CleanUpTilings) { EXPECT_EQ(x, active_layer_->expression); \ } while (false) +#define EXPECT_BOTH_NE(expression, x) \ + do { \ + EXPECT_NE(x, pending_layer_->expression); \ + EXPECT_NE(x, active_layer_->expression); \ + } while (false) + TEST_F(PictureLayerImplTest, DontAddLowResDuringAnimation) { // Make sure this layer covers multiple tiles, since otherwise low // res won't get created because it is too small. @@ -1155,8 +1160,8 @@ TEST_F(PictureLayerImplTest, DontAddLowResForSmallLayers) { ResetTilingsAndRasterScales(); // Mask layers dont create low res since they always fit on one tile. - pending_layer_->SetIsMask(true); - active_layer_->SetIsMask(true); + pending_layer_->pile()->set_is_mask(true); + active_layer_->pile()->set_is_mask(true); SetContentsScaleOnBothLayers(contents_scale, device_scale, page_scale, @@ -1166,6 +1171,53 @@ TEST_F(PictureLayerImplTest, DontAddLowResForSmallLayers) { EXPECT_BOTH_EQ(num_tilings(), 1u); } +TEST_F(PictureLayerImplTest, HugeMasksDontGetTiles) { + gfx::Size tile_size(100, 100); + + scoped_refptr<FakePicturePileImpl> valid_pile = + FakePicturePileImpl::CreateFilledPile(tile_size, gfx::Size(1000, 1000)); + valid_pile->set_is_mask(true); + SetupPendingTree(valid_pile); + + SetupDrawPropertiesAndUpdateTiles(pending_layer_, 1.f, 1.f, 1.f, 1.f, false); + EXPECT_EQ(1.f, pending_layer_->HighResTiling()->contents_scale()); + EXPECT_EQ(1u, pending_layer_->num_tilings()); + + pending_layer_->HighResTiling()->CreateAllTilesForTesting(); + host_impl_.tile_manager()->InitializeTilesWithResourcesForTesting( + pending_layer_->HighResTiling()->AllTilesForTesting()); + + ActivateTree(); + + // Mask layers have a tiling with a single tile in it. + EXPECT_EQ(1u, active_layer_->HighResTiling()->AllTilesForTesting().size()); + // The mask resource exists. + EXPECT_NE(0u, active_layer_->ContentsResourceId()); + + // Resize larger than the max texture size. + int max_texture_size = host_impl_.GetRendererCapabilities().max_texture_size; + scoped_refptr<FakePicturePileImpl> huge_pile = + FakePicturePileImpl::CreateFilledPile( + tile_size, gfx::Size(max_texture_size + 1, 10)); + huge_pile->set_is_mask(true); + SetupPendingTree(huge_pile); + + SetupDrawPropertiesAndUpdateTiles(pending_layer_, 1.f, 1.f, 1.f, 1.f, false); + EXPECT_EQ(1.f, pending_layer_->HighResTiling()->contents_scale()); + EXPECT_EQ(1u, pending_layer_->num_tilings()); + + pending_layer_->HighResTiling()->CreateAllTilesForTesting(); + host_impl_.tile_manager()->InitializeTilesWithResourcesForTesting( + pending_layer_->HighResTiling()->AllTilesForTesting()); + + ActivateTree(); + + // Mask layers have a tiling, but there should be no tiles in it. + EXPECT_EQ(0u, active_layer_->HighResTiling()->AllTilesForTesting().size()); + // The mask resource is empty. + EXPECT_EQ(0u, active_layer_->ContentsResourceId()); +} + TEST_F(PictureLayerImplTest, ReleaseResources) { gfx::Size tile_size(400, 400); gfx::Size layer_bounds(1300, 1900); @@ -3397,10 +3449,10 @@ TEST_F(PictureLayerImplTest, UpdateTilesForMasksWithNoVisibleContent) { scoped_refptr<FakePicturePileImpl> pending_pile = FakePicturePileImpl::CreateFilledPile(tile_size, bounds); + pending_pile->set_is_mask(true); scoped_ptr<FakePictureLayerImpl> mask = FakePictureLayerImpl::CreateWithPile( host_impl_.pending_tree(), 3, pending_pile); - mask->SetIsMask(true); mask->SetBounds(bounds); mask->SetContentBounds(bounds); mask->SetDrawsContent(true); diff --git a/cc/resources/picture_layer_tiling.cc b/cc/resources/picture_layer_tiling.cc index 3dde0c2..8cb3424 100644 --- a/cc/resources/picture_layer_tiling.cc +++ b/cc/resources/picture_layer_tiling.cc @@ -91,6 +91,10 @@ PictureLayerTiling::PictureLayerTiling(float contents_scale, gfx::Size content_bounds = gfx::ToCeiledSize(gfx::ScaleSize(layer_bounds, contents_scale)); gfx::Size tile_size = client_->CalculateTileSize(content_bounds); + if (tile_size.IsEmpty()) { + layer_bounds_ = gfx::Size(); + content_bounds = gfx::Size(); + } DCHECK(!gfx::ToFlooredSize( gfx::ScaleSize(layer_bounds, contents_scale)).IsEmpty()) << @@ -168,14 +172,20 @@ void PictureLayerTiling::UpdateTilesToCurrentPile( const gfx::Size& new_layer_bounds) { DCHECK(!new_layer_bounds.IsEmpty()); - gfx::Size old_layer_bounds = layer_bounds_; - layer_bounds_ = new_layer_bounds; - - gfx::Size content_bounds = - gfx::ToCeiledSize(gfx::ScaleSize(layer_bounds_, contents_scale_)); gfx::Size tile_size = tiling_data_.max_texture_size(); - if (layer_bounds_ != old_layer_bounds) { + if (new_layer_bounds != layer_bounds_) { + gfx::Size content_bounds = + gfx::ToCeiledSize(gfx::ScaleSize(new_layer_bounds, contents_scale_)); + + tile_size = client_->CalculateTileSize(content_bounds); + if (tile_size.IsEmpty()) { + layer_bounds_ = gfx::Size(); + content_bounds = gfx::Size(); + } else { + layer_bounds_ = new_layer_bounds; + } + // The SetLiveTilesRect() method would drop tiles outside the new bounds, // but may do so incorrectly if resizing the tiling causes the number of // tiles in the tiling_data_ to change. @@ -229,8 +239,6 @@ void PictureLayerTiling::UpdateTilesToCurrentPile( for (int i = before_left; i <= before_right; ++i) CreateTile(i, after_bottom, twin_tiling); } - - tile_size = client_->CalculateTileSize(content_bounds); } if (tile_size != tiling_data_.max_texture_size()) { diff --git a/cc/resources/picture_pile_base.cc b/cc/resources/picture_pile_base.cc index b1132ad..447d1b3 100644 --- a/cc/resources/picture_pile_base.cc +++ b/cc/resources/picture_pile_base.cc @@ -48,7 +48,8 @@ PicturePileBase::PicturePileBase() show_debug_picture_borders_(false), clear_canvas_with_debug_color_(kDefaultClearCanvasSetting), has_any_recordings_(false), - has_text_(false) { + has_text_(false), + is_mask_(false) { tiling_.SetMaxTextureSize(gfx::Size(kBasePictureSize, kBasePictureSize)); tile_grid_info_.fTileInterval.setEmpty(); tile_grid_info_.fMargin.setEmpty(); @@ -69,7 +70,8 @@ PicturePileBase::PicturePileBase(const PicturePileBase* other) show_debug_picture_borders_(other->show_debug_picture_borders_), clear_canvas_with_debug_color_(other->clear_canvas_with_debug_color_), has_any_recordings_(other->has_any_recordings_), - has_text_(other->has_text_) { + has_text_(other->has_text_), + is_mask_(other->is_mask_) { } PicturePileBase::~PicturePileBase() { diff --git a/cc/resources/picture_pile_base.h b/cc/resources/picture_pile_base.h index 3aabcfb..fb6cf5f 100644 --- a/cc/resources/picture_pile_base.h +++ b/cc/resources/picture_pile_base.h @@ -51,6 +51,9 @@ class CC_EXPORT PicturePileBase : public base::RefCounted<PicturePileBase> { // If this pile has ever contained any recordings with text. bool has_text() const { return has_text_; } + void set_is_mask(bool is_mask) { is_mask_ = is_mask; } + bool is_mask() const { return is_mask_; } + static void ComputeTileGridInfo(const gfx::Size& tile_grid_size, SkTileGridFactory::TileGridInfo* info); @@ -119,6 +122,7 @@ class CC_EXPORT PicturePileBase : public base::RefCounted<PicturePileBase> { // positive. bool has_any_recordings_; bool has_text_; + bool is_mask_; private: void SetBufferPixels(int buffer_pixels); diff --git a/cc/trees/layer_tree_impl.cc b/cc/trees/layer_tree_impl.cc index 61b1fcf..797d2d1 100644 --- a/cc/trees/layer_tree_impl.cc +++ b/cc/trees/layer_tree_impl.cc @@ -468,7 +468,7 @@ bool LayerTreeImpl::UpdateDrawProperties() { device_scale_factor(), total_page_scale_factor(), page_scale_layer, - MaxTextureSize(), + resource_provider()->max_texture_size(), settings().can_use_lcd_text, can_render_to_separate_surface, settings().layer_transforms_should_scale_layer_contents, @@ -724,10 +724,6 @@ LayerImpl* LayerTreeImpl::FindRecycleTreeLayerById(int id) { return tree->LayerById(id); } -int LayerTreeImpl::MaxTextureSize() const { - return layer_tree_host_impl_->GetRendererCapabilities().max_texture_size; -} - bool LayerTreeImpl::PinchGestureActive() const { return layer_tree_host_impl_->pinch_gesture_active(); } diff --git a/cc/trees/layer_tree_impl.h b/cc/trees/layer_tree_impl.h index 76d3868..c7b4acf 100644 --- a/cc/trees/layer_tree_impl.h +++ b/cc/trees/layer_tree_impl.h @@ -88,7 +88,6 @@ class CC_EXPORT LayerTreeImpl { LayerImpl* FindActiveTreeLayerById(int id); LayerImpl* FindPendingTreeLayerById(int id); LayerImpl* FindRecycleTreeLayerById(int id); - int MaxTextureSize() const; bool PinchGestureActive() const; BeginFrameArgs CurrentBeginFrameArgs() const; base::TimeDelta begin_impl_frame_interval() const; |