summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cc/layers/picture_layer.cc5
-rw-r--r--cc/layers/picture_layer_impl.cc40
-rw-r--r--cc/layers/picture_layer_impl.h5
-rw-r--r--cc/layers/picture_layer_impl_unittest.cc62
-rw-r--r--cc/resources/picture_layer_tiling.cc24
-rw-r--r--cc/resources/picture_pile_base.cc6
-rw-r--r--cc/resources/picture_pile_base.h4
-rw-r--r--cc/trees/layer_tree_impl.cc6
-rw-r--r--cc/trees/layer_tree_impl.h1
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;