Skip to content

Commit 66e910d

Browse files
authored
Migrate Mutators to DisplayList/Impeller geometry (#164258)
Mutator types and MutatorsStack will now use DisplayList/Impeller geometry objects.
1 parent eb07c51 commit 66e910d

24 files changed

+1226
-964
lines changed

engine/src/flutter/display_list/geometry/dl_path.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ const SkPath& DlPath::GetSkPath() const {
106106
return sk_path.value();
107107
}
108108

109-
Path DlPath::GetPath() const {
109+
const Path& DlPath::GetPath() const {
110110
auto& sk_path = data_->sk_path;
111111
auto& path = data_->path;
112112
if (path.has_value()) {

engine/src/flutter/display_list/geometry/dl_path.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ class DlPath {
6767
DlPath& operator=(const DlPath&) = default;
6868

6969
const SkPath& GetSkPath() const;
70-
impeller::Path GetPath() const;
70+
const impeller::Path& GetPath() const;
7171

7272
/// Intent to render an SkPath multiple times will make the path
7373
/// non-volatile to enable caching in Skia. Calling this method

engine/src/flutter/display_list/skia/dl_sk_conversions_unittests.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -422,7 +422,7 @@ TEST(DisplayListSkConversions, ConicPathToQuads) {
422422
sk_path.conicTo(20, 10, 20, 20, weight);
423423

424424
DlPath dl_path(sk_path);
425-
impeller::Path i_path = dl_path.GetPath();
425+
const impeller::Path& i_path = dl_path.GetPath();
426426

427427
auto it = i_path.begin();
428428
ASSERT_EQ(it.type(), impeller::Path::ComponentType::kContour);

engine/src/flutter/display_list/utils/dl_matrix_clip_tracker.cc

Lines changed: 72 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -246,45 +246,59 @@ DlRect DisplayListMatrixClipState::GetLocalCullCoverage() const {
246246
}
247247

248248
bool DisplayListMatrixClipState::rect_covers_cull(const DlRect& content) const {
249-
if (content.IsEmpty()) {
249+
return TransformedRectCoversBounds(content, matrix_, cull_rect_);
250+
}
251+
252+
bool DisplayListMatrixClipState::TransformedRectCoversBounds(
253+
const DlRect& local_rect,
254+
const DlMatrix& matrix,
255+
const DlRect& cull_bounds) {
256+
if (local_rect.IsEmpty()) {
250257
return false;
251258
}
252-
if (cull_rect_.IsEmpty()) {
259+
if (cull_bounds.IsEmpty()) {
253260
return true;
254261
}
255-
if (matrix_.IsAligned2D()) {
262+
if (matrix.IsAligned2D()) {
256263
// This transform-to-device calculation is faster and more accurate
257264
// for rect-to-rect aligned transformations, but not accurate under
258265
// (non-quadrant) rotations and skews.
259-
return content.TransformAndClipBounds(matrix_).Contains(cull_rect_);
266+
return local_rect.TransformAndClipBounds(matrix).Contains(cull_bounds);
260267
}
261268
DlPoint corners[4];
262-
if (!getLocalCullCorners(corners)) {
269+
if (!GetLocalCorners(corners, cull_bounds, matrix)) {
263270
return false;
264271
}
265272
for (auto corner : corners) {
266-
if (!content.ContainsInclusive(corner)) {
273+
if (!local_rect.ContainsInclusive(corner)) {
267274
return false;
268275
}
269276
}
270277
return true;
271278
}
272279

273280
bool DisplayListMatrixClipState::oval_covers_cull(const DlRect& bounds) const {
274-
if (bounds.IsEmpty()) {
281+
return TransformedOvalCoversBounds(bounds, matrix_, cull_rect_);
282+
}
283+
284+
bool DisplayListMatrixClipState::TransformedOvalCoversBounds(
285+
const DlRect& local_oval_bounds,
286+
const DlMatrix& matrix,
287+
const DlRect& cull_bounds) {
288+
if (local_oval_bounds.IsEmpty()) {
275289
return false;
276290
}
277-
if (cull_rect_.IsEmpty()) {
291+
if (cull_bounds.IsEmpty()) {
278292
return true;
279293
}
280294
DlPoint corners[4];
281-
if (!getLocalCullCorners(corners)) {
295+
if (!GetLocalCorners(corners, cull_bounds, matrix)) {
282296
return false;
283297
}
284-
DlPoint center = bounds.GetCenter();
285-
DlSize scale = 2.0 / bounds.GetSize();
298+
DlPoint center = local_oval_bounds.GetCenter();
299+
DlSize scale = 2.0 / local_oval_bounds.GetSize();
286300
for (auto corner : corners) {
287-
if (!bounds.Contains(corner)) {
301+
if (!local_oval_bounds.Contains(corner)) {
288302
return false;
289303
}
290304
if (((corner - center) * scale).GetLengthSquared() >= 1.0) {
@@ -296,28 +310,37 @@ bool DisplayListMatrixClipState::oval_covers_cull(const DlRect& bounds) const {
296310

297311
bool DisplayListMatrixClipState::rrect_covers_cull(
298312
const DlRoundRect& content) const {
299-
if (content.IsEmpty()) {
313+
return TransformedRRectCoversBounds(content, matrix_, cull_rect_);
314+
}
315+
316+
bool DisplayListMatrixClipState::TransformedRRectCoversBounds(
317+
const DlRoundRect& local_rrect,
318+
const DlMatrix& matrix,
319+
const DlRect& cull_bounds) {
320+
if (local_rrect.IsEmpty()) {
300321
return false;
301322
}
302-
if (cull_rect_.IsEmpty()) {
323+
if (cull_bounds.IsEmpty()) {
303324
return true;
304325
}
305-
if (content.IsRect()) {
306-
return rect_covers_cull(content.GetBounds());
326+
if (local_rrect.IsRect()) {
327+
return TransformedRectCoversBounds(local_rrect.GetBounds(), matrix,
328+
cull_bounds);
307329
}
308-
if (content.IsOval()) {
309-
return oval_covers_cull(content.GetBounds());
330+
if (local_rrect.IsOval()) {
331+
return TransformedOvalCoversBounds(local_rrect.GetBounds(), matrix,
332+
cull_bounds);
310333
}
311-
if (!content.GetRadii().AreAllCornersSame()) {
334+
if (!local_rrect.GetRadii().AreAllCornersSame()) {
312335
return false;
313336
}
314337
DlPoint corners[4];
315-
if (!getLocalCullCorners(corners)) {
338+
if (!GetLocalCorners(corners, cull_bounds, matrix)) {
316339
return false;
317340
}
318-
auto outer = content.GetBounds();
341+
auto outer = local_rrect.GetBounds();
319342
auto center = outer.GetCenter();
320-
auto radii = content.GetRadii().top_left;
343+
auto radii = local_rrect.GetRadii().top_left;
321344
auto inner = outer.GetSize() * 0.5 - radii;
322345
auto scale = 1.0 / radii;
323346
for (auto corner : corners) {
@@ -335,25 +358,34 @@ bool DisplayListMatrixClipState::rrect_covers_cull(
335358

336359
bool DisplayListMatrixClipState::rsuperellipse_covers_cull(
337360
const DlRoundSuperellipse& content) const {
338-
if (content.IsEmpty()) {
361+
return TransformedRoundSuperellipseCoversBounds(content, matrix_, cull_rect_);
362+
}
363+
364+
bool DisplayListMatrixClipState::TransformedRoundSuperellipseCoversBounds(
365+
const DlRoundSuperellipse& local_rse,
366+
const DlMatrix& matrix,
367+
const DlRect& cull_bounds) {
368+
if (local_rse.IsEmpty()) {
339369
return false;
340370
}
341-
if (cull_rect_.IsEmpty()) {
371+
if (cull_bounds.IsEmpty()) {
342372
return true;
343373
}
344-
if (content.IsRect()) {
345-
return rect_covers_cull(content.GetBounds());
374+
if (local_rse.IsRect()) {
375+
return TransformedRectCoversBounds(local_rse.GetBounds(), matrix,
376+
cull_bounds);
346377
}
347-
if (content.IsOval()) {
348-
return oval_covers_cull(content.GetBounds());
378+
if (local_rse.IsOval()) {
379+
return TransformedOvalCoversBounds(local_rse.GetBounds(), matrix,
380+
cull_bounds);
349381
}
350382
DlPoint corners[4];
351-
if (!getLocalCullCorners(corners)) {
383+
if (!GetLocalCorners(corners, cull_bounds, matrix)) {
352384
return false;
353385
}
354-
auto outer = content.GetBounds();
386+
auto outer = local_rse.GetBounds();
355387
auto param = impeller::RoundSuperellipseParam::MakeBoundsRadii(
356-
outer, content.GetRadii());
388+
outer, local_rse.GetRadii());
357389
for (auto corner : corners) {
358390
if (!outer.Contains(corner)) {
359391
return false;
@@ -365,15 +397,17 @@ bool DisplayListMatrixClipState::rsuperellipse_covers_cull(
365397
return true;
366398
}
367399

368-
bool DisplayListMatrixClipState::getLocalCullCorners(DlPoint corners[4]) const {
369-
if (!is_matrix_invertable()) {
400+
bool DisplayListMatrixClipState::GetLocalCorners(DlPoint corners[4],
401+
const DlRect& rect,
402+
const DlMatrix& matrix) {
403+
if (!matrix.IsInvertible()) {
370404
return false;
371405
}
372-
DlMatrix inverse = matrix_.Invert();
373-
corners[0] = inverse * cull_rect_.GetLeftTop();
374-
corners[1] = inverse * cull_rect_.GetRightTop();
375-
corners[2] = inverse * cull_rect_.GetRightBottom();
376-
corners[3] = inverse * cull_rect_.GetLeftBottom();
406+
DlMatrix inverse = matrix.Invert();
407+
corners[0] = inverse * rect.GetLeftTop();
408+
corners[1] = inverse * rect.GetRightTop();
409+
corners[2] = inverse * rect.GetRightBottom();
410+
corners[3] = inverse * rect.GetLeftBottom();
377411
return true;
378412
}
379413

engine/src/flutter/display_list/utils/dl_matrix_clip_tracker.h

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,12 +113,60 @@ class DisplayListMatrixClipState {
113113
bool is_aa);
114114
void clipPath(const DlPath& path, DlClipOp op, bool is_aa);
115115

116+
/// @brief Checks if the local rect, when transformed by the matrix,
117+
/// completely covers the indicated culling bounds.
118+
///
119+
/// This utility method helps answer the question of whether a clip
120+
/// rectangle being intersected under a transform is essentially obsolete
121+
/// because it will not reduce the already existing clip culling bounds.
122+
[[nodiscard]]
123+
static bool TransformedRectCoversBounds(const DlRect& local_rect,
124+
const DlMatrix& matrix,
125+
const DlRect& cull_bounds);
126+
127+
/// @brief Checks if an oval defined by the local bounds, when transformed
128+
/// by the matrix, completely covers the indicated culling bounds.
129+
///
130+
/// This utility method helps answer the question of whether a clip
131+
/// oval being intersected under a transform is essentially obsolete
132+
/// because it will not reduce the already existing clip culling bounds.
133+
[[nodiscard]]
134+
static bool TransformedOvalCoversBounds(const DlRect& local_oval_bounds,
135+
const DlMatrix& matrix,
136+
const DlRect& cull_bounds);
137+
138+
/// @brief Checks if the local round rect, when transformed by the matrix,
139+
/// completely covers the indicated culling bounds.
140+
///
141+
/// This utility method helps answer the question of whether a clip
142+
/// rrect being intersected under a transform is essentially obsolete
143+
/// because it will not reduce the already existing clip culling bounds.
144+
[[nodiscard]]
145+
static bool TransformedRRectCoversBounds(const DlRoundRect& local_rrect,
146+
const DlMatrix& matrix,
147+
const DlRect& cull_bounds);
148+
149+
/// @brief Checks if the local round superellipse, when transformed by the
150+
/// matrix, completely covers the indicated culling bounds.
151+
///
152+
/// This utility method helps answer the question of whether a clip round
153+
/// superellipse being intersected under a transform is essentially obsolete
154+
/// because it will not reduce the already existing clip culling bounds.
155+
[[nodiscard]]
156+
static bool TransformedRoundSuperellipseCoversBounds(
157+
const DlRoundSuperellipse& local_rse,
158+
const DlMatrix& matrix,
159+
const DlRect& cull_bounds);
160+
116161
private:
117162
DlRect cull_rect_;
118163
DlMatrix matrix_;
119164

120-
bool getLocalCullCorners(DlPoint corners[4]) const;
121165
void adjustCullRect(const DlRect& clip, DlClipOp op, bool is_aa);
166+
167+
static bool GetLocalCorners(DlPoint corners[4],
168+
const DlRect& rect,
169+
const DlMatrix& matrix);
122170
};
123171

124172
} // namespace flutter

0 commit comments

Comments
 (0)