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

[SPv175+] Optimize cc operations for blink effect nodes

Previously we always output 2 saveLayers for each effect node, one
for non-filter effect another for filter effect. Now don't output
no-op saveLayer operations.

Bug: 814227
Cq-Include-Trybots: master.tryserver.blink:linux_trusty_blink_rel;master.tryserver.chromium.linux:linux_layout_tests_slimming_paint_v2
Change-Id: I4462c387dfaf3fa246dcf6df6ebca84f30a5d2a2
Reviewed-on: https://chromium-review.googlesource.com/929878
Commit-Queue: Xianzhu Wang <wangxianzhu@chromium.org>
Reviewed-by: default avatarChris Harrelson <chrishtr@chromium.org>
Cr-Commit-Position: refs/heads/master@{#538894}
parent 6ffefffd
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<body style="filter: opacity(0.5)"> <body style="filter: opacity(0.501)">
This test ensures we properly paint the root renderer when an opacity filter is applied. This test ensures we properly paint the root renderer when an opacity filter is applied.
<!DOCTYPE html> <!DOCTYPE html>
<html style="filter: opacity(0.5)"> <html style="filter: opacity(0.501)">
This test ensures we properly paint the root renderer when an opacity filter is applied. This test ensures we properly paint the root renderer when an opacity filter is applied.
...@@ -58,16 +58,6 @@ Canvas log: ...@@ -58,16 +58,6 @@ Canvas log:
} }
} }
} }
10 : {
commandIndex : 10
method : "restore"
params : undefined
}
11 : {
commandIndex : 11
method : "restore"
params : undefined
}
2 : { 2 : {
commandIndex : 2 commandIndex : 2
method : "drawImageRect" method : "drawImageRect"
...@@ -140,34 +130,11 @@ Canvas log: ...@@ -140,34 +130,11 @@ Canvas log:
} }
5 : { 5 : {
commandIndex : 5 commandIndex : 5
method : "saveLayer"
params : {
paint : {
color : "#FF000000"
filterLevel : "None"
flags : "none"
hinting : "Normal"
strokeCap : "Butt"
strokeJoin : "Miter"
strokeMiter : 4
strokeWidth : 0
styleName : "Fill"
textAlign : "Left"
textEncoding : "UTF-8"
textScaleX : 1
textSize : 12
textSkewX : 0
}
saveFlags : ""
}
}
6 : {
commandIndex : 6
method : "save" method : "save"
params : undefined params : undefined
} }
7 : { 6 : {
commandIndex : 7 commandIndex : 6
method : "clipRect" method : "clipRect"
params : { params : {
SkRegion::Op : "kIntersect_Op" SkRegion::Op : "kIntersect_Op"
...@@ -180,8 +147,8 @@ Canvas log: ...@@ -180,8 +147,8 @@ Canvas log:
softClipEdgeStyle : false softClipEdgeStyle : false
} }
} }
8 : { 7 : {
commandIndex : 8 commandIndex : 7
method : "drawRect" method : "drawRect"
params : { params : {
paint : { paint : {
...@@ -208,6 +175,11 @@ Canvas log: ...@@ -208,6 +175,11 @@ Canvas log:
} }
} }
} }
8 : {
commandIndex : 8
method : "restore"
params : undefined
}
9 : { 9 : {
commandIndex : 9 commandIndex : 9
method : "restore" method : "restore"
......
...@@ -130,7 +130,8 @@ class ConversionContext { ...@@ -130,7 +130,8 @@ class ConversionContext {
struct StateEntry { struct StateEntry {
// Remembers the type of paired begin that caused a state to be saved. // Remembers the type of paired begin that caused a state to be saved.
// This is useful for emitting corresponding paired end. // This is useful for emitting corresponding paired end.
enum class PairedType : char { kClip, kEffect } type; enum class PairedType { kClip, kEffect } type;
int saved_count;
const TransformPaintPropertyNode* transform; const TransformPaintPropertyNode* transform;
const ClipPaintPropertyNode* clip; const ClipPaintPropertyNode* clip;
...@@ -142,14 +143,8 @@ class ConversionContext { ...@@ -142,14 +143,8 @@ class ConversionContext {
}; };
ConversionContext::~ConversionContext() { ConversionContext::~ConversionContext() {
for (size_t i = state_stack_.size(); i--;) { for (auto& entry : state_stack_)
if (state_stack_[i].type == StateEntry::PairedType::kClip) { AppendRestore(cc_list_, entry.saved_count);
AppendRestore(cc_list_, 1);
} else {
DCHECK_EQ(StateEntry::PairedType::kEffect, state_stack_[i].type);
AppendRestore(cc_list_, 2);
}
}
} }
void ConversionContext::SwitchToClip(const ClipPaintPropertyNode* target_clip) { void ConversionContext::SwitchToClip(const ClipPaintPropertyNode* target_clip) {
...@@ -172,11 +167,11 @@ void ConversionContext::SwitchToClip(const ClipPaintPropertyNode* target_clip) { ...@@ -172,11 +167,11 @@ void ConversionContext::SwitchToClip(const ClipPaintPropertyNode* target_clip) {
state_stack_.back().type != StateEntry::PairedType::kClip) state_stack_.back().type != StateEntry::PairedType::kClip)
break; break;
StateEntry& previous_state = state_stack_.back(); StateEntry& previous_state = state_stack_.back();
AppendRestore(cc_list_, previous_state.saved_count);
current_transform_ = previous_state.transform; current_transform_ = previous_state.transform;
current_clip_ = previous_state.clip; current_clip_ = previous_state.clip;
DCHECK_EQ(previous_state.effect, current_effect_); DCHECK_EQ(previous_state.effect, current_effect_);
state_stack_.pop_back(); state_stack_.pop_back();
AppendRestore(cc_list_, 1);
} }
// Step 2: Collect all clips between the target clip and the current clip. // Step 2: Collect all clips between the target clip and the current clip.
...@@ -220,7 +215,7 @@ void ConversionContext::SwitchToClip(const ClipPaintPropertyNode* target_clip) { ...@@ -220,7 +215,7 @@ void ConversionContext::SwitchToClip(const ClipPaintPropertyNode* target_clip) {
cc_list_.EndPaintOfPairedBegin(); cc_list_.EndPaintOfPairedBegin();
// Step 3b: Adjust state and push previous state onto clip stack. // Step 3b: Adjust state and push previous state onto clip stack.
state_stack_.emplace_back(StateEntry{StateEntry::PairedType::kClip, state_stack_.emplace_back(StateEntry{StateEntry::PairedType::kClip, 1,
current_transform_, current_clip_, current_transform_, current_clip_,
current_effect_}); current_effect_});
current_transform_ = target_transform; current_transform_ = target_transform;
...@@ -248,12 +243,7 @@ void ConversionContext::SwitchToEffect( ...@@ -248,12 +243,7 @@ void ConversionContext::SwitchToEffect(
break; break;
StateEntry& previous_state = state_stack_.back(); StateEntry& previous_state = state_stack_.back();
if (previous_state.type == StateEntry::PairedType::kClip) { AppendRestore(cc_list_, previous_state.saved_count);
AppendRestore(cc_list_, 1);
} else {
DCHECK_EQ(StateEntry::PairedType::kEffect, previous_state.type);
AppendRestore(cc_list_, 2);
}
current_transform_ = previous_state.transform; current_transform_ = previous_state.transform;
current_clip_ = previous_state.clip; current_clip_ = previous_state.clip;
current_effect_ = previous_state.effect; current_effect_ = previous_state.effect;
...@@ -295,49 +285,70 @@ void ConversionContext::SwitchToEffect( ...@@ -295,49 +285,70 @@ void ConversionContext::SwitchToEffect(
// Step 3b: Apply non-spatial effects first, adjust CTM, then apply spatial // Step 3b: Apply non-spatial effects first, adjust CTM, then apply spatial
// effects. Strictly speaking the CTM shall be appled first, it is done // effects. Strictly speaking the CTM shall be appled first, it is done
// in this particular order only to save one SaveOp. // in this particular order only to save one SaveOp.
// TODO(trchen): Omit one of the SaveLayerOp if no-op.
cc_list_.StartPaint(); cc_list_.StartPaint();
cc::PaintFlags flags; cc::PaintFlags flags;
flags.setBlendMode(sub_effect->BlendMode()); int saved_count = 0;
// TODO(ajuma): This should really be rounding instead of flooring the
// alpha value, but that breaks slimming paint reftests. auto save_layer_once = [this, &flags, &saved_count]() {
flags.setAlpha( if (!saved_count) {
static_cast<uint8_t>(gfx::ToFlooredInt(255 * sub_effect->Opacity()))); saved_count = 1;
flags.setColorFilter(GraphicsContext::WebCoreColorFilterToSkiaColorFilter( cc_list_.push<cc::SaveLayerOp>(nullptr, &flags);
sub_effect->GetColorFilter())); }
cc_list_.push<cc::SaveLayerOp>(nullptr, &flags); };
if (sub_effect->BlendMode() != SkBlendMode::kSrcOver ||
sub_effect->Opacity() != 1.f ||
sub_effect->GetColorFilter() != kColorFilterNone) {
flags.setBlendMode(sub_effect->BlendMode());
// TODO(ajuma): This should really be rounding instead of flooring the
// alpha value, but that breaks slimming paint reftests.
flags.setAlpha(
static_cast<uint8_t>(gfx::ToFlooredInt(255 * sub_effect->Opacity())));
flags.setColorFilter(GraphicsContext::WebCoreColorFilterToSkiaColorFilter(
sub_effect->GetColorFilter()));
save_layer_once();
}
const TransformPaintPropertyNode* target_transform = const TransformPaintPropertyNode* target_transform =
sub_effect->LocalTransformSpace(); sub_effect->LocalTransformSpace();
if (current_transform_ != target_transform) { if (current_transform_ != target_transform) {
save_layer_once();
cc_list_.push<cc::ConcatOp>( cc_list_.push<cc::ConcatOp>(
static_cast<SkMatrix>(TransformationMatrix::ToSkMatrix44( static_cast<SkMatrix>(TransformationMatrix::ToSkMatrix44(
GeometryMapper::SourceToDestinationProjection( GeometryMapper::SourceToDestinationProjection(
target_transform, current_transform_)))); target_transform, current_transform_))));
} }
FloatPoint filter_origin = sub_effect->PaintOffset(); if (sub_effect->Filter().IsEmpty()) {
if (filter_origin != FloatPoint()) save_layer_once();
cc_list_.push<cc::TranslateOp>(filter_origin.X(), filter_origin.Y()); } else {
// The size parameter is only used to computed the origin of zoom FloatPoint filter_origin = sub_effect->PaintOffset();
// operation, which we never generate. if (filter_origin != FloatPoint()) {
gfx::SizeF empty; save_layer_once();
cc::PaintFlags filter_flags; cc_list_.push<cc::TranslateOp>(filter_origin.X(), filter_origin.Y());
filter_flags.setImageFilter(cc::RenderSurfaceFilters::BuildImageFilter( }
sub_effect->Filter().AsCcFilterOperations(), empty)); // The size parameter is only used to computed the origin of zoom
cc_list_.push<cc::SaveLayerOp>(nullptr, &filter_flags); // operation, which we never generate.
if (filter_origin != FloatPoint()) gfx::SizeF empty;
cc_list_.push<cc::TranslateOp>(-filter_origin.X(), -filter_origin.Y()); cc::PaintFlags filter_flags;
filter_flags.setImageFilter(cc::RenderSurfaceFilters::BuildImageFilter(
sub_effect->Filter().AsCcFilterOperations(), empty));
cc_list_.push<cc::SaveLayerOp>(nullptr, &filter_flags);
if (filter_origin != FloatPoint())
cc_list_.push<cc::TranslateOp>(-filter_origin.X(), -filter_origin.Y());
saved_count++;
}
DCHECK(saved_count);
cc_list_.EndPaintOfPairedBegin(); cc_list_.EndPaintOfPairedBegin();
// Step 3c: Adjust state and push previous state onto effect stack. // Step 3c: Adjust state and push previous state onto effect stack.
// TODO(trchen): Change input clip to expansion hint once implemented. // TODO(trchen): Change input clip to expansion hint once implemented.
const ClipPaintPropertyNode* input_clip = current_clip_; const ClipPaintPropertyNode* input_clip = current_clip_;
state_stack_.emplace_back(StateEntry{StateEntry::PairedType::kEffect, state_stack_.emplace_back(StateEntry{StateEntry::PairedType::kEffect,
current_transform_, current_clip_, saved_count, current_transform_,
current_effect_}); current_clip_, current_effect_});
current_transform_ = target_transform; current_transform_ = target_transform;
current_clip_ = input_clip; current_clip_ = input_clip;
current_effect_ = sub_effect; current_effect_ = sub_effect;
......
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