Migrate Mutators to DisplayList/Impeller geometry (#164258)
Mutator types and MutatorsStack will now use DisplayList/Impeller geometry objects.
This commit is contained in:
parent
eb07c51230
commit
66e910d27e
@ -106,7 +106,7 @@ const SkPath& DlPath::GetSkPath() const {
|
||||
return sk_path.value();
|
||||
}
|
||||
|
||||
Path DlPath::GetPath() const {
|
||||
const Path& DlPath::GetPath() const {
|
||||
auto& sk_path = data_->sk_path;
|
||||
auto& path = data_->path;
|
||||
if (path.has_value()) {
|
||||
|
@ -67,7 +67,7 @@ class DlPath {
|
||||
DlPath& operator=(const DlPath&) = default;
|
||||
|
||||
const SkPath& GetSkPath() const;
|
||||
impeller::Path GetPath() const;
|
||||
const impeller::Path& GetPath() const;
|
||||
|
||||
/// Intent to render an SkPath multiple times will make the path
|
||||
/// non-volatile to enable caching in Skia. Calling this method
|
||||
|
@ -422,7 +422,7 @@ TEST(DisplayListSkConversions, ConicPathToQuads) {
|
||||
sk_path.conicTo(20, 10, 20, 20, weight);
|
||||
|
||||
DlPath dl_path(sk_path);
|
||||
impeller::Path i_path = dl_path.GetPath();
|
||||
const impeller::Path& i_path = dl_path.GetPath();
|
||||
|
||||
auto it = i_path.begin();
|
||||
ASSERT_EQ(it.type(), impeller::Path::ComponentType::kContour);
|
||||
|
@ -246,24 +246,31 @@ DlRect DisplayListMatrixClipState::GetLocalCullCoverage() const {
|
||||
}
|
||||
|
||||
bool DisplayListMatrixClipState::rect_covers_cull(const DlRect& content) const {
|
||||
if (content.IsEmpty()) {
|
||||
return TransformedRectCoversBounds(content, matrix_, cull_rect_);
|
||||
}
|
||||
|
||||
bool DisplayListMatrixClipState::TransformedRectCoversBounds(
|
||||
const DlRect& local_rect,
|
||||
const DlMatrix& matrix,
|
||||
const DlRect& cull_bounds) {
|
||||
if (local_rect.IsEmpty()) {
|
||||
return false;
|
||||
}
|
||||
if (cull_rect_.IsEmpty()) {
|
||||
if (cull_bounds.IsEmpty()) {
|
||||
return true;
|
||||
}
|
||||
if (matrix_.IsAligned2D()) {
|
||||
if (matrix.IsAligned2D()) {
|
||||
// This transform-to-device calculation is faster and more accurate
|
||||
// for rect-to-rect aligned transformations, but not accurate under
|
||||
// (non-quadrant) rotations and skews.
|
||||
return content.TransformAndClipBounds(matrix_).Contains(cull_rect_);
|
||||
return local_rect.TransformAndClipBounds(matrix).Contains(cull_bounds);
|
||||
}
|
||||
DlPoint corners[4];
|
||||
if (!getLocalCullCorners(corners)) {
|
||||
if (!GetLocalCorners(corners, cull_bounds, matrix)) {
|
||||
return false;
|
||||
}
|
||||
for (auto corner : corners) {
|
||||
if (!content.ContainsInclusive(corner)) {
|
||||
if (!local_rect.ContainsInclusive(corner)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -271,20 +278,27 @@ bool DisplayListMatrixClipState::rect_covers_cull(const DlRect& content) const {
|
||||
}
|
||||
|
||||
bool DisplayListMatrixClipState::oval_covers_cull(const DlRect& bounds) const {
|
||||
if (bounds.IsEmpty()) {
|
||||
return TransformedOvalCoversBounds(bounds, matrix_, cull_rect_);
|
||||
}
|
||||
|
||||
bool DisplayListMatrixClipState::TransformedOvalCoversBounds(
|
||||
const DlRect& local_oval_bounds,
|
||||
const DlMatrix& matrix,
|
||||
const DlRect& cull_bounds) {
|
||||
if (local_oval_bounds.IsEmpty()) {
|
||||
return false;
|
||||
}
|
||||
if (cull_rect_.IsEmpty()) {
|
||||
if (cull_bounds.IsEmpty()) {
|
||||
return true;
|
||||
}
|
||||
DlPoint corners[4];
|
||||
if (!getLocalCullCorners(corners)) {
|
||||
if (!GetLocalCorners(corners, cull_bounds, matrix)) {
|
||||
return false;
|
||||
}
|
||||
DlPoint center = bounds.GetCenter();
|
||||
DlSize scale = 2.0 / bounds.GetSize();
|
||||
DlPoint center = local_oval_bounds.GetCenter();
|
||||
DlSize scale = 2.0 / local_oval_bounds.GetSize();
|
||||
for (auto corner : corners) {
|
||||
if (!bounds.Contains(corner)) {
|
||||
if (!local_oval_bounds.Contains(corner)) {
|
||||
return false;
|
||||
}
|
||||
if (((corner - center) * scale).GetLengthSquared() >= 1.0) {
|
||||
@ -296,28 +310,37 @@ bool DisplayListMatrixClipState::oval_covers_cull(const DlRect& bounds) const {
|
||||
|
||||
bool DisplayListMatrixClipState::rrect_covers_cull(
|
||||
const DlRoundRect& content) const {
|
||||
if (content.IsEmpty()) {
|
||||
return TransformedRRectCoversBounds(content, matrix_, cull_rect_);
|
||||
}
|
||||
|
||||
bool DisplayListMatrixClipState::TransformedRRectCoversBounds(
|
||||
const DlRoundRect& local_rrect,
|
||||
const DlMatrix& matrix,
|
||||
const DlRect& cull_bounds) {
|
||||
if (local_rrect.IsEmpty()) {
|
||||
return false;
|
||||
}
|
||||
if (cull_rect_.IsEmpty()) {
|
||||
if (cull_bounds.IsEmpty()) {
|
||||
return true;
|
||||
}
|
||||
if (content.IsRect()) {
|
||||
return rect_covers_cull(content.GetBounds());
|
||||
if (local_rrect.IsRect()) {
|
||||
return TransformedRectCoversBounds(local_rrect.GetBounds(), matrix,
|
||||
cull_bounds);
|
||||
}
|
||||
if (content.IsOval()) {
|
||||
return oval_covers_cull(content.GetBounds());
|
||||
if (local_rrect.IsOval()) {
|
||||
return TransformedOvalCoversBounds(local_rrect.GetBounds(), matrix,
|
||||
cull_bounds);
|
||||
}
|
||||
if (!content.GetRadii().AreAllCornersSame()) {
|
||||
if (!local_rrect.GetRadii().AreAllCornersSame()) {
|
||||
return false;
|
||||
}
|
||||
DlPoint corners[4];
|
||||
if (!getLocalCullCorners(corners)) {
|
||||
if (!GetLocalCorners(corners, cull_bounds, matrix)) {
|
||||
return false;
|
||||
}
|
||||
auto outer = content.GetBounds();
|
||||
auto outer = local_rrect.GetBounds();
|
||||
auto center = outer.GetCenter();
|
||||
auto radii = content.GetRadii().top_left;
|
||||
auto radii = local_rrect.GetRadii().top_left;
|
||||
auto inner = outer.GetSize() * 0.5 - radii;
|
||||
auto scale = 1.0 / radii;
|
||||
for (auto corner : corners) {
|
||||
@ -335,25 +358,34 @@ bool DisplayListMatrixClipState::rrect_covers_cull(
|
||||
|
||||
bool DisplayListMatrixClipState::rsuperellipse_covers_cull(
|
||||
const DlRoundSuperellipse& content) const {
|
||||
if (content.IsEmpty()) {
|
||||
return TransformedRoundSuperellipseCoversBounds(content, matrix_, cull_rect_);
|
||||
}
|
||||
|
||||
bool DisplayListMatrixClipState::TransformedRoundSuperellipseCoversBounds(
|
||||
const DlRoundSuperellipse& local_rse,
|
||||
const DlMatrix& matrix,
|
||||
const DlRect& cull_bounds) {
|
||||
if (local_rse.IsEmpty()) {
|
||||
return false;
|
||||
}
|
||||
if (cull_rect_.IsEmpty()) {
|
||||
if (cull_bounds.IsEmpty()) {
|
||||
return true;
|
||||
}
|
||||
if (content.IsRect()) {
|
||||
return rect_covers_cull(content.GetBounds());
|
||||
if (local_rse.IsRect()) {
|
||||
return TransformedRectCoversBounds(local_rse.GetBounds(), matrix,
|
||||
cull_bounds);
|
||||
}
|
||||
if (content.IsOval()) {
|
||||
return oval_covers_cull(content.GetBounds());
|
||||
if (local_rse.IsOval()) {
|
||||
return TransformedOvalCoversBounds(local_rse.GetBounds(), matrix,
|
||||
cull_bounds);
|
||||
}
|
||||
DlPoint corners[4];
|
||||
if (!getLocalCullCorners(corners)) {
|
||||
if (!GetLocalCorners(corners, cull_bounds, matrix)) {
|
||||
return false;
|
||||
}
|
||||
auto outer = content.GetBounds();
|
||||
auto outer = local_rse.GetBounds();
|
||||
auto param = impeller::RoundSuperellipseParam::MakeBoundsRadii(
|
||||
outer, content.GetRadii());
|
||||
outer, local_rse.GetRadii());
|
||||
for (auto corner : corners) {
|
||||
if (!outer.Contains(corner)) {
|
||||
return false;
|
||||
@ -365,15 +397,17 @@ bool DisplayListMatrixClipState::rsuperellipse_covers_cull(
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DisplayListMatrixClipState::getLocalCullCorners(DlPoint corners[4]) const {
|
||||
if (!is_matrix_invertable()) {
|
||||
bool DisplayListMatrixClipState::GetLocalCorners(DlPoint corners[4],
|
||||
const DlRect& rect,
|
||||
const DlMatrix& matrix) {
|
||||
if (!matrix.IsInvertible()) {
|
||||
return false;
|
||||
}
|
||||
DlMatrix inverse = matrix_.Invert();
|
||||
corners[0] = inverse * cull_rect_.GetLeftTop();
|
||||
corners[1] = inverse * cull_rect_.GetRightTop();
|
||||
corners[2] = inverse * cull_rect_.GetRightBottom();
|
||||
corners[3] = inverse * cull_rect_.GetLeftBottom();
|
||||
DlMatrix inverse = matrix.Invert();
|
||||
corners[0] = inverse * rect.GetLeftTop();
|
||||
corners[1] = inverse * rect.GetRightTop();
|
||||
corners[2] = inverse * rect.GetRightBottom();
|
||||
corners[3] = inverse * rect.GetLeftBottom();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -113,12 +113,60 @@ class DisplayListMatrixClipState {
|
||||
bool is_aa);
|
||||
void clipPath(const DlPath& path, DlClipOp op, bool is_aa);
|
||||
|
||||
/// @brief Checks if the local rect, when transformed by the matrix,
|
||||
/// completely covers the indicated culling bounds.
|
||||
///
|
||||
/// This utility method helps answer the question of whether a clip
|
||||
/// rectangle being intersected under a transform is essentially obsolete
|
||||
/// because it will not reduce the already existing clip culling bounds.
|
||||
[[nodiscard]]
|
||||
static bool TransformedRectCoversBounds(const DlRect& local_rect,
|
||||
const DlMatrix& matrix,
|
||||
const DlRect& cull_bounds);
|
||||
|
||||
/// @brief Checks if an oval defined by the local bounds, when transformed
|
||||
/// by the matrix, completely covers the indicated culling bounds.
|
||||
///
|
||||
/// This utility method helps answer the question of whether a clip
|
||||
/// oval being intersected under a transform is essentially obsolete
|
||||
/// because it will not reduce the already existing clip culling bounds.
|
||||
[[nodiscard]]
|
||||
static bool TransformedOvalCoversBounds(const DlRect& local_oval_bounds,
|
||||
const DlMatrix& matrix,
|
||||
const DlRect& cull_bounds);
|
||||
|
||||
/// @brief Checks if the local round rect, when transformed by the matrix,
|
||||
/// completely covers the indicated culling bounds.
|
||||
///
|
||||
/// This utility method helps answer the question of whether a clip
|
||||
/// rrect being intersected under a transform is essentially obsolete
|
||||
/// because it will not reduce the already existing clip culling bounds.
|
||||
[[nodiscard]]
|
||||
static bool TransformedRRectCoversBounds(const DlRoundRect& local_rrect,
|
||||
const DlMatrix& matrix,
|
||||
const DlRect& cull_bounds);
|
||||
|
||||
/// @brief Checks if the local round superellipse, when transformed by the
|
||||
/// matrix, completely covers the indicated culling bounds.
|
||||
///
|
||||
/// This utility method helps answer the question of whether a clip round
|
||||
/// superellipse being intersected under a transform is essentially obsolete
|
||||
/// because it will not reduce the already existing clip culling bounds.
|
||||
[[nodiscard]]
|
||||
static bool TransformedRoundSuperellipseCoversBounds(
|
||||
const DlRoundSuperellipse& local_rse,
|
||||
const DlMatrix& matrix,
|
||||
const DlRect& cull_bounds);
|
||||
|
||||
private:
|
||||
DlRect cull_rect_;
|
||||
DlMatrix matrix_;
|
||||
|
||||
bool getLocalCullCorners(DlPoint corners[4]) const;
|
||||
void adjustCullRect(const DlRect& clip, DlClipOp op, bool is_aa);
|
||||
|
||||
static bool GetLocalCorners(DlPoint corners[4],
|
||||
const DlRect& rect,
|
||||
const DlMatrix& matrix);
|
||||
};
|
||||
|
||||
} // namespace flutter
|
||||
|
@ -468,15 +468,23 @@ TEST(DisplayListMatrixClipState, RectCoverage) {
|
||||
DlRect rect = DlRect::MakeLTRB(100.0f, 100.0f, 200.0f, 200.0f);
|
||||
DisplayListMatrixClipState state(rect);
|
||||
|
||||
EXPECT_TRUE(state.rect_covers_cull(rect));
|
||||
EXPECT_TRUE(state.rect_covers_cull(rect.Expand(0.1f, 0.0f, 0.0f, 0.0f)));
|
||||
EXPECT_TRUE(state.rect_covers_cull(rect.Expand(0.0f, 0.1f, 0.0f, 0.0f)));
|
||||
EXPECT_TRUE(state.rect_covers_cull(rect.Expand(0.0f, 0.0f, 0.1f, 0.0f)));
|
||||
EXPECT_TRUE(state.rect_covers_cull(rect.Expand(0.0f, 0.0f, 0.0f, 0.1f)));
|
||||
EXPECT_FALSE(state.rect_covers_cull(rect.Expand(-0.1f, 0.0f, 0.0f, 0.0f)));
|
||||
EXPECT_FALSE(state.rect_covers_cull(rect.Expand(0.0f, -0.1f, 0.0f, 0.0f)));
|
||||
EXPECT_FALSE(state.rect_covers_cull(rect.Expand(0.0f, 0.0f, -0.1f, 0.0f)));
|
||||
EXPECT_FALSE(state.rect_covers_cull(rect.Expand(0.0f, 0.0f, 0.0f, -0.1f)));
|
||||
auto test_rect = [&state](const DlRect& test_rect, bool expect) {
|
||||
EXPECT_EQ(state.rect_covers_cull(test_rect), expect) << test_rect;
|
||||
EXPECT_EQ(DisplayListMatrixClipState::TransformedRectCoversBounds(
|
||||
test_rect, state.matrix(), state.GetDeviceCullCoverage()),
|
||||
expect)
|
||||
<< test_rect;
|
||||
};
|
||||
|
||||
test_rect(rect, true);
|
||||
test_rect(rect.Expand(0.1f, 0.0f, 0.0f, 0.0f), true);
|
||||
test_rect(rect.Expand(0.0f, 0.1f, 0.0f, 0.0f), true);
|
||||
test_rect(rect.Expand(0.0f, 0.0f, 0.1f, 0.0f), true);
|
||||
test_rect(rect.Expand(0.0f, 0.0f, 0.0f, 0.1f), true);
|
||||
test_rect(rect.Expand(-0.1f, 0.0f, 0.0f, 0.0f), false);
|
||||
test_rect(rect.Expand(0.0f, -0.1f, 0.0f, 0.0f), false);
|
||||
test_rect(rect.Expand(0.0f, 0.0f, -0.1f, 0.0f), false);
|
||||
test_rect(rect.Expand(0.0f, 0.0f, 0.0f, -0.1f), false);
|
||||
}
|
||||
|
||||
TEST(DisplayListMatrixClipState, RectCoverageAccuracy) {
|
||||
@ -495,15 +503,23 @@ TEST(DisplayListMatrixClipState, RectCoverageAccuracy) {
|
||||
DisplayListMatrixClipState state(cull);
|
||||
state.scale(DPR, DPR);
|
||||
|
||||
EXPECT_TRUE(state.rect_covers_cull(rect));
|
||||
EXPECT_TRUE(state.rect_covers_cull(rect.Expand(0.1f, 0.0f, 0.0f, 0.0f)));
|
||||
EXPECT_TRUE(state.rect_covers_cull(rect.Expand(0.0f, 0.1f, 0.0f, 0.0f)));
|
||||
EXPECT_TRUE(state.rect_covers_cull(rect.Expand(0.0f, 0.0f, 0.1f, 0.0f)));
|
||||
EXPECT_TRUE(state.rect_covers_cull(rect.Expand(0.0f, 0.0f, 0.0f, 0.1f)));
|
||||
EXPECT_FALSE(state.rect_covers_cull(rect.Expand(-0.1f, 0.0f, 0.0f, 0.0f)));
|
||||
EXPECT_FALSE(state.rect_covers_cull(rect.Expand(0.0f, -0.1f, 0.0f, 0.0f)));
|
||||
EXPECT_FALSE(state.rect_covers_cull(rect.Expand(0.0f, 0.0f, -0.1f, 0.0f)));
|
||||
EXPECT_FALSE(state.rect_covers_cull(rect.Expand(0.0f, 0.0f, 0.0f, -0.1f)));
|
||||
auto test_rect = [&state](const DlRect& test_rect, bool expect) {
|
||||
EXPECT_EQ(state.rect_covers_cull(test_rect), expect) << test_rect;
|
||||
EXPECT_EQ(DisplayListMatrixClipState::TransformedRectCoversBounds(
|
||||
test_rect, state.matrix(), state.GetDeviceCullCoverage()),
|
||||
expect)
|
||||
<< test_rect;
|
||||
};
|
||||
|
||||
test_rect(rect, true);
|
||||
test_rect(rect.Expand(0.1f, 0.0f, 0.0f, 0.0f), true);
|
||||
test_rect(rect.Expand(0.0f, 0.1f, 0.0f, 0.0f), true);
|
||||
test_rect(rect.Expand(0.0f, 0.0f, 0.1f, 0.0f), true);
|
||||
test_rect(rect.Expand(0.0f, 0.0f, 0.0f, 0.1f), true);
|
||||
test_rect(rect.Expand(-0.1f, 0.0f, 0.0f, 0.0f), false);
|
||||
test_rect(rect.Expand(0.0f, -0.1f, 0.0f, 0.0f), false);
|
||||
test_rect(rect.Expand(0.0f, 0.0f, -0.1f, 0.0f), false);
|
||||
test_rect(rect.Expand(0.0f, 0.0f, 0.0f, -0.1f), false);
|
||||
}
|
||||
|
||||
TEST(DisplayListMatrixClipState, RectCoverageUnderScale) {
|
||||
@ -511,16 +527,24 @@ TEST(DisplayListMatrixClipState, RectCoverageUnderScale) {
|
||||
DisplayListMatrixClipState state(rect);
|
||||
state.scale(2.0f, 2.0f);
|
||||
|
||||
EXPECT_FALSE(state.rect_covers_cull(DlRect::MakeLTRB(100, 100, 200, 200)));
|
||||
EXPECT_TRUE(state.rect_covers_cull(DlRect::MakeLTRB(50, 50, 100, 100)));
|
||||
EXPECT_TRUE(state.rect_covers_cull(DlRect::MakeLTRB(49, 50, 100, 100)));
|
||||
EXPECT_TRUE(state.rect_covers_cull(DlRect::MakeLTRB(50, 49, 100, 100)));
|
||||
EXPECT_TRUE(state.rect_covers_cull(DlRect::MakeLTRB(50, 50, 101, 100)));
|
||||
EXPECT_TRUE(state.rect_covers_cull(DlRect::MakeLTRB(50, 50, 100, 101)));
|
||||
EXPECT_FALSE(state.rect_covers_cull(DlRect::MakeLTRB(51, 50, 100, 100)));
|
||||
EXPECT_FALSE(state.rect_covers_cull(DlRect::MakeLTRB(50, 51, 100, 100)));
|
||||
EXPECT_FALSE(state.rect_covers_cull(DlRect::MakeLTRB(50, 50, 99, 100)));
|
||||
EXPECT_FALSE(state.rect_covers_cull(DlRect::MakeLTRB(50, 50, 100, 99)));
|
||||
auto test_rect = [&state](const DlRect& test_rect, bool expect) {
|
||||
EXPECT_EQ(state.rect_covers_cull(test_rect), expect) << test_rect;
|
||||
EXPECT_EQ(DisplayListMatrixClipState::TransformedRectCoversBounds(
|
||||
test_rect, state.matrix(), state.GetDeviceCullCoverage()),
|
||||
expect)
|
||||
<< test_rect;
|
||||
};
|
||||
|
||||
test_rect(DlRect::MakeLTRB(100, 100, 200, 200), false);
|
||||
test_rect(DlRect::MakeLTRB(50, 50, 100, 100), true);
|
||||
test_rect(DlRect::MakeLTRB(49, 50, 100, 100), true);
|
||||
test_rect(DlRect::MakeLTRB(50, 49, 100, 100), true);
|
||||
test_rect(DlRect::MakeLTRB(50, 50, 101, 100), true);
|
||||
test_rect(DlRect::MakeLTRB(50, 50, 100, 101), true);
|
||||
test_rect(DlRect::MakeLTRB(51, 50, 100, 100), false);
|
||||
test_rect(DlRect::MakeLTRB(50, 51, 100, 100), false);
|
||||
test_rect(DlRect::MakeLTRB(50, 50, 99, 100), false);
|
||||
test_rect(DlRect::MakeLTRB(50, 50, 100, 99), false);
|
||||
}
|
||||
|
||||
TEST(DisplayListMatrixClipState, RectCoverageUnderRotation) {
|
||||
@ -537,6 +561,11 @@ TEST(DisplayListMatrixClipState, RectCoverageUnderRotation) {
|
||||
<< " testing " << test_true << std::endl
|
||||
<< " contains " << state.GetLocalCullCoverage() << std::endl
|
||||
<< " at " << i << " degrees";
|
||||
EXPECT_TRUE(DisplayListMatrixClipState::TransformedRectCoversBounds(
|
||||
test_true, DlMatrix::MakeRotationZ(DlDegrees(i)), cull))
|
||||
<< " testing " << test_true << std::endl
|
||||
<< " contains " << state.GetLocalCullCoverage() << std::endl
|
||||
<< " at " << i << " degrees";
|
||||
if ((i % 90) == 45) {
|
||||
// The cull rect is largest when viewed at multiples of 45
|
||||
// degrees so we will fail to contain it at those angles
|
||||
@ -544,6 +573,11 @@ TEST(DisplayListMatrixClipState, RectCoverageUnderRotation) {
|
||||
<< " testing " << test_false << std::endl
|
||||
<< " contains " << state.GetLocalCullCoverage() << std::endl
|
||||
<< " at " << i << " degrees";
|
||||
EXPECT_FALSE(DisplayListMatrixClipState::TransformedRectCoversBounds(
|
||||
test_false, DlMatrix::MakeRotationZ(DlDegrees(i)), cull))
|
||||
<< " testing " << test_false << std::endl
|
||||
<< " contains " << state.GetLocalCullCoverage() << std::endl
|
||||
<< " at " << i << " degrees";
|
||||
} else {
|
||||
// At other angles, the cull rect is not quite so big as to encroach
|
||||
// upon the expanded test rectangle.
|
||||
@ -551,6 +585,11 @@ TEST(DisplayListMatrixClipState, RectCoverageUnderRotation) {
|
||||
<< " testing " << test_false << std::endl
|
||||
<< " contains " << state.GetLocalCullCoverage() << std::endl
|
||||
<< " at " << i << " degrees";
|
||||
EXPECT_TRUE(DisplayListMatrixClipState::TransformedRectCoversBounds(
|
||||
test_false, DlMatrix::MakeRotationZ(DlDegrees(i)), cull))
|
||||
<< " testing " << test_false << std::endl
|
||||
<< " contains " << state.GetLocalCullCoverage() << std::endl
|
||||
<< " at " << i << " degrees";
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -564,15 +603,23 @@ TEST(DisplayListMatrixClipState, OvalCoverage) {
|
||||
// then use larger expansion/contractions of 0.1f to cover/not-cover it.
|
||||
DlRect test = cull.Scale(impeller::kSqrt2).Expand(0.02f);
|
||||
|
||||
EXPECT_TRUE(state.oval_covers_cull(test));
|
||||
EXPECT_TRUE(state.oval_covers_cull(test.Expand(0.1f, 0.0f, 0.0f, 0.0f)));
|
||||
EXPECT_TRUE(state.oval_covers_cull(test.Expand(0.0f, 0.1f, 0.0f, 0.0f)));
|
||||
EXPECT_TRUE(state.oval_covers_cull(test.Expand(0.0f, 0.0f, 0.1f, 0.0f)));
|
||||
EXPECT_TRUE(state.oval_covers_cull(test.Expand(0.0f, 0.0f, 0.0f, 0.1f)));
|
||||
EXPECT_FALSE(state.oval_covers_cull(test.Expand(-0.1f, 0.0f, 0.0f, 0.0f)));
|
||||
EXPECT_FALSE(state.oval_covers_cull(test.Expand(0.0f, -0.1f, 0.0f, 0.0f)));
|
||||
EXPECT_FALSE(state.oval_covers_cull(test.Expand(0.0f, 0.0f, -0.1f, 0.0f)));
|
||||
EXPECT_FALSE(state.oval_covers_cull(test.Expand(0.0f, 0.0f, 0.0f, -0.1f)));
|
||||
auto test_oval = [&state](const DlRect& test_rect, bool expect) {
|
||||
EXPECT_EQ(state.oval_covers_cull(test_rect), expect) << test_rect;
|
||||
EXPECT_EQ(DisplayListMatrixClipState::TransformedOvalCoversBounds(
|
||||
test_rect, state.matrix(), state.GetDeviceCullCoverage()),
|
||||
expect)
|
||||
<< test_rect;
|
||||
};
|
||||
|
||||
test_oval(test, true);
|
||||
test_oval(test.Expand(0.1f, 0.0f, 0.0f, 0.0f), true);
|
||||
test_oval(test.Expand(0.0f, 0.1f, 0.0f, 0.0f), true);
|
||||
test_oval(test.Expand(0.0f, 0.0f, 0.1f, 0.0f), true);
|
||||
test_oval(test.Expand(0.0f, 0.0f, 0.0f, 0.1f), true);
|
||||
test_oval(test.Expand(-0.1f, 0.0f, 0.0f, 0.0f), false);
|
||||
test_oval(test.Expand(0.0f, -0.1f, 0.0f, 0.0f), false);
|
||||
test_oval(test.Expand(0.0f, 0.0f, -0.1f, 0.0f), false);
|
||||
test_oval(test.Expand(0.0f, 0.0f, 0.0f, -0.1f), false);
|
||||
}
|
||||
|
||||
TEST(DisplayListMatrixClipState, OvalCoverageUnderScale) {
|
||||
@ -587,15 +634,23 @@ TEST(DisplayListMatrixClipState, OvalCoverageUnderScale) {
|
||||
// the cull rect under a 2.0 scale.
|
||||
DlRect test = cull.Scale(0.5f * impeller::kSqrt2).Expand(0.02f);
|
||||
|
||||
EXPECT_TRUE(state.oval_covers_cull(test));
|
||||
EXPECT_TRUE(state.oval_covers_cull(test.Expand(0.1f, 0.0f, 0.0f, 0.0f)));
|
||||
EXPECT_TRUE(state.oval_covers_cull(test.Expand(0.0f, 0.1f, 0.0f, 0.0f)));
|
||||
EXPECT_TRUE(state.oval_covers_cull(test.Expand(0.0f, 0.0f, 0.1f, 0.0f)));
|
||||
EXPECT_TRUE(state.oval_covers_cull(test.Expand(0.0f, 0.0f, 0.0f, 0.1f)));
|
||||
EXPECT_FALSE(state.oval_covers_cull(test.Expand(-0.1f, 0.0f, 0.0f, 0.0f)));
|
||||
EXPECT_FALSE(state.oval_covers_cull(test.Expand(0.0f, -0.1f, 0.0f, 0.0f)));
|
||||
EXPECT_FALSE(state.oval_covers_cull(test.Expand(0.0f, 0.0f, -0.1f, 0.0f)));
|
||||
EXPECT_FALSE(state.oval_covers_cull(test.Expand(0.0f, 0.0f, 0.0f, -0.1f)));
|
||||
auto test_oval = [&state](const DlRect& test_rect, bool expect) {
|
||||
EXPECT_EQ(state.oval_covers_cull(test_rect), expect) << test_rect;
|
||||
EXPECT_EQ(DisplayListMatrixClipState::TransformedOvalCoversBounds(
|
||||
test_rect, state.matrix(), state.GetDeviceCullCoverage()),
|
||||
expect)
|
||||
<< test_rect;
|
||||
};
|
||||
|
||||
test_oval(test, true);
|
||||
test_oval(test.Expand(0.1f, 0.0f, 0.0f, 0.0f), true);
|
||||
test_oval(test.Expand(0.0f, 0.1f, 0.0f, 0.0f), true);
|
||||
test_oval(test.Expand(0.0f, 0.0f, 0.1f, 0.0f), true);
|
||||
test_oval(test.Expand(0.0f, 0.0f, 0.0f, 0.1f), true);
|
||||
test_oval(test.Expand(-0.1f, 0.0f, 0.0f, 0.0f), false);
|
||||
test_oval(test.Expand(0.0f, -0.1f, 0.0f, 0.0f), false);
|
||||
test_oval(test.Expand(0.0f, 0.0f, -0.1f, 0.0f), false);
|
||||
test_oval(test.Expand(0.0f, 0.0f, 0.0f, -0.1f), false);
|
||||
}
|
||||
|
||||
TEST(DisplayListMatrixClipState, OvalCoverageUnderRotation) {
|
||||
@ -620,6 +675,17 @@ TEST(DisplayListMatrixClipState, OvalCoverageUnderRotation) {
|
||||
<< " testing " << test_false << std::endl
|
||||
<< " contains " << state.GetLocalCullCoverage() << std::endl
|
||||
<< " at " << i << " degrees";
|
||||
|
||||
EXPECT_TRUE(DisplayListMatrixClipState::TransformedOvalCoversBounds(
|
||||
test_true, DlMatrix::MakeRotationZ(DlDegrees(i)), cull))
|
||||
<< " testing " << test_true << std::endl
|
||||
<< " contains " << state.GetLocalCullCoverage() << std::endl
|
||||
<< " at " << i << " degrees";
|
||||
EXPECT_FALSE(DisplayListMatrixClipState::TransformedOvalCoversBounds(
|
||||
test_false, DlMatrix::MakeRotationZ(DlDegrees(i)), cull))
|
||||
<< " testing " << test_false << std::endl
|
||||
<< " contains " << state.GetLocalCullCoverage() << std::endl
|
||||
<< " at " << i << " degrees";
|
||||
}
|
||||
}
|
||||
|
||||
@ -632,13 +698,21 @@ TEST(DisplayListMatrixClipState, RRectCoverage) {
|
||||
// RRect of cull with no corners covers
|
||||
EXPECT_TRUE(
|
||||
state.rrect_covers_cull(DlRoundRect::MakeRectXY(cull, 0.0f, 0.0f)));
|
||||
EXPECT_TRUE(DisplayListMatrixClipState::TransformedRRectCoversBounds(
|
||||
DlRoundRect::MakeRectXY(cull, 0.0f, 0.0f), DlMatrix(), cull));
|
||||
|
||||
// RRect of cull with even the tiniest corners does not cover
|
||||
EXPECT_FALSE(
|
||||
state.rrect_covers_cull(DlRoundRect::MakeRectXY(cull, 0.01f, 0.01f)));
|
||||
EXPECT_FALSE(DisplayListMatrixClipState::TransformedRRectCoversBounds(
|
||||
DlRoundRect::MakeRectXY(cull, 0.01f, 0.01f), DlMatrix(), cull));
|
||||
|
||||
// Expanded by 2.0 and then with a corner of 2.0 obviously still covers
|
||||
EXPECT_TRUE(
|
||||
state.rrect_covers_cull(DlRoundRect::MakeRectXY(test, 2.0f, 2.0f)));
|
||||
EXPECT_TRUE(DisplayListMatrixClipState::TransformedRRectCoversBounds(
|
||||
DlRoundRect::MakeRectXY(test, 2.0f, 2.0f), DlMatrix(), cull));
|
||||
|
||||
// The corner point of the cull rect is at (c-2, c-2) relative to the
|
||||
// corner of the rrect bounds so we compute its distance to the center
|
||||
// of the circular part and compare it to the radius of the corner (c)
|
||||
@ -663,9 +737,14 @@ TEST(DisplayListMatrixClipState, RRectCoverage) {
|
||||
// corners set to 6.82 should still cover the cull rect
|
||||
EXPECT_TRUE(
|
||||
state.rrect_covers_cull(DlRoundRect::MakeRectXY(test, 6.82f, 6.82f)));
|
||||
EXPECT_TRUE(DisplayListMatrixClipState::TransformedRRectCoversBounds(
|
||||
DlRoundRect::MakeRectXY(test, 6.82f, 6.82f), DlMatrix(), cull));
|
||||
|
||||
// but corners set to 6.83 should not cover the cull rect
|
||||
EXPECT_FALSE(
|
||||
state.rrect_covers_cull(DlRoundRect::MakeRectXY(test, 6.84f, 6.84f)));
|
||||
EXPECT_FALSE(DisplayListMatrixClipState::TransformedRRectCoversBounds(
|
||||
DlRoundRect::MakeRectXY(test, 6.84f, 6.84f), DlMatrix(), cull));
|
||||
}
|
||||
|
||||
} // namespace testing
|
||||
|
@ -23,10 +23,10 @@ TEST(EmbeddedViewParams, GetBoundingRectAfterMutationsWithNoMutations) {
|
||||
|
||||
TEST(EmbeddedViewParams, GetBoundingRectAfterMutationsWithScale) {
|
||||
MutatorsStack stack;
|
||||
SkMatrix matrix = SkMatrix::Scale(2, 2);
|
||||
DlMatrix matrix = DlMatrix::MakeScale({2, 2, 1});
|
||||
stack.PushTransform(matrix);
|
||||
|
||||
EmbeddedViewParams params(matrix, SkSize::Make(1, 1), stack);
|
||||
EmbeddedViewParams params(ToSkMatrix(matrix), SkSize::Make(1, 1), stack);
|
||||
const SkRect& rect = params.finalBoundingRect();
|
||||
ASSERT_TRUE(SkScalarNearlyEqual(rect.x(), 0));
|
||||
ASSERT_TRUE(SkScalarNearlyEqual(rect.y(), 0));
|
||||
@ -36,10 +36,10 @@ TEST(EmbeddedViewParams, GetBoundingRectAfterMutationsWithScale) {
|
||||
|
||||
TEST(EmbeddedViewParams, GetBoundingRectAfterMutationsWithTranslate) {
|
||||
MutatorsStack stack;
|
||||
SkMatrix matrix = SkMatrix::Translate(1, 1);
|
||||
DlMatrix matrix = DlMatrix::MakeTranslation({1, 1});
|
||||
stack.PushTransform(matrix);
|
||||
|
||||
EmbeddedViewParams params(matrix, SkSize::Make(1, 1), stack);
|
||||
EmbeddedViewParams params(ToSkMatrix(matrix), SkSize::Make(1, 1), stack);
|
||||
const SkRect& rect = params.finalBoundingRect();
|
||||
ASSERT_TRUE(SkScalarNearlyEqual(rect.x(), 1));
|
||||
ASSERT_TRUE(SkScalarNearlyEqual(rect.y(), 1));
|
||||
@ -49,11 +49,10 @@ TEST(EmbeddedViewParams, GetBoundingRectAfterMutationsWithTranslate) {
|
||||
|
||||
TEST(EmbeddedViewParams, GetBoundingRectAfterMutationsWithRotation90) {
|
||||
MutatorsStack stack;
|
||||
SkMatrix matrix;
|
||||
matrix.setRotate(90);
|
||||
DlMatrix matrix = DlMatrix::MakeRotationZ(DlDegrees(90));
|
||||
stack.PushTransform(matrix);
|
||||
|
||||
EmbeddedViewParams params(matrix, SkSize::Make(1, 1), stack);
|
||||
EmbeddedViewParams params(ToSkMatrix(matrix), SkSize::Make(1, 1), stack);
|
||||
const SkRect& rect = params.finalBoundingRect();
|
||||
|
||||
ASSERT_TRUE(SkScalarNearlyEqual(rect.x(), -1));
|
||||
@ -64,11 +63,10 @@ TEST(EmbeddedViewParams, GetBoundingRectAfterMutationsWithRotation90) {
|
||||
|
||||
TEST(EmbeddedViewParams, GetBoundingRectAfterMutationsWithRotation45) {
|
||||
MutatorsStack stack;
|
||||
SkMatrix matrix;
|
||||
matrix.setRotate(45);
|
||||
DlMatrix matrix = DlMatrix::MakeRotationZ(DlDegrees(45));
|
||||
stack.PushTransform(matrix);
|
||||
|
||||
EmbeddedViewParams params(matrix, SkSize::Make(1, 1), stack);
|
||||
EmbeddedViewParams params(ToSkMatrix(matrix), SkSize::Make(1, 1), stack);
|
||||
const SkRect& rect = params.finalBoundingRect();
|
||||
ASSERT_TRUE(SkScalarNearlyEqual(rect.x(), -sqrt(2) / 2));
|
||||
ASSERT_TRUE(SkScalarNearlyEqual(rect.y(), 0));
|
||||
@ -78,14 +76,14 @@ TEST(EmbeddedViewParams, GetBoundingRectAfterMutationsWithRotation45) {
|
||||
|
||||
TEST(EmbeddedViewParams,
|
||||
GetBoundingRectAfterMutationsWithTranslateScaleAndRotation) {
|
||||
SkMatrix matrix = SkMatrix::Translate(2, 2);
|
||||
matrix.preScale(3, 3);
|
||||
matrix.preRotate(90);
|
||||
DlMatrix matrix = DlMatrix::MakeTranslation({2, 2}) *
|
||||
DlMatrix::MakeScale({3, 3, 1}) *
|
||||
DlMatrix::MakeRotationZ(DlDegrees(90));
|
||||
|
||||
MutatorsStack stack;
|
||||
stack.PushTransform(matrix);
|
||||
|
||||
EmbeddedViewParams params(matrix, SkSize::Make(1, 1), stack);
|
||||
EmbeddedViewParams params(ToSkMatrix(matrix), SkSize::Make(1, 1), stack);
|
||||
const SkRect& rect = params.finalBoundingRect();
|
||||
ASSERT_TRUE(SkScalarNearlyEqual(rect.x(), -1));
|
||||
ASSERT_TRUE(SkScalarNearlyEqual(rect.y(), 2));
|
||||
|
@ -58,34 +58,39 @@ bool ExternalViewEmbedder::SupportsDynamicThreadMerging() {
|
||||
|
||||
void ExternalViewEmbedder::Teardown() {}
|
||||
|
||||
void MutatorsStack::PushClipRect(const SkRect& rect) {
|
||||
void MutatorsStack::PushClipRect(const DlRect& rect) {
|
||||
std::shared_ptr<Mutator> element = std::make_shared<Mutator>(rect);
|
||||
vector_.push_back(element);
|
||||
}
|
||||
|
||||
void MutatorsStack::PushClipRRect(const SkRRect& rrect) {
|
||||
void MutatorsStack::PushClipRRect(const DlRoundRect& rrect) {
|
||||
std::shared_ptr<Mutator> element = std::make_shared<Mutator>(rrect);
|
||||
vector_.push_back(element);
|
||||
}
|
||||
|
||||
void MutatorsStack::PushClipPath(const SkPath& path) {
|
||||
void MutatorsStack::PushClipRSE(const DlRoundSuperellipse& rrect) {
|
||||
std::shared_ptr<Mutator> element = std::make_shared<Mutator>(rrect);
|
||||
vector_.push_back(element);
|
||||
}
|
||||
|
||||
void MutatorsStack::PushClipPath(const DlPath& path) {
|
||||
std::shared_ptr<Mutator> element = std::make_shared<Mutator>(path);
|
||||
vector_.push_back(element);
|
||||
}
|
||||
|
||||
void MutatorsStack::PushTransform(const SkMatrix& matrix) {
|
||||
void MutatorsStack::PushTransform(const DlMatrix& matrix) {
|
||||
std::shared_ptr<Mutator> element = std::make_shared<Mutator>(matrix);
|
||||
vector_.push_back(element);
|
||||
}
|
||||
|
||||
void MutatorsStack::PushOpacity(const int& alpha) {
|
||||
void MutatorsStack::PushOpacity(const uint8_t& alpha) {
|
||||
std::shared_ptr<Mutator> element = std::make_shared<Mutator>(alpha);
|
||||
vector_.push_back(element);
|
||||
}
|
||||
|
||||
void MutatorsStack::PushBackdropFilter(
|
||||
const std::shared_ptr<DlImageFilter>& filter,
|
||||
const SkRect& filter_rect) {
|
||||
const DlRect& filter_rect) {
|
||||
std::shared_ptr<Mutator> element =
|
||||
std::make_shared<Mutator>(filter, filter_rect);
|
||||
vector_.push_back(element);
|
||||
|
@ -7,6 +7,7 @@
|
||||
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
#include <variant>
|
||||
#include <vector>
|
||||
|
||||
#include "flutter/display_list/dl_builder.h"
|
||||
@ -14,11 +15,6 @@
|
||||
#include "flutter/flow/surface_frame.h"
|
||||
#include "flutter/fml/memory/ref_counted.h"
|
||||
#include "flutter/fml/raster_thread_merger.h"
|
||||
#include "third_party/skia/include/core/SkMatrix.h"
|
||||
#include "third_party/skia/include/core/SkPath.h"
|
||||
#include "third_party/skia/include/core/SkRRect.h"
|
||||
#include "third_party/skia/include/core/SkRect.h"
|
||||
#include "third_party/skia/include/core/SkSize.h"
|
||||
|
||||
#if IMPELLER_SUPPORTS_RENDERING
|
||||
#include "flutter/impeller/display_list/aiks_context.h" // nogncheck
|
||||
@ -34,9 +30,10 @@ class GrDirectContext;
|
||||
|
||||
namespace flutter {
|
||||
|
||||
enum MutatorType {
|
||||
enum class MutatorType {
|
||||
kClipRect,
|
||||
kClipRRect,
|
||||
kClipRSE,
|
||||
kClipPath,
|
||||
kTransform,
|
||||
kOpacity,
|
||||
@ -46,16 +43,14 @@ enum MutatorType {
|
||||
// Represents an image filter mutation.
|
||||
//
|
||||
// Should be used for image_filter_layer and backdrop_filter_layer.
|
||||
// TODO(cyanglaz): Refactor this into a ImageFilterMutator class.
|
||||
// https://github.com/flutter/flutter/issues/108470
|
||||
class ImageFilterMutation {
|
||||
public:
|
||||
ImageFilterMutation(std::shared_ptr<DlImageFilter> filter,
|
||||
const SkRect& filter_rect)
|
||||
const DlRect& filter_rect)
|
||||
: filter_(std::move(filter)), filter_rect_(filter_rect) {}
|
||||
|
||||
const DlImageFilter& GetFilter() const { return *filter_; }
|
||||
const SkRect& GetFilterRect() const { return filter_rect_; }
|
||||
const DlRect& GetFilterRect() const { return filter_rect_; }
|
||||
|
||||
bool operator==(const ImageFilterMutation& other) const {
|
||||
return *filter_ == *other.filter_ && filter_rect_ == other.filter_rect_;
|
||||
@ -67,7 +62,7 @@ class ImageFilterMutation {
|
||||
|
||||
private:
|
||||
std::shared_ptr<DlImageFilter> filter_;
|
||||
const SkRect filter_rect_;
|
||||
const DlRect filter_rect_;
|
||||
};
|
||||
|
||||
// Stores mutation information like clipping or kTransform.
|
||||
@ -78,112 +73,65 @@ class ImageFilterMutation {
|
||||
// clipped. One mutation object must only contain one type of mutation.
|
||||
class Mutator {
|
||||
public:
|
||||
Mutator(const Mutator& other) {
|
||||
type_ = other.type_;
|
||||
switch (other.type_) {
|
||||
case kClipRect:
|
||||
rect_ = other.rect_;
|
||||
break;
|
||||
case kClipRRect:
|
||||
rrect_ = other.rrect_;
|
||||
break;
|
||||
case kClipPath:
|
||||
path_ = new SkPath(*other.path_);
|
||||
break;
|
||||
case kTransform:
|
||||
matrix_ = other.matrix_;
|
||||
break;
|
||||
case kOpacity:
|
||||
alpha_ = other.alpha_;
|
||||
break;
|
||||
case kBackdropFilter:
|
||||
filter_mutation_ = other.filter_mutation_;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
Mutator(const Mutator& other) : data_(other.data_) {}
|
||||
|
||||
explicit Mutator(const SkRect& rect) : type_(kClipRect), rect_(rect) {}
|
||||
explicit Mutator(const SkRRect& rrect) : type_(kClipRRect), rrect_(rrect) {}
|
||||
explicit Mutator(const SkPath& path)
|
||||
: type_(kClipPath), path_(new SkPath(path)) {}
|
||||
explicit Mutator(const SkMatrix& matrix)
|
||||
: type_(kTransform), matrix_(matrix) {}
|
||||
explicit Mutator(const int& alpha) : type_(kOpacity), alpha_(alpha) {}
|
||||
explicit Mutator(const std::shared_ptr<DlImageFilter>& filter,
|
||||
const SkRect& filter_rect)
|
||||
: type_(kBackdropFilter),
|
||||
filter_mutation_(
|
||||
std::make_shared<ImageFilterMutation>(filter, filter_rect)) {}
|
||||
|
||||
explicit Mutator(const DlRect& rect) : Mutator(ToSkRect(rect)) {}
|
||||
explicit Mutator(const DlRoundRect& rrect) : Mutator(ToSkRRect(rrect)) {}
|
||||
explicit Mutator(const DlPath& path) : Mutator(path.GetSkPath()) {}
|
||||
explicit Mutator(const DlMatrix& matrix) : Mutator(ToSkMatrix(matrix)) {}
|
||||
explicit Mutator(const DlRect& rect) : data_(rect) {}
|
||||
explicit Mutator(const DlRoundRect& rrect) : data_(rrect) {}
|
||||
explicit Mutator(const DlRoundSuperellipse& rrect) : data_(rrect) {}
|
||||
explicit Mutator(const DlPath& path) : data_(path) {}
|
||||
explicit Mutator(const DlMatrix& matrix) : data_(matrix) {}
|
||||
explicit Mutator(const uint8_t& alpha) : data_(alpha) {}
|
||||
explicit Mutator(const std::shared_ptr<DlImageFilter>& filter,
|
||||
const DlRect& filter_rect)
|
||||
: Mutator(filter, ToSkRect(filter_rect)) {}
|
||||
: data_(ImageFilterMutation(filter, filter_rect)) {}
|
||||
|
||||
const MutatorType& GetType() const { return type_; }
|
||||
const SkRect& GetRect() const { return rect_; }
|
||||
const SkRRect& GetRRect() const { return rrect_; }
|
||||
const SkPath& GetPath() const { return *path_; }
|
||||
const SkMatrix& GetMatrix() const { return matrix_; }
|
||||
MutatorType GetType() const {
|
||||
return static_cast<MutatorType>(data_.index());
|
||||
}
|
||||
|
||||
const DlRect& GetRect() const { return std::get<DlRect>(data_); }
|
||||
const DlRoundRect& GetRRect() const { return std::get<DlRoundRect>(data_); }
|
||||
const DlRoundSuperellipse& GetRSE() const {
|
||||
return std::get<DlRoundSuperellipse>(data_);
|
||||
}
|
||||
const DlRoundRect GetRSEApproximation() const {
|
||||
return GetRSE().ToApproximateRoundRect();
|
||||
}
|
||||
const DlPath& GetPath() const { return std::get<DlPath>(data_); }
|
||||
const DlMatrix& GetMatrix() const { return std::get<DlMatrix>(data_); }
|
||||
const ImageFilterMutation& GetFilterMutation() const {
|
||||
return *filter_mutation_;
|
||||
return std::get<ImageFilterMutation>(data_);
|
||||
}
|
||||
const int& GetAlpha() const { return alpha_; }
|
||||
float GetAlphaFloat() const { return (alpha_ / 255.0f); }
|
||||
const uint8_t& GetAlpha() const { return std::get<uint8_t>(data_); }
|
||||
float GetAlphaFloat() const { return DlColor::toOpacity(GetAlpha()); }
|
||||
|
||||
bool operator==(const Mutator& other) const {
|
||||
if (type_ != other.type_) {
|
||||
return false;
|
||||
}
|
||||
switch (type_) {
|
||||
case kClipRect:
|
||||
return rect_ == other.rect_;
|
||||
case kClipRRect:
|
||||
return rrect_ == other.rrect_;
|
||||
case kClipPath:
|
||||
return *path_ == *other.path_;
|
||||
case kTransform:
|
||||
return matrix_ == other.matrix_;
|
||||
case kOpacity:
|
||||
return alpha_ == other.alpha_;
|
||||
case kBackdropFilter:
|
||||
return *filter_mutation_ == *other.filter_mutation_;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
bool operator==(const Mutator& other) const { return data_ == other.data_; }
|
||||
|
||||
bool operator!=(const Mutator& other) const { return !operator==(other); }
|
||||
|
||||
bool IsClipType() {
|
||||
return type_ == kClipRect || type_ == kClipRRect || type_ == kClipPath;
|
||||
switch (GetType()) {
|
||||
case MutatorType::kClipRect:
|
||||
case MutatorType::kClipPath:
|
||||
case MutatorType::kClipRRect:
|
||||
case MutatorType::kClipRSE:
|
||||
return true;
|
||||
case MutatorType::kOpacity:
|
||||
case MutatorType::kTransform:
|
||||
case MutatorType::kBackdropFilter:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
~Mutator() {
|
||||
if (type_ == kClipPath) {
|
||||
delete path_;
|
||||
}
|
||||
};
|
||||
|
||||
private:
|
||||
MutatorType type_;
|
||||
|
||||
// TODO(cyanglaz): Remove union.
|
||||
// https://github.com/flutter/flutter/issues/108470
|
||||
union {
|
||||
SkRect rect_;
|
||||
SkRRect rrect_;
|
||||
SkMatrix matrix_;
|
||||
SkPath* path_;
|
||||
int alpha_;
|
||||
};
|
||||
|
||||
std::shared_ptr<ImageFilterMutation> filter_mutation_;
|
||||
std::variant<DlRect,
|
||||
DlRoundRect,
|
||||
DlRoundSuperellipse,
|
||||
DlPath,
|
||||
DlMatrix,
|
||||
uint8_t,
|
||||
ImageFilterMutation>
|
||||
data_;
|
||||
}; // Mutator
|
||||
|
||||
// A stack of mutators that can be applied to an embedded platform view.
|
||||
@ -199,14 +147,15 @@ class MutatorsStack {
|
||||
public:
|
||||
MutatorsStack() = default;
|
||||
|
||||
void PushClipRect(const SkRect& rect);
|
||||
void PushClipRRect(const SkRRect& rrect);
|
||||
void PushClipPath(const SkPath& path);
|
||||
void PushTransform(const SkMatrix& matrix);
|
||||
void PushOpacity(const int& alpha);
|
||||
void PushClipRect(const DlRect& rect);
|
||||
void PushClipRRect(const DlRoundRect& rrect);
|
||||
void PushClipRSE(const DlRoundSuperellipse& rrect);
|
||||
void PushClipPath(const DlPath& path);
|
||||
void PushTransform(const DlMatrix& matrix);
|
||||
void PushOpacity(const uint8_t& alpha);
|
||||
// `filter_rect` is in global coordinates.
|
||||
void PushBackdropFilter(const std::shared_ptr<DlImageFilter>& filter,
|
||||
const SkRect& filter_rect);
|
||||
const DlRect& filter_rect);
|
||||
|
||||
// Removes the `Mutator` on the top of the stack
|
||||
// and destroys it.
|
||||
@ -306,7 +255,7 @@ class EmbeddedViewParams {
|
||||
// `filter_rect` is in global coordinates.
|
||||
void PushImageFilter(const std::shared_ptr<DlImageFilter>& filter,
|
||||
const SkRect& filter_rect) {
|
||||
mutators_stack_.PushBackdropFilter(filter, filter_rect);
|
||||
mutators_stack_.PushBackdropFilter(filter, ToDlRect(filter_rect));
|
||||
}
|
||||
|
||||
bool operator==(const EmbeddedViewParams& other) const {
|
||||
|
@ -93,7 +93,7 @@ TEST_F(ClipRSuperellipseLayerTest, PaintingCulledLayerDies) {
|
||||
EXPECT_EQ(mock_layer->parent_cull_rect(), DlRect());
|
||||
EXPECT_EQ(mock_layer->parent_matrix(), initial_matrix);
|
||||
EXPECT_EQ(mock_layer->parent_mutators(),
|
||||
std::vector({Mutator(ToApproximateSkRRect(layer_rsuperellipse))}));
|
||||
std::vector({Mutator(layer_rsuperellipse)}));
|
||||
|
||||
auto mutator = paint_context().state_stack.save();
|
||||
mutator.clipRect(distant_bounds, false);
|
||||
@ -145,7 +145,7 @@ TEST_F(ClipRSuperellipseLayerTest, ChildOutsideBounds) {
|
||||
EXPECT_EQ(mock_layer->parent_cull_rect(), clip_cull_rect.value());
|
||||
EXPECT_EQ(mock_layer->parent_matrix(), initial_matrix);
|
||||
EXPECT_EQ(mock_layer->parent_mutators(),
|
||||
std::vector({Mutator(ToApproximateSkRRect(clip_rsuperellipse))}));
|
||||
std::vector({Mutator(clip_rsuperellipse)}));
|
||||
|
||||
EXPECT_FALSE(mock_layer->needs_painting(paint_context()));
|
||||
ASSERT_FALSE(layer->needs_painting(paint_context()));
|
||||
@ -182,7 +182,7 @@ TEST_F(ClipRSuperellipseLayerTest, FullyContainedChild) {
|
||||
EXPECT_EQ(mock_layer->parent_cull_rect(), layer_bounds);
|
||||
EXPECT_EQ(mock_layer->parent_matrix(), initial_matrix);
|
||||
EXPECT_EQ(mock_layer->parent_mutators(),
|
||||
std::vector({Mutator(ToApproximateSkRRect(layer_rsuperellipse))}));
|
||||
std::vector({Mutator(layer_rsuperellipse)}));
|
||||
|
||||
layer->Paint(display_list_paint_context());
|
||||
DisplayListBuilder expected_builder;
|
||||
@ -238,7 +238,7 @@ TEST_F(ClipRSuperellipseLayerTest, PartiallyContainedChild) {
|
||||
EXPECT_EQ(mock_layer->parent_cull_rect(), clip_cull_rect.value());
|
||||
EXPECT_EQ(mock_layer->parent_matrix(), initial_matrix);
|
||||
EXPECT_EQ(mock_layer->parent_mutators(),
|
||||
std::vector({Mutator(ToApproximateSkRRect(clip_rsuperellipse))}));
|
||||
std::vector({Mutator(clip_rsuperellipse)}));
|
||||
|
||||
layer->Paint(display_list_paint_context());
|
||||
DisplayListBuilder expected_builder;
|
||||
|
@ -246,7 +246,7 @@ class SaveLayerEntry : public LayerStateStack::StateEntry {
|
||||
class OpacityEntry : public LayerStateStack::StateEntry {
|
||||
public:
|
||||
OpacityEntry(const DlRect& bounds,
|
||||
SkScalar opacity,
|
||||
DlScalar opacity,
|
||||
const LayerStateStack::RenderingAttributes& prev)
|
||||
: bounds_(bounds),
|
||||
opacity_(opacity),
|
||||
@ -376,18 +376,17 @@ class BackdropFilterEntry : public SaveLayerEntry {
|
||||
|
||||
class TranslateEntry : public LayerStateStack::StateEntry {
|
||||
public:
|
||||
TranslateEntry(SkScalar tx, SkScalar ty) : tx_(tx), ty_(ty) {}
|
||||
TranslateEntry(DlScalar tx, DlScalar ty) : translation_(tx, ty) {}
|
||||
|
||||
void apply(LayerStateStack* stack) const override {
|
||||
stack->delegate_->translate(tx_, ty_);
|
||||
stack->delegate_->translate(translation_.x, translation_.y);
|
||||
}
|
||||
void update_mutators(MutatorsStack* mutators_stack) const override {
|
||||
mutators_stack->PushTransform(SkMatrix::Translate(tx_, ty_));
|
||||
mutators_stack->PushTransform(DlMatrix::MakeTranslation(translation_));
|
||||
}
|
||||
|
||||
private:
|
||||
const SkScalar tx_;
|
||||
const SkScalar ty_;
|
||||
const DlPoint translation_;
|
||||
|
||||
FML_DISALLOW_COPY_ASSIGN_AND_MOVE(TranslateEntry);
|
||||
};
|
||||
@ -400,7 +399,7 @@ class TransformMatrixEntry : public LayerStateStack::StateEntry {
|
||||
stack->delegate_->transform(matrix_);
|
||||
}
|
||||
void update_mutators(MutatorsStack* mutators_stack) const override {
|
||||
mutators_stack->PushTransform(ToSkMatrix(matrix_));
|
||||
mutators_stack->PushTransform(matrix_);
|
||||
}
|
||||
|
||||
private:
|
||||
@ -430,7 +429,7 @@ class ClipRectEntry : public LayerStateStack::StateEntry {
|
||||
stack->delegate_->clipRect(clip_rect_, DlClipOp::kIntersect, is_aa_);
|
||||
}
|
||||
void update_mutators(MutatorsStack* mutators_stack) const override {
|
||||
mutators_stack->PushClipRect(ToSkRect(clip_rect_));
|
||||
mutators_stack->PushClipRect(clip_rect_);
|
||||
}
|
||||
|
||||
private:
|
||||
@ -449,7 +448,7 @@ class ClipRRectEntry : public LayerStateStack::StateEntry {
|
||||
stack->delegate_->clipRRect(clip_rrect_, DlClipOp::kIntersect, is_aa_);
|
||||
}
|
||||
void update_mutators(MutatorsStack* mutators_stack) const override {
|
||||
mutators_stack->PushClipRRect(ToSkRRect(clip_rrect_));
|
||||
mutators_stack->PushClipRRect(clip_rrect_);
|
||||
}
|
||||
|
||||
private:
|
||||
@ -470,13 +469,7 @@ class ClipRSuperellipseEntry : public LayerStateStack::StateEntry {
|
||||
DlClipOp::kIntersect, is_aa_);
|
||||
}
|
||||
void update_mutators(MutatorsStack* mutators_stack) const override {
|
||||
// MutatorsStack doesn't support non-Skia classes, and therefore this method
|
||||
// has to use approximate RRect, which might cause trouble for certain
|
||||
// embedded apps.
|
||||
// TODO(dkwingsmt): Make this method push a correct ClipRoundedSuperellipse
|
||||
// mutator.
|
||||
// https://github.com/flutter/flutter/issues/163716
|
||||
mutators_stack->PushClipRRect(ToApproximateSkRRect(clip_rsuperellipse_));
|
||||
mutators_stack->PushClipRSE(clip_rsuperellipse_);
|
||||
}
|
||||
|
||||
private:
|
||||
@ -496,7 +489,7 @@ class ClipPathEntry : public LayerStateStack::StateEntry {
|
||||
stack->delegate_->clipPath(clip_path_, DlClipOp::kIntersect, is_aa_);
|
||||
}
|
||||
void update_mutators(MutatorsStack* mutators_stack) const override {
|
||||
mutators_stack->PushClipPath(clip_path_.GetSkPath());
|
||||
mutators_stack->PushClipPath(clip_path_);
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -16,8 +16,8 @@ TEST(MutatorsStack, Initialization) {
|
||||
|
||||
TEST(MutatorsStack, CopyConstructor) {
|
||||
MutatorsStack stack;
|
||||
auto rrect = SkRRect::MakeEmpty();
|
||||
auto rect = SkRect::MakeEmpty();
|
||||
auto rrect = DlRoundRect();
|
||||
auto rect = DlRect();
|
||||
stack.PushClipRect(rect);
|
||||
stack.PushClipRRect(rrect);
|
||||
MutatorsStack copy = MutatorsStack(stack);
|
||||
@ -26,8 +26,8 @@ TEST(MutatorsStack, CopyConstructor) {
|
||||
|
||||
TEST(MutatorsStack, CopyAndUpdateTheCopy) {
|
||||
MutatorsStack stack;
|
||||
auto rrect = SkRRect::MakeEmpty();
|
||||
auto rect = SkRect::MakeEmpty();
|
||||
auto rrect = DlRoundRect();
|
||||
auto rect = DlRect();
|
||||
stack.PushClipRect(rect);
|
||||
stack.PushClipRRect(rrect);
|
||||
MutatorsStack copy = MutatorsStack(stack);
|
||||
@ -46,7 +46,7 @@ TEST(MutatorsStack, CopyAndUpdateTheCopy) {
|
||||
|
||||
TEST(MutatorsStack, PushClipRect) {
|
||||
MutatorsStack stack;
|
||||
auto rect = SkRect::MakeEmpty();
|
||||
auto rect = DlRect();
|
||||
stack.PushClipRect(rect);
|
||||
auto iter = stack.Bottom();
|
||||
ASSERT_TRUE(iter->get()->GetType() == MutatorType::kClipRect);
|
||||
@ -55,16 +55,25 @@ TEST(MutatorsStack, PushClipRect) {
|
||||
|
||||
TEST(MutatorsStack, PushClipRRect) {
|
||||
MutatorsStack stack;
|
||||
auto rrect = SkRRect::MakeEmpty();
|
||||
auto rrect = DlRoundRect();
|
||||
stack.PushClipRRect(rrect);
|
||||
auto iter = stack.Bottom();
|
||||
ASSERT_TRUE(iter->get()->GetType() == MutatorType::kClipRRect);
|
||||
ASSERT_TRUE(iter->get()->GetRRect() == rrect);
|
||||
}
|
||||
|
||||
TEST(MutatorsStack, PushClipRSE) {
|
||||
MutatorsStack stack;
|
||||
auto rse = DlRoundSuperellipse();
|
||||
stack.PushClipRSE(rse);
|
||||
auto iter = stack.Bottom();
|
||||
ASSERT_TRUE(iter->get()->GetType() == MutatorType::kClipRSE);
|
||||
ASSERT_TRUE(iter->get()->GetRSE() == rse);
|
||||
}
|
||||
|
||||
TEST(MutatorsStack, PushClipPath) {
|
||||
MutatorsStack stack;
|
||||
SkPath path;
|
||||
DlPath path;
|
||||
stack.PushClipPath(path);
|
||||
auto iter = stack.Bottom();
|
||||
ASSERT_TRUE(iter->get()->GetType() == flutter::MutatorType::kClipPath);
|
||||
@ -73,8 +82,7 @@ TEST(MutatorsStack, PushClipPath) {
|
||||
|
||||
TEST(MutatorsStack, PushTransform) {
|
||||
MutatorsStack stack;
|
||||
SkMatrix matrix;
|
||||
matrix.setIdentity();
|
||||
DlMatrix matrix;
|
||||
stack.PushTransform(matrix);
|
||||
auto iter = stack.Bottom();
|
||||
ASSERT_TRUE(iter->get()->GetType() == MutatorType::kTransform);
|
||||
@ -83,7 +91,7 @@ TEST(MutatorsStack, PushTransform) {
|
||||
|
||||
TEST(MutatorsStack, PushOpacity) {
|
||||
MutatorsStack stack;
|
||||
int alpha = 240;
|
||||
uint8_t alpha = 240;
|
||||
stack.PushOpacity(alpha);
|
||||
auto iter = stack.Bottom();
|
||||
ASSERT_TRUE(iter->get()->GetType() == MutatorType::kOpacity);
|
||||
@ -95,7 +103,7 @@ TEST(MutatorsStack, PushBackdropFilter) {
|
||||
const int num_of_mutators = 10;
|
||||
for (int i = 0; i < num_of_mutators; i++) {
|
||||
auto filter = DlImageFilter::MakeBlur(i, 5, DlTileMode::kClamp);
|
||||
stack.PushBackdropFilter(filter, SkRect::MakeXYWH(i, i, i, i));
|
||||
stack.PushBackdropFilter(filter, DlRect::MakeXYWH(i, i, i, i));
|
||||
}
|
||||
|
||||
auto iter = stack.Begin();
|
||||
@ -104,10 +112,10 @@ TEST(MutatorsStack, PushBackdropFilter) {
|
||||
ASSERT_EQ(iter->get()->GetType(), MutatorType::kBackdropFilter);
|
||||
ASSERT_EQ(iter->get()->GetFilterMutation().GetFilter().asBlur()->sigma_x(),
|
||||
i);
|
||||
ASSERT_EQ(iter->get()->GetFilterMutation().GetFilterRect().x(), i);
|
||||
ASSERT_EQ(iter->get()->GetFilterMutation().GetFilterRect().x(), i);
|
||||
ASSERT_EQ(iter->get()->GetFilterMutation().GetFilterRect().width(), i);
|
||||
ASSERT_EQ(iter->get()->GetFilterMutation().GetFilterRect().height(), i);
|
||||
ASSERT_EQ(iter->get()->GetFilterMutation().GetFilterRect().GetX(), i);
|
||||
ASSERT_EQ(iter->get()->GetFilterMutation().GetFilterRect().GetY(), i);
|
||||
ASSERT_EQ(iter->get()->GetFilterMutation().GetFilterRect().GetWidth(), i);
|
||||
ASSERT_EQ(iter->get()->GetFilterMutation().GetFilterRect().GetHeight(), i);
|
||||
++iter;
|
||||
++i;
|
||||
}
|
||||
@ -116,8 +124,7 @@ TEST(MutatorsStack, PushBackdropFilter) {
|
||||
|
||||
TEST(MutatorsStack, Pop) {
|
||||
MutatorsStack stack;
|
||||
SkMatrix matrix;
|
||||
matrix.setIdentity();
|
||||
DlMatrix matrix;
|
||||
stack.PushTransform(matrix);
|
||||
stack.Pop();
|
||||
auto iter = stack.Bottom();
|
||||
@ -126,12 +133,11 @@ TEST(MutatorsStack, Pop) {
|
||||
|
||||
TEST(MutatorsStack, Traversal) {
|
||||
MutatorsStack stack;
|
||||
SkMatrix matrix;
|
||||
matrix.setIdentity();
|
||||
DlMatrix matrix;
|
||||
stack.PushTransform(matrix);
|
||||
auto rect = SkRect::MakeEmpty();
|
||||
auto rect = DlRect();
|
||||
stack.PushClipRect(rect);
|
||||
auto rrect = SkRRect::MakeEmpty();
|
||||
auto rrect = DlRoundRect();
|
||||
stack.PushClipRRect(rrect);
|
||||
auto iter = stack.Bottom();
|
||||
int index = 0;
|
||||
@ -159,153 +165,165 @@ TEST(MutatorsStack, Traversal) {
|
||||
|
||||
TEST(MutatorsStack, Equality) {
|
||||
MutatorsStack stack;
|
||||
SkMatrix matrix = SkMatrix::Scale(1, 1);
|
||||
DlMatrix matrix = DlMatrix::MakeScale({1, 1, 1});
|
||||
stack.PushTransform(matrix);
|
||||
SkRect rect = SkRect::MakeEmpty();
|
||||
DlRect rect = DlRect();
|
||||
stack.PushClipRect(rect);
|
||||
SkRRect rrect = SkRRect::MakeEmpty();
|
||||
DlRoundRect rrect = DlRoundRect();
|
||||
stack.PushClipRRect(rrect);
|
||||
SkPath path;
|
||||
DlPath path;
|
||||
stack.PushClipPath(path);
|
||||
int alpha = 240;
|
||||
uint8_t alpha = 240;
|
||||
stack.PushOpacity(alpha);
|
||||
auto filter = DlImageFilter::MakeBlur(5, 5, DlTileMode::kClamp);
|
||||
stack.PushBackdropFilter(filter, SkRect::MakeEmpty());
|
||||
stack.PushBackdropFilter(filter, DlRect());
|
||||
|
||||
MutatorsStack stack_other;
|
||||
SkMatrix matrix_other = SkMatrix::Scale(1, 1);
|
||||
DlMatrix matrix_other = DlMatrix::MakeScale({1, 1, 1});
|
||||
stack_other.PushTransform(matrix_other);
|
||||
SkRect rect_other = SkRect::MakeEmpty();
|
||||
DlRect rect_other = DlRect();
|
||||
stack_other.PushClipRect(rect_other);
|
||||
SkRRect rrect_other = SkRRect::MakeEmpty();
|
||||
DlRoundRect rrect_other = DlRoundRect();
|
||||
stack_other.PushClipRRect(rrect_other);
|
||||
SkPath other_path;
|
||||
DlPath other_path;
|
||||
stack_other.PushClipPath(other_path);
|
||||
int other_alpha = 240;
|
||||
uint8_t other_alpha = 240;
|
||||
stack_other.PushOpacity(other_alpha);
|
||||
auto other_filter = DlImageFilter::MakeBlur(5, 5, DlTileMode::kClamp);
|
||||
stack_other.PushBackdropFilter(other_filter, SkRect::MakeEmpty());
|
||||
stack_other.PushBackdropFilter(other_filter, DlRect());
|
||||
|
||||
ASSERT_TRUE(stack == stack_other);
|
||||
}
|
||||
|
||||
TEST(Mutator, Initialization) {
|
||||
SkRect rect = SkRect::MakeEmpty();
|
||||
DlRect rect = DlRect();
|
||||
Mutator mutator = Mutator(rect);
|
||||
ASSERT_TRUE(mutator.GetType() == MutatorType::kClipRect);
|
||||
ASSERT_TRUE(mutator.GetRect() == rect);
|
||||
|
||||
SkRRect rrect = SkRRect::MakeEmpty();
|
||||
DlRoundRect rrect = DlRoundRect();
|
||||
Mutator mutator2 = Mutator(rrect);
|
||||
ASSERT_TRUE(mutator2.GetType() == MutatorType::kClipRRect);
|
||||
ASSERT_TRUE(mutator2.GetRRect() == rrect);
|
||||
|
||||
SkPath path;
|
||||
DlRoundSuperellipse rse = DlRoundSuperellipse();
|
||||
Mutator mutator2se = Mutator(rse);
|
||||
ASSERT_TRUE(mutator2se.GetType() == MutatorType::kClipRSE);
|
||||
ASSERT_TRUE(mutator2se.GetRSE() == rse);
|
||||
|
||||
DlPath path;
|
||||
Mutator mutator3 = Mutator(path);
|
||||
ASSERT_TRUE(mutator3.GetType() == MutatorType::kClipPath);
|
||||
ASSERT_TRUE(mutator3.GetPath() == path);
|
||||
|
||||
SkMatrix matrix;
|
||||
matrix.setIdentity();
|
||||
DlMatrix matrix;
|
||||
Mutator mutator4 = Mutator(matrix);
|
||||
ASSERT_TRUE(mutator4.GetType() == MutatorType::kTransform);
|
||||
ASSERT_TRUE(mutator4.GetMatrix() == matrix);
|
||||
|
||||
int alpha = 240;
|
||||
uint8_t alpha = 240;
|
||||
Mutator mutator5 = Mutator(alpha);
|
||||
ASSERT_TRUE(mutator5.GetType() == MutatorType::kOpacity);
|
||||
|
||||
auto filter = DlImageFilter::MakeBlur(5, 5, DlTileMode::kClamp);
|
||||
Mutator mutator6 = Mutator(filter, SkRect::MakeEmpty());
|
||||
Mutator mutator6 = Mutator(filter, DlRect());
|
||||
ASSERT_TRUE(mutator6.GetType() == MutatorType::kBackdropFilter);
|
||||
ASSERT_TRUE(mutator6.GetFilterMutation().GetFilter() == *filter);
|
||||
}
|
||||
|
||||
TEST(Mutator, CopyConstructor) {
|
||||
SkRect rect = SkRect::MakeEmpty();
|
||||
DlRect rect = DlRect();
|
||||
Mutator mutator = Mutator(rect);
|
||||
Mutator copy = Mutator(mutator);
|
||||
ASSERT_TRUE(mutator == copy);
|
||||
|
||||
SkRRect rrect = SkRRect::MakeEmpty();
|
||||
DlRoundRect rrect = DlRoundRect();
|
||||
Mutator mutator2 = Mutator(rrect);
|
||||
Mutator copy2 = Mutator(mutator2);
|
||||
ASSERT_TRUE(mutator2 == copy2);
|
||||
|
||||
SkPath path;
|
||||
DlRoundSuperellipse rse = DlRoundSuperellipse();
|
||||
Mutator mutator2se = Mutator(rse);
|
||||
Mutator copy2se = Mutator(mutator2se);
|
||||
ASSERT_TRUE(mutator2se == copy2se);
|
||||
|
||||
DlPath path;
|
||||
Mutator mutator3 = Mutator(path);
|
||||
Mutator copy3 = Mutator(mutator3);
|
||||
ASSERT_TRUE(mutator3 == copy3);
|
||||
|
||||
SkMatrix matrix;
|
||||
matrix.setIdentity();
|
||||
DlMatrix matrix;
|
||||
Mutator mutator4 = Mutator(matrix);
|
||||
Mutator copy4 = Mutator(mutator4);
|
||||
ASSERT_TRUE(mutator4 == copy4);
|
||||
|
||||
int alpha = 240;
|
||||
uint8_t alpha = 240;
|
||||
Mutator mutator5 = Mutator(alpha);
|
||||
Mutator copy5 = Mutator(mutator5);
|
||||
ASSERT_TRUE(mutator5 == copy5);
|
||||
|
||||
auto filter = DlImageFilter::MakeBlur(5, 5, DlTileMode::kClamp);
|
||||
Mutator mutator6 = Mutator(filter, SkRect::MakeEmpty());
|
||||
Mutator mutator6 = Mutator(filter, DlRect());
|
||||
Mutator copy6 = Mutator(mutator6);
|
||||
ASSERT_TRUE(mutator6 == copy6);
|
||||
}
|
||||
|
||||
TEST(Mutator, Equality) {
|
||||
SkMatrix matrix;
|
||||
matrix.setIdentity();
|
||||
DlMatrix matrix;
|
||||
Mutator mutator = Mutator(matrix);
|
||||
Mutator other_mutator = Mutator(matrix);
|
||||
ASSERT_TRUE(mutator == other_mutator);
|
||||
|
||||
SkRect rect = SkRect::MakeEmpty();
|
||||
DlRect rect = DlRect();
|
||||
Mutator mutator2 = Mutator(rect);
|
||||
Mutator other_mutator2 = Mutator(rect);
|
||||
ASSERT_TRUE(mutator2 == other_mutator2);
|
||||
|
||||
SkRRect rrect = SkRRect::MakeEmpty();
|
||||
DlRoundRect rrect = DlRoundRect();
|
||||
Mutator mutator3 = Mutator(rrect);
|
||||
Mutator other_mutator3 = Mutator(rrect);
|
||||
ASSERT_TRUE(mutator3 == other_mutator3);
|
||||
|
||||
SkPath path;
|
||||
DlRoundSuperellipse rse = DlRoundSuperellipse();
|
||||
Mutator mutator3se = Mutator(rse);
|
||||
Mutator other_mutator3se = Mutator(rse);
|
||||
ASSERT_TRUE(mutator3se == other_mutator3se);
|
||||
|
||||
DlPath path;
|
||||
flutter::Mutator mutator4 = flutter::Mutator(path);
|
||||
flutter::Mutator other_mutator4 = flutter::Mutator(path);
|
||||
ASSERT_TRUE(mutator4 == other_mutator4);
|
||||
ASSERT_FALSE(mutator2 == mutator);
|
||||
int alpha = 240;
|
||||
|
||||
uint8_t alpha = 240;
|
||||
Mutator mutator5 = Mutator(alpha);
|
||||
Mutator other_mutator5 = Mutator(alpha);
|
||||
ASSERT_TRUE(mutator5 == other_mutator5);
|
||||
|
||||
auto filter1 = DlImageFilter::MakeBlur(5, 5, DlTileMode::kClamp);
|
||||
auto filter2 = DlImageFilter::MakeBlur(5, 5, DlTileMode::kClamp);
|
||||
Mutator mutator6 = Mutator(filter1, SkRect::MakeEmpty());
|
||||
Mutator other_mutator6 = Mutator(filter2, SkRect::MakeEmpty());
|
||||
Mutator mutator6 = Mutator(filter1, DlRect());
|
||||
Mutator other_mutator6 = Mutator(filter2, DlRect());
|
||||
ASSERT_TRUE(mutator6 == other_mutator6);
|
||||
}
|
||||
|
||||
TEST(Mutator, UnEquality) {
|
||||
SkRect rect = SkRect::MakeEmpty();
|
||||
DlRect rect = DlRect();
|
||||
Mutator mutator = Mutator(rect);
|
||||
SkMatrix matrix;
|
||||
matrix.setIdentity();
|
||||
DlMatrix matrix;
|
||||
Mutator not_equal_mutator = Mutator(matrix);
|
||||
ASSERT_TRUE(not_equal_mutator != mutator);
|
||||
|
||||
int alpha = 240;
|
||||
int alpha2 = 241;
|
||||
uint8_t alpha = 240;
|
||||
uint8_t alpha2 = 241;
|
||||
Mutator mutator2 = Mutator(alpha);
|
||||
Mutator other_mutator2 = Mutator(alpha2);
|
||||
ASSERT_TRUE(mutator2 != other_mutator2);
|
||||
|
||||
auto filter = DlImageFilter::MakeBlur(5, 5, DlTileMode::kClamp);
|
||||
auto filter2 = DlImageFilter::MakeBlur(10, 10, DlTileMode::kClamp);
|
||||
Mutator mutator3 = Mutator(filter, SkRect::MakeEmpty());
|
||||
Mutator other_mutator3 = Mutator(filter2, SkRect::MakeEmpty());
|
||||
Mutator mutator3 = Mutator(filter, DlRect());
|
||||
Mutator other_mutator3 = Mutator(filter2, DlRect());
|
||||
ASSERT_TRUE(mutator3 != other_mutator3);
|
||||
}
|
||||
|
||||
|
@ -53,8 +53,7 @@ TEST_F(MockLayerTest, SimpleParams) {
|
||||
EXPECT_EQ(preroll_context()->has_platform_view, false);
|
||||
EXPECT_EQ(layer->paint_bounds(), path.GetBounds());
|
||||
EXPECT_TRUE(layer->needs_painting(paint_context()));
|
||||
EXPECT_EQ(layer->parent_mutators(),
|
||||
std::vector{Mutator(ToSkMatrix(scale_matrix))});
|
||||
EXPECT_EQ(layer->parent_mutators(), std::vector{Mutator(scale_matrix)});
|
||||
EXPECT_EQ(layer->parent_matrix(), combined_matrix);
|
||||
EXPECT_EQ(layer->parent_cull_rect(), local_cull_rect);
|
||||
EXPECT_EQ(layer->parent_has_platform_view(), parent_has_platform_view);
|
||||
|
@ -1016,7 +1016,7 @@ TEST_F(ShellTest, PushBackdropFilterToVisitedPlatformViews) {
|
||||
// Make sure the filterRect is in global coordinates (contains the (1,1)
|
||||
// translation).
|
||||
ASSERT_EQ(mutator->GetFilterMutation().GetFilterRect(),
|
||||
SkRect::MakeLTRB(1, 1, 31, 31));
|
||||
DlRect::MakeLTRB(1, 1, 31, 31));
|
||||
|
||||
DestroyShell(std::move(shell));
|
||||
#endif // OS_FUCHSIA
|
||||
|
@ -340,17 +340,15 @@ TEST(AndroidExternalViewEmbedder, SubmitFlutterView) {
|
||||
|
||||
// Add an Android view.
|
||||
MutatorsStack stack1;
|
||||
SkMatrix matrix1;
|
||||
matrix1.setIdentity();
|
||||
SkMatrix scale = SkMatrix::Scale(1.5, 1.5);
|
||||
SkMatrix trans = SkMatrix::Translate(100, 100);
|
||||
matrix1.setConcat(scale, trans);
|
||||
DlMatrix scale = DlMatrix::MakeScale({1.5, 1.5, 1});
|
||||
DlMatrix trans = DlMatrix::MakeTranslation({100, 100});
|
||||
DlMatrix matrix1 = scale * trans;
|
||||
stack1.PushTransform(scale);
|
||||
stack1.PushTransform(trans);
|
||||
// TODO(egarciad): Investigate why Flow applies the device pixel ratio to
|
||||
// the offsetPixels, but not the sizePoints.
|
||||
auto view_params_1 = std::make_unique<EmbeddedViewParams>(
|
||||
matrix1, SkSize::Make(200, 200), stack1);
|
||||
ToSkMatrix(matrix1), SkSize::Make(200, 200), stack1);
|
||||
|
||||
embedder->PrerollCompositeEmbeddedView(0, std::move(view_params_1));
|
||||
// This is the recording canvas flow writes to.
|
||||
@ -411,17 +409,15 @@ TEST(AndroidExternalViewEmbedder, SubmitFlutterView) {
|
||||
|
||||
// Add an Android view.
|
||||
MutatorsStack stack1;
|
||||
SkMatrix matrix1;
|
||||
matrix1.setIdentity();
|
||||
SkMatrix scale = SkMatrix::Scale(1.5, 1.5);
|
||||
SkMatrix trans = SkMatrix::Translate(100, 100);
|
||||
matrix1.setConcat(scale, trans);
|
||||
DlMatrix scale = DlMatrix::MakeScale({1.5, 1.5, 1});
|
||||
DlMatrix trans = DlMatrix::MakeTranslation({100, 100});
|
||||
DlMatrix matrix1 = scale * trans;
|
||||
stack1.PushTransform(scale);
|
||||
stack1.PushTransform(trans);
|
||||
// TODO(egarciad): Investigate why Flow applies the device pixel ratio to
|
||||
// the offsetPixels, but not the sizePoints.
|
||||
auto view_params_1 = std::make_unique<EmbeddedViewParams>(
|
||||
matrix1, SkSize::Make(200, 200), stack1);
|
||||
ToSkMatrix(matrix1), SkSize::Make(200, 200), stack1);
|
||||
|
||||
embedder->PrerollCompositeEmbeddedView(0, std::move(view_params_1));
|
||||
// This is the recording canvas flow writes to.
|
||||
@ -623,7 +619,7 @@ TEST(AndroidExternalViewEmbedder, SubmitFrameOverlayComposition) {
|
||||
// Add first Android view.
|
||||
SkMatrix matrix;
|
||||
MutatorsStack stack;
|
||||
stack.PushTransform(SkMatrix::Translate(0, 0));
|
||||
stack.PushTransform(DlMatrix::MakeTranslation({0, 0}));
|
||||
|
||||
embedder->PrerollCompositeEmbeddedView(
|
||||
0, std::make_unique<EmbeddedViewParams>(matrix, SkSize::Make(200, 200),
|
||||
@ -644,7 +640,7 @@ TEST(AndroidExternalViewEmbedder, SubmitFrameOverlayComposition) {
|
||||
// Add second Android view.
|
||||
SkMatrix matrix;
|
||||
MutatorsStack stack;
|
||||
stack.PushTransform(SkMatrix::Translate(0, 100));
|
||||
stack.PushTransform(DlMatrix::MakeTranslation({0, 100}));
|
||||
|
||||
embedder->PrerollCompositeEmbeddedView(
|
||||
1, std::make_unique<EmbeddedViewParams>(matrix, SkSize::Make(100, 100),
|
||||
@ -730,7 +726,7 @@ TEST(AndroidExternalViewEmbedder, SubmitFramePlatformViewWithoutAnyOverlay) {
|
||||
// Add Android view.
|
||||
SkMatrix matrix;
|
||||
MutatorsStack stack;
|
||||
stack.PushTransform(SkMatrix::Translate(0, 0));
|
||||
stack.PushTransform(DlMatrix::MakeTranslation({0, 0}));
|
||||
|
||||
embedder->PrerollCompositeEmbeddedView(
|
||||
0, std::make_unique<EmbeddedViewParams>(matrix, SkSize::Make(200, 200),
|
||||
|
@ -1637,10 +1637,13 @@ void PlatformViewAndroidJNIImpl::FlutterViewOnDisplayPlatformView(
|
||||
mutators_stack.Begin();
|
||||
while (iter != mutators_stack.End()) {
|
||||
switch ((*iter)->GetType()) {
|
||||
case kTransform: {
|
||||
const SkMatrix& matrix = (*iter)->GetMatrix();
|
||||
SkScalar matrix_array[9];
|
||||
matrix.get9(matrix_array);
|
||||
case MutatorType::kTransform: {
|
||||
const DlMatrix& matrix = (*iter)->GetMatrix();
|
||||
DlScalar matrix_array[9]{
|
||||
matrix.m[0], matrix.m[4], matrix.m[12], //
|
||||
matrix.m[1], matrix.m[5], matrix.m[13], //
|
||||
matrix.m[3], matrix.m[7], matrix.m[15],
|
||||
};
|
||||
fml::jni::ScopedJavaLocalRef<jfloatArray> transformMatrix(
|
||||
env, env->NewFloatArray(9));
|
||||
|
||||
@ -1650,40 +1653,65 @@ void PlatformViewAndroidJNIImpl::FlutterViewOnDisplayPlatformView(
|
||||
transformMatrix.obj());
|
||||
break;
|
||||
}
|
||||
case kClipRect: {
|
||||
const SkRect& rect = (*iter)->GetRect();
|
||||
env->CallVoidMethod(
|
||||
mutatorsStack, g_mutators_stack_push_cliprect_method,
|
||||
static_cast<int>(rect.left()), static_cast<int>(rect.top()),
|
||||
static_cast<int>(rect.right()), static_cast<int>(rect.bottom()));
|
||||
case MutatorType::kClipRect: {
|
||||
const DlRect& rect = (*iter)->GetRect();
|
||||
env->CallVoidMethod(mutatorsStack,
|
||||
g_mutators_stack_push_cliprect_method,
|
||||
static_cast<int>(rect.GetLeft()), //
|
||||
static_cast<int>(rect.GetTop()), //
|
||||
static_cast<int>(rect.GetRight()), //
|
||||
static_cast<int>(rect.GetBottom()));
|
||||
break;
|
||||
}
|
||||
case kClipRRect: {
|
||||
const SkRRect& rrect = (*iter)->GetRRect();
|
||||
const SkRect& rect = rrect.rect();
|
||||
const SkVector& upper_left = rrect.radii(SkRRect::kUpperLeft_Corner);
|
||||
const SkVector& upper_right = rrect.radii(SkRRect::kUpperRight_Corner);
|
||||
const SkVector& lower_right = rrect.radii(SkRRect::kLowerRight_Corner);
|
||||
const SkVector& lower_left = rrect.radii(SkRRect::kLowerLeft_Corner);
|
||||
case MutatorType::kClipRRect: {
|
||||
const DlRoundRect& rrect = (*iter)->GetRRect();
|
||||
const DlRect& rect = rrect.GetBounds();
|
||||
const DlRoundingRadii radii = rrect.GetRadii();
|
||||
SkScalar radiis[8] = {
|
||||
upper_left.x(), upper_left.y(), upper_right.x(), upper_right.y(),
|
||||
lower_right.x(), lower_right.y(), lower_left.x(), lower_left.y(),
|
||||
radii.top_left.width, radii.top_left.height,
|
||||
radii.top_right.width, radii.top_right.height,
|
||||
radii.bottom_right.width, radii.bottom_right.height,
|
||||
radii.bottom_left.width, radii.bottom_left.height,
|
||||
};
|
||||
fml::jni::ScopedJavaLocalRef<jfloatArray> radiisArray(
|
||||
env, env->NewFloatArray(8));
|
||||
env->SetFloatArrayRegion(radiisArray.obj(), 0, 8, radiis);
|
||||
env->CallVoidMethod(
|
||||
mutatorsStack, g_mutators_stack_push_cliprrect_method,
|
||||
static_cast<int>(rect.left()), static_cast<int>(rect.top()),
|
||||
static_cast<int>(rect.right()), static_cast<int>(rect.bottom()),
|
||||
radiisArray.obj());
|
||||
env->CallVoidMethod(mutatorsStack,
|
||||
g_mutators_stack_push_cliprrect_method,
|
||||
static_cast<int>(rect.GetLeft()), //
|
||||
static_cast<int>(rect.GetTop()), //
|
||||
static_cast<int>(rect.GetRight()), //
|
||||
static_cast<int>(rect.GetBottom()), //
|
||||
radiisArray.obj());
|
||||
break;
|
||||
}
|
||||
case MutatorType::kClipRSE: {
|
||||
const DlRoundRect& rrect = (*iter)->GetRSEApproximation();
|
||||
const DlRect& rect = rrect.GetBounds();
|
||||
const DlRoundingRadii radii = rrect.GetRadii();
|
||||
SkScalar radiis[8] = {
|
||||
radii.top_left.width, radii.top_left.height,
|
||||
radii.top_right.width, radii.top_right.height,
|
||||
radii.bottom_right.width, radii.bottom_right.height,
|
||||
radii.bottom_left.width, radii.bottom_left.height,
|
||||
};
|
||||
fml::jni::ScopedJavaLocalRef<jfloatArray> radiisArray(
|
||||
env, env->NewFloatArray(8));
|
||||
env->SetFloatArrayRegion(radiisArray.obj(), 0, 8, radiis);
|
||||
env->CallVoidMethod(mutatorsStack,
|
||||
g_mutators_stack_push_cliprrect_method,
|
||||
static_cast<int>(rect.GetLeft()), //
|
||||
static_cast<int>(rect.GetTop()), //
|
||||
static_cast<int>(rect.GetRight()), //
|
||||
static_cast<int>(rect.GetBottom()), //
|
||||
radiisArray.obj());
|
||||
break;
|
||||
}
|
||||
// TODO(cyanglaz): Implement other mutators.
|
||||
// https://github.com/flutter/flutter/issues/58426
|
||||
case kClipPath:
|
||||
case kOpacity:
|
||||
case kBackdropFilter:
|
||||
case MutatorType::kClipPath:
|
||||
case MutatorType::kOpacity:
|
||||
case MutatorType::kBackdropFilter:
|
||||
break;
|
||||
}
|
||||
++iter;
|
||||
@ -2017,10 +2045,13 @@ void PlatformViewAndroidJNIImpl::onDisplayPlatformView2(
|
||||
mutators_stack.Begin();
|
||||
while (iter != mutators_stack.End()) {
|
||||
switch ((*iter)->GetType()) {
|
||||
case kTransform: {
|
||||
const SkMatrix& matrix = (*iter)->GetMatrix();
|
||||
SkScalar matrix_array[9];
|
||||
matrix.get9(matrix_array);
|
||||
case MutatorType::kTransform: {
|
||||
const DlMatrix& matrix = (*iter)->GetMatrix();
|
||||
DlScalar matrix_array[9]{
|
||||
matrix.m[0], matrix.m[4], matrix.m[12], //
|
||||
matrix.m[1], matrix.m[5], matrix.m[13], //
|
||||
matrix.m[3], matrix.m[7], matrix.m[15],
|
||||
};
|
||||
fml::jni::ScopedJavaLocalRef<jfloatArray> transformMatrix(
|
||||
env, env->NewFloatArray(9));
|
||||
|
||||
@ -2030,98 +2061,192 @@ void PlatformViewAndroidJNIImpl::onDisplayPlatformView2(
|
||||
transformMatrix.obj());
|
||||
break;
|
||||
}
|
||||
case kClipRect: {
|
||||
const SkRect& rect = (*iter)->GetRect();
|
||||
env->CallVoidMethod(
|
||||
mutatorsStack, g_mutators_stack_push_cliprect_method,
|
||||
static_cast<int>(rect.left()), static_cast<int>(rect.top()),
|
||||
static_cast<int>(rect.right()), static_cast<int>(rect.bottom()));
|
||||
case MutatorType::kClipRect: {
|
||||
const DlRect& rect = (*iter)->GetRect();
|
||||
env->CallVoidMethod(mutatorsStack,
|
||||
g_mutators_stack_push_cliprect_method,
|
||||
static_cast<int>(rect.GetLeft()), //
|
||||
static_cast<int>(rect.GetTop()), //
|
||||
static_cast<int>(rect.GetRight()), //
|
||||
static_cast<int>(rect.GetBottom()));
|
||||
break;
|
||||
}
|
||||
case kClipRRect: {
|
||||
const SkRRect& rrect = (*iter)->GetRRect();
|
||||
const SkRect& rect = rrect.rect();
|
||||
const SkVector& upper_left = rrect.radii(SkRRect::kUpperLeft_Corner);
|
||||
const SkVector& upper_right = rrect.radii(SkRRect::kUpperRight_Corner);
|
||||
const SkVector& lower_right = rrect.radii(SkRRect::kLowerRight_Corner);
|
||||
const SkVector& lower_left = rrect.radii(SkRRect::kLowerLeft_Corner);
|
||||
case MutatorType::kClipRRect: {
|
||||
const DlRoundRect& rrect = (*iter)->GetRRect();
|
||||
const DlRect& rect = rrect.GetBounds();
|
||||
const DlRoundingRadii& radii = rrect.GetRadii();
|
||||
SkScalar radiis[8] = {
|
||||
upper_left.x(), upper_left.y(), upper_right.x(), upper_right.y(),
|
||||
lower_right.x(), lower_right.y(), lower_left.x(), lower_left.y(),
|
||||
radii.top_left.width, radii.top_left.height,
|
||||
radii.top_right.width, radii.top_right.height,
|
||||
radii.bottom_right.width, radii.bottom_right.height,
|
||||
radii.bottom_left.width, radii.bottom_left.height,
|
||||
};
|
||||
fml::jni::ScopedJavaLocalRef<jfloatArray> radiisArray(
|
||||
env, env->NewFloatArray(8));
|
||||
env->SetFloatArrayRegion(radiisArray.obj(), 0, 8, radiis);
|
||||
env->CallVoidMethod(
|
||||
mutatorsStack, g_mutators_stack_push_cliprrect_method,
|
||||
static_cast<int>(rect.left()), static_cast<int>(rect.top()),
|
||||
static_cast<int>(rect.right()), static_cast<int>(rect.bottom()),
|
||||
radiisArray.obj());
|
||||
env->CallVoidMethod(mutatorsStack,
|
||||
g_mutators_stack_push_cliprrect_method,
|
||||
static_cast<int>(rect.GetLeft()), //
|
||||
static_cast<int>(rect.GetTop()), //
|
||||
static_cast<int>(rect.GetRight()), //
|
||||
static_cast<int>(rect.GetBottom()), //
|
||||
radiisArray.obj());
|
||||
break;
|
||||
}
|
||||
case kOpacity: {
|
||||
case MutatorType::kClipRSE: {
|
||||
const DlRoundRect& rrect = (*iter)->GetRSEApproximation();
|
||||
const DlRect& rect = rrect.GetBounds();
|
||||
const DlRoundingRadii& radii = rrect.GetRadii();
|
||||
SkScalar radiis[8] = {
|
||||
radii.top_left.width, radii.top_left.height,
|
||||
radii.top_right.width, radii.top_right.height,
|
||||
radii.bottom_right.width, radii.bottom_right.height,
|
||||
radii.bottom_left.width, radii.bottom_left.height,
|
||||
};
|
||||
fml::jni::ScopedJavaLocalRef<jfloatArray> radiisArray(
|
||||
env, env->NewFloatArray(8));
|
||||
env->SetFloatArrayRegion(radiisArray.obj(), 0, 8, radiis);
|
||||
env->CallVoidMethod(mutatorsStack,
|
||||
g_mutators_stack_push_cliprrect_method,
|
||||
static_cast<int>(rect.GetLeft()), //
|
||||
static_cast<int>(rect.GetTop()), //
|
||||
static_cast<int>(rect.GetRight()), //
|
||||
static_cast<int>(rect.GetBottom()), //
|
||||
radiisArray.obj());
|
||||
break;
|
||||
}
|
||||
case MutatorType::kOpacity: {
|
||||
float opacity = (*iter)->GetAlphaFloat();
|
||||
env->CallVoidMethod(mutatorsStack, g_mutators_stack_push_opacity_method,
|
||||
opacity);
|
||||
break;
|
||||
}
|
||||
// TODO(cyanglaz): Implement other mutators.
|
||||
// https://github.com/flutter/flutter/issues/58426
|
||||
case kClipPath: {
|
||||
const SkPath& path = (*iter)->GetPath();
|
||||
case MutatorType::kClipPath: {
|
||||
auto& dlPath = (*iter)->GetPath();
|
||||
// Sometimes a kClipPath mutator is actually housing a simpler
|
||||
// shape. This isn't usually an issue, but the impeller Path version
|
||||
// of an oval or round rect may be too approximated to really match
|
||||
// well between the rendering operations (which check for simpler
|
||||
// shapes) and handing a raw path to the platform. To make things
|
||||
// match better, we do the same shape reduction checks here as most
|
||||
// renderers perform (we don't look for a Rect shape, though as
|
||||
// those match pretty well on their own).
|
||||
//
|
||||
// This should eventually be handled at a higher level, as in the
|
||||
// clip_path_layer.
|
||||
// See https://github.com/flutter/flutter/issues/164666
|
||||
std::optional<DlRoundRect> path_rrect;
|
||||
{
|
||||
DlRect rect;
|
||||
if (dlPath.IsOval(&rect)) {
|
||||
path_rrect = DlRoundRect::MakeOval(rect);
|
||||
} else {
|
||||
DlRoundRect rrect;
|
||||
if (dlPath.IsRoundRect(&rrect)) {
|
||||
path_rrect = rrect;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (path_rrect.has_value()) {
|
||||
const DlRect& rect = path_rrect->GetBounds();
|
||||
const DlRoundingRadii& radii = path_rrect->GetRadii();
|
||||
SkScalar radiis[8] = {
|
||||
radii.top_left.width, radii.top_left.height,
|
||||
radii.top_right.width, radii.top_right.height,
|
||||
radii.bottom_right.width, radii.bottom_right.height,
|
||||
radii.bottom_left.width, radii.bottom_left.height,
|
||||
};
|
||||
fml::jni::ScopedJavaLocalRef<jfloatArray> radiisArray(
|
||||
env, env->NewFloatArray(8));
|
||||
env->SetFloatArrayRegion(radiisArray.obj(), 0, 8, radiis);
|
||||
env->CallVoidMethod(mutatorsStack,
|
||||
g_mutators_stack_push_cliprrect_method,
|
||||
static_cast<int>(rect.GetLeft()), //
|
||||
static_cast<int>(rect.GetTop()), //
|
||||
static_cast<int>(rect.GetRight()), //
|
||||
static_cast<int>(rect.GetBottom()), //
|
||||
radiisArray.obj());
|
||||
break;
|
||||
}
|
||||
|
||||
// Define and populate an Android Path with data from the Skia SkPath
|
||||
// Define and populate an Android Path with data from the DlPath
|
||||
jobject androidPath =
|
||||
env->NewObject(path_class->obj(), path_constructor);
|
||||
|
||||
SkPath::Iter pathIter(path, false);
|
||||
SkPoint points[4];
|
||||
SkPath::Verb verb;
|
||||
bool subpath_needs_close = false;
|
||||
std::optional<flutter::DlPoint> pending_moveto;
|
||||
|
||||
while ((verb = pathIter.next(points)) != SkPath::kDone_Verb) {
|
||||
switch (verb) {
|
||||
case SkPath::kMove_Verb: {
|
||||
env->CallVoidMethod(androidPath, path_move_to_method,
|
||||
points[0].fX, points[0].fY);
|
||||
auto resolve_moveto = [&env, &pending_moveto, &androidPath]() {
|
||||
if (pending_moveto.has_value()) {
|
||||
env->CallVoidMethod(androidPath, path_move_to_method,
|
||||
pending_moveto->x, pending_moveto->y);
|
||||
pending_moveto.reset();
|
||||
}
|
||||
};
|
||||
|
||||
auto& path = dlPath.GetPath();
|
||||
for (auto it = path.begin(), end = path.end(); it != end; ++it) {
|
||||
switch (it.type()) {
|
||||
case impeller::Path::ComponentType::kContour: {
|
||||
const impeller::ContourComponent* contour = it.contour();
|
||||
FML_DCHECK(contour != nullptr);
|
||||
if (subpath_needs_close) {
|
||||
env->CallVoidMethod(androidPath, path_close_method);
|
||||
}
|
||||
pending_moveto = contour->destination;
|
||||
subpath_needs_close = contour->IsClosed();
|
||||
break;
|
||||
}
|
||||
case SkPath::kLine_Verb: {
|
||||
case impeller::Path::ComponentType::kLinear: {
|
||||
const impeller::LinearPathComponent* linear = it.linear();
|
||||
FML_DCHECK(linear != nullptr);
|
||||
resolve_moveto();
|
||||
env->CallVoidMethod(androidPath, path_line_to_method,
|
||||
points[1].fX, points[1].fY);
|
||||
linear->p2.x, linear->p2.y);
|
||||
break;
|
||||
}
|
||||
case SkPath::kQuad_Verb: {
|
||||
case impeller::Path::ComponentType::kQuadratic: {
|
||||
const impeller::QuadraticPathComponent* quadratic =
|
||||
it.quadratic();
|
||||
FML_DCHECK(quadratic != nullptr);
|
||||
resolve_moveto();
|
||||
env->CallVoidMethod(androidPath, path_quad_to_method,
|
||||
points[1].fX, points[1].fY, points[2].fX,
|
||||
points[2].fY);
|
||||
quadratic->cp.x, quadratic->cp.y,
|
||||
quadratic->p2.x, quadratic->p2.y);
|
||||
break;
|
||||
}
|
||||
case SkPath::kCubic_Verb: {
|
||||
env->CallVoidMethod(androidPath, path_cubic_to_method,
|
||||
points[1].fX, points[1].fY, points[2].fX,
|
||||
points[2].fY, points[3].fX, points[3].fY);
|
||||
break;
|
||||
}
|
||||
case SkPath::kConic_Verb: {
|
||||
case impeller::Path::ComponentType::kConic: {
|
||||
const impeller::ConicPathComponent* conic = it.conic();
|
||||
FML_DCHECK(conic != nullptr);
|
||||
resolve_moveto();
|
||||
FML_DCHECK(path_conic_to_method != nullptr);
|
||||
env->CallVoidMethod(androidPath, path_conic_to_method,
|
||||
points[1].fX, points[1].fY, points[2].fX,
|
||||
points[2].fY, pathIter.conicWeight());
|
||||
conic->cp.x, conic->cp.y, //
|
||||
conic->p2.x, conic->p2.y, conic->weight);
|
||||
break;
|
||||
}
|
||||
|
||||
case SkPath::kClose_Verb: {
|
||||
env->CallVoidMethod(androidPath, path_close_method);
|
||||
case impeller::Path::ComponentType::kCubic: {
|
||||
const impeller::CubicPathComponent* cubic = it.cubic();
|
||||
FML_DCHECK(cubic != nullptr);
|
||||
resolve_moveto();
|
||||
env->CallVoidMethod(androidPath, path_cubic_to_method,
|
||||
cubic->cp1.x, cubic->cp1.y, //
|
||||
cubic->cp2.x, cubic->cp2.y, //
|
||||
cubic->p2.x, cubic->p2.y);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (subpath_needs_close) {
|
||||
env->CallVoidMethod(androidPath, path_close_method);
|
||||
}
|
||||
|
||||
env->CallVoidMethod(mutatorsStack,
|
||||
g_mutators_stack_push_clippath_method, androidPath);
|
||||
}
|
||||
case kBackdropFilter:
|
||||
// TODO(cyanglaz): Implement other mutators.
|
||||
// https://github.com/flutter/flutter/issues/58426
|
||||
case MutatorType::kBackdropFilter:
|
||||
break;
|
||||
}
|
||||
++iter;
|
||||
|
@ -12,26 +12,35 @@
|
||||
|
||||
FLUTTER_ASSERT_ARC
|
||||
|
||||
static constexpr int kMaxPointsInVerb = 4;
|
||||
|
||||
namespace {
|
||||
CGRect GetCGRectFromSkRect(const SkRect& clipSkRect) {
|
||||
return CGRectMake(clipSkRect.fLeft, clipSkRect.fTop, clipSkRect.fRight - clipSkRect.fLeft,
|
||||
clipSkRect.fBottom - clipSkRect.fTop);
|
||||
static CGRect GetCGRectFromDlRect(const flutter::DlRect& clipDlRect) {
|
||||
return CGRectMake(clipDlRect.GetX(), //
|
||||
clipDlRect.GetY(), //
|
||||
clipDlRect.GetWidth(), //
|
||||
clipDlRect.GetHeight());
|
||||
}
|
||||
|
||||
CATransform3D GetCATransform3DFromSkMatrix(const SkMatrix& matrix) {
|
||||
// Skia only supports 2D transform so we don't map z.
|
||||
CATransform3D GetCATransform3DFromDlMatrix(const flutter::DlMatrix& matrix) {
|
||||
CATransform3D transform = CATransform3DIdentity;
|
||||
transform.m11 = matrix.getScaleX();
|
||||
transform.m21 = matrix.getSkewX();
|
||||
transform.m41 = matrix.getTranslateX();
|
||||
transform.m14 = matrix.getPerspX();
|
||||
transform.m11 = matrix.m[0];
|
||||
transform.m12 = matrix.m[1];
|
||||
transform.m13 = matrix.m[2];
|
||||
transform.m14 = matrix.m[3];
|
||||
|
||||
transform.m12 = matrix.getSkewY();
|
||||
transform.m22 = matrix.getScaleY();
|
||||
transform.m42 = matrix.getTranslateY();
|
||||
transform.m24 = matrix.getPerspY();
|
||||
transform.m21 = matrix.m[4];
|
||||
transform.m22 = matrix.m[5];
|
||||
transform.m23 = matrix.m[6];
|
||||
transform.m24 = matrix.m[7];
|
||||
|
||||
transform.m31 = matrix.m[8];
|
||||
transform.m32 = matrix.m[9];
|
||||
transform.m33 = matrix.m[10];
|
||||
transform.m34 = matrix.m[11];
|
||||
|
||||
transform.m41 = matrix.m[12];
|
||||
transform.m42 = matrix.m[13];
|
||||
transform.m43 = matrix.m[14];
|
||||
transform.m44 = matrix.m[15];
|
||||
return transform;
|
||||
}
|
||||
} // namespace
|
||||
@ -278,12 +287,12 @@ static BOOL _preparedOnce = NO;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)clipRect:(const SkRect&)clipSkRect matrix:(const SkMatrix&)matrix {
|
||||
CGRect clipRect = GetCGRectFromSkRect(clipSkRect);
|
||||
- (void)clipRect:(const flutter::DlRect&)clipDlRect matrix:(const flutter::DlMatrix&)matrix {
|
||||
CGRect clipRect = GetCGRectFromDlRect(clipDlRect);
|
||||
CGPathRef path = CGPathCreateWithRect(clipRect, nil);
|
||||
// The `matrix` is based on the physical pixels, convert it to UIKit points.
|
||||
CATransform3D matrixInPoints =
|
||||
CATransform3DConcat(GetCATransform3DFromSkMatrix(matrix), _reverseScreenScale);
|
||||
CATransform3DConcat(GetCATransform3DFromDlMatrix(matrix), _reverseScreenScale);
|
||||
paths_.push_back([self getTransformedPath:path matrix:matrixInPoints]);
|
||||
CGAffineTransform affine = [self affineWithMatrix:matrixInPoints];
|
||||
// Make sure the rect is not rotated (only translated or scaled).
|
||||
@ -294,139 +303,155 @@ static BOOL _preparedOnce = NO;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)clipRRect:(const SkRRect&)clipSkRRect matrix:(const SkMatrix&)matrix {
|
||||
containsNonRectPath_ = YES;
|
||||
CGPathRef pathRef = nullptr;
|
||||
switch (clipSkRRect.getType()) {
|
||||
case SkRRect::kEmpty_Type: {
|
||||
break;
|
||||
}
|
||||
case SkRRect::kRect_Type: {
|
||||
[self clipRect:clipSkRRect.rect() matrix:matrix];
|
||||
return;
|
||||
}
|
||||
case SkRRect::kOval_Type:
|
||||
case SkRRect::kSimple_Type: {
|
||||
CGRect clipRect = GetCGRectFromSkRect(clipSkRRect.rect());
|
||||
pathRef = CGPathCreateWithRoundedRect(clipRect, clipSkRRect.getSimpleRadii().x(),
|
||||
clipSkRRect.getSimpleRadii().y(), nil);
|
||||
break;
|
||||
}
|
||||
case SkRRect::kNinePatch_Type:
|
||||
case SkRRect::kComplex_Type: {
|
||||
- (void)clipRRect:(const flutter::DlRoundRect&)clipDlRRect matrix:(const flutter::DlMatrix&)matrix {
|
||||
if (clipDlRRect.IsEmpty()) {
|
||||
return;
|
||||
} else if (clipDlRRect.IsRect()) {
|
||||
[self clipRect:clipDlRRect.GetBounds() matrix:matrix];
|
||||
return;
|
||||
} else {
|
||||
CGPathRef pathRef = nullptr;
|
||||
containsNonRectPath_ = YES;
|
||||
|
||||
if (clipDlRRect.GetRadii().AreAllCornersSame()) {
|
||||
CGRect clipRect = GetCGRectFromDlRect(clipDlRRect.GetBounds());
|
||||
auto radii = clipDlRRect.GetRadii();
|
||||
pathRef =
|
||||
CGPathCreateWithRoundedRect(clipRect, radii.top_left.width, radii.top_left.height, nil);
|
||||
} else {
|
||||
CGMutablePathRef mutablePathRef = CGPathCreateMutable();
|
||||
// Complex types, we manually add each corner.
|
||||
SkRect clipSkRect = clipSkRRect.rect();
|
||||
SkVector topLeftRadii = clipSkRRect.radii(SkRRect::kUpperLeft_Corner);
|
||||
SkVector topRightRadii = clipSkRRect.radii(SkRRect::kUpperRight_Corner);
|
||||
SkVector bottomRightRadii = clipSkRRect.radii(SkRRect::kLowerRight_Corner);
|
||||
SkVector bottomLeftRadii = clipSkRRect.radii(SkRRect::kLowerLeft_Corner);
|
||||
flutter::DlRect clipDlRect = clipDlRRect.GetBounds();
|
||||
auto left = clipDlRect.GetLeft();
|
||||
auto top = clipDlRect.GetTop();
|
||||
auto right = clipDlRect.GetRight();
|
||||
auto bottom = clipDlRect.GetBottom();
|
||||
flutter::DlRoundingRadii radii = clipDlRRect.GetRadii();
|
||||
auto& top_left = radii.top_left;
|
||||
auto& top_right = radii.top_right;
|
||||
auto& bottom_left = radii.bottom_left;
|
||||
auto& bottom_right = radii.bottom_right;
|
||||
|
||||
// Start drawing RRect
|
||||
// These calculations are off, the AddCurve methods add a Bezier curve
|
||||
// which, for round rects should be a "magic distance" from the end
|
||||
// point of the horizontal/vertical section to the corner.
|
||||
// Move point to the top left corner adding the top left radii's x.
|
||||
CGPathMoveToPoint(mutablePathRef, nil, clipSkRect.fLeft + topLeftRadii.x(), clipSkRect.fTop);
|
||||
CGPathMoveToPoint(mutablePathRef, nil, //
|
||||
left + top_left.width, top);
|
||||
// Move point horizontally right to the top right corner and add the top right curve.
|
||||
CGPathAddLineToPoint(mutablePathRef, nil, clipSkRect.fRight - topRightRadii.x(),
|
||||
clipSkRect.fTop);
|
||||
CGPathAddCurveToPoint(mutablePathRef, nil, clipSkRect.fRight, clipSkRect.fTop,
|
||||
clipSkRect.fRight, clipSkRect.fTop + topRightRadii.y(),
|
||||
clipSkRect.fRight, clipSkRect.fTop + topRightRadii.y());
|
||||
CGPathAddLineToPoint(mutablePathRef, nil, //
|
||||
right - top_right.width, top);
|
||||
CGPathAddCurveToPoint(mutablePathRef, nil, //
|
||||
right, top, //
|
||||
right, top + top_right.height, //
|
||||
right, top + top_right.height);
|
||||
// Move point vertically down to the bottom right corner and add the bottom right curve.
|
||||
CGPathAddLineToPoint(mutablePathRef, nil, clipSkRect.fRight,
|
||||
clipSkRect.fBottom - bottomRightRadii.y());
|
||||
CGPathAddCurveToPoint(mutablePathRef, nil, clipSkRect.fRight, clipSkRect.fBottom,
|
||||
clipSkRect.fRight - bottomRightRadii.x(), clipSkRect.fBottom,
|
||||
clipSkRect.fRight - bottomRightRadii.x(), clipSkRect.fBottom);
|
||||
CGPathAddLineToPoint(mutablePathRef, nil, //
|
||||
right, bottom - bottom_right.height);
|
||||
CGPathAddCurveToPoint(mutablePathRef, nil, //
|
||||
right, bottom, //
|
||||
right - bottom_right.width, bottom, //
|
||||
right - bottom_right.width, bottom);
|
||||
// Move point horizontally left to the bottom left corner and add the bottom left curve.
|
||||
CGPathAddLineToPoint(mutablePathRef, nil, clipSkRect.fLeft + bottomLeftRadii.x(),
|
||||
clipSkRect.fBottom);
|
||||
CGPathAddCurveToPoint(mutablePathRef, nil, clipSkRect.fLeft, clipSkRect.fBottom,
|
||||
clipSkRect.fLeft, clipSkRect.fBottom - bottomLeftRadii.y(),
|
||||
clipSkRect.fLeft, clipSkRect.fBottom - bottomLeftRadii.y());
|
||||
CGPathAddLineToPoint(mutablePathRef, nil, //
|
||||
left + bottom_left.width, bottom);
|
||||
CGPathAddCurveToPoint(mutablePathRef, nil, //
|
||||
left, bottom, //
|
||||
left, bottom - bottom_left.height, //
|
||||
left, bottom - bottom_left.height);
|
||||
// Move point vertically up to the top left corner and add the top left curve.
|
||||
CGPathAddLineToPoint(mutablePathRef, nil, clipSkRect.fLeft,
|
||||
clipSkRect.fTop + topLeftRadii.y());
|
||||
CGPathAddCurveToPoint(mutablePathRef, nil, clipSkRect.fLeft, clipSkRect.fTop,
|
||||
clipSkRect.fLeft + topLeftRadii.x(), clipSkRect.fTop,
|
||||
clipSkRect.fLeft + topLeftRadii.x(), clipSkRect.fTop);
|
||||
CGPathAddLineToPoint(mutablePathRef, nil, //
|
||||
left, top + top_left.height);
|
||||
CGPathAddCurveToPoint(mutablePathRef, nil, //
|
||||
left, top, //
|
||||
left + top_left.width, top, //
|
||||
left + top_left.width, top);
|
||||
CGPathCloseSubpath(mutablePathRef);
|
||||
|
||||
pathRef = mutablePathRef;
|
||||
break;
|
||||
}
|
||||
// The `matrix` is based on the physical pixels, convert it to UIKit points.
|
||||
CATransform3D matrixInPoints =
|
||||
CATransform3DConcat(GetCATransform3DFromDlMatrix(matrix), _reverseScreenScale);
|
||||
// TODO(cyanglaz): iOS does not seem to support hard edge on CAShapeLayer. It clearly stated
|
||||
// that the CAShaperLayer will be drawn antialiased. Need to figure out a way to do the hard
|
||||
// edge clipping on iOS.
|
||||
paths_.push_back([self getTransformedPath:pathRef matrix:matrixInPoints]);
|
||||
}
|
||||
// The `matrix` is based on the physical pixels, convert it to UIKit points.
|
||||
CATransform3D matrixInPoints =
|
||||
CATransform3DConcat(GetCATransform3DFromSkMatrix(matrix), _reverseScreenScale);
|
||||
// TODO(cyanglaz): iOS does not seem to support hard edge on CAShapeLayer. It clearly stated that
|
||||
// the CAShaperLayer will be drawn antialiased. Need to figure out a way to do the hard edge
|
||||
// clipping on iOS.
|
||||
paths_.push_back([self getTransformedPath:pathRef matrix:matrixInPoints]);
|
||||
}
|
||||
|
||||
- (void)clipPath:(const SkPath&)path matrix:(const SkMatrix&)matrix {
|
||||
if (!path.isValid()) {
|
||||
return;
|
||||
}
|
||||
if (path.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
- (void)clipPath:(const flutter::DlPath&)dlPath matrix:(const flutter::DlMatrix&)matrix {
|
||||
containsNonRectPath_ = YES;
|
||||
CGMutablePathRef pathRef = CGPathCreateMutable();
|
||||
bool subpath_needs_close = false;
|
||||
std::optional<flutter::DlPoint> pending_moveto;
|
||||
|
||||
// Loop through all verbs and translate them into CGPath
|
||||
SkPath::Iter iter(path, true);
|
||||
SkPoint pts[kMaxPointsInVerb];
|
||||
SkPath::Verb verb = iter.next(pts);
|
||||
SkPoint last_pt_from_last_verb = SkPoint::Make(0, 0);
|
||||
while (verb != SkPath::kDone_Verb) {
|
||||
if (verb == SkPath::kLine_Verb || verb == SkPath::kQuad_Verb || verb == SkPath::kConic_Verb ||
|
||||
verb == SkPath::kCubic_Verb) {
|
||||
FML_DCHECK(last_pt_from_last_verb == pts[0]);
|
||||
auto resolve_moveto = [&pending_moveto, &pathRef]() {
|
||||
if (pending_moveto.has_value()) {
|
||||
CGPathMoveToPoint(pathRef, nil, pending_moveto->x, pending_moveto->y);
|
||||
pending_moveto.reset();
|
||||
}
|
||||
switch (verb) {
|
||||
case SkPath::kMove_Verb: {
|
||||
CGPathMoveToPoint(pathRef, nil, pts[0].x(), pts[0].y());
|
||||
last_pt_from_last_verb = pts[0];
|
||||
};
|
||||
|
||||
auto& path = dlPath.GetPath();
|
||||
for (auto it = path.begin(), end = path.end(); it != end; ++it) {
|
||||
switch (it.type()) {
|
||||
case impeller::Path::ComponentType::kContour: {
|
||||
const impeller::ContourComponent* contour = it.contour();
|
||||
FML_DCHECK(contour != nullptr);
|
||||
if (subpath_needs_close) {
|
||||
CGPathCloseSubpath(pathRef);
|
||||
}
|
||||
pending_moveto = contour->destination;
|
||||
subpath_needs_close = contour->IsClosed();
|
||||
break;
|
||||
}
|
||||
case SkPath::kLine_Verb: {
|
||||
CGPathAddLineToPoint(pathRef, nil, pts[1].x(), pts[1].y());
|
||||
last_pt_from_last_verb = pts[1];
|
||||
case impeller::Path::ComponentType::kLinear: {
|
||||
const impeller::LinearPathComponent* linear = it.linear();
|
||||
FML_DCHECK(linear != nullptr);
|
||||
resolve_moveto();
|
||||
CGPathAddLineToPoint(pathRef, nil, linear->p2.x, linear->p2.y);
|
||||
break;
|
||||
}
|
||||
case SkPath::kQuad_Verb: {
|
||||
CGPathAddQuadCurveToPoint(pathRef, nil, pts[1].x(), pts[1].y(), pts[2].x(), pts[2].y());
|
||||
last_pt_from_last_verb = pts[2];
|
||||
case impeller::Path::ComponentType::kQuadratic: {
|
||||
const impeller::QuadraticPathComponent* quadratic = it.quadratic();
|
||||
FML_DCHECK(quadratic != nullptr);
|
||||
resolve_moveto();
|
||||
CGPathAddQuadCurveToPoint(pathRef, nil, //
|
||||
quadratic->cp.x, quadratic->cp.y, //
|
||||
quadratic->p2.x, quadratic->p2.y);
|
||||
break;
|
||||
}
|
||||
case SkPath::kConic_Verb: {
|
||||
case impeller::Path::ComponentType::kConic: {
|
||||
const impeller::ConicPathComponent* conic = it.conic();
|
||||
FML_DCHECK(conic != nullptr);
|
||||
resolve_moveto();
|
||||
// Conic is not available in quartz, we use quad to approximate.
|
||||
// TODO(cyanglaz): Better approximate the conic path.
|
||||
// https://github.com/flutter/flutter/issues/35062
|
||||
CGPathAddQuadCurveToPoint(pathRef, nil, pts[1].x(), pts[1].y(), pts[2].x(), pts[2].y());
|
||||
last_pt_from_last_verb = pts[2];
|
||||
CGPathAddQuadCurveToPoint(pathRef, nil, //
|
||||
conic->cp.x, conic->cp.y, //
|
||||
conic->p2.x, conic->p2.y);
|
||||
break;
|
||||
}
|
||||
case SkPath::kCubic_Verb: {
|
||||
CGPathAddCurveToPoint(pathRef, nil, pts[1].x(), pts[1].y(), pts[2].x(), pts[2].y(),
|
||||
pts[3].x(), pts[3].y());
|
||||
last_pt_from_last_verb = pts[3];
|
||||
break;
|
||||
}
|
||||
case SkPath::kClose_Verb: {
|
||||
CGPathCloseSubpath(pathRef);
|
||||
break;
|
||||
}
|
||||
case SkPath::kDone_Verb: {
|
||||
case impeller::Path::ComponentType::kCubic: {
|
||||
const impeller::CubicPathComponent* cubic = it.cubic();
|
||||
FML_DCHECK(cubic != nullptr);
|
||||
resolve_moveto();
|
||||
CGPathAddCurveToPoint(pathRef, nil, //
|
||||
cubic->cp1.x, cubic->cp1.y, //
|
||||
cubic->cp2.x, cubic->cp2.y, //
|
||||
cubic->p2.x, cubic->p2.y);
|
||||
break;
|
||||
}
|
||||
}
|
||||
verb = iter.next(pts);
|
||||
}
|
||||
if (subpath_needs_close) {
|
||||
CGPathCloseSubpath(pathRef);
|
||||
}
|
||||
// The `matrix` is based on the physical pixels, convert it to UIKit points.
|
||||
CATransform3D matrixInPoints =
|
||||
CATransform3DConcat(GetCATransform3DFromSkMatrix(matrix), _reverseScreenScale);
|
||||
CATransform3DConcat(GetCATransform3DFromDlMatrix(matrix), _reverseScreenScale);
|
||||
paths_.push_back([self getTransformedPath:pathRef matrix:matrixInPoints]);
|
||||
}
|
||||
|
||||
|
@ -5,6 +5,7 @@
|
||||
#import "shell/platform/darwin/ios/framework/Source/FlutterPlatformViewsController.h"
|
||||
|
||||
#include "flutter/display_list/effects/image_filters/dl_blur_image_filter.h"
|
||||
#include "flutter/display_list/utils/dl_matrix_clip_tracker.h"
|
||||
#include "flutter/flow/surface_frame.h"
|
||||
#include "flutter/flow/view_slicer.h"
|
||||
#include "flutter/fml/make_copyable.h"
|
||||
@ -15,6 +16,10 @@
|
||||
#include "flutter/shell/platform/darwin/ios/framework/Source/overlay_layer_pool.h"
|
||||
#import "flutter/shell/platform/darwin/ios/ios_surface.h"
|
||||
|
||||
using flutter::DlMatrix;
|
||||
using flutter::DlRect;
|
||||
using flutter::DlRoundRect;
|
||||
|
||||
static constexpr NSUInteger kFlutterClippingMaskViewPoolCapacity = 5;
|
||||
|
||||
struct LayerData {
|
||||
@ -38,18 +43,27 @@ struct PlatformViewData {
|
||||
// Converts a SkMatrix to CATransform3D.
|
||||
//
|
||||
// Certain fields are ignored in CATransform3D since SkMatrix is 3x3 and CATransform3D is 4x4.
|
||||
static CATransform3D GetCATransform3DFromSkMatrix(const SkMatrix& matrix) {
|
||||
// Skia only supports 2D transform so we don't map z.
|
||||
static CATransform3D GetCATransform3DFromDlMatrix(const DlMatrix& matrix) {
|
||||
CATransform3D transform = CATransform3DIdentity;
|
||||
transform.m11 = matrix.getScaleX();
|
||||
transform.m21 = matrix.getSkewX();
|
||||
transform.m41 = matrix.getTranslateX();
|
||||
transform.m14 = matrix.getPerspX();
|
||||
transform.m11 = matrix.m[0];
|
||||
transform.m12 = matrix.m[1];
|
||||
transform.m13 = matrix.m[2];
|
||||
transform.m14 = matrix.m[3];
|
||||
|
||||
transform.m12 = matrix.getSkewY();
|
||||
transform.m22 = matrix.getScaleY();
|
||||
transform.m42 = matrix.getTranslateY();
|
||||
transform.m24 = matrix.getPerspY();
|
||||
transform.m21 = matrix.m[4];
|
||||
transform.m22 = matrix.m[5];
|
||||
transform.m23 = matrix.m[6];
|
||||
transform.m24 = matrix.m[7];
|
||||
|
||||
transform.m31 = matrix.m[8];
|
||||
transform.m32 = matrix.m[9];
|
||||
transform.m33 = matrix.m[10];
|
||||
transform.m34 = matrix.m[11];
|
||||
|
||||
transform.m41 = matrix.m[12];
|
||||
transform.m42 = matrix.m[13];
|
||||
transform.m43 = matrix.m[14];
|
||||
transform.m44 = matrix.m[15];
|
||||
return transform;
|
||||
}
|
||||
|
||||
@ -62,57 +76,11 @@ static void ResetAnchor(CALayer* layer) {
|
||||
layer.position = CGPointZero;
|
||||
}
|
||||
|
||||
static CGRect GetCGRectFromSkRect(const SkRect& clipSkRect) {
|
||||
return CGRectMake(clipSkRect.fLeft, clipSkRect.fTop, clipSkRect.fRight - clipSkRect.fLeft,
|
||||
clipSkRect.fBottom - clipSkRect.fTop);
|
||||
}
|
||||
|
||||
// Determines if the `clip_rect` from a clipRect mutator contains the
|
||||
// `platformview_boundingrect`.
|
||||
//
|
||||
// `clip_rect` is in its own coordinate space. The rect needs to be transformed by
|
||||
// `transform_matrix` to be in the coordinate space where the PlatformView is displayed.
|
||||
//
|
||||
// `platformview_boundingrect` is the final bounding rect of the PlatformView in the coordinate
|
||||
// space where the PlatformView is displayed.
|
||||
static bool ClipRectContainsPlatformViewBoundingRect(const SkRect& clip_rect,
|
||||
const SkRect& platformview_boundingrect,
|
||||
const SkMatrix& transform_matrix) {
|
||||
SkRect transformed_rect = transform_matrix.mapRect(clip_rect);
|
||||
return transformed_rect.contains(platformview_boundingrect);
|
||||
}
|
||||
|
||||
// Determines if the `clipRRect` from a clipRRect mutator contains the
|
||||
// `platformview_boundingrect`.
|
||||
//
|
||||
// `clip_rrect` is in its own coordinate space. The rrect needs to be transformed by
|
||||
// `transform_matrix` to be in the coordinate space where the PlatformView is displayed.
|
||||
//
|
||||
// `platformview_boundingrect` is the final bounding rect of the PlatformView in the coordinate
|
||||
// space where the PlatformView is displayed.
|
||||
static bool ClipRRectContainsPlatformViewBoundingRect(const SkRRect& clip_rrect,
|
||||
const SkRect& platformview_boundingrect,
|
||||
const SkMatrix& transform_matrix) {
|
||||
SkVector upper_left = clip_rrect.radii(SkRRect::Corner::kUpperLeft_Corner);
|
||||
SkVector upper_right = clip_rrect.radii(SkRRect::Corner::kUpperRight_Corner);
|
||||
SkVector lower_right = clip_rrect.radii(SkRRect::Corner::kLowerRight_Corner);
|
||||
SkVector lower_left = clip_rrect.radii(SkRRect::Corner::kLowerLeft_Corner);
|
||||
SkScalar transformed_upper_left_x = transform_matrix.mapRadius(upper_left.x());
|
||||
SkScalar transformed_upper_left_y = transform_matrix.mapRadius(upper_left.y());
|
||||
SkScalar transformed_upper_right_x = transform_matrix.mapRadius(upper_right.x());
|
||||
SkScalar transformed_upper_right_y = transform_matrix.mapRadius(upper_right.y());
|
||||
SkScalar transformed_lower_right_x = transform_matrix.mapRadius(lower_right.x());
|
||||
SkScalar transformed_lower_right_y = transform_matrix.mapRadius(lower_right.y());
|
||||
SkScalar transformed_lower_left_x = transform_matrix.mapRadius(lower_left.x());
|
||||
SkScalar transformed_lower_left_y = transform_matrix.mapRadius(lower_left.y());
|
||||
SkRect transformed_clip_rect = transform_matrix.mapRect(clip_rrect.rect());
|
||||
SkRRect transformed_rrect;
|
||||
SkVector corners[] = {{transformed_upper_left_x, transformed_upper_left_y},
|
||||
{transformed_upper_right_x, transformed_upper_right_y},
|
||||
{transformed_lower_right_x, transformed_lower_right_y},
|
||||
{transformed_lower_left_x, transformed_lower_left_y}};
|
||||
transformed_rrect.setRectRadii(transformed_clip_rect, corners);
|
||||
return transformed_rrect.contains(platformview_boundingrect);
|
||||
static CGRect GetCGRectFromDlRect(const DlRect& clipDlRect) {
|
||||
return CGRectMake(clipDlRect.GetLeft(), //
|
||||
clipDlRect.GetTop(), //
|
||||
clipDlRect.GetWidth(), //
|
||||
clipDlRect.GetHeight());
|
||||
}
|
||||
|
||||
@interface FlutterPlatformViewsController ()
|
||||
@ -531,7 +499,8 @@ static bool ClipRRectContainsPlatformViewBoundingRect(const SkRRect& clip_rrect,
|
||||
ResetAnchor(embeddedView.layer);
|
||||
ChildClippingView* clipView = (ChildClippingView*)embeddedView.superview;
|
||||
|
||||
SkMatrix transformMatrix;
|
||||
DlMatrix transformMatrix;
|
||||
const DlRect& dlBoundingRect = flutter::ToDlRect(boundingRect);
|
||||
NSMutableArray* blurFilters = [[NSMutableArray alloc] init];
|
||||
FML_DCHECK(!clipView.maskView ||
|
||||
[clipView.maskView isKindOfClass:[FlutterClippingMaskView class]]);
|
||||
@ -543,13 +512,13 @@ static bool ClipRRectContainsPlatformViewBoundingRect(const SkRRect& clip_rrect,
|
||||
auto iter = mutatorsStack.Begin();
|
||||
while (iter != mutatorsStack.End()) {
|
||||
switch ((*iter)->GetType()) {
|
||||
case flutter::kTransform: {
|
||||
transformMatrix.preConcat((*iter)->GetMatrix());
|
||||
case flutter::MutatorType::kTransform: {
|
||||
transformMatrix = transformMatrix * (*iter)->GetMatrix();
|
||||
break;
|
||||
}
|
||||
case flutter::kClipRect: {
|
||||
if (ClipRectContainsPlatformViewBoundingRect((*iter)->GetRect(), boundingRect,
|
||||
transformMatrix)) {
|
||||
case flutter::MutatorType::kClipRect: {
|
||||
if (flutter::DisplayListMatrixClipState::TransformedRectCoversBounds(
|
||||
(*iter)->GetRect(), transformMatrix, dlBoundingRect)) {
|
||||
break;
|
||||
}
|
||||
[self clipViewSetMaskView:clipView];
|
||||
@ -557,9 +526,9 @@ static bool ClipRRectContainsPlatformViewBoundingRect(const SkRRect& clip_rrect,
|
||||
matrix:transformMatrix];
|
||||
break;
|
||||
}
|
||||
case flutter::kClipRRect: {
|
||||
if (ClipRRectContainsPlatformViewBoundingRect((*iter)->GetRRect(), boundingRect,
|
||||
transformMatrix)) {
|
||||
case flutter::MutatorType::kClipRRect: {
|
||||
if (flutter::DisplayListMatrixClipState::TransformedRRectCoversBounds(
|
||||
(*iter)->GetRRect(), transformMatrix, dlBoundingRect)) {
|
||||
break;
|
||||
}
|
||||
[self clipViewSetMaskView:clipView];
|
||||
@ -567,7 +536,17 @@ static bool ClipRRectContainsPlatformViewBoundingRect(const SkRRect& clip_rrect,
|
||||
matrix:transformMatrix];
|
||||
break;
|
||||
}
|
||||
case flutter::kClipPath: {
|
||||
case flutter::MutatorType::kClipRSE: {
|
||||
if (flutter::DisplayListMatrixClipState::TransformedRoundSuperellipseCoversBounds(
|
||||
(*iter)->GetRSE(), transformMatrix, dlBoundingRect)) {
|
||||
break;
|
||||
}
|
||||
[self clipViewSetMaskView:clipView];
|
||||
[(FlutterClippingMaskView*)clipView.maskView clipRRect:(*iter)->GetRRect()
|
||||
matrix:transformMatrix];
|
||||
break;
|
||||
}
|
||||
case flutter::MutatorType::kClipPath: {
|
||||
// TODO(cyanglaz): Find a way to pre-determine if path contains the PlatformView boudning
|
||||
// rect. See `ClipRRectContainsPlatformViewBoundingRect`.
|
||||
// https://github.com/flutter/flutter/issues/118650
|
||||
@ -576,15 +555,15 @@ static bool ClipRRectContainsPlatformViewBoundingRect(const SkRRect& clip_rrect,
|
||||
matrix:transformMatrix];
|
||||
break;
|
||||
}
|
||||
case flutter::kOpacity:
|
||||
case flutter::MutatorType::kOpacity:
|
||||
embeddedView.alpha = (*iter)->GetAlphaFloat() * embeddedView.alpha;
|
||||
break;
|
||||
case flutter::kBackdropFilter: {
|
||||
case flutter::MutatorType::kBackdropFilter: {
|
||||
// Only support DlBlurImageFilter for BackdropFilter.
|
||||
if (!self.canApplyBlurBackdrop || !(*iter)->GetFilterMutation().GetFilter().asBlur()) {
|
||||
break;
|
||||
}
|
||||
CGRect filterRect = GetCGRectFromSkRect((*iter)->GetFilterMutation().GetFilterRect());
|
||||
CGRect filterRect = GetCGRectFromDlRect((*iter)->GetFilterMutation().GetFilterRect());
|
||||
// `filterRect` is in global coordinates. We need to convert to local space.
|
||||
filterRect = CGRectApplyAffineTransform(
|
||||
filterRect, CGAffineTransformMakeScale(1 / screenScale, 1 / screenScale));
|
||||
@ -626,7 +605,8 @@ static bool ClipRRectContainsPlatformViewBoundingRect(const SkRRect& clip_rrect,
|
||||
// However, flow is based on the physical resolution. For example, 1000 pixels in flow equals
|
||||
// 500 points in UIKit for devices that has screenScale of 2. We need to scale the transformMatrix
|
||||
// down to the logical resoltion before applying it to the layer of PlatformView.
|
||||
transformMatrix.postScale(1 / screenScale, 1 / screenScale);
|
||||
flutter::DlScalar pointScale = 1.0 / screenScale;
|
||||
transformMatrix = DlMatrix::MakeScale({pointScale, pointScale, 1}) * transformMatrix;
|
||||
|
||||
// Reverse the offset of the clipView.
|
||||
// The clipView's frame includes the final translate of the final transform matrix.
|
||||
@ -635,9 +615,10 @@ static bool ClipRRectContainsPlatformViewBoundingRect(const SkRRect& clip_rrect,
|
||||
//
|
||||
// Note that the transforms are not applied to the clipping paths because clipping paths happen on
|
||||
// the mask view, whose origin is always (0,0) to the _flutterView.
|
||||
transformMatrix.postTranslate(-clipView.frame.origin.x, -clipView.frame.origin.y);
|
||||
impeller::Vector3 origin = impeller::Vector3(clipView.frame.origin.x, clipView.frame.origin.y);
|
||||
transformMatrix = DlMatrix::MakeTranslation(-origin) * transformMatrix;
|
||||
|
||||
embeddedView.layer.transform = GetCATransform3DFromSkMatrix(transformMatrix);
|
||||
embeddedView.layer.transform = GetCATransform3DFromDlMatrix(transformMatrix);
|
||||
}
|
||||
|
||||
- (void)compositeView:(int64_t)viewId withParams:(const flutter::EmbeddedViewParams&)params {
|
||||
|
@ -354,17 +354,16 @@ fml::RefPtr<fml::TaskRunner> GetDefaultTaskRunner() {
|
||||
// Create embedded view params
|
||||
flutter::MutatorsStack stack;
|
||||
// Layer tree always pushes a screen scale factor to the stack
|
||||
CGFloat screenScale = [mockFlutterViewController flutterScreenIfViewLoaded].scale;
|
||||
SkMatrix screenScaleMatrix = SkMatrix::Scale(screenScale, screenScale);
|
||||
flutter::DlScalar screenScale = [mockFlutterViewController flutterScreenIfViewLoaded].scale;
|
||||
flutter::DlMatrix screenScaleMatrix = flutter::DlMatrix::MakeScale({screenScale, screenScale, 1});
|
||||
stack.PushTransform(screenScaleMatrix);
|
||||
// Push a translate matrix
|
||||
SkMatrix translateMatrix = SkMatrix::Translate(100, 100);
|
||||
flutter::DlMatrix translateMatrix = flutter::DlMatrix::MakeTranslation({100, 100});
|
||||
stack.PushTransform(translateMatrix);
|
||||
SkMatrix finalMatrix;
|
||||
finalMatrix.setConcat(screenScaleMatrix, translateMatrix);
|
||||
flutter::DlMatrix finalMatrix = screenScaleMatrix * translateMatrix;
|
||||
|
||||
auto embeddedViewParams =
|
||||
std::make_unique<flutter::EmbeddedViewParams>(finalMatrix, SkSize::Make(300, 300), stack);
|
||||
auto embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
|
||||
flutter::ToSkMatrix(finalMatrix), SkSize::Make(300, 300), stack);
|
||||
|
||||
[flutterPlatformViewsController prerollCompositeEmbeddedView:2
|
||||
withParams:std::move(embeddedViewParams)];
|
||||
@ -514,15 +513,16 @@ fml::RefPtr<fml::TaskRunner> GetDefaultTaskRunner() {
|
||||
// Create embedded view params
|
||||
flutter::MutatorsStack stack;
|
||||
// Layer tree always pushes a screen scale factor to the stack
|
||||
CGFloat screenScale = [mockFlutterViewController flutterScreenIfViewLoaded].scale;
|
||||
SkMatrix screenScaleMatrix = SkMatrix::Scale(screenScale, screenScale);
|
||||
flutter::DlScalar screenScale = [mockFlutterViewController flutterScreenIfViewLoaded].scale;
|
||||
flutter::DlMatrix screenScaleMatrix = flutter::DlMatrix::MakeScale({screenScale, screenScale, 1});
|
||||
stack.PushTransform(screenScaleMatrix);
|
||||
// Push a backdrop filter
|
||||
auto filter = flutter::DlBlurImageFilter::Make(5, 2, flutter::DlTileMode::kClamp);
|
||||
stack.PushBackdropFilter(filter, SkRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
|
||||
stack.PushBackdropFilter(filter,
|
||||
flutter::DlRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
|
||||
|
||||
auto embeddedViewParams =
|
||||
std::make_unique<flutter::EmbeddedViewParams>(screenScaleMatrix, SkSize::Make(10, 10), stack);
|
||||
auto embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
|
||||
flutter::ToSkMatrix(screenScaleMatrix), SkSize::Make(10, 10), stack);
|
||||
|
||||
[flutterPlatformViewsController prerollCompositeEmbeddedView:2
|
||||
withParams:std::move(embeddedViewParams)];
|
||||
@ -598,15 +598,16 @@ fml::RefPtr<fml::TaskRunner> GetDefaultTaskRunner() {
|
||||
// Create embedded view params
|
||||
flutter::MutatorsStack stack;
|
||||
// Layer tree always pushes a screen scale factor to the stack
|
||||
CGFloat screenScale = [mockFlutterViewController flutterScreenIfViewLoaded].scale;
|
||||
SkMatrix screenScaleMatrix = SkMatrix::Scale(screenScale, screenScale);
|
||||
flutter::DlScalar screenScale = [mockFlutterViewController flutterScreenIfViewLoaded].scale;
|
||||
flutter::DlMatrix screenScaleMatrix = flutter::DlMatrix::MakeScale({screenScale, screenScale, 1});
|
||||
stack.PushTransform(screenScaleMatrix);
|
||||
// Push a backdrop filter
|
||||
auto filter = flutter::DlBlurImageFilter::Make(5, 2, flutter::DlTileMode::kClamp);
|
||||
stack.PushBackdropFilter(filter, SkRect::MakeXYWH(0, 0, screenScale * 8, screenScale * 8));
|
||||
stack.PushBackdropFilter(filter,
|
||||
flutter::DlRect::MakeXYWH(0, 0, screenScale * 8, screenScale * 8));
|
||||
|
||||
auto embeddedViewParams =
|
||||
std::make_unique<flutter::EmbeddedViewParams>(screenScaleMatrix, SkSize::Make(5, 10), stack);
|
||||
auto embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
|
||||
flutter::ToSkMatrix(screenScaleMatrix), SkSize::Make(5, 10), stack);
|
||||
|
||||
[flutterPlatformViewsController prerollCompositeEmbeddedView:2
|
||||
withParams:std::move(embeddedViewParams)];
|
||||
@ -682,17 +683,18 @@ fml::RefPtr<fml::TaskRunner> GetDefaultTaskRunner() {
|
||||
// Create embedded view params
|
||||
flutter::MutatorsStack stack;
|
||||
// Layer tree always pushes a screen scale factor to the stack
|
||||
CGFloat screenScale = [mockFlutterViewController flutterScreenIfViewLoaded].scale;
|
||||
SkMatrix screenScaleMatrix = SkMatrix::Scale(screenScale, screenScale);
|
||||
flutter::DlScalar screenScale = [mockFlutterViewController flutterScreenIfViewLoaded].scale;
|
||||
flutter::DlMatrix screenScaleMatrix = flutter::DlMatrix::MakeScale({screenScale, screenScale, 1});
|
||||
stack.PushTransform(screenScaleMatrix);
|
||||
// Push backdrop filters
|
||||
for (int i = 0; i < 50; i++) {
|
||||
auto filter = flutter::DlBlurImageFilter::Make(i, 2, flutter::DlTileMode::kClamp);
|
||||
stack.PushBackdropFilter(filter, SkRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
|
||||
stack.PushBackdropFilter(filter,
|
||||
flutter::DlRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
|
||||
}
|
||||
|
||||
auto embeddedViewParams =
|
||||
std::make_unique<flutter::EmbeddedViewParams>(screenScaleMatrix, SkSize::Make(20, 20), stack);
|
||||
auto embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
|
||||
flutter::ToSkMatrix(screenScaleMatrix), SkSize::Make(20, 20), stack);
|
||||
|
||||
[flutterPlatformViewsController prerollCompositeEmbeddedView:2
|
||||
withParams:std::move(embeddedViewParams)];
|
||||
@ -767,15 +769,16 @@ fml::RefPtr<fml::TaskRunner> GetDefaultTaskRunner() {
|
||||
// Create embedded view params
|
||||
flutter::MutatorsStack stack;
|
||||
// Layer tree always pushes a screen scale factor to the stack
|
||||
CGFloat screenScale = [mockFlutterViewController flutterScreenIfViewLoaded].scale;
|
||||
SkMatrix screenScaleMatrix = SkMatrix::Scale(screenScale, screenScale);
|
||||
flutter::DlScalar screenScale = [mockFlutterViewController flutterScreenIfViewLoaded].scale;
|
||||
flutter::DlMatrix screenScaleMatrix = flutter::DlMatrix::MakeScale({screenScale, screenScale, 1});
|
||||
stack.PushTransform(screenScaleMatrix);
|
||||
// Push a backdrop filter
|
||||
auto filter = flutter::DlBlurImageFilter::Make(5, 2, flutter::DlTileMode::kClamp);
|
||||
stack.PushBackdropFilter(filter, SkRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
|
||||
stack.PushBackdropFilter(filter,
|
||||
flutter::DlRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
|
||||
|
||||
auto embeddedViewParams =
|
||||
std::make_unique<flutter::EmbeddedViewParams>(screenScaleMatrix, SkSize::Make(10, 10), stack);
|
||||
auto embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
|
||||
flutter::ToSkMatrix(screenScaleMatrix), SkSize::Make(10, 10), stack);
|
||||
|
||||
[flutterPlatformViewsController prerollCompositeEmbeddedView:2
|
||||
withParams:std::move(embeddedViewParams)];
|
||||
@ -812,11 +815,12 @@ fml::RefPtr<fml::TaskRunner> GetDefaultTaskRunner() {
|
||||
stack2.PushTransform(screenScaleMatrix);
|
||||
// Push backdrop filters
|
||||
for (int i = 0; i < 2; i++) {
|
||||
stack2.PushBackdropFilter(filter, SkRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
|
||||
stack2.PushBackdropFilter(filter,
|
||||
flutter::DlRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
|
||||
}
|
||||
|
||||
embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(screenScaleMatrix,
|
||||
SkSize::Make(10, 10), stack2);
|
||||
embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
|
||||
flutter::ToSkMatrix(screenScaleMatrix), SkSize::Make(10, 10), stack2);
|
||||
|
||||
[flutterPlatformViewsController prerollCompositeEmbeddedView:2
|
||||
withParams:std::move(embeddedViewParams)];
|
||||
@ -897,17 +901,18 @@ fml::RefPtr<fml::TaskRunner> GetDefaultTaskRunner() {
|
||||
// Create embedded view params
|
||||
flutter::MutatorsStack stack;
|
||||
// Layer tree always pushes a screen scale factor to the stack
|
||||
CGFloat screenScale = [mockFlutterViewController flutterScreenIfViewLoaded].scale;
|
||||
SkMatrix screenScaleMatrix = SkMatrix::Scale(screenScale, screenScale);
|
||||
flutter::DlScalar screenScale = [mockFlutterViewController flutterScreenIfViewLoaded].scale;
|
||||
flutter::DlMatrix screenScaleMatrix = flutter::DlMatrix::MakeScale({screenScale, screenScale, 1});
|
||||
stack.PushTransform(screenScaleMatrix);
|
||||
// Push backdrop filters
|
||||
auto filter = flutter::DlBlurImageFilter::Make(5, 2, flutter::DlTileMode::kClamp);
|
||||
for (int i = 0; i < 5; i++) {
|
||||
stack.PushBackdropFilter(filter, SkRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
|
||||
stack.PushBackdropFilter(filter,
|
||||
flutter::DlRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
|
||||
}
|
||||
|
||||
auto embeddedViewParams =
|
||||
std::make_unique<flutter::EmbeddedViewParams>(screenScaleMatrix, SkSize::Make(10, 10), stack);
|
||||
auto embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
|
||||
flutter::ToSkMatrix(screenScaleMatrix), SkSize::Make(10, 10), stack);
|
||||
|
||||
[flutterPlatformViewsController prerollCompositeEmbeddedView:2
|
||||
withParams:std::move(embeddedViewParams)];
|
||||
@ -942,11 +947,12 @@ fml::RefPtr<fml::TaskRunner> GetDefaultTaskRunner() {
|
||||
stack2.PushTransform(screenScaleMatrix);
|
||||
// Push backdrop filters
|
||||
for (int i = 0; i < 4; i++) {
|
||||
stack2.PushBackdropFilter(filter, SkRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
|
||||
stack2.PushBackdropFilter(filter,
|
||||
flutter::DlRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
|
||||
}
|
||||
|
||||
embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(screenScaleMatrix,
|
||||
SkSize::Make(10, 10), stack2);
|
||||
embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
|
||||
flutter::ToSkMatrix(screenScaleMatrix), SkSize::Make(10, 10), stack2);
|
||||
|
||||
[flutterPlatformViewsController prerollCompositeEmbeddedView:2
|
||||
withParams:std::move(embeddedViewParams)];
|
||||
@ -988,8 +994,8 @@ fml::RefPtr<fml::TaskRunner> GetDefaultTaskRunner() {
|
||||
}
|
||||
// No backdrop filters in the stack, so no nothing to push
|
||||
|
||||
embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(screenScaleMatrix,
|
||||
SkSize::Make(10, 10), stack2);
|
||||
embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
|
||||
flutter::ToSkMatrix(screenScaleMatrix), SkSize::Make(10, 10), stack2);
|
||||
|
||||
[flutterPlatformViewsController prerollCompositeEmbeddedView:2
|
||||
withParams:std::move(embeddedViewParams)];
|
||||
@ -1054,17 +1060,18 @@ fml::RefPtr<fml::TaskRunner> GetDefaultTaskRunner() {
|
||||
// Create embedded view params
|
||||
flutter::MutatorsStack stack;
|
||||
// Layer tree always pushes a screen scale factor to the stack
|
||||
CGFloat screenScale = [mockFlutterViewController flutterScreenIfViewLoaded].scale;
|
||||
SkMatrix screenScaleMatrix = SkMatrix::Scale(screenScale, screenScale);
|
||||
flutter::DlScalar screenScale = [mockFlutterViewController flutterScreenIfViewLoaded].scale;
|
||||
flutter::DlMatrix screenScaleMatrix = flutter::DlMatrix::MakeScale({screenScale, screenScale, 1});
|
||||
stack.PushTransform(screenScaleMatrix);
|
||||
// Push backdrop filters
|
||||
auto filter = flutter::DlBlurImageFilter::Make(5, 2, flutter::DlTileMode::kClamp);
|
||||
for (int i = 0; i < 5; i++) {
|
||||
stack.PushBackdropFilter(filter, SkRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
|
||||
stack.PushBackdropFilter(filter,
|
||||
flutter::DlRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
|
||||
}
|
||||
|
||||
auto embeddedViewParams =
|
||||
std::make_unique<flutter::EmbeddedViewParams>(screenScaleMatrix, SkSize::Make(10, 10), stack);
|
||||
auto embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
|
||||
flutter::ToSkMatrix(screenScaleMatrix), SkSize::Make(10, 10), stack);
|
||||
|
||||
[flutterPlatformViewsController prerollCompositeEmbeddedView:2
|
||||
withParams:std::move(embeddedViewParams)];
|
||||
@ -1102,16 +1109,17 @@ fml::RefPtr<fml::TaskRunner> GetDefaultTaskRunner() {
|
||||
if (i == 3) {
|
||||
auto filter2 = flutter::DlBlurImageFilter::Make(2, 5, flutter::DlTileMode::kClamp);
|
||||
|
||||
stack2.PushBackdropFilter(filter2,
|
||||
SkRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
|
||||
stack2.PushBackdropFilter(
|
||||
filter2, flutter::DlRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
|
||||
continue;
|
||||
}
|
||||
|
||||
stack2.PushBackdropFilter(filter, SkRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
|
||||
stack2.PushBackdropFilter(filter,
|
||||
flutter::DlRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
|
||||
}
|
||||
|
||||
embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(screenScaleMatrix,
|
||||
SkSize::Make(10, 10), stack2);
|
||||
embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
|
||||
flutter::ToSkMatrix(screenScaleMatrix), SkSize::Make(10, 10), stack2);
|
||||
|
||||
[flutterPlatformViewsController prerollCompositeEmbeddedView:2
|
||||
withParams:std::move(embeddedViewParams)];
|
||||
@ -1159,16 +1167,17 @@ fml::RefPtr<fml::TaskRunner> GetDefaultTaskRunner() {
|
||||
for (int i = 0; i < 5; i++) {
|
||||
if (i == 0) {
|
||||
auto filter2 = flutter::DlBlurImageFilter::Make(2, 5, flutter::DlTileMode::kClamp);
|
||||
stack2.PushBackdropFilter(filter2,
|
||||
SkRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
|
||||
stack2.PushBackdropFilter(
|
||||
filter2, flutter::DlRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
|
||||
continue;
|
||||
}
|
||||
|
||||
stack2.PushBackdropFilter(filter, SkRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
|
||||
stack2.PushBackdropFilter(filter,
|
||||
flutter::DlRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
|
||||
}
|
||||
|
||||
embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(screenScaleMatrix,
|
||||
SkSize::Make(10, 10), stack2);
|
||||
embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
|
||||
flutter::ToSkMatrix(screenScaleMatrix), SkSize::Make(10, 10), stack2);
|
||||
|
||||
[flutterPlatformViewsController prerollCompositeEmbeddedView:2
|
||||
withParams:std::move(embeddedViewParams)];
|
||||
@ -1214,16 +1223,17 @@ fml::RefPtr<fml::TaskRunner> GetDefaultTaskRunner() {
|
||||
for (int i = 0; i < 5; i++) {
|
||||
if (i == 4) {
|
||||
auto filter2 = flutter::DlBlurImageFilter::Make(2, 5, flutter::DlTileMode::kClamp);
|
||||
stack2.PushBackdropFilter(filter2,
|
||||
SkRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
|
||||
stack2.PushBackdropFilter(
|
||||
filter2, flutter::DlRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
|
||||
continue;
|
||||
}
|
||||
|
||||
stack2.PushBackdropFilter(filter, SkRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
|
||||
stack2.PushBackdropFilter(filter,
|
||||
flutter::DlRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
|
||||
}
|
||||
|
||||
embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(screenScaleMatrix,
|
||||
SkSize::Make(10, 10), stack2);
|
||||
embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
|
||||
flutter::ToSkMatrix(screenScaleMatrix), SkSize::Make(10, 10), stack2);
|
||||
|
||||
[flutterPlatformViewsController prerollCompositeEmbeddedView:2
|
||||
withParams:std::move(embeddedViewParams)];
|
||||
@ -1271,11 +1281,12 @@ fml::RefPtr<fml::TaskRunner> GetDefaultTaskRunner() {
|
||||
for (int i = 0; i < 5; i++) {
|
||||
auto filter2 = flutter::DlBlurImageFilter::Make(i, 2, flutter::DlTileMode::kClamp);
|
||||
|
||||
stack2.PushBackdropFilter(filter2, SkRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
|
||||
stack2.PushBackdropFilter(filter2,
|
||||
flutter::DlRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
|
||||
}
|
||||
|
||||
embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(screenScaleMatrix,
|
||||
SkSize::Make(10, 10), stack2);
|
||||
embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
|
||||
flutter::ToSkMatrix(screenScaleMatrix), SkSize::Make(10, 10), stack2);
|
||||
|
||||
[flutterPlatformViewsController prerollCompositeEmbeddedView:2
|
||||
withParams:std::move(embeddedViewParams)];
|
||||
@ -1356,15 +1367,15 @@ fml::RefPtr<fml::TaskRunner> GetDefaultTaskRunner() {
|
||||
// Create embedded view params
|
||||
flutter::MutatorsStack stack;
|
||||
// Layer tree always pushes a screen scale factor to the stack
|
||||
CGFloat screenScale = [mockFlutterViewController flutterScreenIfViewLoaded].scale;
|
||||
SkMatrix screenScaleMatrix = SkMatrix::Scale(screenScale, screenScale);
|
||||
flutter::DlScalar screenScale = [mockFlutterViewController flutterScreenIfViewLoaded].scale;
|
||||
flutter::DlMatrix screenScaleMatrix = flutter::DlMatrix::MakeScale({screenScale, screenScale, 1});
|
||||
stack.PushTransform(screenScaleMatrix);
|
||||
// Push a dilate backdrop filter
|
||||
auto dilateFilter = flutter::DlDilateImageFilter::Make(5, 2);
|
||||
stack.PushBackdropFilter(dilateFilter, SkRect::MakeEmpty());
|
||||
stack.PushBackdropFilter(dilateFilter, flutter::DlRect());
|
||||
|
||||
auto embeddedViewParams =
|
||||
std::make_unique<flutter::EmbeddedViewParams>(screenScaleMatrix, SkSize::Make(10, 10), stack);
|
||||
auto embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
|
||||
flutter::ToSkMatrix(screenScaleMatrix), SkSize::Make(10, 10), stack);
|
||||
|
||||
[flutterPlatformViewsController prerollCompositeEmbeddedView:2
|
||||
withParams:std::move(embeddedViewParams)];
|
||||
@ -1398,17 +1409,17 @@ fml::RefPtr<fml::TaskRunner> GetDefaultTaskRunner() {
|
||||
|
||||
for (int i = 0; i < 5; i++) {
|
||||
if (i == 2) {
|
||||
stack2.PushBackdropFilter(dilateFilter,
|
||||
SkRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
|
||||
stack2.PushBackdropFilter(
|
||||
dilateFilter, flutter::DlRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
|
||||
continue;
|
||||
}
|
||||
|
||||
stack2.PushBackdropFilter(blurFilter,
|
||||
SkRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
|
||||
flutter::DlRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
|
||||
}
|
||||
|
||||
embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(screenScaleMatrix,
|
||||
SkSize::Make(10, 10), stack2);
|
||||
embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
|
||||
flutter::ToSkMatrix(screenScaleMatrix), SkSize::Make(10, 10), stack2);
|
||||
|
||||
[flutterPlatformViewsController prerollCompositeEmbeddedView:2
|
||||
withParams:std::move(embeddedViewParams)];
|
||||
@ -1441,17 +1452,17 @@ fml::RefPtr<fml::TaskRunner> GetDefaultTaskRunner() {
|
||||
// Push backdrop filters and dilate filter
|
||||
for (int i = 0; i < 5; i++) {
|
||||
if (i == 0) {
|
||||
stack2.PushBackdropFilter(dilateFilter,
|
||||
SkRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
|
||||
stack2.PushBackdropFilter(
|
||||
dilateFilter, flutter::DlRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
|
||||
continue;
|
||||
}
|
||||
|
||||
stack2.PushBackdropFilter(blurFilter,
|
||||
SkRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
|
||||
flutter::DlRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
|
||||
}
|
||||
|
||||
embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(screenScaleMatrix,
|
||||
SkSize::Make(10, 10), stack2);
|
||||
embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
|
||||
flutter::ToSkMatrix(screenScaleMatrix), SkSize::Make(10, 10), stack2);
|
||||
|
||||
[flutterPlatformViewsController prerollCompositeEmbeddedView:2
|
||||
withParams:std::move(embeddedViewParams)];
|
||||
@ -1484,17 +1495,17 @@ fml::RefPtr<fml::TaskRunner> GetDefaultTaskRunner() {
|
||||
// Push backdrop filters and dilate filter
|
||||
for (int i = 0; i < 5; i++) {
|
||||
if (i == 4) {
|
||||
stack2.PushBackdropFilter(dilateFilter,
|
||||
SkRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
|
||||
stack2.PushBackdropFilter(
|
||||
dilateFilter, flutter::DlRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
|
||||
continue;
|
||||
}
|
||||
|
||||
stack2.PushBackdropFilter(blurFilter,
|
||||
SkRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
|
||||
flutter::DlRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
|
||||
}
|
||||
|
||||
embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(screenScaleMatrix,
|
||||
SkSize::Make(10, 10), stack2);
|
||||
embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
|
||||
flutter::ToSkMatrix(screenScaleMatrix), SkSize::Make(10, 10), stack2);
|
||||
|
||||
[flutterPlatformViewsController prerollCompositeEmbeddedView:2
|
||||
withParams:std::move(embeddedViewParams)];
|
||||
@ -1527,11 +1538,11 @@ fml::RefPtr<fml::TaskRunner> GetDefaultTaskRunner() {
|
||||
// Push dilate filters
|
||||
for (int i = 0; i < 5; i++) {
|
||||
stack2.PushBackdropFilter(dilateFilter,
|
||||
SkRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
|
||||
flutter::DlRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
|
||||
}
|
||||
|
||||
embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(screenScaleMatrix,
|
||||
SkSize::Make(10, 10), stack2);
|
||||
embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
|
||||
flutter::ToSkMatrix(screenScaleMatrix), SkSize::Make(10, 10), stack2);
|
||||
|
||||
[flutterPlatformViewsController prerollCompositeEmbeddedView:2
|
||||
withParams:std::move(embeddedViewParams)];
|
||||
@ -1690,17 +1701,16 @@ fml::RefPtr<fml::TaskRunner> GetDefaultTaskRunner() {
|
||||
// Create embedded view params
|
||||
flutter::MutatorsStack stack;
|
||||
// Layer tree always pushes a screen scale factor to the stack
|
||||
CGFloat screenScale = [mockFlutterViewController flutterScreenIfViewLoaded].scale;
|
||||
SkMatrix screenScaleMatrix = SkMatrix::Scale(screenScale, screenScale);
|
||||
flutter::DlScalar screenScale = [mockFlutterViewController flutterScreenIfViewLoaded].scale;
|
||||
flutter::DlMatrix screenScaleMatrix = flutter::DlMatrix::MakeScale({screenScale, screenScale, 1});
|
||||
stack.PushTransform(screenScaleMatrix);
|
||||
// Push a translate matrix
|
||||
SkMatrix translateMatrix = SkMatrix::Translate(100, 100);
|
||||
flutter::DlMatrix translateMatrix = flutter::DlMatrix::MakeTranslation({100, 100});
|
||||
stack.PushTransform(translateMatrix);
|
||||
SkMatrix finalMatrix;
|
||||
finalMatrix.setConcat(screenScaleMatrix, translateMatrix);
|
||||
flutter::DlMatrix finalMatrix = screenScaleMatrix * translateMatrix;
|
||||
|
||||
auto embeddedViewParams =
|
||||
std::make_unique<flutter::EmbeddedViewParams>(finalMatrix, SkSize::Make(300, 300), stack);
|
||||
auto embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
|
||||
flutter::ToSkMatrix(finalMatrix), SkSize::Make(300, 300), stack);
|
||||
|
||||
[flutterPlatformViewsController prerollCompositeEmbeddedView:2
|
||||
withParams:std::move(embeddedViewParams)];
|
||||
@ -1758,12 +1768,12 @@ fml::RefPtr<fml::TaskRunner> GetDefaultTaskRunner() {
|
||||
// Create embedded view params
|
||||
flutter::MutatorsStack stack;
|
||||
// Layer tree always pushes a screen scale factor to the stack
|
||||
CGFloat screenScale = [mockFlutterViewController flutterScreenIfViewLoaded].scale;
|
||||
SkMatrix screenScaleMatrix = SkMatrix::Scale(screenScale, screenScale);
|
||||
flutter::DlScalar screenScale = [mockFlutterViewController flutterScreenIfViewLoaded].scale;
|
||||
flutter::DlMatrix screenScaleMatrix = flutter::DlMatrix::MakeScale({screenScale, screenScale, 1});
|
||||
stack.PushTransform(screenScaleMatrix);
|
||||
|
||||
auto embeddedViewParams =
|
||||
std::make_unique<flutter::EmbeddedViewParams>(screenScaleMatrix, SkSize::Make(10, 10), stack);
|
||||
auto embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
|
||||
flutter::ToSkMatrix(screenScaleMatrix), SkSize::Make(10, 10), stack);
|
||||
|
||||
[flutterPlatformViewsController beginFrameWithSize:SkISize::Make(0, 0)];
|
||||
[flutterPlatformViewsController prerollCompositeEmbeddedView:2
|
||||
@ -1800,8 +1810,8 @@ fml::RefPtr<fml::TaskRunner> GetDefaultTaskRunner() {
|
||||
XCTAssertEqual(numberOfExpectedVisualEffectView, 1u);
|
||||
|
||||
// New frame, with no filter pushed.
|
||||
auto embeddedViewParams2 =
|
||||
std::make_unique<flutter::EmbeddedViewParams>(screenScaleMatrix, SkSize::Make(10, 10), stack);
|
||||
auto embeddedViewParams2 = std::make_unique<flutter::EmbeddedViewParams>(
|
||||
flutter::ToSkMatrix(screenScaleMatrix), SkSize::Make(10, 10), stack);
|
||||
[flutterPlatformViewsController beginFrameWithSize:SkISize::Make(0, 0)];
|
||||
[flutterPlatformViewsController prerollCompositeEmbeddedView:2
|
||||
withParams:std::move(embeddedViewParams2)];
|
||||
@ -1869,18 +1879,16 @@ fml::RefPtr<fml::TaskRunner> GetDefaultTaskRunner() {
|
||||
// Create embedded view params
|
||||
flutter::MutatorsStack stack;
|
||||
// Layer tree always pushes a screen scale factor to the stack
|
||||
CGFloat screenScale = [mockFlutterViewController flutterScreenIfViewLoaded].scale;
|
||||
SkMatrix screenScaleMatrix = SkMatrix::Scale(screenScale, screenScale);
|
||||
flutter::DlScalar screenScale = [mockFlutterViewController flutterScreenIfViewLoaded].scale;
|
||||
flutter::DlMatrix screenScaleMatrix = flutter::DlMatrix::MakeScale({screenScale, screenScale, 1});
|
||||
stack.PushTransform(screenScaleMatrix);
|
||||
// Push a rotate matrix
|
||||
SkMatrix rotateMatrix;
|
||||
rotateMatrix.setRotate(10);
|
||||
flutter::DlMatrix rotateMatrix = flutter::DlMatrix::MakeRotationZ(flutter::DlDegrees(10));
|
||||
stack.PushTransform(rotateMatrix);
|
||||
SkMatrix finalMatrix;
|
||||
finalMatrix.setConcat(screenScaleMatrix, rotateMatrix);
|
||||
flutter::DlMatrix finalMatrix = screenScaleMatrix * rotateMatrix;
|
||||
|
||||
auto embeddedViewParams =
|
||||
std::make_unique<flutter::EmbeddedViewParams>(finalMatrix, SkSize::Make(300, 300), stack);
|
||||
auto embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
|
||||
flutter::ToSkMatrix(finalMatrix), SkSize::Make(300, 300), stack);
|
||||
|
||||
[flutterPlatformViewsController prerollCompositeEmbeddedView:2
|
||||
withParams:std::move(embeddedViewParams)];
|
||||
@ -1952,23 +1960,23 @@ fml::RefPtr<fml::TaskRunner> GetDefaultTaskRunner() {
|
||||
// Create embedded view params.
|
||||
flutter::MutatorsStack stack;
|
||||
// Layer tree always pushes a screen scale factor to the stack.
|
||||
CGFloat screenScale = [mockFlutterViewController flutterScreenIfViewLoaded].scale;
|
||||
SkMatrix screenScaleMatrix = SkMatrix::Scale(screenScale, screenScale);
|
||||
flutter::DlScalar screenScale = [mockFlutterViewController flutterScreenIfViewLoaded].scale;
|
||||
flutter::DlMatrix screenScaleMatrix = flutter::DlMatrix::MakeScale({screenScale, screenScale, 1});
|
||||
stack.PushTransform(screenScaleMatrix);
|
||||
SkMatrix translateMatrix = SkMatrix::Translate(5, 5);
|
||||
flutter::DlMatrix translateMatrix = flutter::DlMatrix::MakeTranslation({5, 5});
|
||||
// The platform view's rect for this test will be (5, 5, 10, 10).
|
||||
stack.PushTransform(translateMatrix);
|
||||
// Push a clip rect, big enough to contain the entire platform view bound.
|
||||
SkRect rect = SkRect::MakeXYWH(0, 0, 25, 25);
|
||||
flutter::DlRect rect = flutter::DlRect::MakeXYWH(0, 0, 25, 25);
|
||||
stack.PushClipRect(rect);
|
||||
// Push a clip rrect, big enough to contain the entire platform view bound without clipping it.
|
||||
// Make the origin (-1, -1) so that the top left rounded corner isn't clipping the PlatformView.
|
||||
SkRect rect_for_rrect = SkRect::MakeXYWH(-1, -1, 25, 25);
|
||||
SkRRect rrect = SkRRect::MakeRectXY(rect_for_rrect, 1, 1);
|
||||
flutter::DlRect rect_for_rrect = flutter::DlRect::MakeXYWH(-1, -1, 25, 25);
|
||||
flutter::DlRoundRect rrect = flutter::DlRoundRect::MakeRectXY(rect_for_rrect, 1, 1);
|
||||
stack.PushClipRRect(rrect);
|
||||
|
||||
auto embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
|
||||
SkMatrix::Concat(screenScaleMatrix, translateMatrix), SkSize::Make(5, 5), stack);
|
||||
flutter::ToSkMatrix(screenScaleMatrix * translateMatrix), SkSize::Make(5, 5), stack);
|
||||
|
||||
[flutterPlatformViewsController prerollCompositeEmbeddedView:2
|
||||
withParams:std::move(embeddedViewParams)];
|
||||
@ -2031,21 +2039,21 @@ fml::RefPtr<fml::TaskRunner> GetDefaultTaskRunner() {
|
||||
// Create embedded view params
|
||||
flutter::MutatorsStack stack;
|
||||
// Layer tree always pushes a screen scale factor to the stack.
|
||||
CGFloat screenScale = [mockFlutterViewController flutterScreenIfViewLoaded].scale;
|
||||
SkMatrix screenScaleMatrix = SkMatrix::Scale(screenScale, screenScale);
|
||||
flutter::DlScalar screenScale = [mockFlutterViewController flutterScreenIfViewLoaded].scale;
|
||||
flutter::DlMatrix screenScaleMatrix = flutter::DlMatrix::MakeScale({screenScale, screenScale, 1});
|
||||
stack.PushTransform(screenScaleMatrix);
|
||||
SkMatrix translateMatrix = SkMatrix::Translate(5, 5);
|
||||
flutter::DlMatrix translateMatrix = flutter::DlMatrix::MakeTranslation({5, 5});
|
||||
// The platform view's rect for this test will be (5, 5, 10, 10).
|
||||
stack.PushTransform(translateMatrix);
|
||||
|
||||
// Push a clip rrect, the rect of the rrect is the same as the PlatformView of the corner should.
|
||||
// clip the PlatformView.
|
||||
SkRect rect_for_rrect = SkRect::MakeXYWH(0, 0, 10, 10);
|
||||
SkRRect rrect = SkRRect::MakeRectXY(rect_for_rrect, 1, 1);
|
||||
flutter::DlRect rect_for_rrect = flutter::DlRect::MakeXYWH(0, 0, 10, 10);
|
||||
flutter::DlRoundRect rrect = flutter::DlRoundRect::MakeRectXY(rect_for_rrect, 1, 1);
|
||||
stack.PushClipRRect(rrect);
|
||||
|
||||
auto embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
|
||||
SkMatrix::Concat(screenScaleMatrix, translateMatrix), SkSize::Make(5, 5), stack);
|
||||
flutter::ToSkMatrix(screenScaleMatrix * translateMatrix), SkSize::Make(5, 5), stack);
|
||||
|
||||
[flutterPlatformViewsController prerollCompositeEmbeddedView:2
|
||||
withParams:std::move(embeddedViewParams)];
|
||||
@ -2109,15 +2117,15 @@ fml::RefPtr<fml::TaskRunner> GetDefaultTaskRunner() {
|
||||
// Create embedded view params
|
||||
flutter::MutatorsStack stack;
|
||||
// Layer tree always pushes a screen scale factor to the stack
|
||||
CGFloat screenScale = [mockFlutterViewController flutterScreenIfViewLoaded].scale;
|
||||
SkMatrix screenScaleMatrix = SkMatrix::Scale(screenScale, screenScale);
|
||||
flutter::DlScalar screenScale = [mockFlutterViewController flutterScreenIfViewLoaded].scale;
|
||||
flutter::DlMatrix screenScaleMatrix = flutter::DlMatrix::MakeScale({screenScale, screenScale, 1});
|
||||
stack.PushTransform(screenScaleMatrix);
|
||||
// Push a clip rect
|
||||
SkRect rect = SkRect::MakeXYWH(2, 2, 3, 3);
|
||||
flutter::DlRect rect = flutter::DlRect::MakeXYWH(2, 2, 3, 3);
|
||||
stack.PushClipRect(rect);
|
||||
|
||||
auto embeddedViewParams =
|
||||
std::make_unique<flutter::EmbeddedViewParams>(screenScaleMatrix, SkSize::Make(10, 10), stack);
|
||||
auto embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
|
||||
flutter::ToSkMatrix(screenScaleMatrix), SkSize::Make(10, 10), stack);
|
||||
|
||||
[flutterPlatformViewsController prerollCompositeEmbeddedView:2
|
||||
withParams:std::move(embeddedViewParams)];
|
||||
@ -2192,18 +2200,18 @@ fml::RefPtr<fml::TaskRunner> GetDefaultTaskRunner() {
|
||||
// Create embedded view params
|
||||
flutter::MutatorsStack stack;
|
||||
// Layer tree always pushes a screen scale factor to the stack
|
||||
CGFloat screenScale = [mockFlutterViewController flutterScreenIfViewLoaded].scale;
|
||||
SkMatrix screenScaleMatrix = SkMatrix::Scale(screenScale, screenScale);
|
||||
flutter::DlScalar screenScale = [mockFlutterViewController flutterScreenIfViewLoaded].scale;
|
||||
flutter::DlMatrix screenScaleMatrix = flutter::DlMatrix::MakeScale({screenScale, screenScale, 1});
|
||||
stack.PushTransform(screenScaleMatrix);
|
||||
// Push a clip rect
|
||||
SkRect rect1 = SkRect::MakeXYWH(2, 2, 3, 3);
|
||||
flutter::DlRect rect1 = flutter::DlRect::MakeXYWH(2, 2, 3, 3);
|
||||
stack.PushClipRect(rect1);
|
||||
// Push another clip rect
|
||||
SkRect rect2 = SkRect::MakeXYWH(3, 3, 3, 3);
|
||||
flutter::DlRect rect2 = flutter::DlRect::MakeXYWH(3, 3, 3, 3);
|
||||
stack.PushClipRect(rect2);
|
||||
|
||||
auto embeddedViewParams =
|
||||
std::make_unique<flutter::EmbeddedViewParams>(screenScaleMatrix, SkSize::Make(10, 10), stack);
|
||||
auto embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
|
||||
flutter::ToSkMatrix(screenScaleMatrix), SkSize::Make(10, 10), stack);
|
||||
|
||||
[flutterPlatformViewsController prerollCompositeEmbeddedView:2
|
||||
withParams:std::move(embeddedViewParams)];
|
||||
@ -2295,15 +2303,16 @@ fml::RefPtr<fml::TaskRunner> GetDefaultTaskRunner() {
|
||||
// Create embedded view params
|
||||
flutter::MutatorsStack stack;
|
||||
// Layer tree always pushes a screen scale factor to the stack
|
||||
CGFloat screenScale = [mockFlutterViewController flutterScreenIfViewLoaded].scale;
|
||||
SkMatrix screenScaleMatrix = SkMatrix::Scale(screenScale, screenScale);
|
||||
flutter::DlScalar screenScale = [mockFlutterViewController flutterScreenIfViewLoaded].scale;
|
||||
flutter::DlMatrix screenScaleMatrix = flutter::DlMatrix::MakeScale({screenScale, screenScale, 1});
|
||||
stack.PushTransform(screenScaleMatrix);
|
||||
// Push a clip rrect
|
||||
SkRRect rrect = SkRRect::MakeRectXY(SkRect::MakeXYWH(2, 2, 6, 6), 1, 1);
|
||||
flutter::DlRoundRect rrect =
|
||||
flutter::DlRoundRect::MakeRectXY(flutter::DlRect::MakeXYWH(2, 2, 6, 6), 1, 1);
|
||||
stack.PushClipRRect(rrect);
|
||||
|
||||
auto embeddedViewParams =
|
||||
std::make_unique<flutter::EmbeddedViewParams>(screenScaleMatrix, SkSize::Make(10, 10), stack);
|
||||
auto embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
|
||||
flutter::ToSkMatrix(screenScaleMatrix), SkSize::Make(10, 10), stack);
|
||||
|
||||
[flutterPlatformViewsController prerollCompositeEmbeddedView:2
|
||||
withParams:std::move(embeddedViewParams)];
|
||||
@ -2405,18 +2414,19 @@ fml::RefPtr<fml::TaskRunner> GetDefaultTaskRunner() {
|
||||
// Create embedded view params
|
||||
flutter::MutatorsStack stack;
|
||||
// Layer tree always pushes a screen scale factor to the stack
|
||||
CGFloat screenScale = [mockFlutterViewController flutterScreenIfViewLoaded].scale;
|
||||
SkMatrix screenScaleMatrix = SkMatrix::Scale(screenScale, screenScale);
|
||||
flutter::DlScalar screenScale = [mockFlutterViewController flutterScreenIfViewLoaded].scale;
|
||||
flutter::DlMatrix screenScaleMatrix = flutter::DlMatrix::MakeScale({screenScale, screenScale, 1});
|
||||
stack.PushTransform(screenScaleMatrix);
|
||||
// Push a clip rrect
|
||||
SkRRect rrect = SkRRect::MakeRectXY(SkRect::MakeXYWH(2, 2, 6, 6), 1, 1);
|
||||
flutter::DlRoundRect rrect =
|
||||
flutter::DlRoundRect::MakeRectXY(flutter::DlRect::MakeXYWH(2, 2, 6, 6), 1, 1);
|
||||
stack.PushClipRRect(rrect);
|
||||
// Push a clip rect
|
||||
SkRect rect = SkRect::MakeXYWH(4, 2, 6, 6);
|
||||
flutter::DlRect rect = flutter::DlRect::MakeXYWH(4, 2, 6, 6);
|
||||
stack.PushClipRect(rect);
|
||||
|
||||
auto embeddedViewParams =
|
||||
std::make_unique<flutter::EmbeddedViewParams>(screenScaleMatrix, SkSize::Make(10, 10), stack);
|
||||
auto embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
|
||||
flutter::ToSkMatrix(screenScaleMatrix), SkSize::Make(10, 10), stack);
|
||||
|
||||
[flutterPlatformViewsController prerollCompositeEmbeddedView:2
|
||||
withParams:std::move(embeddedViewParams)];
|
||||
@ -2532,16 +2542,16 @@ fml::RefPtr<fml::TaskRunner> GetDefaultTaskRunner() {
|
||||
// Create embedded view params
|
||||
flutter::MutatorsStack stack;
|
||||
// Layer tree always pushes a screen scale factor to the stack
|
||||
CGFloat screenScale = [mockFlutterViewController flutterScreenIfViewLoaded].scale;
|
||||
SkMatrix screenScaleMatrix = SkMatrix::Scale(screenScale, screenScale);
|
||||
flutter::DlScalar screenScale = [mockFlutterViewController flutterScreenIfViewLoaded].scale;
|
||||
flutter::DlMatrix screenScaleMatrix = flutter::DlMatrix::MakeScale({screenScale, screenScale, 1});
|
||||
stack.PushTransform(screenScaleMatrix);
|
||||
// Push a clip path
|
||||
SkPath path;
|
||||
path.addRoundRect(SkRect::MakeXYWH(2, 2, 6, 6), 1, 1);
|
||||
flutter::DlPath path =
|
||||
flutter::DlPath::MakeRoundRectXY(flutter::DlRect::MakeXYWH(2, 2, 6, 6), 1, 1);
|
||||
stack.PushClipPath(path);
|
||||
|
||||
auto embeddedViewParams =
|
||||
std::make_unique<flutter::EmbeddedViewParams>(screenScaleMatrix, SkSize::Make(10, 10), stack);
|
||||
auto embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
|
||||
flutter::ToSkMatrix(screenScaleMatrix), SkSize::Make(10, 10), stack);
|
||||
|
||||
[flutterPlatformViewsController prerollCompositeEmbeddedView:2
|
||||
withParams:std::move(embeddedViewParams)];
|
||||
@ -2643,19 +2653,19 @@ fml::RefPtr<fml::TaskRunner> GetDefaultTaskRunner() {
|
||||
// Create embedded view params
|
||||
flutter::MutatorsStack stack;
|
||||
// Layer tree always pushes a screen scale factor to the stack
|
||||
CGFloat screenScale = [mockFlutterViewController flutterScreenIfViewLoaded].scale;
|
||||
SkMatrix screenScaleMatrix = SkMatrix::Scale(screenScale, screenScale);
|
||||
flutter::DlScalar screenScale = [mockFlutterViewController flutterScreenIfViewLoaded].scale;
|
||||
flutter::DlMatrix screenScaleMatrix = flutter::DlMatrix::MakeScale({screenScale, screenScale, 1});
|
||||
stack.PushTransform(screenScaleMatrix);
|
||||
// Push a clip path
|
||||
SkPath path;
|
||||
path.addRoundRect(SkRect::MakeXYWH(2, 2, 6, 6), 1, 1);
|
||||
flutter::DlPath path =
|
||||
flutter::DlPath::MakeRoundRectXY(flutter::DlRect::MakeXYWH(2, 2, 6, 6), 1, 1);
|
||||
stack.PushClipPath(path);
|
||||
// Push a clip rect
|
||||
SkRect rect = SkRect::MakeXYWH(4, 2, 6, 6);
|
||||
flutter::DlRect rect = flutter::DlRect::MakeXYWH(4, 2, 6, 6);
|
||||
stack.PushClipRect(rect);
|
||||
|
||||
auto embeddedViewParams =
|
||||
std::make_unique<flutter::EmbeddedViewParams>(screenScaleMatrix, SkSize::Make(10, 10), stack);
|
||||
auto embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
|
||||
flutter::ToSkMatrix(screenScaleMatrix), SkSize::Make(10, 10), stack);
|
||||
|
||||
[flutterPlatformViewsController prerollCompositeEmbeddedView:2
|
||||
withParams:std::move(embeddedViewParams)];
|
||||
@ -3495,10 +3505,10 @@ fml::RefPtr<fml::TaskRunner> GetDefaultTaskRunner() {
|
||||
|
||||
// Create embedded view params
|
||||
flutter::MutatorsStack stack;
|
||||
SkMatrix finalMatrix;
|
||||
flutter::DlMatrix finalMatrix;
|
||||
|
||||
auto embeddedViewParams_1 =
|
||||
std::make_unique<flutter::EmbeddedViewParams>(finalMatrix, SkSize::Make(300, 300), stack);
|
||||
auto embeddedViewParams_1 = std::make_unique<flutter::EmbeddedViewParams>(
|
||||
flutter::ToSkMatrix(finalMatrix), SkSize::Make(300, 300), stack);
|
||||
|
||||
[flutterPlatformViewsController prerollCompositeEmbeddedView:2
|
||||
withParams:std::move(embeddedViewParams_1)];
|
||||
@ -3516,8 +3526,8 @@ fml::RefPtr<fml::TaskRunner> GetDefaultTaskRunner() {
|
||||
submitFrame:std::move(mock_surface)
|
||||
withIosContext:std::make_shared<flutter::IOSContextNoop>()]);
|
||||
|
||||
auto embeddedViewParams_2 =
|
||||
std::make_unique<flutter::EmbeddedViewParams>(finalMatrix, SkSize::Make(300, 300), stack);
|
||||
auto embeddedViewParams_2 = std::make_unique<flutter::EmbeddedViewParams>(
|
||||
flutter::ToSkMatrix(finalMatrix), SkSize::Make(300, 300), stack);
|
||||
[flutterPlatformViewsController prerollCompositeEmbeddedView:2
|
||||
withParams:std::move(embeddedViewParams_2)];
|
||||
[flutterPlatformViewsController
|
||||
@ -3576,9 +3586,9 @@ fml::RefPtr<fml::TaskRunner> GetDefaultTaskRunner() {
|
||||
result:result];
|
||||
|
||||
flutter::MutatorsStack stack;
|
||||
SkMatrix finalMatrix;
|
||||
auto embeddedViewParams =
|
||||
std::make_unique<flutter::EmbeddedViewParams>(finalMatrix, SkSize::Make(300, 300), stack);
|
||||
flutter::DlMatrix finalMatrix;
|
||||
auto embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
|
||||
flutter::ToSkMatrix(finalMatrix), SkSize::Make(300, 300), stack);
|
||||
[flutterPlatformViewsController prerollCompositeEmbeddedView:2
|
||||
withParams:std::move(embeddedViewParams)];
|
||||
|
||||
@ -3636,9 +3646,9 @@ fml::RefPtr<fml::TaskRunner> GetDefaultTaskRunner() {
|
||||
// First frame, |embeddedViewCount| is not empty after composite.
|
||||
[flutterPlatformViewsController beginFrameWithSize:SkISize::Make(300, 300)];
|
||||
flutter::MutatorsStack stack;
|
||||
SkMatrix finalMatrix;
|
||||
auto embeddedViewParams1 =
|
||||
std::make_unique<flutter::EmbeddedViewParams>(finalMatrix, SkSize::Make(300, 300), stack);
|
||||
flutter::DlMatrix finalMatrix;
|
||||
auto embeddedViewParams1 = std::make_unique<flutter::EmbeddedViewParams>(
|
||||
flutter::ToSkMatrix(finalMatrix), SkSize::Make(300, 300), stack);
|
||||
[flutterPlatformViewsController prerollCompositeEmbeddedView:0
|
||||
withParams:std::move(embeddedViewParams1)];
|
||||
[flutterPlatformViewsController
|
||||
@ -3651,8 +3661,8 @@ fml::RefPtr<fml::TaskRunner> GetDefaultTaskRunner() {
|
||||
[flutterPlatformViewsController beginFrameWithSize:SkISize::Make(300, 300)];
|
||||
XCTAssertEqual(flutterPlatformViewsController.embeddedViewCount, 0UL);
|
||||
|
||||
auto embeddedViewParams2 =
|
||||
std::make_unique<flutter::EmbeddedViewParams>(finalMatrix, SkSize::Make(300, 300), stack);
|
||||
auto embeddedViewParams2 = std::make_unique<flutter::EmbeddedViewParams>(
|
||||
flutter::ToSkMatrix(finalMatrix), SkSize::Make(300, 300), stack);
|
||||
[flutterPlatformViewsController prerollCompositeEmbeddedView:0
|
||||
withParams:std::move(embeddedViewParams2)];
|
||||
[flutterPlatformViewsController
|
||||
@ -3717,14 +3727,14 @@ fml::RefPtr<fml::TaskRunner> GetDefaultTaskRunner() {
|
||||
|
||||
[flutterPlatformViewsController beginFrameWithSize:SkISize::Make(300, 300)];
|
||||
flutter::MutatorsStack stack;
|
||||
SkMatrix finalMatrix;
|
||||
auto embeddedViewParams1 =
|
||||
std::make_unique<flutter::EmbeddedViewParams>(finalMatrix, SkSize::Make(300, 300), stack);
|
||||
flutter::DlMatrix finalMatrix;
|
||||
auto embeddedViewParams1 = std::make_unique<flutter::EmbeddedViewParams>(
|
||||
flutter::ToSkMatrix(finalMatrix), SkSize::Make(300, 300), stack);
|
||||
[flutterPlatformViewsController prerollCompositeEmbeddedView:0
|
||||
withParams:std::move(embeddedViewParams1)];
|
||||
|
||||
auto embeddedViewParams2 =
|
||||
std::make_unique<flutter::EmbeddedViewParams>(finalMatrix, SkSize::Make(500, 500), stack);
|
||||
auto embeddedViewParams2 = std::make_unique<flutter::EmbeddedViewParams>(
|
||||
flutter::ToSkMatrix(finalMatrix), SkSize::Make(500, 500), stack);
|
||||
[flutterPlatformViewsController prerollCompositeEmbeddedView:1
|
||||
withParams:std::move(embeddedViewParams2)];
|
||||
|
||||
@ -3748,13 +3758,13 @@ fml::RefPtr<fml::TaskRunner> GetDefaultTaskRunner() {
|
||||
// Need to recreate these params since they are `std::move`ed.
|
||||
[flutterPlatformViewsController beginFrameWithSize:SkISize::Make(300, 300)];
|
||||
// Process the second frame in the opposite order.
|
||||
embeddedViewParams2 =
|
||||
std::make_unique<flutter::EmbeddedViewParams>(finalMatrix, SkSize::Make(500, 500), stack);
|
||||
embeddedViewParams2 = std::make_unique<flutter::EmbeddedViewParams>(
|
||||
flutter::ToSkMatrix(finalMatrix), SkSize::Make(500, 500), stack);
|
||||
[flutterPlatformViewsController prerollCompositeEmbeddedView:1
|
||||
withParams:std::move(embeddedViewParams2)];
|
||||
|
||||
embeddedViewParams1 =
|
||||
std::make_unique<flutter::EmbeddedViewParams>(finalMatrix, SkSize::Make(300, 300), stack);
|
||||
embeddedViewParams1 = std::make_unique<flutter::EmbeddedViewParams>(
|
||||
flutter::ToSkMatrix(finalMatrix), SkSize::Make(300, 300), stack);
|
||||
[flutterPlatformViewsController prerollCompositeEmbeddedView:0
|
||||
withParams:std::move(embeddedViewParams1)];
|
||||
|
||||
@ -3827,14 +3837,14 @@ fml::RefPtr<fml::TaskRunner> GetDefaultTaskRunner() {
|
||||
|
||||
[flutterPlatformViewsController beginFrameWithSize:SkISize::Make(300, 300)];
|
||||
flutter::MutatorsStack stack;
|
||||
SkMatrix finalMatrix;
|
||||
auto embeddedViewParams1 =
|
||||
std::make_unique<flutter::EmbeddedViewParams>(finalMatrix, SkSize::Make(300, 300), stack);
|
||||
flutter::DlMatrix finalMatrix;
|
||||
auto embeddedViewParams1 = std::make_unique<flutter::EmbeddedViewParams>(
|
||||
flutter::ToSkMatrix(finalMatrix), SkSize::Make(300, 300), stack);
|
||||
[flutterPlatformViewsController prerollCompositeEmbeddedView:0
|
||||
withParams:std::move(embeddedViewParams1)];
|
||||
|
||||
auto embeddedViewParams2 =
|
||||
std::make_unique<flutter::EmbeddedViewParams>(finalMatrix, SkSize::Make(500, 500), stack);
|
||||
auto embeddedViewParams2 = std::make_unique<flutter::EmbeddedViewParams>(
|
||||
flutter::ToSkMatrix(finalMatrix), SkSize::Make(500, 500), stack);
|
||||
[flutterPlatformViewsController prerollCompositeEmbeddedView:1
|
||||
withParams:std::move(embeddedViewParams2)];
|
||||
|
||||
@ -3858,13 +3868,13 @@ fml::RefPtr<fml::TaskRunner> GetDefaultTaskRunner() {
|
||||
// Need to recreate these params since they are `std::move`ed.
|
||||
[flutterPlatformViewsController beginFrameWithSize:SkISize::Make(300, 300)];
|
||||
// Process the second frame in the same order.
|
||||
embeddedViewParams1 =
|
||||
std::make_unique<flutter::EmbeddedViewParams>(finalMatrix, SkSize::Make(300, 300), stack);
|
||||
embeddedViewParams1 = std::make_unique<flutter::EmbeddedViewParams>(
|
||||
flutter::ToSkMatrix(finalMatrix), SkSize::Make(300, 300), stack);
|
||||
[flutterPlatformViewsController prerollCompositeEmbeddedView:0
|
||||
withParams:std::move(embeddedViewParams1)];
|
||||
|
||||
embeddedViewParams2 =
|
||||
std::make_unique<flutter::EmbeddedViewParams>(finalMatrix, SkSize::Make(500, 500), stack);
|
||||
embeddedViewParams2 = std::make_unique<flutter::EmbeddedViewParams>(
|
||||
flutter::ToSkMatrix(finalMatrix), SkSize::Make(500, 500), stack);
|
||||
[flutterPlatformViewsController prerollCompositeEmbeddedView:1
|
||||
withParams:std::move(embeddedViewParams2)];
|
||||
|
||||
@ -4012,15 +4022,15 @@ fml::RefPtr<fml::TaskRunner> GetDefaultTaskRunner() {
|
||||
// Create embedded view params
|
||||
flutter::MutatorsStack stack1;
|
||||
// Layer tree always pushes a screen scale factor to the stack
|
||||
CGFloat screenScale = [mockFlutterViewController flutterScreenIfViewLoaded].scale;
|
||||
SkMatrix screenScaleMatrix = SkMatrix::Scale(screenScale, screenScale);
|
||||
flutter::DlScalar screenScale = [mockFlutterViewController flutterScreenIfViewLoaded].scale;
|
||||
flutter::DlMatrix screenScaleMatrix = flutter::DlMatrix::MakeScale({screenScale, screenScale, 1});
|
||||
stack1.PushTransform(screenScaleMatrix);
|
||||
// Push a clip rect
|
||||
SkRect rect = SkRect::MakeXYWH(2, 2, 3, 3);
|
||||
flutter::DlRect rect = flutter::DlRect::MakeXYWH(2, 2, 3, 3);
|
||||
stack1.PushClipRect(rect);
|
||||
|
||||
auto embeddedViewParams1 = std::make_unique<flutter::EmbeddedViewParams>(
|
||||
screenScaleMatrix, SkSize::Make(10, 10), stack1);
|
||||
flutter::ToSkMatrix(screenScaleMatrix), SkSize::Make(10, 10), stack1);
|
||||
|
||||
[flutterPlatformViewsController prerollCompositeEmbeddedView:1
|
||||
withParams:std::move(embeddedViewParams1)];
|
||||
@ -4036,9 +4046,9 @@ fml::RefPtr<fml::TaskRunner> GetDefaultTaskRunner() {
|
||||
[flutterPlatformViewsController beginFrameWithSize:SkISize::Make(100, 100)];
|
||||
flutter::MutatorsStack stack2;
|
||||
auto embeddedViewParams2 = std::make_unique<flutter::EmbeddedViewParams>(
|
||||
screenScaleMatrix, SkSize::Make(10, 10), stack2);
|
||||
flutter::ToSkMatrix(screenScaleMatrix), SkSize::Make(10, 10), stack2);
|
||||
auto embeddedViewParams3 = std::make_unique<flutter::EmbeddedViewParams>(
|
||||
screenScaleMatrix, SkSize::Make(10, 10), stack2);
|
||||
flutter::ToSkMatrix(screenScaleMatrix), SkSize::Make(10, 10), stack2);
|
||||
[flutterPlatformViewsController prerollCompositeEmbeddedView:1
|
||||
withParams:std::move(embeddedViewParams3)];
|
||||
[flutterPlatformViewsController
|
||||
@ -4057,7 +4067,7 @@ fml::RefPtr<fml::TaskRunner> GetDefaultTaskRunner() {
|
||||
result:result];
|
||||
|
||||
auto embeddedViewParams4 = std::make_unique<flutter::EmbeddedViewParams>(
|
||||
screenScaleMatrix, SkSize::Make(10, 10), stack1);
|
||||
flutter::ToSkMatrix(screenScaleMatrix), SkSize::Make(10, 10), stack1);
|
||||
[flutterPlatformViewsController prerollCompositeEmbeddedView:2
|
||||
withParams:std::move(embeddedViewParams4)];
|
||||
[flutterPlatformViewsController
|
||||
@ -4128,20 +4138,20 @@ fml::RefPtr<fml::TaskRunner> GetDefaultTaskRunner() {
|
||||
// Create embedded view params
|
||||
flutter::MutatorsStack stack1;
|
||||
// Layer tree always pushes a screen scale factor to the stack
|
||||
CGFloat screenScale = [mockFlutterViewController flutterScreenIfViewLoaded].scale;
|
||||
SkMatrix screenScaleMatrix = SkMatrix::Scale(screenScale, screenScale);
|
||||
flutter::DlScalar screenScale = [mockFlutterViewController flutterScreenIfViewLoaded].scale;
|
||||
flutter::DlMatrix screenScaleMatrix = flutter::DlMatrix::MakeScale({screenScale, screenScale, 1});
|
||||
stack1.PushTransform(screenScaleMatrix);
|
||||
// Push a clip rect
|
||||
SkRect rect = SkRect::MakeXYWH(2, 2, 3, 3);
|
||||
flutter::DlRect rect = flutter::DlRect::MakeXYWH(2, 2, 3, 3);
|
||||
stack1.PushClipRect(rect);
|
||||
|
||||
auto embeddedViewParams1 = std::make_unique<flutter::EmbeddedViewParams>(
|
||||
screenScaleMatrix, SkSize::Make(10, 10), stack1);
|
||||
flutter::ToSkMatrix(screenScaleMatrix), SkSize::Make(10, 10), stack1);
|
||||
|
||||
flutter::MutatorsStack stack2;
|
||||
stack2.PushClipRect(rect);
|
||||
auto embeddedViewParams2 = std::make_unique<flutter::EmbeddedViewParams>(
|
||||
screenScaleMatrix, SkSize::Make(10, 10), stack2);
|
||||
flutter::ToSkMatrix(screenScaleMatrix), SkSize::Make(10, 10), stack2);
|
||||
|
||||
[flutterPlatformViewsController prerollCompositeEmbeddedView:1
|
||||
withParams:std::move(embeddedViewParams1)];
|
||||
@ -4208,20 +4218,20 @@ fml::RefPtr<fml::TaskRunner> GetDefaultTaskRunner() {
|
||||
// Create embedded view params
|
||||
flutter::MutatorsStack stack1;
|
||||
// Layer tree always pushes a screen scale factor to the stack
|
||||
CGFloat screenScale = [mockFlutterViewController flutterScreenIfViewLoaded].scale;
|
||||
SkMatrix screenScaleMatrix = SkMatrix::Scale(screenScale, screenScale);
|
||||
flutter::DlScalar screenScale = [mockFlutterViewController flutterScreenIfViewLoaded].scale;
|
||||
flutter::DlMatrix screenScaleMatrix = flutter::DlMatrix::MakeScale({screenScale, screenScale, 1});
|
||||
stack1.PushTransform(screenScaleMatrix);
|
||||
// Push a clip rect
|
||||
SkRect rect = SkRect::MakeXYWH(2, 2, 3, 3);
|
||||
flutter::DlRect rect = flutter::DlRect::MakeXYWH(2, 2, 3, 3);
|
||||
stack1.PushClipRect(rect);
|
||||
|
||||
auto embeddedViewParams1 = std::make_unique<flutter::EmbeddedViewParams>(
|
||||
screenScaleMatrix, SkSize::Make(10, 10), stack1);
|
||||
flutter::ToSkMatrix(screenScaleMatrix), SkSize::Make(10, 10), stack1);
|
||||
|
||||
flutter::MutatorsStack stack2;
|
||||
stack2.PushClipRect(rect);
|
||||
auto embeddedViewParams2 = std::make_unique<flutter::EmbeddedViewParams>(
|
||||
screenScaleMatrix, SkSize::Make(10, 10), stack2);
|
||||
flutter::ToSkMatrix(screenScaleMatrix), SkSize::Make(10, 10), stack2);
|
||||
|
||||
[flutterPlatformViewsController prerollCompositeEmbeddedView:1
|
||||
withParams:std::move(embeddedViewParams1)];
|
||||
@ -4317,14 +4327,14 @@ fml::RefPtr<fml::TaskRunner> GetDefaultTaskRunner() {
|
||||
// No view should be disposed, or removed from the composition order.
|
||||
[flutterPlatformViewsController beginFrameWithSize:SkISize::Make(300, 300)];
|
||||
flutter::MutatorsStack stack;
|
||||
SkMatrix finalMatrix;
|
||||
auto embeddedViewParams0 =
|
||||
std::make_unique<flutter::EmbeddedViewParams>(finalMatrix, SkSize::Make(300, 300), stack);
|
||||
flutter::DlMatrix finalMatrix;
|
||||
auto embeddedViewParams0 = std::make_unique<flutter::EmbeddedViewParams>(
|
||||
flutter::ToSkMatrix(finalMatrix), SkSize::Make(300, 300), stack);
|
||||
[flutterPlatformViewsController prerollCompositeEmbeddedView:0
|
||||
withParams:std::move(embeddedViewParams0)];
|
||||
|
||||
auto embeddedViewParams1 =
|
||||
std::make_unique<flutter::EmbeddedViewParams>(finalMatrix, SkSize::Make(300, 300), stack);
|
||||
auto embeddedViewParams1 = std::make_unique<flutter::EmbeddedViewParams>(
|
||||
flutter::ToSkMatrix(finalMatrix), SkSize::Make(300, 300), stack);
|
||||
[flutterPlatformViewsController prerollCompositeEmbeddedView:1
|
||||
withParams:std::move(embeddedViewParams1)];
|
||||
|
||||
@ -4362,9 +4372,9 @@ fml::RefPtr<fml::TaskRunner> GetDefaultTaskRunner() {
|
||||
// View 0 is removed from the composition order in this frame, hence also disposed.
|
||||
[flutterPlatformViewsController beginFrameWithSize:SkISize::Make(300, 300)];
|
||||
flutter::MutatorsStack stack;
|
||||
SkMatrix finalMatrix;
|
||||
auto embeddedViewParams1 =
|
||||
std::make_unique<flutter::EmbeddedViewParams>(finalMatrix, SkSize::Make(300, 300), stack);
|
||||
flutter::DlMatrix finalMatrix;
|
||||
auto embeddedViewParams1 = std::make_unique<flutter::EmbeddedViewParams>(
|
||||
flutter::ToSkMatrix(finalMatrix), SkSize::Make(300, 300), stack);
|
||||
[flutterPlatformViewsController prerollCompositeEmbeddedView:1
|
||||
withParams:std::move(embeddedViewParams1)];
|
||||
|
||||
@ -4426,17 +4436,16 @@ fml::RefPtr<fml::TaskRunner> GetDefaultTaskRunner() {
|
||||
// Create embedded view params
|
||||
flutter::MutatorsStack stack;
|
||||
// Layer tree always pushes a screen scale factor to the stack
|
||||
CGFloat screenScale = [mockFlutterViewController flutterScreenIfViewLoaded].scale;
|
||||
SkMatrix screenScaleMatrix = SkMatrix::Scale(screenScale, screenScale);
|
||||
flutter::DlScalar screenScale = [mockFlutterViewController flutterScreenIfViewLoaded].scale;
|
||||
flutter::DlMatrix screenScaleMatrix = flutter::DlMatrix::MakeScale({screenScale, screenScale, 1});
|
||||
stack.PushTransform(screenScaleMatrix);
|
||||
// Push a translate matrix
|
||||
SkMatrix translateMatrix = SkMatrix::Translate(100, 100);
|
||||
flutter::DlMatrix translateMatrix = flutter::DlMatrix::MakeTranslation({100, 100});
|
||||
stack.PushTransform(translateMatrix);
|
||||
SkMatrix finalMatrix;
|
||||
finalMatrix.setConcat(screenScaleMatrix, translateMatrix);
|
||||
flutter::DlMatrix finalMatrix = screenScaleMatrix * translateMatrix;
|
||||
|
||||
auto embeddedViewParams =
|
||||
std::make_unique<flutter::EmbeddedViewParams>(finalMatrix, SkSize::Make(300, 300), stack);
|
||||
auto embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
|
||||
flutter::ToSkMatrix(finalMatrix), SkSize::Make(300, 300), stack);
|
||||
|
||||
[flutterPlatformViewsController prerollCompositeEmbeddedView:2
|
||||
withParams:std::move(embeddedViewParams)];
|
||||
@ -4500,17 +4509,16 @@ fml::RefPtr<fml::TaskRunner> GetDefaultTaskRunner() {
|
||||
// Create embedded view params
|
||||
flutter::MutatorsStack stack;
|
||||
// Layer tree always pushes a screen scale factor to the stack
|
||||
CGFloat screenScale = [mockFlutterViewController flutterScreenIfViewLoaded].scale;
|
||||
SkMatrix screenScaleMatrix = SkMatrix::Scale(screenScale, screenScale);
|
||||
flutter::DlScalar screenScale = [mockFlutterViewController flutterScreenIfViewLoaded].scale;
|
||||
flutter::DlMatrix screenScaleMatrix = flutter::DlMatrix::MakeScale({screenScale, screenScale, 1});
|
||||
stack.PushTransform(screenScaleMatrix);
|
||||
// Push a translate matrix
|
||||
SkMatrix translateMatrix = SkMatrix::Translate(100, 100);
|
||||
flutter::DlMatrix translateMatrix = flutter::DlMatrix::MakeTranslation({100, 100});
|
||||
stack.PushTransform(translateMatrix);
|
||||
SkMatrix finalMatrix;
|
||||
finalMatrix.setConcat(screenScaleMatrix, translateMatrix);
|
||||
flutter::DlMatrix finalMatrix = screenScaleMatrix * translateMatrix;
|
||||
|
||||
auto embeddedViewParams =
|
||||
std::make_unique<flutter::EmbeddedViewParams>(finalMatrix, SkSize::Make(300, 300), stack);
|
||||
auto embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
|
||||
flutter::ToSkMatrix(finalMatrix), SkSize::Make(300, 300), stack);
|
||||
|
||||
[flutterPlatformViewsController prerollCompositeEmbeddedView:2
|
||||
withParams:std::move(embeddedViewParams)];
|
||||
@ -4577,17 +4585,16 @@ fml::RefPtr<fml::TaskRunner> GetDefaultTaskRunner() {
|
||||
// Create embedded view params
|
||||
flutter::MutatorsStack stack;
|
||||
// Layer tree always pushes a screen scale factor to the stack
|
||||
CGFloat screenScale = [mockFlutterViewController flutterScreenIfViewLoaded].scale;
|
||||
SkMatrix screenScaleMatrix = SkMatrix::Scale(screenScale, screenScale);
|
||||
flutter::DlScalar screenScale = [mockFlutterViewController flutterScreenIfViewLoaded].scale;
|
||||
flutter::DlMatrix screenScaleMatrix = flutter::DlMatrix::MakeScale({screenScale, screenScale, 1});
|
||||
stack.PushTransform(screenScaleMatrix);
|
||||
// Push a translate matrix
|
||||
SkMatrix translateMatrix = SkMatrix::Translate(100, 100);
|
||||
flutter::DlMatrix translateMatrix = flutter::DlMatrix::MakeTranslation({100, 100});
|
||||
stack.PushTransform(translateMatrix);
|
||||
SkMatrix finalMatrix;
|
||||
finalMatrix.setConcat(screenScaleMatrix, translateMatrix);
|
||||
flutter::DlMatrix finalMatrix = screenScaleMatrix * translateMatrix;
|
||||
|
||||
auto embeddedViewParams =
|
||||
std::make_unique<flutter::EmbeddedViewParams>(finalMatrix, SkSize::Make(300, 300), stack);
|
||||
auto embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
|
||||
flutter::ToSkMatrix(finalMatrix), SkSize::Make(300, 300), stack);
|
||||
|
||||
[flutterPlatformViewsController prerollCompositeEmbeddedView:2
|
||||
withParams:std::move(embeddedViewParams)];
|
||||
@ -4688,14 +4695,14 @@ fml::RefPtr<fml::TaskRunner> GetDefaultTaskRunner() {
|
||||
|
||||
[flutterPlatformViewsController beginFrameWithSize:SkISize::Make(300, 300)];
|
||||
flutter::MutatorsStack stack;
|
||||
SkMatrix finalMatrix;
|
||||
auto embeddedViewParams1 =
|
||||
std::make_unique<flutter::EmbeddedViewParams>(finalMatrix, SkSize::Make(300, 300), stack);
|
||||
flutter::DlMatrix finalMatrix;
|
||||
auto embeddedViewParams1 = std::make_unique<flutter::EmbeddedViewParams>(
|
||||
flutter::ToSkMatrix(finalMatrix), SkSize::Make(300, 300), stack);
|
||||
[flutterPlatformViewsController prerollCompositeEmbeddedView:0
|
||||
withParams:std::move(embeddedViewParams1)];
|
||||
|
||||
auto embeddedViewParams2 =
|
||||
std::make_unique<flutter::EmbeddedViewParams>(finalMatrix, SkSize::Make(500, 500), stack);
|
||||
auto embeddedViewParams2 = std::make_unique<flutter::EmbeddedViewParams>(
|
||||
flutter::ToSkMatrix(finalMatrix), SkSize::Make(500, 500), stack);
|
||||
[flutterPlatformViewsController prerollCompositeEmbeddedView:1
|
||||
withParams:std::move(embeddedViewParams2)];
|
||||
|
||||
|
@ -37,17 +37,17 @@
|
||||
// Adds a clip rect operation to the queue.
|
||||
//
|
||||
// The `clipSkRect` is transformed with the `matrix` before adding to the queue.
|
||||
- (void)clipRect:(const SkRect&)clipSkRect matrix:(const SkMatrix&)matrix;
|
||||
- (void)clipRect:(const flutter::DlRect&)clipDlRect matrix:(const flutter::DlMatrix&)matrix;
|
||||
|
||||
// Adds a clip rrect operation to the queue.
|
||||
//
|
||||
// The `clipSkRRect` is transformed with the `matrix` before adding to the queue.
|
||||
- (void)clipRRect:(const SkRRect&)clipSkRRect matrix:(const SkMatrix&)matrix;
|
||||
- (void)clipRRect:(const flutter::DlRoundRect&)clipDlRRect matrix:(const flutter::DlMatrix&)matrix;
|
||||
|
||||
// Adds a clip path operation to the queue.
|
||||
//
|
||||
// The `path` is transformed with the `matrix` before adding to the queue.
|
||||
- (void)clipPath:(const SkPath&)path matrix:(const SkMatrix&)matrix;
|
||||
- (void)clipPath:(const flutter::DlPath&)path matrix:(const flutter::DlMatrix&)matrix;
|
||||
|
||||
@end
|
||||
|
||||
|
@ -145,42 +145,42 @@ struct PlatformView {
|
||||
view_identifier = view->GetViewIdentifier();
|
||||
params = view->GetEmbeddedViewParams();
|
||||
|
||||
clipped_frame = view->GetEmbeddedViewParams()->finalBoundingRect();
|
||||
SkMatrix transform;
|
||||
DlRect clip = ToDlRect(view->GetEmbeddedViewParams()->finalBoundingRect());
|
||||
DlMatrix matrix;
|
||||
for (auto i = params->mutatorsStack().Begin();
|
||||
i != params->mutatorsStack().End(); ++i) {
|
||||
const auto& m = *i;
|
||||
switch (m->GetType()) {
|
||||
case kClipRect: {
|
||||
auto rect = transform.mapRect(m->GetRect());
|
||||
if (!clipped_frame.intersect(rect)) {
|
||||
clipped_frame = SkRect::MakeEmpty();
|
||||
}
|
||||
case MutatorType::kClipRect: {
|
||||
auto rect = m->GetRect().TransformAndClipBounds(matrix);
|
||||
clip = clip.IntersectionOrEmpty(rect);
|
||||
break;
|
||||
}
|
||||
case kClipRRect: {
|
||||
auto rect = transform.mapRect(m->GetRRect().getBounds());
|
||||
if (!clipped_frame.intersect(rect)) {
|
||||
clipped_frame = SkRect::MakeEmpty();
|
||||
}
|
||||
case MutatorType::kClipRRect: {
|
||||
auto rect = m->GetRRect().GetBounds().TransformAndClipBounds(matrix);
|
||||
clip = clip.IntersectionOrEmpty(rect);
|
||||
break;
|
||||
}
|
||||
case kClipPath: {
|
||||
auto rect = transform.mapRect(m->GetPath().getBounds());
|
||||
if (!clipped_frame.intersect(rect)) {
|
||||
clipped_frame = SkRect::MakeEmpty();
|
||||
}
|
||||
case MutatorType::kClipRSE: {
|
||||
auto rect = m->GetRSE().GetBounds().TransformAndClipBounds(matrix);
|
||||
clip = clip.IntersectionOrEmpty(rect);
|
||||
break;
|
||||
}
|
||||
case kTransform: {
|
||||
transform.preConcat(m->GetMatrix());
|
||||
case MutatorType::kClipPath: {
|
||||
auto rect = m->GetPath().GetBounds().TransformAndClipBounds(matrix);
|
||||
clip = clip.IntersectionOrEmpty(rect);
|
||||
break;
|
||||
}
|
||||
case kOpacity:
|
||||
case kBackdropFilter:
|
||||
case MutatorType::kTransform: {
|
||||
matrix = matrix * m->GetMatrix();
|
||||
break;
|
||||
}
|
||||
case MutatorType::kOpacity:
|
||||
case MutatorType::kBackdropFilter:
|
||||
break;
|
||||
}
|
||||
}
|
||||
clipped_frame = ToSkRect(clip);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -79,56 +79,57 @@ static std::unique_ptr<FlutterPlatformViewMutation> ConvertMutation(
|
||||
}
|
||||
|
||||
static std::unique_ptr<FlutterPlatformViewMutation> ConvertMutation(
|
||||
const SkRect& rect) {
|
||||
const DlRect& rect) {
|
||||
FlutterPlatformViewMutation mutation = {};
|
||||
mutation.type = kFlutterPlatformViewMutationTypeClipRect;
|
||||
mutation.clip_rect.left = rect.left();
|
||||
mutation.clip_rect.top = rect.top();
|
||||
mutation.clip_rect.right = rect.right();
|
||||
mutation.clip_rect.bottom = rect.bottom();
|
||||
mutation.clip_rect.left = rect.GetLeft();
|
||||
mutation.clip_rect.top = rect.GetTop();
|
||||
mutation.clip_rect.right = rect.GetRight();
|
||||
mutation.clip_rect.bottom = rect.GetBottom();
|
||||
return std::make_unique<FlutterPlatformViewMutation>(mutation);
|
||||
}
|
||||
|
||||
static FlutterSize VectorToSize(const SkVector& vector) {
|
||||
static FlutterSize ConvertSize(const DlSize& vector) {
|
||||
FlutterSize size = {};
|
||||
size.width = vector.x();
|
||||
size.height = vector.y();
|
||||
size.width = vector.width;
|
||||
size.height = vector.height;
|
||||
return size;
|
||||
}
|
||||
|
||||
static std::unique_ptr<FlutterPlatformViewMutation> ConvertMutation(
|
||||
const SkRRect& rrect) {
|
||||
const DlRoundRect& rrect) {
|
||||
FlutterPlatformViewMutation mutation = {};
|
||||
mutation.type = kFlutterPlatformViewMutationTypeClipRoundedRect;
|
||||
const auto& rect = rrect.rect();
|
||||
mutation.clip_rounded_rect.rect.left = rect.left();
|
||||
mutation.clip_rounded_rect.rect.top = rect.top();
|
||||
mutation.clip_rounded_rect.rect.right = rect.right();
|
||||
mutation.clip_rounded_rect.rect.bottom = rect.bottom();
|
||||
const auto& rect = rrect.GetBounds();
|
||||
mutation.clip_rounded_rect.rect.left = rect.GetLeft();
|
||||
mutation.clip_rounded_rect.rect.top = rect.GetTop();
|
||||
mutation.clip_rounded_rect.rect.right = rect.GetRight();
|
||||
mutation.clip_rounded_rect.rect.bottom = rect.GetBottom();
|
||||
const auto& radii = rrect.GetRadii();
|
||||
mutation.clip_rounded_rect.upper_left_corner_radius =
|
||||
VectorToSize(rrect.radii(SkRRect::Corner::kUpperLeft_Corner));
|
||||
ConvertSize(radii.top_left);
|
||||
mutation.clip_rounded_rect.upper_right_corner_radius =
|
||||
VectorToSize(rrect.radii(SkRRect::Corner::kUpperRight_Corner));
|
||||
ConvertSize(radii.top_right);
|
||||
mutation.clip_rounded_rect.lower_right_corner_radius =
|
||||
VectorToSize(rrect.radii(SkRRect::Corner::kLowerRight_Corner));
|
||||
ConvertSize(radii.bottom_right);
|
||||
mutation.clip_rounded_rect.lower_left_corner_radius =
|
||||
VectorToSize(rrect.radii(SkRRect::Corner::kLowerLeft_Corner));
|
||||
ConvertSize(radii.bottom_left);
|
||||
return std::make_unique<FlutterPlatformViewMutation>(mutation);
|
||||
}
|
||||
|
||||
static std::unique_ptr<FlutterPlatformViewMutation> ConvertMutation(
|
||||
const SkMatrix& matrix) {
|
||||
const DlMatrix& matrix) {
|
||||
FlutterPlatformViewMutation mutation = {};
|
||||
mutation.type = kFlutterPlatformViewMutationTypeTransformation;
|
||||
mutation.transformation.scaleX = matrix[SkMatrix::kMScaleX];
|
||||
mutation.transformation.skewX = matrix[SkMatrix::kMSkewX];
|
||||
mutation.transformation.transX = matrix[SkMatrix::kMTransX];
|
||||
mutation.transformation.skewY = matrix[SkMatrix::kMSkewY];
|
||||
mutation.transformation.scaleY = matrix[SkMatrix::kMScaleY];
|
||||
mutation.transformation.transY = matrix[SkMatrix::kMTransY];
|
||||
mutation.transformation.pers0 = matrix[SkMatrix::kMPersp0];
|
||||
mutation.transformation.pers1 = matrix[SkMatrix::kMPersp1];
|
||||
mutation.transformation.pers2 = matrix[SkMatrix::kMPersp2];
|
||||
mutation.transformation.scaleX = matrix.m[0];
|
||||
mutation.transformation.skewX = matrix.m[4];
|
||||
mutation.transformation.transX = matrix.m[12];
|
||||
mutation.transformation.skewY = matrix.m[1];
|
||||
mutation.transformation.scaleY = matrix.m[5];
|
||||
mutation.transformation.transY = matrix.m[13];
|
||||
mutation.transformation.pers0 = matrix.m[3];
|
||||
mutation.transformation.pers1 = matrix.m[7];
|
||||
mutation.transformation.pers2 = matrix.m[15];
|
||||
return std::make_unique<FlutterPlatformViewMutation>(mutation);
|
||||
}
|
||||
|
||||
@ -159,12 +160,18 @@ void EmbedderLayers::PushPlatformViewLayer(
|
||||
.emplace_back(ConvertMutation(mutator->GetRRect()))
|
||||
.get());
|
||||
} break;
|
||||
case MutatorType::kClipRSE: {
|
||||
mutations_array.push_back(
|
||||
mutations_referenced_
|
||||
.emplace_back(ConvertMutation(mutator->GetRSEApproximation()))
|
||||
.get());
|
||||
} break;
|
||||
case MutatorType::kClipPath: {
|
||||
// Unsupported mutation.
|
||||
} break;
|
||||
case MutatorType::kTransform: {
|
||||
const auto& matrix = mutator->GetMatrix();
|
||||
if (!matrix.isIdentity()) {
|
||||
if (!matrix.IsIdentity()) {
|
||||
mutations_array.push_back(
|
||||
mutations_referenced_.emplace_back(ConvertMutation(matrix))
|
||||
.get());
|
||||
@ -188,10 +195,9 @@ void EmbedderLayers::PushPlatformViewLayer(
|
||||
// If there are going to be any mutations, they must first take into
|
||||
// account the root surface transformation.
|
||||
if (!root_surface_transformation_.isIdentity()) {
|
||||
auto matrix = ToDlMatrix(root_surface_transformation_);
|
||||
mutations_array.push_back(
|
||||
mutations_referenced_
|
||||
.emplace_back(ConvertMutation(root_surface_transformation_))
|
||||
.get());
|
||||
mutations_referenced_.emplace_back(ConvertMutation(matrix)).get());
|
||||
}
|
||||
|
||||
auto mutations =
|
||||
|
@ -609,8 +609,8 @@ void ExternalViewEmbedder::Reset() {
|
||||
ExternalViewEmbedder::ViewMutators ExternalViewEmbedder::ParseMutatorStack(
|
||||
const flutter::MutatorsStack& mutators_stack) {
|
||||
ViewMutators mutators;
|
||||
SkMatrix total_transform = SkMatrix::I();
|
||||
SkMatrix transform_accumulator = SkMatrix::I();
|
||||
flutter::DlMatrix total_transform;
|
||||
flutter::DlMatrix transform_accumulator;
|
||||
|
||||
for (auto i = mutators_stack.Begin(); i != mutators_stack.End(); ++i) {
|
||||
const auto& mutator = *i;
|
||||
@ -619,37 +619,44 @@ ExternalViewEmbedder::ViewMutators ExternalViewEmbedder::ParseMutatorStack(
|
||||
mutators.opacity *= std::clamp(mutator->GetAlphaFloat(), 0.f, 1.f);
|
||||
} break;
|
||||
case flutter::MutatorType::kTransform: {
|
||||
total_transform.preConcat(mutator->GetMatrix());
|
||||
transform_accumulator.preConcat(mutator->GetMatrix());
|
||||
total_transform = total_transform * mutator->GetMatrix();
|
||||
transform_accumulator = transform_accumulator * mutator->GetMatrix();
|
||||
} break;
|
||||
case flutter::MutatorType::kClipRect: {
|
||||
mutators.clips.emplace_back(TransformedClip{
|
||||
.transform = transform_accumulator,
|
||||
.rect = mutator->GetRect(),
|
||||
.transform = flutter::ToSkMatrix(transform_accumulator),
|
||||
.rect = flutter::ToSkRect(mutator->GetRect()),
|
||||
});
|
||||
transform_accumulator = SkMatrix::I();
|
||||
transform_accumulator = flutter::DlMatrix();
|
||||
} break;
|
||||
case flutter::MutatorType::kClipRRect: {
|
||||
mutators.clips.emplace_back(TransformedClip{
|
||||
.transform = transform_accumulator,
|
||||
.rect = mutator->GetRRect().getBounds(),
|
||||
.transform = flutter::ToSkMatrix(transform_accumulator),
|
||||
.rect = flutter::ToSkRect(mutator->GetRRect().GetBounds()),
|
||||
});
|
||||
transform_accumulator = SkMatrix::I();
|
||||
transform_accumulator = flutter::DlMatrix();
|
||||
} break;
|
||||
case flutter::MutatorType::kClipRSE: {
|
||||
mutators.clips.emplace_back(TransformedClip{
|
||||
.transform = flutter::ToSkMatrix(transform_accumulator),
|
||||
.rect = flutter::ToSkRect(mutator->GetRSE().GetBounds()),
|
||||
});
|
||||
transform_accumulator = flutter::DlMatrix();
|
||||
} break;
|
||||
case flutter::MutatorType::kClipPath: {
|
||||
mutators.clips.emplace_back(TransformedClip{
|
||||
.transform = transform_accumulator,
|
||||
.rect = mutator->GetPath().getBounds(),
|
||||
.transform = flutter::ToSkMatrix(transform_accumulator),
|
||||
.rect = flutter::ToSkRect(mutator->GetPath().GetBounds()),
|
||||
});
|
||||
transform_accumulator = SkMatrix::I();
|
||||
transform_accumulator = flutter::DlMatrix();
|
||||
} break;
|
||||
default: {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
mutators.total_transform = total_transform;
|
||||
mutators.transform = transform_accumulator;
|
||||
mutators.total_transform = flutter::ToSkMatrix(total_transform);
|
||||
mutators.transform = flutter::ToSkMatrix(transform_accumulator);
|
||||
mutators.opacity = std::clamp(mutators.opacity, 0.f, 1.f);
|
||||
|
||||
return mutators;
|
||||
|
@ -34,6 +34,8 @@
|
||||
#include "gmock/gmock.h" // For EXPECT_THAT and matchers
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
using flutter::DlColor;
|
||||
using flutter::DlMatrix;
|
||||
using flutter::DlRect;
|
||||
using flutter::DlSize;
|
||||
using fuchsia::scenic::scheduling::FramePresentedInfo;
|
||||
@ -607,20 +609,18 @@ TEST_F(ExternalViewEmbedderTest, SceneWithOneView) {
|
||||
auto [child_view_token, child_viewport_token] = ViewTokenPair::New();
|
||||
const uint32_t child_view_id = child_viewport_token.value.get();
|
||||
|
||||
const int kOpacity = 200;
|
||||
const float kOpacityFloat = 200 / 255.0f;
|
||||
const uint8_t kOpacity = 200u;
|
||||
const float kOpacityFloat = DlColor::toOpacity(kOpacity);
|
||||
const fuchsia::math::VecF kScale{3.0f, 4.0f};
|
||||
|
||||
auto matrix = SkMatrix::I();
|
||||
matrix.setScaleX(kScale.x);
|
||||
matrix.setScaleY(kScale.y);
|
||||
DlMatrix matrix = DlMatrix::MakeScale({kScale.x, kScale.y, 1});
|
||||
|
||||
auto mutators_stack = flutter::MutatorsStack();
|
||||
mutators_stack.PushOpacity(kOpacity);
|
||||
mutators_stack.PushTransform(matrix);
|
||||
|
||||
flutter::EmbeddedViewParams child_view_params(matrix, child_view_size_signed,
|
||||
mutators_stack);
|
||||
flutter::EmbeddedViewParams child_view_params(
|
||||
flutter::ToSkMatrix(matrix), child_view_size_signed, mutators_stack);
|
||||
external_view_embedder.CreateView(
|
||||
child_view_id, []() {},
|
||||
[](fuchsia::ui::composition::ContentId,
|
||||
@ -830,33 +830,31 @@ TEST_F(ExternalViewEmbedderTest, SceneWithOneClippedView) {
|
||||
auto [child_view_token, child_viewport_token] = ViewTokenPair::New();
|
||||
const uint32_t child_view_id = child_viewport_token.value.get();
|
||||
|
||||
const int kOpacity = 200;
|
||||
const float kOpacityFloat = 200 / 255.0f;
|
||||
const uint8_t kOpacity = 200u;
|
||||
const float kOpacityFloat = DlColor::toOpacity(kOpacity);
|
||||
const fuchsia::math::VecF kScale{3.0f, 4.0f};
|
||||
const int kTranslateX = 10;
|
||||
const int kTranslateY = 20;
|
||||
|
||||
auto matrix = SkMatrix::I();
|
||||
matrix.setScaleX(kScale.x);
|
||||
matrix.setScaleY(kScale.y);
|
||||
matrix.setTranslateX(kTranslateX);
|
||||
matrix.setTranslateY(kTranslateY);
|
||||
DlMatrix matrix = DlMatrix::MakeTranslation({kTranslateX, kTranslateY}) *
|
||||
DlMatrix::MakeScale({kScale.x, kScale.y, 1});
|
||||
|
||||
SkRect kClipRect =
|
||||
SkRect::MakeXYWH(30, 40, child_view_size_signed.width() - 50,
|
||||
DlRect kClipRect =
|
||||
DlRect::MakeXYWH(30, 40, child_view_size_signed.width() - 50,
|
||||
child_view_size_signed.height() - 60);
|
||||
fuchsia::math::Rect kClipInMathRect = {
|
||||
static_cast<int32_t>(kClipRect.x()), static_cast<int32_t>(kClipRect.y()),
|
||||
static_cast<int32_t>(kClipRect.width()),
|
||||
static_cast<int32_t>(kClipRect.height())};
|
||||
static_cast<int32_t>(kClipRect.GetX()),
|
||||
static_cast<int32_t>(kClipRect.GetY()),
|
||||
static_cast<int32_t>(kClipRect.GetWidth()),
|
||||
static_cast<int32_t>(kClipRect.GetHeight())};
|
||||
|
||||
auto mutators_stack = flutter::MutatorsStack();
|
||||
mutators_stack.PushOpacity(kOpacity);
|
||||
mutators_stack.PushTransform(matrix);
|
||||
mutators_stack.PushClipRect(kClipRect);
|
||||
|
||||
flutter::EmbeddedViewParams child_view_params(matrix, child_view_size_signed,
|
||||
mutators_stack);
|
||||
flutter::EmbeddedViewParams child_view_params(
|
||||
flutter::ToSkMatrix(matrix), child_view_size_signed, mutators_stack);
|
||||
external_view_embedder.CreateView(
|
||||
child_view_id, []() {},
|
||||
[](fuchsia::ui::composition::ContentId,
|
||||
@ -939,14 +937,13 @@ TEST_F(ExternalViewEmbedderTest, SceneWithOneClippedView) {
|
||||
|
||||
// Draw another frame with view, but get rid of the clips this time. This
|
||||
// should remove all ClipTransformLayer instances.
|
||||
auto new_matrix = SkMatrix::I();
|
||||
new_matrix.setScaleX(kScale.x);
|
||||
new_matrix.setScaleY(kScale.y);
|
||||
DlMatrix new_matrix = DlMatrix::MakeScale({kScale.x, kScale.y, 1});
|
||||
auto new_mutators_stack = flutter::MutatorsStack();
|
||||
new_mutators_stack.PushOpacity(kOpacity);
|
||||
new_mutators_stack.PushTransform(new_matrix);
|
||||
flutter::EmbeddedViewParams new_child_view_params(
|
||||
new_matrix, child_view_size_signed, new_mutators_stack);
|
||||
flutter::ToSkMatrix(new_matrix), child_view_size_signed,
|
||||
new_mutators_stack);
|
||||
DrawFrameWithView(
|
||||
external_view_embedder, frame_size_signed, kDPR, child_view_id,
|
||||
new_child_view_params,
|
||||
@ -1071,20 +1068,18 @@ TEST_F(ExternalViewEmbedderTest, SceneWithOneView_NoOverlay) {
|
||||
auto [child_view_token, child_viewport_token] = ViewTokenPair::New();
|
||||
const uint32_t child_view_id = child_viewport_token.value.get();
|
||||
|
||||
const int kOpacity = 125;
|
||||
const float kOpacityFloat = 125 / 255.0f;
|
||||
const uint8_t kOpacity = 125u;
|
||||
const float kOpacityFloat = DlColor::toOpacity(kOpacity);
|
||||
const fuchsia::math::VecF kScale{2.f, 3.0f};
|
||||
|
||||
auto matrix = SkMatrix::I();
|
||||
matrix.setScaleX(kScale.x);
|
||||
matrix.setScaleY(kScale.y);
|
||||
DlMatrix matrix = DlMatrix::MakeScale({kScale.x, kScale.y, 1});
|
||||
|
||||
auto mutators_stack = flutter::MutatorsStack();
|
||||
mutators_stack.PushOpacity(kOpacity);
|
||||
mutators_stack.PushTransform(matrix);
|
||||
|
||||
flutter::EmbeddedViewParams child_view_params(matrix, child_view_size_signed,
|
||||
mutators_stack);
|
||||
flutter::EmbeddedViewParams child_view_params(
|
||||
flutter::ToSkMatrix(matrix), child_view_size_signed, mutators_stack);
|
||||
external_view_embedder.CreateView(
|
||||
child_view_id, []() {},
|
||||
[](fuchsia::ui::composition::ContentId,
|
||||
@ -1587,20 +1582,18 @@ TEST_F(ExternalViewEmbedderTest, ViewportCoveredWithInputInterceptor) {
|
||||
auto [child_view_token, child_viewport_token] = ViewTokenPair::New();
|
||||
const uint32_t child_view_id = child_viewport_token.value.get();
|
||||
|
||||
const int kOpacity = 200;
|
||||
const float kOpacityFloat = 200 / 255.0f;
|
||||
const uint8_t kOpacity = 200u;
|
||||
const float kOpacityFloat = DlColor::toOpacity(kOpacity);
|
||||
const fuchsia::math::VecF kScale{3.0f, 4.0f};
|
||||
|
||||
auto matrix = SkMatrix::I();
|
||||
matrix.setScaleX(kScale.x);
|
||||
matrix.setScaleY(kScale.y);
|
||||
DlMatrix matrix = DlMatrix::MakeScale({kScale.x, kScale.y, 1});
|
||||
|
||||
auto mutators_stack = flutter::MutatorsStack();
|
||||
mutators_stack.PushOpacity(kOpacity);
|
||||
mutators_stack.PushTransform(matrix);
|
||||
|
||||
flutter::EmbeddedViewParams child_view_params(matrix, child_view_size_signed,
|
||||
mutators_stack);
|
||||
flutter::EmbeddedViewParams child_view_params(
|
||||
flutter::ToSkMatrix(matrix), child_view_size_signed, mutators_stack);
|
||||
external_view_embedder.CreateView(
|
||||
child_view_id, []() {},
|
||||
[](fuchsia::ui::composition::ContentId,
|
||||
@ -1624,24 +1617,23 @@ TEST_F(ExternalViewEmbedderTest, ViewportCoveredWithInputInterceptor) {
|
||||
const fuchsia::math::SizeU frame_size{
|
||||
static_cast<uint32_t>(frame_size_signed.width()),
|
||||
static_cast<uint32_t>(frame_size_signed.height())};
|
||||
DrawFrameWithView(
|
||||
external_view_embedder, frame_size_signed, kDPR, child_view_id,
|
||||
child_view_params,
|
||||
[](flutter::DlCanvas* canvas) {
|
||||
const DlSize canvas_size(canvas->GetBaseLayerDimensions());
|
||||
flutter::DlPaint rect_paint;
|
||||
rect_paint.setColor(flutter::DlColor::kGreen());
|
||||
canvas->Translate(canvas_size.width / 4.f, canvas_size.height / 2.f);
|
||||
canvas->DrawRect(DlRect::MakeSize(canvas_size / 32.f), rect_paint);
|
||||
},
|
||||
[](flutter::DlCanvas* canvas) {
|
||||
const DlSize canvas_size(canvas->GetBaseLayerDimensions());
|
||||
flutter::DlPaint rect_paint;
|
||||
rect_paint.setColor(flutter::DlColor::kRed());
|
||||
canvas->Translate(canvas_size.width * 3.f / 4.f,
|
||||
canvas_size.height / 2.f);
|
||||
canvas->DrawRect(DlRect::MakeSize(canvas_size / 32.f), rect_paint);
|
||||
});
|
||||
auto background_draw_callback = [](flutter::DlCanvas* canvas) {
|
||||
const DlSize canvas_size(canvas->GetBaseLayerDimensions());
|
||||
flutter::DlPaint rect_paint;
|
||||
rect_paint.setColor(flutter::DlColor::kGreen());
|
||||
canvas->Translate(canvas_size.width / 4.f, canvas_size.height / 2.f);
|
||||
canvas->DrawRect(DlRect::MakeSize(canvas_size / 32.f), rect_paint);
|
||||
};
|
||||
auto overlay_draw_callback = [](flutter::DlCanvas* canvas) {
|
||||
const DlSize canvas_size(canvas->GetBaseLayerDimensions());
|
||||
flutter::DlPaint rect_paint;
|
||||
rect_paint.setColor(flutter::DlColor::kRed());
|
||||
canvas->Translate(canvas_size.width * 3.f / 4.f, canvas_size.height / 2.f);
|
||||
canvas->DrawRect(DlRect::MakeSize(canvas_size / 32.f), rect_paint);
|
||||
};
|
||||
DrawFrameWithView(external_view_embedder, frame_size_signed, kDPR,
|
||||
child_view_id, child_view_params, background_draw_callback,
|
||||
overlay_draw_callback);
|
||||
EXPECT_THAT(fake_flatland().graph(),
|
||||
IsFlutterGraph(parent_viewport_watcher, viewport_creation_token,
|
||||
view_ref_clone, {IsInputShield()}));
|
||||
|
Loading…
x
Reference in New Issue
Block a user