Add a display list op to clear to transformation stack. (flutter/engine#32050)

This allows for the implementation of the
DisplayListCanvasRecoder::didSetM44. Instead of another operation that
clears the transformation stack along with setting a new transformation
on it. A single no-payload operation that clears the stack is added.
Existing ops to push to the stack are then reused.
This commit is contained in:
Chinmay Garde 2022-03-16 12:40:24 -07:00 committed by GitHub
parent b14fd230bf
commit 2a63aa8396
12 changed files with 46 additions and 9 deletions

2
DEPS
View File

@ -110,7 +110,7 @@ deps = {
'src': 'https://github.com/flutter/buildroot.git' + '@' + '8cbf38af7d48cc298ae86e614533b4b2d0dc6758',
'src/flutter/impeller':
Var('github_git') + '/flutter/impeller' + '@' + 'c1572a3335c4a533dacc28b86cbebdf08b5a57ed',
Var('github_git') + '/flutter/impeller' + '@' + 'b662deba147396d68e549e41d5d2d6b1cb0b0119',
# Fuchsia compatibility
#

View File

@ -103,6 +103,7 @@ namespace flutter {
V(Skew) \
V(Transform2DAffine) \
V(TransformFullPerspective) \
V(TransformReset) \
\
V(ClipIntersectRect) \
V(ClipIntersectRRect) \

View File

@ -427,8 +427,10 @@ void DisplayListBuilder::transformFullPerspective(
mwx, mwy, mwz, mwt);
}
}
// clang-format on
void DisplayListBuilder::transformReset() {
Push<TransformResetOp>(0, 0);
}
void DisplayListBuilder::clipRect(const SkRect& rect,
SkClipOp clip_op,

View File

@ -176,8 +176,8 @@ class DisplayListBuilder final : public virtual Dispatcher,
SkScalar myx, SkScalar myy, SkScalar myz, SkScalar myt,
SkScalar mzx, SkScalar mzy, SkScalar mzz, SkScalar mzt,
SkScalar mwx, SkScalar mwy, SkScalar mwz, SkScalar mwt) override;
// clang-format on
void transformReset() override;
void clipRect(const SkRect& rect, SkClipOp clip_op, bool is_aa) override;
void clipRRect(const SkRRect& rrect, SkClipOp clip_op, bool is_aa) override;

View File

@ -100,6 +100,9 @@ void DisplayListCanvasDispatcher::transformFullPerspective(
mwx, mwy, mwz, mwt));
}
// clang-format on
void DisplayListCanvasDispatcher::transformReset() {
canvas_->resetMatrix();
}
void DisplayListCanvasDispatcher::clipRect(const SkRect& rect,
SkClipOp clip_op,

View File

@ -46,6 +46,7 @@ class DisplayListCanvasDispatcher : public virtual Dispatcher,
SkScalar mzx, SkScalar mzy, SkScalar mzz, SkScalar mzt,
SkScalar mwx, SkScalar mwy, SkScalar mwz, SkScalar mwt) override;
// clang-format on
void transformReset() override;
void clipRect(const SkRect& rect, SkClipOp clip_op, bool is_aa) override;
void clipRRect(const SkRRect& rrect, SkClipOp clip_op, bool is_aa) override;

View File

@ -28,6 +28,10 @@ void DisplayListCanvasRecorder::didConcat44(const SkM44& m44) {
m44.rc(3, 0), m44.rc(3, 1), m44.rc(3, 2), m44.rc(3, 3));
}
// clang-format on
void DisplayListCanvasRecorder::didSetM44(const SkM44& matrix) {
builder_->transformReset();
didConcat44(matrix);
}
void DisplayListCanvasRecorder::didTranslate(SkScalar tx, SkScalar ty) {
builder_->translate(tx, ty);
}
@ -230,11 +234,6 @@ void DisplayListCanvasRecorder::onDrawShadowRec(const SkPath& path,
<< __FUNCTION__;
}
void DisplayListCanvasRecorder::didSetM44(const SkM44&) {
FML_DLOG(ERROR) << "Unimplemented DisplayListCanvasRecorder::"
<< __FUNCTION__;
}
void DisplayListCanvasRecorder::onDrawBehind(const SkPaint&) {
FML_DLOG(ERROR) << "Unimplemented DisplayListCanvasRecorder::"
<< __FUNCTION__;

View File

@ -168,9 +168,11 @@ class Dispatcher {
SkScalar myx, SkScalar myy, SkScalar myz, SkScalar myt,
SkScalar mzx, SkScalar mzy, SkScalar mzz, SkScalar mzt,
SkScalar mwx, SkScalar mwy, SkScalar mwz, SkScalar mwt) = 0;
// clang-format on
// Clears the transformation stack.
virtual void transformReset() = 0;
virtual void clipRect(const SkRect& rect, SkClipOp clip_op, bool is_aa) = 0;
virtual void clipRRect(const SkRRect& rrect,
SkClipOp clip_op,

View File

@ -382,6 +382,15 @@ struct TransformFullPerspectiveOp final : DLOp {
}
};
// 4 byte header with no payload.
struct TransformResetOp final : DLOp {
static const auto kType = DisplayListOpType::kTransformReset;
TransformResetOp() = default;
void dispatch(Dispatcher& dispatcher) const { dispatcher.transformReset(); }
};
// 4 byte header + 4 byte common payload packs into minimum 8 bytes
// SkRect is 16 more bytes, which packs efficiently into 24 bytes total
// SkRRect is 52 more bytes, which rounds up to 56 bytes (4 bytes unused)

View File

@ -1370,6 +1370,18 @@ TEST(DisplayList, DisplayListFullPerspectiveTransformHandling) {
}
}
TEST(DisplayList, DisplayListTransformResetHandling) {
DisplayListBuilder builder;
builder.scale(20.0, 20.0);
builder.transformReset();
auto list = builder.Build();
ASSERT_NE(list, nullptr);
sk_sp<SkSurface> surface = SkSurface::MakeRasterN32Premul(10, 10);
SkCanvas* canvas = surface->getCanvas();
list->RenderTo(canvas);
ASSERT_TRUE(canvas->getTotalMatrix().isIdentity());
}
TEST(DisplayList, SingleOpsMightSupportGroupOpacityWithOrWithoutBlendMode) {
auto run_tests = [](std::string name,
void build(DisplayListBuilder & builder),

View File

@ -152,6 +152,11 @@ void SkMatrixDispatchHelper::transformFullPerspective(
// clang-format on
void SkMatrixDispatchHelper::transformReset() {
matrix_ = {};
matrix33_ = {};
}
void SkMatrixDispatchHelper::save() {
saved_.push_back(matrix_);
}

View File

@ -88,6 +88,7 @@ class IgnoreTransformDispatchHelper : public virtual Dispatcher {
SkScalar mzx, SkScalar mzy, SkScalar mzz, SkScalar mzt,
SkScalar mwx, SkScalar mwy, SkScalar mwz, SkScalar mwt) override {}
// clang-format on
void transformReset() override {}
};
class IgnoreDrawDispatchHelper : public virtual Dispatcher {
@ -273,6 +274,8 @@ class SkMatrixDispatchHelper : public virtual Dispatcher,
// clang-format on
void transformReset() override;
void save() override;
void restore() override;