Skip to content

Commit

Permalink
Tile non-backdrop-filter mask layers normally
Browse files Browse the repository at this point in the history
After crrev.com/c/1799701, non-backdrop-filter mask layers become
normal layers with DstIn blend mode, thus they can be tiled normally
to avoid the problems caused by single tile before (e.g. too much
memory usage for huge masks, no benefits of tile management).

Bug: 1003414
Change-Id: Ic0c5d318bc3e657de861f6c7246c417399900209
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1805468
Reviewed-by: Philip Rogers <pdr@chromium.org>
Reviewed-by: Malay Keshav <malaykeshav@chromium.org>
Commit-Queue: Xianzhu Wang <wangxianzhu@chromium.org>
Cr-Commit-Position: refs/heads/master@{#697816}
  • Loading branch information
wangxianzhu authored and Commit Bot committed Sep 18, 2019
1 parent bb01bb3 commit 34c8269
Show file tree
Hide file tree
Showing 10 changed files with 77 additions and 59 deletions.
1 change: 0 additions & 1 deletion cc/layers/layer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -608,7 +608,6 @@ void Layer::SetMaskLayer(scoped_refptr<PictureLayer> mask_layer) {
mask_layer->inputs_.position = gfx::PointF();
mask_layer->SetIsDrawable(true);
mask_layer->SetBlendMode(SkBlendMode::kDstIn);
mask_layer->SetIsMask(true);
AddChild(mask_layer);
}
inputs_.mask_layer = mask_layer.get();
Expand Down
11 changes: 0 additions & 11 deletions cc/layers/picture_layer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,6 @@ void PictureLayer::PushPropertiesTo(LayerImpl* base_layer) {
ShouldUseTransformedRasterization());
layer_impl->set_gpu_raster_max_texture_size(
layer_tree_host()->device_viewport_rect().size());

layer_impl->SetIsMask(is_mask());
layer_impl->SetIsBackdropFilterMask(is_backdrop_filter_mask());

// TODO(enne): http://crbug.com/918126 debugging
Expand Down Expand Up @@ -232,19 +230,10 @@ bool PictureLayer::HasDrawableContent() const {
return picture_layer_inputs_.client && Layer::HasDrawableContent();
}

void PictureLayer::SetIsMask(bool is_mask) {
if (picture_layer_inputs_.is_mask == is_mask)
return;

picture_layer_inputs_.is_mask = is_mask;
SetNeedsCommit();
}

void PictureLayer::SetIsBackdropFilterMask(bool is_backdrop_filter_mask) {
if (picture_layer_inputs_.is_backdrop_filter_mask == is_backdrop_filter_mask)
return;

DCHECK(!is_backdrop_filter_mask || is_mask());
picture_layer_inputs_.is_backdrop_filter_mask = is_backdrop_filter_mask;
SetNeedsCommit();
}
Expand Down
6 changes: 0 additions & 6 deletions cc/layers/picture_layer.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,6 @@ class CC_EXPORT PictureLayer : public Layer {
return picture_layer_inputs_.transformed_rasterization_allowed;
}

// TODO(crbug.com/1003414): Remove this flag when we tile mask layers (except
// for backdrop filter masks) normally.
void SetIsMask(bool is_mask);
bool is_mask() const { return picture_layer_inputs_.is_mask; }

void SetIsBackdropFilterMask(bool is_backdrop_filter_mask);
bool is_backdrop_filter_mask() const {
return picture_layer_inputs_.is_backdrop_filter_mask;
Expand Down Expand Up @@ -77,7 +72,6 @@ class CC_EXPORT PictureLayer : public Layer {
ContentLayerClient* client = nullptr;
bool nearest_neighbor = false;
bool transformed_rasterization_allowed = false;
bool is_mask = false;
bool is_backdrop_filter_mask = false;
gfx::Rect recorded_viewport;
scoped_refptr<DisplayItemList> display_list;
Expand Down
46 changes: 21 additions & 25 deletions cc/layers/picture_layer_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,6 @@ PictureLayerImpl::PictureLayerImpl(LayerTreeImpl* tree_impl, int id)
raster_source_scale_(0.f),
raster_contents_scale_(0.f),
low_res_raster_contents_scale_(0.f),
is_mask_(false),
is_backdrop_filter_mask_(false),
was_screen_space_transform_animating_(false),
only_used_low_res_last_append_quads_(false),
Expand Down Expand Up @@ -153,7 +152,6 @@ void PictureLayerImpl::PushPropertiesTo(LayerImpl* base_layer) {

layer_impl->SetNearestNeighbor(nearest_neighbor_);
layer_impl->SetUseTransformedRasterization(use_transformed_rasterization_);
layer_impl->SetIsMask(is_mask_);
layer_impl->SetIsBackdropFilterMask(is_backdrop_filter_mask_);

// Solid color layers have no tilings.
Expand Down Expand Up @@ -189,8 +187,8 @@ void PictureLayerImpl::AppendQuads(viz::RenderPass* render_pass,
AppendQuadsData* append_quads_data) {
// RenderSurfaceImpl::AppendQuads sets mask properties in the DrawQuad for
// the masked surface, which will apply to both the backdrop filter and the
// contents of the masked surface, so we should not quad of the mask layer
// in DstIn blend mode.
// contents of the masked surface, so we should not append quads of the mask
// layer in DstIn blend mode which would apply the mask in another codepath.
if (is_backdrop_filter_mask_)
return;

Expand Down Expand Up @@ -224,11 +222,7 @@ void PictureLayerImpl::AppendQuads(viz::RenderPass* render_pass,

gfx::Rect scaled_visible_layer_rect =
shared_quad_state->visible_quad_layer_rect;
Occlusion occlusion;
// TODO(sunxd): Compute the correct occlusion for mask layers.
if (!is_mask_) {
occlusion = draw_properties().occlusion_in_content_space;
}
Occlusion occlusion = draw_properties().occlusion_in_content_space;

EffectNode* effect_node = GetEffectTree().Node(effect_tree_index());
SolidColorLayerImpl::AppendSolidQuads(
Expand All @@ -247,13 +241,10 @@ void PictureLayerImpl::AppendQuads(viz::RenderPass* render_pass,
tilings_->num_tilings() ? MaximumTilingContentsScale() : 1.f;
PopulateScaledSharedQuadState(shared_quad_state, max_contents_scale,
contents_opaque());
Occlusion scaled_occlusion;
if (!is_mask_) {
scaled_occlusion =
draw_properties()
.occlusion_in_content_space.GetOcclusionWithGivenDrawTransform(
shared_quad_state->quad_to_target_transform);
}
Occlusion scaled_occlusion =
draw_properties()
.occlusion_in_content_space.GetOcclusionWithGivenDrawTransform(
shared_quad_state->quad_to_target_transform);

if (current_draw_mode_ == DRAW_MODE_RESOURCELESS_SOFTWARE) {
DCHECK(shared_quad_state->quad_layer_rect.origin() == gfx::Point(0, 0));
Expand Down Expand Up @@ -442,7 +433,7 @@ void PictureLayerImpl::AppendQuads(viz::RenderPass* render_pass,
float alpha =
(SkColorGetA(draw_info.solid_color()) * (1.0f / 255.0f)) *
shared_quad_state->opacity;
if (is_mask_ || alpha >= std::numeric_limits<float>::epsilon()) {
if (alpha >= std::numeric_limits<float>::epsilon()) {
auto* quad =
render_pass->CreateAndAppendDrawQuad<viz::SolidColorDrawQuad>();
quad->SetNew(
Expand All @@ -462,7 +453,7 @@ void PictureLayerImpl::AppendQuads(viz::RenderPass* render_pass,
if (!has_draw_quad) {
// Checkerboard.
SkColor color = SafeOpaqueBackgroundColor();
if (!is_mask_ && ShowDebugBorders(DebugBorderType::LAYER)) {
if (ShowDebugBorders(DebugBorderType::LAYER)) {
// Fill the whole tile with the missing tile color.
color = DebugColors::DefaultCheckerboardColor();
}
Expand Down Expand Up @@ -813,11 +804,10 @@ std::unique_ptr<Tile> PictureLayerImpl::CreateTile(
const Tile::CreateInfo& info) {
int flags = 0;

// We don't handle solid color masks if mask tiling is disabled, we also don't
// handle solid color single texture masks if the flag is enabled, so we
// shouldn't bother analyzing those.
// We don't handle solid color single texture masks for backdrop filters,
// so we shouldn't bother analyzing those.
// Otherwise, always analyze to maximize memory savings.
if (!is_mask_)
if (!is_backdrop_filter_mask_)
flags = Tile::USE_PICTURE_ANALYSIS;

if (contents_opaque())
Expand Down Expand Up @@ -907,6 +897,12 @@ void PictureLayerImpl::GetContentsResourceId(
viz::ResourceId* resource_id,
gfx::Size* resource_size,
gfx::SizeF* resource_uv_size) const {
// We need contents resource for backdrop filter masks only.
if (!is_backdrop_filter_mask()) {
*resource_id = 0;
return;
}

// 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(raster_source_->GetSize().IsEmpty() ||
Expand Down Expand Up @@ -1349,9 +1345,9 @@ float PictureLayerImpl::MaximumContentsScale() const {
// have tilings that would become larger than the max_texture_size since they
// use a single tile for the entire tiling. Other layers can have tilings such
// that dimension * scale does not overflow.
float max_dimension =
static_cast<float>(is_mask_ ? layer_tree_impl()->max_texture_size()
: std::numeric_limits<int>::max());
float max_dimension = static_cast<float>(
is_backdrop_filter_mask_ ? layer_tree_impl()->max_texture_size()
: std::numeric_limits<int>::max());
int higher_dimension = std::max(bounds().width(), bounds().height());
float max_scale = max_dimension / higher_dimension;

Expand Down
7 changes: 0 additions & 7 deletions cc/layers/picture_layer_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,13 +43,7 @@ class CC_EXPORT PictureLayerImpl

PictureLayerImpl& operator=(const PictureLayerImpl&) = delete;

// TODO(crbug.com/1003414): Remove this flag when we tile mask layers (except
// for backdrop filter masks) normally.
void SetIsMask(bool is_mask) { is_mask_ = is_mask; }
bool is_mask() const { return is_mask_; }

void SetIsBackdropFilterMask(bool is_backdrop_filter_mask) {
DCHECK(!is_backdrop_filter_mask || is_mask_);
is_backdrop_filter_mask_ = is_backdrop_filter_mask;
}
bool is_backdrop_filter_mask() const { return is_backdrop_filter_mask_; }
Expand Down Expand Up @@ -229,7 +223,6 @@ class CC_EXPORT PictureLayerImpl
float raster_contents_scale_;
float low_res_raster_contents_scale_;

bool is_mask_ : 1;
bool is_backdrop_filter_mask_ : 1;

bool was_screen_space_transform_animating_ : 1;
Expand Down
57 changes: 53 additions & 4 deletions cc/layers/picture_layer_impl_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1177,7 +1177,7 @@ TEST_F(PictureLayerImplTest, DontAddLowResForSmallLayers) {
EXPECT_EQ(mask->num_tilings(), 1u);
}

TEST_F(PictureLayerImplTest, HugeMasksGetScaledDown) {
TEST_F(PictureLayerImplTest, HugeBackdropFilterMasksGetScaledDown) {
host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1));

gfx::Size layer_bounds(1000, 1000);
Expand All @@ -1186,10 +1186,12 @@ TEST_F(PictureLayerImplTest, HugeMasksGetScaledDown) {
FakeRasterSource::CreateFilled(layer_bounds);
SetupPendingTree(valid_raster_source);

CreateEffectNode(pending_layer());
CreateEffectNode(pending_layer())
.backdrop_filters.Append(FilterOperation::CreateInvertFilter(1.0));
auto* pending_mask = AddLayer<FakePictureLayerImpl>(
host_impl()->pending_tree(), valid_raster_source);
SetupMaskProperties(pending_layer(), pending_mask);
ASSERT_TRUE(pending_mask->is_backdrop_filter_mask());

host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1));
UpdateDrawProperties(host_impl()->pending_tree());
Expand Down Expand Up @@ -1301,7 +1303,7 @@ TEST_F(PictureLayerImplTest, HugeMasksGetScaledDown) {
EXPECT_EQ(0u, pending_mask->num_tilings());
}

TEST_F(PictureLayerImplTest, ScaledMaskLayer) {
TEST_F(PictureLayerImplTest, ScaledBackdropFilterMaskLayer) {
host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1));

gfx::Size layer_bounds(1000, 1000);
Expand All @@ -1312,10 +1314,12 @@ TEST_F(PictureLayerImplTest, ScaledMaskLayer) {
FakeRasterSource::CreateFilled(layer_bounds);
SetupPendingTree(valid_raster_source);

CreateEffectNode(pending_layer());
CreateEffectNode(pending_layer())
.backdrop_filters.Append(FilterOperation::CreateInvertFilter(1.0));
auto* pending_mask = AddLayer<FakePictureLayerImpl>(
host_impl()->pending_tree(), valid_raster_source);
SetupMaskProperties(pending_layer(), pending_mask);
ASSERT_TRUE(pending_mask->is_backdrop_filter_mask());

host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1));
UpdateDrawProperties(host_impl()->pending_tree());
Expand Down Expand Up @@ -1347,6 +1351,51 @@ TEST_F(PictureLayerImplTest, ScaledMaskLayer) {
EXPECT_EQ(gfx::SizeF(1.0f, 1.0f), mask_uv_size);
}

TEST_F(PictureLayerImplTest, ScaledMaskLayer) {
host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1));

gfx::Size layer_bounds(1000, 1000);

SetInitialDeviceScaleFactor(1.3f);

scoped_refptr<FakeRasterSource> valid_raster_source =
FakeRasterSource::CreateFilled(layer_bounds);
SetupPendingTree(valid_raster_source);

CreateEffectNode(pending_layer());
auto* pending_mask = AddLayer<FakePictureLayerImpl>(
host_impl()->pending_tree(), valid_raster_source);
SetupMaskProperties(pending_layer(), pending_mask);
ASSERT_FALSE(pending_mask->is_backdrop_filter_mask());

host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1));
UpdateDrawProperties(host_impl()->pending_tree());

// Masks are scaled, and do not have a low res tiling.
EXPECT_EQ(1.3f, pending_mask->HighResTiling()->contents_scale_key());
EXPECT_EQ(1u, pending_mask->num_tilings());

host_impl()->tile_manager()->InitializeTilesWithResourcesForTesting(
pending_mask->HighResTiling()->AllTilesForTesting());

ActivateTree();

FakePictureLayerImpl* active_mask = static_cast<FakePictureLayerImpl*>(
host_impl()->active_tree()->LayerById(pending_mask->id()));

// Non-backdrop-filter mask layers are tiled normally.
EXPECT_EQ(36u, active_mask->HighResTiling()->AllTilesForTesting().size());
// And don't have mask resources.
viz::ResourceId mask_resource_id;
gfx::Size mask_texture_size;
gfx::SizeF mask_uv_size;
active_mask->GetContentsResourceId(&mask_resource_id, &mask_texture_size,
&mask_uv_size);
EXPECT_EQ(0u, mask_resource_id);
EXPECT_EQ(gfx::Size(), mask_texture_size);
EXPECT_EQ(gfx::SizeF(), mask_uv_size);
}

TEST_F(PictureLayerImplTest, ReleaseTileResources) {
gfx::Size layer_bounds(1300, 1900);
SetupDefaultTrees(layer_bounds);
Expand Down
6 changes: 3 additions & 3 deletions cc/layers/tile_size_calculator.cc
Original file line number Diff line number Diff line change
Expand Up @@ -124,9 +124,9 @@ TileSizeCalculator::AffectingParams TileSizeCalculator::GetAffectingParams() {
gfx::Size TileSizeCalculator::CalculateTileSize() {
gfx::Size content_bounds = layer_impl()->content_bounds();

if (layer_impl()->is_mask()) {
// Masks are not tiled, so if we can't cover the whole mask with one tile,
// we shouldn't have such a tiling at all.
if (layer_impl()->is_backdrop_filter_mask()) {
// Backdrop filter masks are not tiled, so if we can't cover the whole mask
// with one tile, we shouldn't have such a tiling at all.
DCHECK_LE(content_bounds.width(),
layer_impl()->layer_tree_impl()->max_texture_size());
DCHECK_LE(content_bounds.height(),
Expand Down
1 change: 0 additions & 1 deletion cc/test/property_tree_test_utils.cc
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,6 @@ ScrollNode& CreateScrollNodeInternal(LayerType* layer, int parent_id) {
template <typename LayerType, typename MaskLayerType>
void SetupMaskPropertiesInternal(LayerType* masked_layer,
MaskLayerType* mask_layer) {
mask_layer->SetIsMask(true);
if (!GetEffectNode(masked_layer)->backdrop_filters.IsEmpty())
mask_layer->SetIsBackdropFilterMask(true);
mask_layer->SetBounds(masked_layer->bounds());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1733,7 +1733,6 @@ bool CompositedLayerMapping::UpdateMaskLayer(bool needs_mask_layer) {
GetLayoutObject().UniqueId(),
CompositorElementIdNamespace::kEffectMask);
mask_layer_->SetElementId(element_id);
mask_layer_->CcLayer()->SetIsMask(true);
if (GetLayoutObject().HasBackdropFilter())
mask_layer_->CcLayer()->SetIsBackdropFilterMask(true);
layer_changed = true;
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 34c8269

Please sign in to comment.