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

[SPv175+] Don't create transform operations for identity transforms

This avoids many extra Save/Transform(identity)/../Restore,
Save/../Restore without transform. Also simplifies
Save/ClipRect/Transform(identity)/Save/ClipRect/Transform/../Restore/Restore
to Save/ClipRect(combined)/Transform/../Restore.

This especially fixes the performance regression of perf tests containing
svg images.

https://pinpoint-dot-chromeperf.appspot.com/results2/16c651cec40000
shows 18% improvement of frame_time of
tough_canvas_cases/rendering_throughput/bouncing_svg_images.html.

Bug: 823452
Cq-Include-Trybots: master.tryserver.blink:linux_trusty_blink_rel;master.tryserver.chromium.linux:linux_layout_tests_slimming_paint_v2
Change-Id: I4576646cbe9c59bc8a7f56b67ef59f2ad57f159d
Reviewed-on: https://chromium-review.googlesource.com/1020152
Commit-Queue: Xianzhu Wang <wangxianzhu@chromium.org>
Reviewed-by: default avatarPhilip Rogers <pdr@chromium.org>
Reviewed-by: default avatarTien-Ren Chen <trchen@chromium.org>
Cr-Commit-Position: refs/heads/master@{#552511}
parent d6d671bb
...@@ -132,7 +132,9 @@ class ConversionContext { ...@@ -132,7 +132,9 @@ class ConversionContext {
void ApplyTransform(const TransformPaintPropertyNode* target_transform) { void ApplyTransform(const TransformPaintPropertyNode* target_transform) {
if (target_transform == current_transform_) if (target_transform == current_transform_)
return; return;
cc_list_.push<cc::ConcatOp>(GetSkMatrix(target_transform)); auto sk_matrix = GetSkMatrix(target_transform);
if (!sk_matrix.isIdentity())
cc_list_.push<cc::ConcatOp>(sk_matrix);
} }
SkMatrix GetSkMatrix( SkMatrix GetSkMatrix(
...@@ -319,8 +321,12 @@ void ConversionContext::SwitchToClip(const ClipPaintPropertyNode* target_clip) { ...@@ -319,8 +321,12 @@ void ConversionContext::SwitchToClip(const ClipPaintPropertyNode* target_clip) {
bool has_rounded_clip_or_clip_path = bool has_rounded_clip_or_clip_path =
sub_clip->ClipRect().IsRounded() || sub_clip->ClipPath(); sub_clip->ClipRect().IsRounded() || sub_clip->ClipPath();
if (!has_rounded_clip_or_clip_path && pending_combined_clip_rect && if (!has_rounded_clip_or_clip_path && pending_combined_clip_rect &&
sub_clip->Parent()->LocalTransformSpace() == (sub_clip->Parent()->LocalTransformSpace() ==
sub_clip->LocalTransformSpace()) { sub_clip->LocalTransformSpace() ||
GeometryMapper::SourceToDestinationProjection(
sub_clip->Parent()->LocalTransformSpace(),
sub_clip->LocalTransformSpace())
.IsIdentity())) {
// Continue to combine rectangular clips in the same transform space. // Continue to combine rectangular clips in the same transform space.
pending_combined_clip_rect->Intersect(sub_clip->ClipRect().Rect()); pending_combined_clip_rect->Intersect(sub_clip->ClipRect().Rect());
lowest_combined_clip_node = sub_clip; lowest_combined_clip_node = sub_clip;
...@@ -605,10 +611,16 @@ void ConversionContext::SwitchToTransform( ...@@ -605,10 +611,16 @@ void ConversionContext::SwitchToTransform(
return; return;
EndTransform(); EndTransform();
if (target_transform == current_transform_)
return;
auto sk_matrix = GetSkMatrix(target_transform);
if (sk_matrix.isIdentity())
return;
cc_list_.StartPaint(); cc_list_.StartPaint();
cc_list_.push<cc::SaveOp>(); cc_list_.push<cc::SaveOp>();
ApplyTransform(target_transform); cc_list_.push<cc::ConcatOp>(sk_matrix);
cc_list_.EndPaintOfPairedBegin(); cc_list_.EndPaintOfPairedBegin();
previous_transform_ = current_transform_; previous_transform_ = current_transform_;
current_transform_ = target_transform; current_transform_ = target_transform;
......
...@@ -829,5 +829,42 @@ TEST_F(PaintChunksToCcLayerTest, ChunksSamePropertyTreeState) { ...@@ -829,5 +829,42 @@ TEST_F(PaintChunksToCcLayerTest, ChunksSamePropertyTreeState) {
cc::PaintOpType::Restore})); // </c1></t1> cc::PaintOpType::Restore})); // </c1></t1>
} }
TEST_F(PaintChunksToCcLayerTest, NoOpForIdentityTransforms) {
auto t1 = CreateTransform(t0(), TransformationMatrix());
auto t2 = CreateTransform(t1.get(), TransformationMatrix());
auto t3 = CreateTransform(t2.get(), TransformationMatrix());
auto c1 =
ClipPaintPropertyNode::Create(c0(), t2, FloatRoundedRect(0, 0, 100, 100));
auto c2 =
ClipPaintPropertyNode::Create(c1, t3, FloatRoundedRect(0, 0, 200, 50));
TestChunks chunks;
chunks.AddChunk(t0(), c0(), e0());
chunks.AddChunk(t1.get(), c0(), e0());
chunks.AddChunk(t0(), c0(), e0());
chunks.AddChunk(t1.get(), c0(), e0());
chunks.AddChunk(t2.get(), c0(), e0());
chunks.AddChunk(t1.get(), c0(), e0());
chunks.AddChunk(t1.get(), c2.get(), e0());
auto output =
PaintChunksToCcLayer::Convert(
chunks.chunks, PropertyTreeState(t0(), c0(), e0()), gfx::Vector2dF(),
chunks.items, cc::DisplayItemList::kToBeReleasedAsPaintOpBuffer)
->ReleaseAsRecord();
EXPECT_THAT(*output,
PaintRecordMatcher::Make(
{cc::PaintOpType::DrawRecord, // <p0/>
cc::PaintOpType::DrawRecord, // <p1/>
cc::PaintOpType::DrawRecord, // <p2/>
cc::PaintOpType::DrawRecord, // <p3/>
cc::PaintOpType::DrawRecord, // <p4/>
cc::PaintOpType::DrawRecord, // <p5/>
cc::PaintOpType::Save, cc::PaintOpType::ClipRect, // <c1+c2>
cc::PaintOpType::DrawRecord, // <p6/>
cc::PaintOpType::Restore})); // </c1+c2>
}
} // namespace } // namespace
} // namespace blink } // namespace blink
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