Sitelet https://github.com/flutter/flutter/pull/187891
Skip to content

Avoid unnecessary work in BoxDecoration and RenderPhysicalModel - #187891

Merged
auto-submit[bot] merged 1 commit into
flutter:masterfrom
bernaferrari:painting-rendering-path-cleanups
Jul 29, 2026
Merged

auto-submit[bot] merged 1 commit into
flutter:masterfrom
bernaferrari:painting-rendering-path-cleanups

Conversation

@bernaferrari

@bernaferrari bernaferrari commented Jun 11, 2026 •

Copy link
Copy Markdown
Contributor
image Part of https://github.com//issues/187894

Improve box_decoration.dart

In Flutter’s codebase that pattern already exists in similar hit-test code (RenderClipOval.hitTest

).

Old code:

final double distance = (position - center).distance;
return distance <= math.min(size.width, size.height) / 2.0;

Offset.distance computes: sqrt(dx * dx + dy * dy)


New code:

final double radius = math.min(size.width, size.height) / 2.0;
return (position - center).distanceSquared <= radius * radius;

Offset.distanceSquared computes only: dx * dx + dy * dy
Then it compares that to radius * radius.
Mathematically: sqrt(dx² + dy²) <= r is equivalent to: dx² + dy² <= r²

Then, I also found an issue: elevated shadow path doesn't need to be initialized when there is no elevation to use it for.

@flutter-dashboard flutter-dashboard Bot added the CICD Run CI/CD label Jun 11, 2026
@github-actions github-actions Bot added the framework flutter/packages/flutter repository. See also f: labels. label Jun 11, 2026

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request optimizes 'BoxDecoration.hitTest' for circular shapes by using squared distance to avoid square root calculations, and defers the creation of 'offsetRRectAsPath' in 'RenderPhysicalModel.paint' to only occur when elevation is non-zero. It also adds corresponding unit tests for both modifications. Feedback on the changes points out that the new test in 'proxy_box_test.dart' uses a non-standard matcher 'paintsExactlyCountTimes' which will cause compilation failure, and suggests refactoring it to use the standard 'paints' matcher.

Comment on lines +87 to +97
expect(
(PaintingContext context, Offset offset) => root.paint(context, offset),
paintsExactlyCountTimes(#drawShadow, 0),
);

root.elevation = 1.0;
pumpFrame(phase: EnginePhase.paint);
expect(
(PaintingContext context, Offset offset) => root.paint(context, offset),
paintsExactlyCountTimes(#drawShadow, 1),
);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The matcher paintsExactlyCountTimes is not a standard matcher in the Flutter test framework, which will cause this test to fail to compile. Instead, use the standard paints matcher from package:flutter_test to assert whether a shadow is painted or not. This is more idiomatic, concise, and avoids custom matchers.

Suggested change
expect(
(PaintingContext context, Offset offset) => root.paint(context, offset),
paintsExactlyCountTimes(#drawShadow, 0),
);
root.elevation = 1.0;
pumpFrame(phase: EnginePhase.paint);
expect(
(PaintingContext context, Offset offset) => root.paint(context, offset),
paintsExactlyCountTimes(#drawShadow, 1),
);
expect(root, isNot(paints..shadow()));
root.elevation = 1.0;
pumpFrame(phase: EnginePhase.paint);
expect(root, paints..shadow());

@bernaferrari bernaferrari Jun 11, 2026 •

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are wrong.

paintsExactlyCountTimes is part of Flutter’s test framework: it is exported by package:flutter_test/flutter_test.dart from src/mock_canvas.dart. It is also already used elsewhere in this file and throughout the Flutter test suite.

I’m keeping it here because this test is specifically verifying the number of drawShadow calls: zero at elevation 0, and one when elevation is non-zero. Analyzer and the focused test pass on the current base.
paintsExactlyCountTimes is exported by package:flutter_test/flutter_test.dart:
packages/flutter_test/lib/flutter_test.dart exports src/mock_canvas.dart, and src/mock_canvas.dart defines paintsExactlyCountTimes.

We can check if CI/CD passes, then.

@bernaferrari
bernaferrari force-pushed the painting-rendering-path-cleanups branch from 8aae925 to a2cb627 Compare June 11, 2026 22:06
@github-actions github-actions Bot removed the CICD Run CI/CD label Jun 11, 2026
@bernaferrari
bernaferrari force-pushed the painting-rendering-path-cleanups branch from a2cb627 to a7baf3e Compare June 11, 2026 22:11
@flutter-dashboard flutter-dashboard Bot added the CICD Run CI/CD label Jun 11, 2026
@bernaferrari
bernaferrari force-pushed the painting-rendering-path-cleanups branch from a7baf3e to c640084 Compare June 11, 2026 22:32
@github-actions github-actions Bot removed the CICD Run CI/CD label Jun 11, 2026
@bernaferrari bernaferrari added the CICD Run CI/CD label Jun 11, 2026
@Renzo-Olivares
Renzo-Olivares self-requested a review June 11, 2026 23:36
@flutter-dashboard

Copy link
Copy Markdown

This pull request executed golden file tests, but it has not been updated in a while (20+ days). Test results from Gold expire after as many days, so this pull request will need to be updated with a fresh commit in order to get results from Gold.

For more guidance, visit Writing a golden file test for package:flutter.

Reviewers: Read the Tree Hygiene page and make sure this patch meets those guidelines before LGTMing.

@Renzo-Olivares Renzo-Olivares left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thank you for the contribution!

@justinmc justinmc left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM 👍 . Thanks for improving performance @bernaferrari!

final double distance = (position - center).distance;
return distance <= math.min(size.width, size.height) / 2.0;
final double radius = math.min(size.width, size.height) / 2.0;
// Comparing squared distances avoids computing sqrt(dx * dx + dy * dy).

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good call!

@justinmc justinmc added autosubmit Merge PR when tree becomes green via auto submit App CICD Run CI/CD and removed CICD Run CI/CD labels Jul 28, 2026
@auto-submit auto-submit Bot removed the autosubmit Merge PR when tree becomes green via auto submit App label Jul 28, 2026
@auto-submit

auto-submit Bot commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

autosubmit label was removed for flutter/flutter/187891, because The base commit of the PR is older than 7 days and can not be merged. Please merge the latest changes from the main into this branch and resubmit the PR.

@bernaferrari
bernaferrari force-pushed the painting-rendering-path-cleanups branch from c640084 to b22a73c Compare July 28, 2026 23:11
@bernaferrari bernaferrari added autosubmit Merge PR when tree becomes green via auto submit App CICD Run CI/CD and removed CICD Run CI/CD labels Jul 28, 2026
@auto-submit
auto-submit Bot added this pull request to the merge queue Jul 29, 2026
Merged via the queue into flutter:master with commit 3392c91 Jul 29, 2026
30 checks passed
@flutter-dashboard flutter-dashboard Bot removed the autosubmit Merge PR when tree becomes green via auto submit App label Jul 29, 2026
@bernaferrari
bernaferrari deleted the painting-rendering-path-cleanups branch July 29, 2026 03:53
auto-submit Bot pushed a commit to flutter/packages that referenced this pull request Aug 8, 2026
…12393)

Manual roll requested by stuartmorgan@google.com

flutter/flutter@2a230d1...2757a77

2026-07-29 engine-flutter-autoroll@skia.org Roll Skia from 3ae9e364d30b to 0f35bba4945c (2 revisions) (flutter/flutter#190215)
2026-07-29 kustermann@google.com [web] Fix deferred loading with wasm (flutter/flutter#190140)
2026-07-29 engine-flutter-autoroll@skia.org Roll Dart SDK from 1bbaacba6a5a to 43f7de5f4977 (1 revision) (flutter/flutter#190211)
2026-07-29 engine-flutter-autoroll@skia.org Roll Skia from 119cae396625 to 3ae9e364d30b (6 revisions) (flutter/flutter#190208)
2026-07-29 matej.knopp@gmail.com [Win32] Ignore mouse move events without capture when dragging (flutter/flutter#190029)
2026-07-29 engine-flutter-autoroll@skia.org Roll Dart SDK from 49c637261348 to 1bbaacba6a5a (7 revisions) (flutter/flutter#190196)
2026-07-29 engine-flutter-autoroll@skia.org Roll Skia from 30ad01017a46 to 119cae396625 (2 revisions) (flutter/flutter#190183)
2026-07-29 46920873+gabrimatic@users.noreply.github.com Fix NestedScrollView example crash when switching tabs on desktop (flutter/flutter#186993)
2026-07-29 engine-flutter-autoroll@skia.org Roll Fuchsia Linux SDK from OZkZC_2CZ_G5rbMIS... to J8rVTlBnjnUpuHYk3... (flutter/flutter#190174)
2026-07-29 git@schultek.dev Update widget location tracking to use the new generalized api (flutter/flutter#189725)
2026-07-29 bernaferrari2@gmail.com Avoid unnecessary work in `BoxDecoration` and `RenderPhysicalModel` (flutter/flutter#187891)
2026-07-29 me@davidmiguel.com Fix web context-menu client lifecycle in SelectableRegion (flutter/flutter#189587)
2026-07-29 engine-flutter-autoroll@skia.org Roll Skia from 70733f74d415 to 30ad01017a46 (2 revisions) (flutter/flutter#190173)
2026-07-29 jason-simmons@users.noreply.github.com Manual roll of Dart from 28e63ac22d8d to 49c637261348 (flutter/flutter#190158)

If this roll has caused a breakage, revert this CL and stop the roller
using the controls here:
https://autoroll.skia.org/r/flutter-packages
Please CC boetger@google.com,stuartmorgan@google.com on the revert to ensure that a human
is aware of the problem.

To file a bug in Packages: https://github.com/flutter/flutter/issues/new/choose

To report a problem with the AutoRoller itself, please file a bug:
https://issues.skia.org/issues/new?component=1389291&template=1850622

Documentation for the AutoRoller is here:
https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CICD Run CI/CD framework flutter/packages/flutter repository. See also f: labels.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants