diff options
author | danakj <danakj@chromium.org> | 2014-09-06 23:08:16 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2014-09-07 06:09:33 +0000 |
commit | 132fdfe17dd03c0066e27fe876602122c522aa8b (patch) | |
tree | 138f3b9eb8d134e908a60584ec8e48b3332f0b9a /cc | |
parent | 272c8d7b1978f66b18b9621bf1ec4c9692f18e9f (diff) | |
download | chromium_src-132fdfe17dd03c0066e27fe876602122c522aa8b.zip chromium_src-132fdfe17dd03c0066e27fe876602122c522aa8b.tar.gz chromium_src-132fdfe17dd03c0066e27fe876602122c522aa8b.tar.bz2 |
cc: Don't make tiles for mask layers that are too big for a texture.
If a mask layer's width or height are larger than the max texture size,
we do not use the contents of the mask layer. So if we're not going to
use the contents, there's no reason to make tiles and allocate memory
for them.
This changes PictureLayerImpl to return an empty tile size for masks
that are too large to have tiles. Then changes PictureLayerTiling to
use the empty tile size as a signal to make the whole tiling an empty
size.
Last, we use the empty tile size to also signal not making a low res
tiling, so that masks continue to not get a low res tiling if they are
large.
R=enne, vmpstr
BUG=409984
Review URL: https://codereview.chromium.org/547463002
Cr-Commit-Position: refs/heads/master@{#293656}
Diffstat (limited to 'cc')
-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; |