Commit a382113d authored by Xianzhu Wang's avatar Xianzhu Wang Committed by Commit Bot

Skip cc::DisplayItemList conversion from paint chunks if nothing changed

Only convert paint chunks if the layer bounds changed, we have
invalidated raster or we are checking raster under-invalidation.
Otherwise just keep the existing cc::DisplayItemList.

Change-Id: I9ee584344ede6df8fb88af64b4347460389142e7
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2363643Reviewed-by: default avatarStefan Zager <szager@chromium.org>
Commit-Queue: Xianzhu Wang <wangxianzhu@chromium.org>
Cr-Commit-Position: refs/heads/master@{#799648}
parent dc57ebd5
...@@ -88,10 +88,22 @@ scoped_refptr<cc::PictureLayer> ContentLayerClientImpl::UpdateCcPictureLayer( ...@@ -88,10 +88,22 @@ scoped_refptr<cc::PictureLayer> ContentLayerClientImpl::UpdateCcPictureLayer(
if (layer_state != layer_state_) if (layer_state != layer_state_)
cc_picture_layer_->SetSubtreePropertyChanged(); cc_picture_layer_->SetSubtreePropertyChanged();
raster_invalidated_ = false;
gfx::Size old_layer_size = raster_invalidator_.LayerBounds().size();
DCHECK_EQ(old_layer_size, cc_picture_layer_->bounds());
raster_invalidator_.Generate(raster_invalidation_function_, paint_artifact, raster_invalidator_.Generate(raster_invalidation_function_, paint_artifact,
paint_chunks, layer_bounds, layer_state); paint_chunks, layer_bounds, layer_state);
layer_state_ = layer_state; layer_state_ = layer_state;
base::Optional<RasterUnderInvalidationCheckingParams>
raster_under_invalidation_params;
if (RuntimeEnabledFeatures::PaintUnderInvalidationCheckingEnabled()) {
raster_under_invalidation_params.emplace(
*raster_invalidator_.GetTracking(),
IntRect(0, 0, layer_bounds.width(), layer_bounds.height()),
paint_chunks[0].id.client.DebugName());
}
// Note: cc::Layer API assumes the layer bounds start at (0, 0), but the // Note: cc::Layer API assumes the layer bounds start at (0, 0), but the
// bounding box of a paint chunk does not necessarily start at (0, 0) (and // bounding box of a paint chunk does not necessarily start at (0, 0) (and
// could even be negative). Internally the generated layer translates the // could even be negative). Internally the generated layer translates the
...@@ -99,20 +111,23 @@ scoped_refptr<cc::PictureLayer> ContentLayerClientImpl::UpdateCcPictureLayer( ...@@ -99,20 +111,23 @@ scoped_refptr<cc::PictureLayer> ContentLayerClientImpl::UpdateCcPictureLayer(
// offset_to_transform_parent with the origin of the paint chunk here. // offset_to_transform_parent with the origin of the paint chunk here.
cc_picture_layer_->SetOffsetToTransformParent( cc_picture_layer_->SetOffsetToTransformParent(
layer_bounds.OffsetFromOrigin()); layer_bounds.OffsetFromOrigin());
cc_picture_layer_->SetBounds(layer_bounds.size());
cc_picture_layer_->SetHitTestable(true);
base::Optional<RasterUnderInvalidationCheckingParams> params; // If nothing changed in the layer, keep the original display item list.
if (RuntimeEnabledFeatures::PaintUnderInvalidationCheckingEnabled()) { // Here check layer_bounds because RasterInvalidator doesn't issue raster
params.emplace(*raster_invalidator_.GetTracking(), // invalidation when layer_bounds become empty or non-empty from empty.
IntRect(0, 0, layer_bounds.width(), layer_bounds.height()), if (layer_bounds.size() == old_layer_size && !raster_invalidated_ &&
paint_chunks[0].id.client.DebugName()); !raster_under_invalidation_params && cc_display_item_list_) {
DCHECK_EQ(cc_picture_layer_->bounds(), layer_bounds.size());
return cc_picture_layer_;
} }
cc_display_item_list_ = PaintChunksToCcLayer::Convert( cc_display_item_list_ = PaintChunksToCcLayer::Convert(
paint_chunks, layer_state, layer_bounds.OffsetFromOrigin(), paint_chunks, layer_state, layer_bounds.OffsetFromOrigin(),
display_item_list, cc::DisplayItemList::kTopLevelDisplayItemList, display_item_list, cc::DisplayItemList::kTopLevelDisplayItemList,
base::OptionalOrNullptr(params)); base::OptionalOrNullptr(raster_under_invalidation_params));
cc_picture_layer_->SetBounds(layer_bounds.size());
cc_picture_layer_->SetHitTestable(true);
cc_picture_layer_->SetIsDrawable( cc_picture_layer_->SetIsDrawable(
(!layer_bounds.IsEmpty() && cc_display_item_list_->TotalOpCount()) || (!layer_bounds.IsEmpty() && cc_display_item_list_->TotalOpCount()) ||
// Backdrop effects and filters require the layer to be drawable even if // Backdrop effects and filters require the layer to be drawable even if
......
...@@ -67,6 +67,7 @@ class PLATFORM_EXPORT ContentLayerClientImpl : public cc::ContentLayerClient, ...@@ -67,6 +67,7 @@ class PLATFORM_EXPORT ContentLayerClientImpl : public cc::ContentLayerClient,
private: private:
// Callback from raster_invalidator_. // Callback from raster_invalidator_.
void InvalidateRect(const IntRect& rect) { void InvalidateRect(const IntRect& rect) {
raster_invalidated_ = true;
cc_picture_layer_->SetNeedsDisplayRect(rect); cc_picture_layer_->SetNeedsDisplayRect(rect);
} }
...@@ -75,6 +76,7 @@ class PLATFORM_EXPORT ContentLayerClientImpl : public cc::ContentLayerClient, ...@@ -75,6 +76,7 @@ class PLATFORM_EXPORT ContentLayerClientImpl : public cc::ContentLayerClient,
scoped_refptr<cc::DisplayItemList> cc_display_item_list_; scoped_refptr<cc::DisplayItemList> cc_display_item_list_;
RasterInvalidator raster_invalidator_; RasterInvalidator raster_invalidator_;
RasterInvalidator::RasterInvalidationFunction raster_invalidation_function_; RasterInvalidator::RasterInvalidationFunction raster_invalidation_function_;
bool raster_invalidated_ = false;
PropertyTreeState layer_state_; PropertyTreeState layer_state_;
......
...@@ -4856,13 +4856,17 @@ TEST_P(PaintArtifactCompositorTest, TransformChange) { ...@@ -4856,13 +4856,17 @@ TEST_P(PaintArtifactCompositorTest, TransformChange) {
t2_state.direct_compositing_reasons = CompositingReason::k3DTransform; t2_state.direct_compositing_reasons = CompositingReason::k3DTransform;
auto t2 = TransformPaintPropertyNode::Create(*t1, std::move(t2_state)); auto t2 = TransformPaintPropertyNode::Create(*t1, std::move(t2_state));
FakeDisplayItemClient client;
client.Validate();
Update(TestPaintArtifact() Update(TestPaintArtifact()
.Chunk(1) .Chunk(1)
.Properties(*t2, c0(), e0()) .Properties(*t2, c0(), e0())
.RectDrawing(IntRect(100, 100, 200, 100), Color::kBlack) .RectDrawing(client, IntRect(100, 100, 200, 100), Color::kBlack)
.Build()); .Build());
ASSERT_EQ(1u, LayerCount()); ASSERT_EQ(1u, LayerCount());
cc::Layer* layer = LayerAt(0); auto* layer = static_cast<cc::PictureLayer*>(LayerAt(0));
auto display_item_list = layer->client()->PaintContentsToDisplayList(
cc::ContentLayerClient::PAINTING_BEHAVIOR_NORMAL);
// Change t1 but not t2. // Change t1 but not t2.
layer->ClearSubtreePropertyChangedForTesting(); layer->ClearSubtreePropertyChangedForTesting();
...@@ -4874,11 +4878,16 @@ TEST_P(PaintArtifactCompositorTest, TransformChange) { ...@@ -4874,11 +4878,16 @@ TEST_P(PaintArtifactCompositorTest, TransformChange) {
Update(TestPaintArtifact() Update(TestPaintArtifact()
.Chunk(1) .Chunk(1)
.Properties(*t2, c0(), e0()) .Properties(*t2, c0(), e0())
.RectDrawing(IntRect(100, 100, 200, 100), Color::kBlack) .RectDrawing(client, IntRect(100, 100, 200, 100), Color::kBlack)
.Build()); .Build());
ASSERT_EQ(1u, LayerCount()); ASSERT_EQ(1u, LayerCount());
ASSERT_EQ(layer, LayerAt(0)); ASSERT_EQ(layer, LayerAt(0));
EXPECT_EQ(display_item_list.get(),
layer->client()
->PaintContentsToDisplayList(
cc::ContentLayerClient::PAINTING_BEHAVIOR_NORMAL)
.get());
// TODO(wangxianzhu): Probably avoid setting this flag on transform change. // TODO(wangxianzhu): Probably avoid setting this flag on transform change.
EXPECT_TRUE(layer->subtree_property_changed()); EXPECT_TRUE(layer->subtree_property_changed());
// This is set by cc when propagating ancestor change flag to descendants. // This is set by cc when propagating ancestor change flag to descendants.
...@@ -4899,11 +4908,16 @@ TEST_P(PaintArtifactCompositorTest, TransformChange) { ...@@ -4899,11 +4908,16 @@ TEST_P(PaintArtifactCompositorTest, TransformChange) {
Update(TestPaintArtifact() Update(TestPaintArtifact()
.Chunk(1) .Chunk(1)
.Properties(*t2, c0(), e0()) .Properties(*t2, c0(), e0())
.RectDrawing(IntRect(100, 100, 200, 100), Color::kBlack) .RectDrawing(client, IntRect(100, 100, 200, 100), Color::kBlack)
.Build()); .Build());
ASSERT_EQ(1u, LayerCount()); ASSERT_EQ(1u, LayerCount());
ASSERT_EQ(layer, LayerAt(0)); ASSERT_EQ(layer, LayerAt(0));
EXPECT_EQ(display_item_list.get(),
layer->client()
->PaintContentsToDisplayList(
cc::ContentLayerClient::PAINTING_BEHAVIOR_NORMAL)
.get());
// TODO(wangxianzhu): Probably avoid setting this flag on transform change. // TODO(wangxianzhu): Probably avoid setting this flag on transform change.
EXPECT_TRUE(layer->subtree_property_changed()); EXPECT_TRUE(layer->subtree_property_changed());
EXPECT_TRUE(GetTransformNode(layer).transform_changed); EXPECT_TRUE(GetTransformNode(layer).transform_changed);
...@@ -4921,16 +4935,39 @@ TEST_P(PaintArtifactCompositorTest, TransformChange) { ...@@ -4921,16 +4935,39 @@ TEST_P(PaintArtifactCompositorTest, TransformChange) {
Update(TestPaintArtifact() Update(TestPaintArtifact()
.Chunk(1) .Chunk(1)
.Properties(*t2, c0(), e0()) .Properties(*t2, c0(), e0())
.RectDrawing(IntRect(100, 100, 200, 100), Color::kBlack) .RectDrawing(client, IntRect(100, 100, 200, 100), Color::kBlack)
.Build()); .Build());
ASSERT_EQ(1u, LayerCount()); ASSERT_EQ(1u, LayerCount());
ASSERT_EQ(layer, LayerAt(0)); ASSERT_EQ(layer, LayerAt(0));
EXPECT_EQ(display_item_list.get(),
layer->client()
->PaintContentsToDisplayList(
cc::ContentLayerClient::PAINTING_BEHAVIOR_NORMAL)
.get());
// The new transform is decomposited, so there is no transform_changed, but // The new transform is decomposited, so there is no transform_changed, but
// we set subtree_property_changed because offset_from_transform_parent // we set subtree_property_changed because offset_from_transform_parent
// (calculated from the decomposited transforms) changed. // (calculated from the decomposited transforms) changed.
EXPECT_TRUE(layer->subtree_property_changed()); EXPECT_TRUE(layer->subtree_property_changed());
EXPECT_FALSE(GetTransformNode(layer).transform_changed); EXPECT_FALSE(GetTransformNode(layer).transform_changed);
// Change no transform nodes, but invalidate client.
layer->ClearSubtreePropertyChangedForTesting();
t2->ClearChangedToRoot();
client.Invalidate(PaintInvalidationReason::kBackground);
Update(TestPaintArtifact()
.Chunk(1)
.Properties(*t2, c0(), e0())
.RectDrawing(client, IntRect(100, 100, 200, 100), Color::kWhite)
.Build());
ASSERT_EQ(1u, LayerCount());
ASSERT_EQ(layer, LayerAt(0));
EXPECT_NE(display_item_list.get(),
layer->client()
->PaintContentsToDisplayList(
cc::ContentLayerClient::PAINTING_BEHAVIOR_NORMAL)
.get());
} }
TEST_P(PaintArtifactCompositorTest, EffectChange) { TEST_P(PaintArtifactCompositorTest, EffectChange) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment