Skip to content

Commit 1ef3f75

Browse files
authored
Verbose display list comparisons (flutter#32737)
1 parent 47af169 commit 1ef3f75

11 files changed

+1105
-29
lines changed

display_list/display_list.cc

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -196,16 +196,19 @@ void DisplayList::RenderTo(SkCanvas* canvas, SkScalar opacity) const {
196196
Dispatch(dispatcher);
197197
}
198198

199-
bool DisplayList::Equals(const DisplayList& other) const {
200-
if (byte_count_ != other.byte_count_ || op_count_ != other.op_count_) {
199+
bool DisplayList::Equals(const DisplayList* other) const {
200+
if (this == other) {
201+
return true;
202+
}
203+
if (byte_count_ != other->byte_count_ || op_count_ != other->op_count_) {
201204
return false;
202205
}
203206
uint8_t* ptr = storage_.get();
204-
uint8_t* o_ptr = other.storage_.get();
207+
uint8_t* o_ptr = other->storage_.get();
205208
if (ptr == o_ptr) {
206209
return true;
207210
}
208-
return CompareOps(ptr, ptr + byte_count_, o_ptr, o_ptr + other.byte_count_);
211+
return CompareOps(ptr, ptr + byte_count_, o_ptr, o_ptr + other->byte_count_);
209212
}
210213

211214
} // namespace flutter

display_list/display_list.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,11 @@ class DisplayList : public SkRefCnt {
254254
return bounds_;
255255
}
256256

257-
bool Equals(const DisplayList& other) const;
257+
bool Equals(const DisplayList* other) const;
258+
bool Equals(const DisplayList& other) const { return Equals(&other); }
259+
bool Equals(sk_sp<const DisplayList> other) const {
260+
return Equals(other.get());
261+
}
258262

259263
bool can_apply_group_opacity() { return can_apply_group_opacity_; }
260264

display_list/display_list_builder.cc

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -474,6 +474,20 @@ void DisplayListBuilder::transformFullPerspective(
474474
void DisplayListBuilder::transformReset() {
475475
Push<TransformResetOp>(0, 0);
476476
}
477+
void DisplayListBuilder::transform(const SkMatrix* matrix) {
478+
if (matrix != nullptr) {
479+
transform(SkM44(*matrix));
480+
}
481+
}
482+
void DisplayListBuilder::transform(const SkM44* m44) {
483+
if (m44 != nullptr) {
484+
transformFullPerspective(
485+
m44->rc(0, 0), m44->rc(0, 1), m44->rc(0, 2), m44->rc(0, 3),
486+
m44->rc(1, 0), m44->rc(1, 1), m44->rc(1, 2), m44->rc(1, 3),
487+
m44->rc(2, 0), m44->rc(2, 1), m44->rc(2, 2), m44->rc(2, 3),
488+
m44->rc(3, 0), m44->rc(3, 1), m44->rc(3, 2), m44->rc(3, 3));
489+
}
490+
}
477491

478492
void DisplayListBuilder::clipRect(const SkRect& rect,
479493
SkClipOp clip_op,

display_list/display_list_builder.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,10 @@ class DisplayListBuilder final : public virtual Dispatcher,
182182
SkScalar mwx, SkScalar mwy, SkScalar mwz, SkScalar mwt) override;
183183
// clang-format on
184184
void transformReset() override;
185+
void transform(const SkMatrix* matrix);
186+
void transform(const SkM44* matrix44);
187+
void transform(const SkMatrix& matrix) { transform(&matrix); }
188+
void transform(const SkM44& matrix44) { transform(&matrix44); }
185189

186190
void clipRect(const SkRect& rect, SkClipOp clip_op, bool is_aa) override;
187191
void clipRRect(const SkRRect& rrect, SkClipOp clip_op, bool is_aa) override;

display_list/display_list_canvas_recorder.cc

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,17 +21,12 @@ sk_sp<DisplayList> DisplayListCanvasRecorder::Build() {
2121

2222
// clang-format off
2323
void DisplayListCanvasRecorder::didConcat44(const SkM44& m44) {
24-
// transform4x4 takes a full 4x4 transform in row major order
25-
builder_->transformFullPerspective(
26-
m44.rc(0, 0), m44.rc(0, 1), m44.rc(0, 2), m44.rc(0, 3),
27-
m44.rc(1, 0), m44.rc(1, 1), m44.rc(1, 2), m44.rc(1, 3),
28-
m44.rc(2, 0), m44.rc(2, 1), m44.rc(2, 2), m44.rc(2, 3),
29-
m44.rc(3, 0), m44.rc(3, 1), m44.rc(3, 2), m44.rc(3, 3));
24+
builder_->transform(m44);
3025
}
3126
// clang-format on
3227
void DisplayListCanvasRecorder::didSetM44(const SkM44& matrix) {
3328
builder_->transformReset();
34-
didConcat44(matrix);
29+
builder_->transform(matrix);
3530
}
3631
void DisplayListCanvasRecorder::didTranslate(SkScalar tx, SkScalar ty) {
3732
builder_->translate(tx, ty);

display_list/display_list_unittests.cc

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include "flutter/display_list/display_list_canvas_recorder.h"
88
#include "flutter/display_list/display_list_utils.h"
99
#include "flutter/fml/math.h"
10+
#include "flutter/testing/display_list_testing.h"
1011
#include "flutter/testing/testing.h"
1112
#include "third_party/skia/include/core/SkPictureRecorder.h"
1213
#include "third_party/skia/include/core/SkSurface.h"
@@ -860,10 +861,10 @@ TEST(DisplayList, SingleOpDisplayListsNotEqualEmpty) {
860861
auto desc =
861862
group.op_name + "(variant " + std::to_string(i + 1) + " != empty)";
862863
if (group.variants[i].is_empty()) {
863-
ASSERT_TRUE(dl->Equals(*empty)) << desc;
864+
ASSERT_TRUE(DisplayListsEQ_Verbose(dl, empty));
864865
ASSERT_TRUE(empty->Equals(*dl)) << desc;
865866
} else {
866-
ASSERT_FALSE(dl->Equals(*empty)) << desc;
867+
ASSERT_TRUE(DisplayListsNE_Verbose(dl, empty));
867868
ASSERT_FALSE(empty->Equals(*dl)) << desc;
868869
}
869870
}

flow/layers/opacity_layer_unittests.cc

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include "flutter/flow/testing/layer_test.h"
1010
#include "flutter/flow/testing/mock_layer.h"
1111
#include "flutter/fml/macros.h"
12+
#include "flutter/testing/display_list_testing.h"
1213
#include "flutter/testing/mock_canvas.h"
1314

1415
namespace flutter {
@@ -302,23 +303,24 @@ TEST_F(OpacityLayerTest, HalfTransparent) {
302303
SkRect opacity_bounds;
303304
expected_layer_bounds.makeOffset(-layer_offset.fX, -layer_offset.fY)
304305
.roundOut(&opacity_bounds);
305-
auto expected_draw_calls = std::vector(
306-
{MockCanvas::DrawCall{0, MockCanvas::SaveData{1}},
307-
MockCanvas::DrawCall{
308-
1, MockCanvas::ConcatMatrixData{SkM44(layer_transform)}},
306+
307+
auto expected_builder = DisplayListBuilder();
308+
expected_builder.save();
309+
expected_builder.translate(layer_offset.fX, layer_offset.fY);
309310
#ifndef SUPPORT_FRACTIONAL_TRANSLATION
310-
MockCanvas::DrawCall{
311-
1, MockCanvas::SetMatrixData{SkM44(integral_layer_transform)}},
311+
expected_builder.transformReset();
312+
expected_builder.transform(SkM44(integral_layer_transform));
312313
#endif
313-
MockCanvas::DrawCall{
314-
1, MockCanvas::SaveLayerData{opacity_bounds, opacity_paint, nullptr,
315-
2}},
316-
MockCanvas::DrawCall{2,
317-
MockCanvas::DrawPathData{child_path, child_paint}},
318-
MockCanvas::DrawCall{2, MockCanvas::RestoreData{1}},
319-
MockCanvas::DrawCall{1, MockCanvas::RestoreData{0}}});
320-
layer->Paint(paint_context());
321-
EXPECT_EQ(mock_canvas().draw_calls(), expected_draw_calls);
314+
expected_builder.setColor(alpha_half << 24);
315+
expected_builder.saveLayer(&opacity_bounds, true);
316+
expected_builder.setColor(SkColors::kGreen.toSkColor());
317+
expected_builder.drawPath(child_path);
318+
expected_builder.restore();
319+
expected_builder.restore();
320+
sk_sp<DisplayList> expected_display_list = expected_builder.Build();
321+
322+
layer->Paint(display_list_paint_context());
323+
EXPECT_TRUE(DisplayListsEQ_Verbose(display_list(), expected_display_list));
322324
}
323325

324326
TEST_F(OpacityLayerTest, Nested) {

flow/testing/layer_test.h

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include "flutter/flow/testing/mock_raster_cache.h"
1515
#include "flutter/fml/macros.h"
1616
#include "flutter/testing/canvas_test.h"
17+
#include "flutter/testing/display_list_testing.h"
1718
#include "flutter/testing/mock_canvas.h"
1819
#include "third_party/skia/include/core/SkCanvas.h"
1920
#include "third_party/skia/include/core/SkImageInfo.h"
@@ -71,6 +72,23 @@ class LayerTestBase : public CanvasTestBase<BaseT> {
7172
.frame_device_pixel_ratio = 1.0f,
7273
// clang-format on
7374
},
75+
display_list_recorder_(kGiantRect),
76+
internal_display_list_canvas_(kGiantRect.width(), kGiantRect.height()),
77+
display_list_paint_context_{
78+
// clang-format off
79+
.internal_nodes_canvas = &internal_display_list_canvas_,
80+
.leaf_nodes_canvas = &display_list_recorder_,
81+
.gr_context = nullptr,
82+
.view_embedder = nullptr,
83+
.raster_time = raster_time_,
84+
.ui_time = ui_time_,
85+
.texture_registry = texture_registry_,
86+
.raster_cache = nullptr,
87+
.checkerboard_offscreen_layers = false,
88+
.frame_device_pixel_ratio = 1.0f,
89+
.leaf_nodes_builder = display_list_recorder_.builder().get(),
90+
// clang-format on
91+
},
7492
check_board_context_{
7593
// clang-format off
7694
.internal_nodes_canvas = TestT::mock_internal_canvas(),
@@ -85,6 +103,7 @@ class LayerTestBase : public CanvasTestBase<BaseT> {
85103
.frame_device_pixel_ratio = 1.0f,
86104
// clang-format on
87105
} {
106+
internal_display_list_canvas_.addCanvas(&display_list_recorder_);
88107
use_null_raster_cache();
89108
}
90109

@@ -141,9 +160,24 @@ class LayerTestBase : public CanvasTestBase<BaseT> {
141160
RasterCache* raster_cache() { return raster_cache_.get(); }
142161
PrerollContext* preroll_context() { return &preroll_context_; }
143162
Layer::PaintContext& paint_context() { return paint_context_; }
163+
Layer::PaintContext& display_list_paint_context() {
164+
return display_list_paint_context_;
165+
}
144166
Layer::PaintContext& check_board_context() { return check_board_context_; }
145167
LayerSnapshotStore& layer_snapshot_store() { return snapshot_store_; }
146168

169+
sk_sp<DisplayList> display_list() {
170+
if (display_list_ == nullptr) {
171+
display_list_ = display_list_recorder_.Build();
172+
// null out the canvas and recorder fields of the PaintContext
173+
// to prevent future use.
174+
display_list_paint_context_.leaf_nodes_canvas = nullptr;
175+
display_list_paint_context_.internal_nodes_canvas = nullptr;
176+
display_list_paint_context_.leaf_nodes_builder = nullptr;
177+
}
178+
return display_list_;
179+
}
180+
147181
void enable_leaf_layer_tracing() {
148182
paint_context_.enable_leaf_layer_tracing = true;
149183
paint_context_.layer_snapshot_store = &snapshot_store_;
@@ -169,6 +203,10 @@ class LayerTestBase : public CanvasTestBase<BaseT> {
169203
std::unique_ptr<RasterCache> raster_cache_;
170204
PrerollContext preroll_context_;
171205
Layer::PaintContext paint_context_;
206+
DisplayListCanvasRecorder display_list_recorder_;
207+
sk_sp<DisplayList> display_list_;
208+
SkNWayCanvas internal_display_list_canvas_;
209+
Layer::PaintContext display_list_paint_context_;
172210
Layer::PaintContext check_board_context_;
173211
LayerSnapshotStore snapshot_store_;
174212

testing/BUILD.gn

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ source_set("testing_lib") {
1717

1818
sources = [
1919
"assertions.h",
20+
"display_list_testing.cc",
21+
"display_list_testing.h",
2022
"post_task_sync.cc",
2123
"post_task_sync.h",
2224
"testing.cc",
@@ -26,6 +28,7 @@ source_set("testing_lib") {
2628
]
2729

2830
public_deps = [
31+
"//flutter/display_list",
2932
"//flutter/fml",
3033
"//third_party/googletest:gmock",
3134
"//third_party/googletest:gtest",

0 commit comments

Comments
 (0)