in display_list/display_list_canvas_unittests.cc [711:895]
static void RenderWithSaveRestore(const TestParameters& testP,
const RenderEnvironment& env,
const BoundsTolerance& tolerance) {
SkRect clip = SkRect::MakeXYWH(RenderCenterX - 1, RenderCenterY - 1, 2, 2);
SkRect rect = SkRect::MakeXYWH(RenderCenterX, RenderCenterY, 10, 10);
SkColor alpha_layer_color = SkColorSetARGB(0x7f, 0x00, 0xff, 0xff);
SkColor default_color = SkPaint().getColor();
CvRenderer cv_restore = [=](SkCanvas* cv, const SkPaint& p) {
// Draw another primitive to disable peephole optimizations
cv->drawRect(RenderBounds.makeOffset(500, 500), p);
cv->restore();
};
DlRenderer dl_restore = [=](DisplayListBuilder& b) {
// Draw another primitive to disable peephole optimizations
b.drawRect(RenderBounds.makeOffset(500, 500));
b.restore();
};
SkRect layer_bounds = RenderBounds.makeInset(15, 15);
RenderWith(testP, env, tolerance,
CaseParameters(
"With prior save/clip/restore",
[=](SkCanvas* cv, SkPaint& p) {
cv->save();
cv->clipRect(clip, SkClipOp::kIntersect, false);
SkPaint p2;
cv->drawRect(rect, p2);
p2.setBlendMode(SkBlendMode::kClear);
cv->drawRect(rect, p2);
cv->restore();
},
[=](DisplayListBuilder& b) {
b.save();
b.clipRect(clip, SkClipOp::kIntersect, false);
b.drawRect(rect);
b.setBlendMode(SkBlendMode::kClear);
b.drawRect(rect);
b.setBlendMode(SkBlendMode::kSrcOver);
b.restore();
}));
RenderWith(testP, env, tolerance,
CaseParameters(
"saveLayer no paint, no bounds",
[=](SkCanvas* cv, SkPaint& p) { //
cv->saveLayer(nullptr, nullptr);
},
[=](DisplayListBuilder& b) { //
b.saveLayer(nullptr, false);
})
.with_restore(cv_restore, dl_restore, false));
RenderWith(testP, env, tolerance,
CaseParameters(
"saveLayer no paint, with bounds",
[=](SkCanvas* cv, SkPaint& p) { //
cv->saveLayer(layer_bounds, nullptr);
},
[=](DisplayListBuilder& b) { //
b.saveLayer(&layer_bounds, false);
})
.with_restore(cv_restore, dl_restore, true));
RenderWith(testP, env, tolerance,
CaseParameters(
"saveLayer with alpha, no bounds",
[=](SkCanvas* cv, SkPaint& p) {
SkPaint save_p;
save_p.setColor(alpha_layer_color);
cv->saveLayer(nullptr, &save_p);
},
[=](DisplayListBuilder& b) {
b.setColor(alpha_layer_color);
b.saveLayer(nullptr, true);
b.setColor(default_color);
})
.with_restore(cv_restore, dl_restore, true));
RenderWith(testP, env, tolerance,
CaseParameters(
"saveLayer with alpha and bounds",
[=](SkCanvas* cv, SkPaint& p) {
SkPaint save_p;
save_p.setColor(alpha_layer_color);
cv->saveLayer(layer_bounds, &save_p);
},
[=](DisplayListBuilder& b) {
b.setColor(alpha_layer_color);
b.saveLayer(&layer_bounds, true);
b.setColor(default_color);
})
.with_restore(cv_restore, dl_restore, true));
{
// clang-format off
constexpr float rotate_alpha_color_matrix[20] = {
0, 1, 0, 0 , 0,
0, 0, 1, 0 , 0,
1, 0, 0, 0 , 0,
0, 0, 0, 0.5, 0,
};
// clang-format on
sk_sp<SkColorFilter> filter =
SkColorFilters::Matrix(rotate_alpha_color_matrix);
{
RenderWith(testP, env, tolerance,
CaseParameters(
"saveLayer ColorFilter, no bounds",
[=](SkCanvas* cv, SkPaint& p) {
SkPaint save_p;
save_p.setColorFilter(filter);
cv->saveLayer(nullptr, &save_p);
p.setStrokeWidth(5.0);
},
[=](DisplayListBuilder& b) {
b.setColorFilter(filter);
b.saveLayer(nullptr, true);
b.setColorFilter(nullptr);
b.setStrokeWidth(5.0);
})
.with_restore(cv_restore, dl_restore, true));
}
EXPECT_TRUE(filter->unique())
<< "saveLayer ColorFilter, no bounds Cleanup";
{
RenderWith(testP, env, tolerance,
CaseParameters(
"saveLayer ColorFilter and bounds",
[=](SkCanvas* cv, SkPaint& p) {
SkPaint save_p;
save_p.setColorFilter(filter);
cv->saveLayer(RenderBounds, &save_p);
p.setStrokeWidth(5.0);
},
[=](DisplayListBuilder& b) {
b.setColorFilter(filter);
b.saveLayer(&RenderBounds, true);
b.setColorFilter(nullptr);
b.setStrokeWidth(5.0);
})
.with_restore(cv_restore, dl_restore, true));
}
EXPECT_TRUE(filter->unique())
<< "saveLayer ColorFilter and bounds Cleanup";
}
{
sk_sp<SkImageFilter> filter = SkImageFilters::Arithmetic(
0.1, 0.1, 0.1, 0.25, true, nullptr, nullptr);
{
RenderWith(testP, env, tolerance,
CaseParameters(
"saveLayer ImageFilter, no bounds",
[=](SkCanvas* cv, SkPaint& p) {
SkPaint save_p;
save_p.setImageFilter(filter);
cv->saveLayer(nullptr, &save_p);
p.setStrokeWidth(5.0);
},
[=](DisplayListBuilder& b) {
b.setImageFilter(filter);
b.saveLayer(nullptr, true);
b.setImageFilter(nullptr);
b.setStrokeWidth(5.0);
})
.with_restore(cv_restore, dl_restore, true));
}
EXPECT_TRUE(filter->unique())
<< "saveLayer ImageFilter, no bounds Cleanup";
{
RenderWith(testP, env, tolerance,
CaseParameters(
"saveLayer ImageFilter and bounds",
[=](SkCanvas* cv, SkPaint& p) {
SkPaint save_p;
save_p.setImageFilter(filter);
cv->saveLayer(RenderBounds, &save_p);
p.setStrokeWidth(5.0);
},
[=](DisplayListBuilder& b) {
b.setImageFilter(filter);
b.saveLayer(&RenderBounds, true);
b.setImageFilter(nullptr);
b.setStrokeWidth(5.0);
})
.with_restore(cv_restore, dl_restore, true));
}
EXPECT_TRUE(filter->unique())
<< "saveLayer ImageFilter and bounds Cleanup";
}
}