Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Conversation

@jonahwilliams
Copy link
Contributor

@jonahwilliams jonahwilliams commented Nov 22, 2024

For flutter/flutter#158881

The new Android m3 page transition animates a saveLayer w/ opacity + slide in animation. See example video from linked PR:

387832059-a806f25d-8564-4cad-8dfc-eb4585294181.mov

On each frame, we intersect the coverage rect of this saveLayer contents with the screen rect, and shrink it to a partial rectangle. But this changes each frame, which forces us to re-allocate a large texture each frame, causing performance issues.

Why not ignore the cull rect entirely? We sometimes ignore the cull rect for the image filter layer for similar reasons, but from observation, the sizes of these saveLayer can be slightly larger than the screen for flutter gallery. Instead, I attempted to use the cull rect size to shrink the saveLayer by shifting the origin before intersecting.

I think this should be safe to do, as I believe it could only leave the coverage as larger than it would have been and not smaller.

@jonahwilliams
Copy link
Contributor Author

@flar / @gaaclarke does this make sense to you?

jonahwilliams added 2 commits November 22, 2024 13:07
@jonahwilliams jonahwilliams marked this pull request as ready for review November 22, 2024 21:58
@flar
Copy link
Contributor

flar commented Nov 22, 2024

The algorithm feels highly speculative and very specific to the sliding transition. The two coverages could differ by a large shift and we'd allocate a coverage that was very greatly larger than we need, wasting rendering time.

I like the fact that it first checks if there is any intersection at all - that at least prevents this over-estimated coverage when the source isn't even visible. But, what if the transformed intersection is 5x5 but the shifted intersection is 500x700? We'd allocate 14k times as many pixels as we need without even batting an eye. And what if that particular case happened to be static so we paid that price on every frame without any indication that it was animating towards a larger intersection?

If this is to prevent thrashing, what if we just increased the granularity of temporary texture allocations to minimize the number without trying to completely eliminate them?

@flar
Copy link
Contributor

flar commented Nov 22, 2024

Overall I'd vote against this particular heuristic without any other limits or predictive evidence guiding its actions, but I am intrigued by the concept of trying to avoid varying allocations during transitions.

@jonahwilliams
Copy link
Contributor Author

Re: lack of limits, that is a good point. For the slide in, I think the values are only in the 10 to 15% range. So I could limit this by limiting how much I'm willing to slide it over.

The algorithm feels highly speculative and very specific to the sliding transition

It is highly specific to that transition, but that transition will be the default for all android applications soon - so its going to be extremely widespread.

@flar
Copy link
Contributor

flar commented Nov 23, 2024

One thought is that we could advertise transitions to the engine by having something along the lines of ui.Canvas.interpolateTransorm(matrixA, matrixB, t) - that way we see the entire range of transforms we will encounter and the t value specifies the specific transition point currently in effect.

@flar
Copy link
Contributor

flar commented Nov 23, 2024

Re: lack of limits, that is a good point. For the slide in, I think the values are only in the 10 to 15% range. So I could limit this by limiting how much I'm willing to slide it over.

Also, this form of performance improvement is a compromise. It's not "simply" saving us thrashing the cache, it's causing us to render more in lieu of thrashing the cache.

We should only render the true intersection on this frame even if we allocate what we believe will be the entire operation. I don't see that addressed here. Perhaps return a {intersected bounds, potential size} tuple?

@flar
Copy link
Contributor

flar commented Nov 24, 2024

Another idea, the transform interpolation could be an internal thing with TransformLayer if it could understand that it is part of an animation and tell its engine layer "Hey, I'm going from A to B and currently at state t" without having to modify the ui.Canvas API in a confusing way. (iow - It might be an internal call on DlCanvas invoked from the TransformLayer, but not visible on ui.Canvas).

@jonahwilliams
Copy link
Contributor Author

I've narrowed down this case so that it only applies to slide in like transations. I agree that this fix is overly specific, and I think the real fix for the allocation problems is flutter/flutter#156503 . This is essentially to round up allocations to some sort of interval sizing. This would almost fix this issue, however for reasons I'm not entirely sure of yet, the framework is reporting that one of the saveLayers is a ~8 or so pixels wider than the onscreen size in a way that doesn't seem entirely stable.

That said, I would like to land this ahead of attempting larger changes as I don't want the new android page transition to be delayed nor do I want the first versions of it to regress overally performance. I do not believe that this change, while overly specific, is harmful, though let benchmarks and framework CI strike me down if I'm wrong.

Copy link
Contributor

@flar flar left a comment

Choose a reason for hiding this comment

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

Just some suggestions.

// intersection using only the sizing by shifting the coverage rect into the
// cull rect origin.
Point delta = coverage_limit.GetOrigin() - transformed_coverage.GetOrigin();
if (ScalarNearlyEqual(delta.y, 0) || ScalarNearlyEqual(delta.x, 0)) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Not sure if this needs a code comment. My first reading of this line was "wait, we only do this if there is very nearly no delta?" before I realized it was looking for horizontal or vertical transitions.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added more documentation


ASSERT_TRUE(coverage.has_value());
EXPECT_EQ(coverage.value(), Rect::MakeLTRB(5, 5, 100, 100));
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Perhaps add a test where the threshold is too large in X and another in Y.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

Copy link
Member

@gaaclarke gaaclarke left a comment

Choose a reason for hiding this comment

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

I share some concerns like Jim, if we want to go down this route I think we need even more complete documentation.

// Sometimes a saveLayer is only slightly shifted outside of the cull rect,
// but is being animated in. This is common for the Android slide in page
// transitions. In these cases, computing a cull that is too tight can cause
// thrasing of the texture cache. Instead, we try to determine the
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
// thrasing of the texture cache. Instead, we try to determine the
// thrashing of the texture cache. Instead, we try to determine the

Why does it cause thrashing?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

because the intersected size is different each frame, while the original size is stable

Copy link
Member

Choose a reason for hiding this comment

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

Can you add that to the comment please?

if (ScalarNearlyEqual(delta.y, 0) || ScalarNearlyEqual(delta.x, 0)) {
Scalar threshold = std::max(std::abs(delta.x / coverage_limit.GetWidth()),
std::abs(delta.y / coverage_limit.GetHeight()));
if (threshold < 0.3) {
Copy link
Member

Choose a reason for hiding this comment

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

This magic number needs to be pulled out into a const with documentation about where it comes from.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done

Copy link
Contributor

@flar flar left a comment

Choose a reason for hiding this comment

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

LGTM

Copy link
Member

@gaaclarke gaaclarke left a comment

Choose a reason for hiding this comment

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

Let's make sure to revisit this after we get benchmark results, trying it out well documented sgtm.

@jonahwilliams jonahwilliams added the autosubmit Merge PR when tree becomes green via auto submit App label Nov 25, 2024
@auto-submit auto-submit bot merged commit 0d4d2cc into flutter:main Nov 25, 2024
31 checks passed
@jonahwilliams jonahwilliams deleted the slide_in_heuristics branch November 25, 2024 23:48
engine-flutter-autoroll added a commit to engine-flutter-autoroll/flutter that referenced this pull request Nov 26, 2024
engine-flutter-autoroll added a commit to engine-flutter-autoroll/flutter that referenced this pull request Nov 26, 2024
github-merge-queue bot pushed a commit to flutter/flutter that referenced this pull request Nov 26, 2024
…159461)

flutter/engine@fe45a66...fb64399

2024-11-26 [email protected] iOS: Migrate PlatformViewsController to
Objective-C (flutter/engine#56790)
2024-11-26 [email protected] Started caching
HandleGLES's hash and made them immutable (flutter/engine#56800)
2024-11-26 98614782+auto-submit[bot]@users.noreply.github.com Reverts
"[iOS] Full keyboard access scrolling (#56606)" (flutter/engine#56802)
2024-11-26 [email protected] Roll Skia from 12c8bd6ac1d9 to
c1c8ff84997c (14 revisions) (flutter/engine#56801)
2024-11-25 [email protected] [Impeller] better handle allocation
herustics of Android slide in page transition. (flutter/engine#56762)
2024-11-25 [email protected] iOS: Eliminate logging of non-zero origin
platformviews (flutter/engine#56796)
2024-11-25 [email protected] [impeller] gles:
started storing the number of handle deletions to avoid reallocation
(flutter/engine#56799)
2024-11-25 [email protected] Roll Fuchsia Linux SDK from
9o0fWa2xVhmxV6Mtn... to 50xtjbMWWrqay_7m_... (flutter/engine#56795)
2024-11-25 [email protected] Roll Dart SDK from
df716eaa6ed2 to 4b49546a1dfa (1 revision) (flutter/engine#56793)
2024-11-25 [email protected] [iOS] Full
keyboard access scrolling (flutter/engine#56606)
2024-11-25 [email protected] [android] remove fml_check from
surface_texture_external_texture (flutter/engine#56760)
2024-11-25 [email protected] removed unused
variable for skia initialization (flutter/engine#56791)

Also rolling transitive DEPS:
  fuchsia/sdk/core/linux-amd64 from 9o0fWa2xVhmx to 50xtjbMWWrqa

If this roll has caused a breakage, revert this CL and stop the roller
using the controls here:
https://autoroll.skia.org/r/flutter-engine-flutter-autoroll
Please CC [email protected],[email protected] on the revert to ensure
that a human
is aware of the problem.

To file a bug in Flutter:
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
github-merge-queue bot pushed a commit to flutter/flutter that referenced this pull request Nov 26, 2024
…visions) (#159461)" (#159498)

<!-- start_original_pr_link -->
Reverts: #159461
<!-- end_original_pr_link -->
<!-- start_initiating_author -->
Initiated by: yjbanov
<!-- end_initiating_author -->
<!-- start_revert_reason -->
Reason for reverting: engine regression
#159497
<!-- end_revert_reason -->
<!-- start_original_pr_author -->
Original PR Author: engine-flutter-autoroll
<!-- end_original_pr_author -->

<!-- start_reviewers -->
Reviewed By: {fluttergithubbot}
<!-- end_reviewers -->

<!-- start_revert_body -->
This change reverts the following previous change:

flutter/engine@fe45a66...fb64399

2024-11-26 [email protected] iOS: Migrate PlatformViewsController to
Objective-C (flutter/engine#56790)
2024-11-26 [email protected] Started caching
HandleGLES's hash and made them immutable (flutter/engine#56800)
2024-11-26 98614782+auto-submit[bot]@users.noreply.github.com Reverts
"[iOS] Full keyboard access scrolling (#56606)" (flutter/engine#56802)
2024-11-26 [email protected] Roll Skia from 12c8bd6ac1d9 to
c1c8ff84997c (14 revisions) (flutter/engine#56801)
2024-11-25 [email protected] [Impeller] better handle allocation
herustics of Android slide in page transition. (flutter/engine#56762)
2024-11-25 [email protected] iOS: Eliminate logging of non-zero origin
platformviews (flutter/engine#56796)
2024-11-25 [email protected] [impeller] gles:
started storing the number of handle deletions to avoid reallocation
(flutter/engine#56799)
2024-11-25 [email protected] Roll Fuchsia Linux SDK from
9o0fWa2xVhmxV6Mtn... to 50xtjbMWWrqay_7m_... (flutter/engine#56795)
2024-11-25 [email protected] Roll Dart SDK from
df716eaa6ed2 to 4b49546a1dfa (1 revision) (flutter/engine#56793)
2024-11-25 [email protected] [iOS] Full
keyboard access scrolling (flutter/engine#56606)
2024-11-25 [email protected] [android] remove fml_check from
surface_texture_external_texture (flutter/engine#56760)
2024-11-25 [email protected] removed unused
variable for skia initialization (flutter/engine#56791)

Also rolling transitive DEPS:
  fuchsia/sdk/core/linux-amd64 from 9o0fWa2xVhmx to 50xtjbMWWrqa

If this roll has caused a breakage, revert this CL and stop the roller
using the controls here:
https://autoroll.skia.org/r/flutter-engine-flutter-autoroll
Please CC [email protected],[email protected] on the revert to ensure
that a human
is aware of the problem.

To file a bug in Flutter:
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

<!-- end_revert_body -->

Co-authored-by: auto-submit[bot] <[email protected]>
engine-flutter-autoroll added a commit to engine-flutter-autoroll/flutter that referenced this pull request Nov 26, 2024
github-merge-queue bot pushed a commit to flutter/flutter that referenced this pull request Nov 26, 2024
…159504)

flutter/engine@fe45a66...bd165dc

2024-11-26 [email protected] Revert "iOS: Migrate PlatformViewsController
to Objective-C (#56790)" (flutter/engine#56817)
2024-11-26 [email protected] iOS: Rename FlutterPlatformViews_Internal.mm
(flutter/engine#56816)
2024-11-26 [email protected] iOS: Eliminate global in platformviews
controller (flutter/engine#56805)
2024-11-26 [email protected] Roll Skia from a276978ba7c8 to
f149f852c70a (1 revision) (flutter/engine#56812)
2024-11-26 [email protected] Roll Skia from d7a267d88fd6 to
a276978ba7c8 (1 revision) (flutter/engine#56811)
2024-11-26 [email protected] Roll Skia from 8d9d892657a7 to
d7a267d88fd6 (1 revision) (flutter/engine#56810)
2024-11-26 [email protected] Roll Dart SDK from
bdb76c714009 to ca02d403f1a8 (1 revision) (flutter/engine#56809)
2024-11-26 [email protected] Roll Skia from b697dd1b03b2 to
8d9d892657a7 (1 revision) (flutter/engine#56808)
2024-11-26 [email protected] Roll Skia from c1c8ff84997c to
b697dd1b03b2 (1 revision) (flutter/engine#56807)
2024-11-26 [email protected] iOS: Delete
FlutterPlatformViewsController.layerPoolSize (flutter/engine#56806)
2024-11-26 [email protected] Roll Dart SDK from
4b49546a1dfa to bdb76c714009 (1 revision) (flutter/engine#56803)
2024-11-26 [email protected] iOS: Migrate PlatformViewsController to
Objective-C (flutter/engine#56790)
2024-11-26 [email protected] Started caching
HandleGLES's hash and made them immutable (flutter/engine#56800)
2024-11-26 98614782+auto-submit[bot]@users.noreply.github.com Reverts
"[iOS] Full keyboard access scrolling (#56606)" (flutter/engine#56802)
2024-11-26 [email protected] Roll Skia from 12c8bd6ac1d9 to
c1c8ff84997c (14 revisions) (flutter/engine#56801)
2024-11-25 [email protected] [Impeller] better handle allocation
herustics of Android slide in page transition. (flutter/engine#56762)
2024-11-25 [email protected] iOS: Eliminate logging of non-zero origin
platformviews (flutter/engine#56796)
2024-11-25 [email protected] [impeller] gles:
started storing the number of handle deletions to avoid reallocation
(flutter/engine#56799)
2024-11-25 [email protected] Roll Fuchsia Linux SDK from
9o0fWa2xVhmxV6Mtn... to 50xtjbMWWrqay_7m_... (flutter/engine#56795)
2024-11-25 [email protected] Roll Dart SDK from
df716eaa6ed2 to 4b49546a1dfa (1 revision) (flutter/engine#56793)
2024-11-25 [email protected] [iOS] Full
keyboard access scrolling (flutter/engine#56606)
2024-11-25 [email protected] [android] remove fml_check from
surface_texture_external_texture (flutter/engine#56760)
2024-11-25 [email protected] removed unused
variable for skia initialization (flutter/engine#56791)

Also rolling transitive DEPS:
  fuchsia/sdk/core/linux-amd64 from 9o0fWa2xVhmx to 50xtjbMWWrqa

If this roll has caused a breakage, revert this CL and stop the roller
using the controls here:
https://autoroll.skia.org/r/flutter-engine-flutter-autoroll
Please CC [email protected] on the revert to ensure that a human
is aware of the problem.

To file a bug in Flutter:
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
nick9822 pushed a commit to nick9822/flutter that referenced this pull request Dec 18, 2024
…e transition. (flutter/engine#56762)

For flutter#158881

The new Android m3 page transition animates a saveLayer w/ opacity + slide in animation. See example video from linked PR:

https://github.com/user-attachments/assets/1382374a-4e0c-4a0e-9d70-948ce12e6298

On each frame, we intersect the coverage rect of this saveLayer contents with the screen rect, and shrink it to a partial rectangle. But this changes each frame, which forces us to re-allocate a large texture each frame, causing performance issues.

Why not ignore the cull rect entirely? We sometimes ignore the cull rect for the image filter layer for similar reasons, but from observation, the sizes of these saveLayer can be slightly larger than the screen for flutter gallery. Instead, I attempted to use the cull rect size to shrink the saveLayer by shifting the origin before intersecting.

I think this should be safe to do, as I believe it could only leave the coverage as larger than it would have been and not smaller.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

autosubmit Merge PR when tree becomes green via auto submit App e: impeller

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants