Skip to content

Commit

Permalink
Move checkerboard unit tests onto DisplayList mechanism (flutter#41951)
Browse files Browse the repository at this point in the history
Part of an ongoing set of efforts to address flutter/flutter#106448

Move the checkerboard layer unit tests onto the DisplayList version of the paint contexts and fix some bugs in the reusability of the DisplayListBuilder that this migration uncovered.
  • Loading branch information
flar authored May 25, 2023
1 parent f32002a commit ff04d2f
Show file tree
Hide file tree
Showing 20 changed files with 444 additions and 135 deletions.
2 changes: 1 addition & 1 deletion display_list/benchmarking/dl_complexity_helper.h
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ class ComplexityCalculatorHelper

void setAntiAlias(bool aa) override { current_paint_.setAntiAlias(aa); }

void setStyle(DlDrawStyle style) override {
void setDrawStyle(DlDrawStyle style) override {
current_paint_.setDrawStyle(style);
}

Expand Down
235 changes: 235 additions & 0 deletions display_list/display_list_unittests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ DlOpReceiver& DisplayListBuilderTestingAccessor(DisplayListBuilder& builder) {
return builder.asReceiver();
}

DlPaint DisplayListBuilderTestingAttributes(DisplayListBuilder& builder) {
return builder.CurrentAttributes();
}

namespace testing {

static std::vector<testing::DisplayListInvocationGroup> allGroups =
Expand Down Expand Up @@ -87,11 +91,49 @@ class DisplayListTestBase : public BaseT {
return dl;
}

static void check_defaults(
DisplayListBuilder& builder,
const SkRect& cull_rect = DisplayListBuilder::kMaxCullRect) {
DlPaint builder_paint = DisplayListBuilderTestingAttributes(builder);
DlPaint defaults;

EXPECT_EQ(builder_paint.isAntiAlias(), defaults.isAntiAlias());
EXPECT_EQ(builder_paint.isDither(), defaults.isDither());
EXPECT_EQ(builder_paint.isInvertColors(), defaults.isInvertColors());
EXPECT_EQ(builder_paint.getColor(), defaults.getColor());
EXPECT_EQ(builder_paint.getBlendMode(), defaults.getBlendMode());
EXPECT_EQ(builder_paint.getDrawStyle(), defaults.getDrawStyle());
EXPECT_EQ(builder_paint.getStrokeWidth(), defaults.getStrokeWidth());
EXPECT_EQ(builder_paint.getStrokeMiter(), defaults.getStrokeMiter());
EXPECT_EQ(builder_paint.getStrokeCap(), defaults.getStrokeCap());
EXPECT_EQ(builder_paint.getStrokeJoin(), defaults.getStrokeJoin());
EXPECT_EQ(builder_paint.getColorSource(), defaults.getColorSource());
EXPECT_EQ(builder_paint.getColorFilter(), defaults.getColorFilter());
EXPECT_EQ(builder_paint.getImageFilter(), defaults.getImageFilter());
EXPECT_EQ(builder_paint.getMaskFilter(), defaults.getMaskFilter());
EXPECT_EQ(builder_paint.getPathEffect(), defaults.getPathEffect());
EXPECT_EQ(builder_paint, defaults);
EXPECT_TRUE(builder_paint.isDefault());

EXPECT_EQ(builder.GetTransform(), SkMatrix());
EXPECT_EQ(builder.GetTransformFullPerspective(), SkM44());

EXPECT_EQ(builder.GetLocalClipBounds(), cull_rect);
EXPECT_EQ(builder.GetDestinationClipBounds(), cull_rect);

EXPECT_EQ(builder.GetSaveCount(), 1);
}

private:
FML_DISALLOW_COPY_AND_ASSIGN(DisplayListTestBase);
};
using DisplayListTest = DisplayListTestBase<::testing::Test>;

TEST_F(DisplayListTest, Defaults) {
DisplayListBuilder builder;
check_defaults(builder);
}

TEST_F(DisplayListTest, EmptyBuild) {
DisplayListBuilder builder;
auto dl = builder.Build();
Expand All @@ -117,6 +159,199 @@ TEST_F(DisplayListTest, BuilderCanBeReused) {
ASSERT_TRUE(dl->Equals(dl2));
}

TEST_F(DisplayListTest, SaveRestoreRestoresTransform) {
SkRect cull_rect = SkRect::MakeLTRB(-10.0f, -10.0f, 500.0f, 500.0f);
DisplayListBuilder builder(cull_rect);

builder.Save();
builder.Translate(10.0f, 10.0f);
builder.Restore();
check_defaults(builder, cull_rect);

builder.Save();
builder.Scale(10.0f, 10.0f);
builder.Restore();
check_defaults(builder, cull_rect);

builder.Save();
builder.Skew(0.1f, 0.1f);
builder.Restore();
check_defaults(builder, cull_rect);

builder.Save();
builder.Rotate(45.0f);
builder.Restore();
check_defaults(builder, cull_rect);

builder.Save();
builder.Transform(SkMatrix::Scale(10.0f, 10.0f));
builder.Restore();
check_defaults(builder, cull_rect);

builder.Save();
builder.Transform2DAffine(1.0f, 0.0f, 12.0f, //
0.0f, 1.0f, 35.0f);
builder.Restore();
check_defaults(builder, cull_rect);

builder.Save();
builder.Transform(SkM44(SkMatrix::Scale(10.0f, 10.0f)));
builder.Restore();
check_defaults(builder, cull_rect);

builder.Save();
builder.TransformFullPerspective(1.0f, 0.0f, 0.0f, 12.0f, //
0.0f, 1.0f, 0.0f, 35.0f, //
0.0f, 0.0f, 1.0f, 5.0f, //
0.0f, 0.0f, 0.0f, 1.0f);
builder.Restore();
check_defaults(builder, cull_rect);
}

TEST_F(DisplayListTest, BuildRestoresTransform) {
SkRect cull_rect = SkRect::MakeLTRB(-10.0f, -10.0f, 500.0f, 500.0f);
DisplayListBuilder builder(cull_rect);

builder.Translate(10.0f, 10.0f);
builder.Build();
check_defaults(builder, cull_rect);

builder.Scale(10.0f, 10.0f);
builder.Build();
check_defaults(builder, cull_rect);

builder.Skew(0.1f, 0.1f);
builder.Build();
check_defaults(builder, cull_rect);

builder.Rotate(45.0f);
builder.Build();
check_defaults(builder, cull_rect);

builder.Transform(SkMatrix::Scale(10.0f, 10.0f));
builder.Build();
check_defaults(builder, cull_rect);

builder.Transform2DAffine(1.0f, 0.0f, 12.0f, //
0.0f, 1.0f, 35.0f);
builder.Build();
check_defaults(builder, cull_rect);

builder.Transform(SkM44(SkMatrix::Scale(10.0f, 10.0f)));
builder.Build();
check_defaults(builder, cull_rect);

builder.TransformFullPerspective(1.0f, 0.0f, 0.0f, 12.0f, //
0.0f, 1.0f, 0.0f, 35.0f, //
0.0f, 0.0f, 1.0f, 5.0f, //
0.0f, 0.0f, 0.0f, 1.0f);
builder.Build();
check_defaults(builder, cull_rect);
}

TEST_F(DisplayListTest, SaveRestoreRestoresClip) {
SkRect cull_rect = SkRect::MakeLTRB(-10.0f, -10.0f, 500.0f, 500.0f);
DisplayListBuilder builder(cull_rect);

builder.Save();
builder.ClipRect({0.0f, 0.0f, 10.0f, 10.0f});
builder.Restore();
check_defaults(builder, cull_rect);

builder.Save();
builder.ClipRRect(SkRRect::MakeRectXY({0.0f, 0.0f, 5.0f, 5.0f}, 2.0f, 2.0f));
builder.Restore();
check_defaults(builder, cull_rect);

builder.Save();
builder.ClipPath(SkPath().addOval({0.0f, 0.0f, 10.0f, 10.0f}));
builder.Restore();
check_defaults(builder, cull_rect);
}

TEST_F(DisplayListTest, BuildRestoresClip) {
SkRect cull_rect = SkRect::MakeLTRB(-10.0f, -10.0f, 500.0f, 500.0f);
DisplayListBuilder builder(cull_rect);

builder.ClipRect({0.0f, 0.0f, 10.0f, 10.0f});
builder.Build();
check_defaults(builder, cull_rect);

builder.ClipRRect(SkRRect::MakeRectXY({0.0f, 0.0f, 5.0f, 5.0f}, 2.0f, 2.0f));
builder.Build();
check_defaults(builder, cull_rect);

builder.ClipPath(SkPath().addOval({0.0f, 0.0f, 10.0f, 10.0f}));
builder.Build();
check_defaults(builder, cull_rect);
}

TEST_F(DisplayListTest, BuildRestoresAttributes) {
SkRect cull_rect = SkRect::MakeLTRB(-10.0f, -10.0f, 500.0f, 500.0f);
DisplayListBuilder builder(cull_rect);
DlOpReceiver& receiver = ToReceiver(builder);

receiver.setAntiAlias(true);
builder.Build();
check_defaults(builder, cull_rect);

receiver.setDither(true);
builder.Build();
check_defaults(builder, cull_rect);

receiver.setInvertColors(true);
builder.Build();
check_defaults(builder, cull_rect);

receiver.setColor(DlColor::kRed());
builder.Build();
check_defaults(builder, cull_rect);

receiver.setBlendMode(DlBlendMode::kColorBurn);
builder.Build();
check_defaults(builder, cull_rect);

receiver.setDrawStyle(DlDrawStyle::kStrokeAndFill);
builder.Build();
check_defaults(builder, cull_rect);

receiver.setStrokeWidth(300.0f);
builder.Build();
check_defaults(builder, cull_rect);

receiver.setStrokeMiter(300.0f);
builder.Build();
check_defaults(builder, cull_rect);

receiver.setStrokeCap(DlStrokeCap::kRound);
builder.Build();
check_defaults(builder, cull_rect);

receiver.setStrokeJoin(DlStrokeJoin::kRound);
builder.Build();
check_defaults(builder, cull_rect);

receiver.setColorSource(&kTestSource1);
builder.Build();
check_defaults(builder, cull_rect);

receiver.setColorFilter(&kTestMatrixColorFilter1);
builder.Build();
check_defaults(builder, cull_rect);

receiver.setImageFilter(&kTestBlurImageFilter1);
builder.Build();
check_defaults(builder, cull_rect);

receiver.setMaskFilter(&kTestMaskFilter1);
builder.Build();
check_defaults(builder, cull_rect);

receiver.setPathEffect(kTestPathEffect1.get());
builder.Build();
check_defaults(builder, cull_rect);
}

TEST_F(DisplayListTest, BuilderBoundsTransformComparedToSkia) {
const SkRect frame_rect = SkRect::MakeLTRB(10, 10, 100, 100);
DisplayListBuilder builder(frame_rect);
Expand Down
15 changes: 11 additions & 4 deletions display_list/dl_builder.cc
Original file line number Diff line number Diff line change
Expand Up @@ -65,15 +65,22 @@ sk_sp<DisplayList> DisplayListBuilder::Build() {
while (layer_stack_.size() > 1) {
restore();
}

size_t bytes = used_;
int count = render_op_count_;
size_t nested_bytes = nested_bytes_;
int nested_count = nested_op_count_;
bool compatible = layer_stack_.back().is_group_opacity_compatible();
bool is_safe = is_ui_thread_safe_;

used_ = allocated_ = render_op_count_ = op_index_ = 0;
nested_bytes_ = nested_op_count_ = 0;
storage_.realloc(bytes);
bool compatible = layer_stack_.back().is_group_opacity_compatible();
bool is_safe = is_ui_thread_safe_;
layer_stack_.pop_back();
layer_stack_.emplace_back();
tracker_.reset();
current_ = DlPaint();

return sk_sp<DisplayList>(
new DisplayList(std::move(storage_), bytes, count, nested_bytes,
nested_count, bounds(), compatible, is_safe, rtree()));
Expand Down Expand Up @@ -129,7 +136,7 @@ void DisplayListBuilder::onSetStrokeJoin(DlStrokeJoin join) {
current_.setStrokeJoin(join);
Push<SetStrokeJoinOp>(0, 0, join);
}
void DisplayListBuilder::onSetStyle(DlDrawStyle style) {
void DisplayListBuilder::onSetDrawStyle(DlDrawStyle style) {
current_.setDrawStyle(style);
Push<SetStyleOp>(0, 0, style);
}
Expand Down Expand Up @@ -346,7 +353,7 @@ void DisplayListBuilder::SetAttributesFromPaint(
setBlendMode(paint.getBlendMode());
}
if (flags.applies_style()) {
setStyle(paint.getDrawStyle());
setDrawStyle(paint.getDrawStyle());
}
if (flags.is_stroked(paint.getDrawStyle())) {
setStrokeWidth(paint.getStrokeWidth());
Expand Down
10 changes: 7 additions & 3 deletions display_list/dl_builder.h
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,8 @@ class DisplayListBuilder final : public virtual DlCanvas,
DisplayListBuilder& builder);
friend DlOpReceiver& DisplayListBuilderTestingAccessor(
DisplayListBuilder& builder);
friend DlPaint DisplayListBuilderTestingAttributes(
DisplayListBuilder& builder);

void SetAttributesFromPaint(const DlPaint& paint,
const DisplayListAttributeFlags flags);
Expand Down Expand Up @@ -282,9 +284,9 @@ class DisplayListBuilder final : public virtual DlCanvas,
}
}
// |DlOpReceiver|
void setStyle(DlDrawStyle style) override {
void setDrawStyle(DlDrawStyle style) override {
if (current_.getDrawStyle() != style) {
onSetStyle(style);
onSetDrawStyle(style);
}
}
// |DlOpReceiver|
Expand Down Expand Up @@ -342,6 +344,8 @@ class DisplayListBuilder final : public virtual DlCanvas,
}
}

DlPaint CurrentAttributes() const { return current_; }

// |DlOpReceiver|
void save() override { Save(); }
// Only the |renders_with_attributes()| option will be accepted here. Any
Expand Down Expand Up @@ -654,7 +658,7 @@ class DisplayListBuilder final : public virtual DlCanvas,
void onSetInvertColors(bool invert);
void onSetStrokeCap(DlStrokeCap cap);
void onSetStrokeJoin(DlStrokeJoin join);
void onSetStyle(DlDrawStyle style);
void onSetDrawStyle(DlDrawStyle style);
void onSetStrokeWidth(SkScalar width);
void onSetStrokeMiter(SkScalar limit);
void onSetColor(DlColor color);
Expand Down
2 changes: 1 addition & 1 deletion display_list/dl_op_receiver.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ class DlOpReceiver {
// attributes is not affected by |save| and |restore|.
virtual void setAntiAlias(bool aa) = 0;
virtual void setDither(bool dither) = 0;
virtual void setStyle(DlDrawStyle style) = 0;
virtual void setDrawStyle(DlDrawStyle style) = 0;
virtual void setColor(DlColor color) = 0;
virtual void setStrokeWidth(float width) = 0;
virtual void setStrokeMiter(float limit) = 0;
Expand Down
4 changes: 3 additions & 1 deletion display_list/dl_op_records.h
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,9 @@ struct SetStyleOp final : DLOp {

const DlDrawStyle style;

void dispatch(DispatchContext& ctx) const { ctx.receiver.setStyle(style); }
void dispatch(DispatchContext& ctx) const {
ctx.receiver.setDrawStyle(style);
}
};
// 4 byte header + 4 byte payload packs into minimum 8 bytes
struct SetStrokeWidthOp final : DLOp {
Expand Down
3 changes: 2 additions & 1 deletion display_list/dl_paint.cc
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ bool DlPaint::operator==(DlPaint const& other) const {
Equals(colorSource_, other.colorSource_) && //
Equals(colorFilter_, other.colorFilter_) && //
Equals(imageFilter_, other.imageFilter_) && //
Equals(maskFilter_, other.maskFilter_);
Equals(maskFilter_, other.maskFilter_) && //
Equals(pathEffect_, other.pathEffect_);
}

const DlPaint DlPaint::kDefault;
Expand Down
Loading

0 comments on commit ff04d2f

Please sign in to comment.