Skip to content

Implements the Android native stretch effect as a fragment shader (Impeller-only).#169293

Merged
auto-submit[bot] merged 36 commits intoflutter:masterfrom
MTtankkeo:stretch
Aug 14, 2025
Merged

Implements the Android native stretch effect as a fragment shader (Impeller-only).#169293
auto-submit[bot] merged 36 commits intoflutter:masterfrom
MTtankkeo:stretch

Conversation

@MTtankkeo
Copy link
Contributor

@MTtankkeo MTtankkeo commented May 22, 2025

Sorry, Closing PR #169196 and reopening this in a new PR for clarity and a cleaner commit history.

Fixes #82906

In the existing Flutter implementation, the Android stretch overscroll effect is achieved using Transform. However, this approach does not evenly stretch the screen as it does in the native Android environment. Therefore, in the Impeller environment, add or modify files to implement the effect using a fragment shader identical to the one used in native Android.

Note

  • The addition of a separate test file for StretchOverscrollEffect was not included because it would likely duplicate coverage already provided by the changes made in overscroll_stretch_indicator_test.dart within this PR.

However, since determining whether stretching occurred by referencing global coordinates is currently considered impossible with the new Fragment Shader approach, the code was modified to partially exclude the relevant test logic in the Impeller.

For reference, in the page_view_test.dart test, there was an issue with referencing the child Transform widget, but because the StretchOverscrollEffect widget is defined instead of the Transform widget in the Impeller environment, the code logic was adjusted accordingly.

  • Golden image tests were updated as the visual effect changes.

Reference Source

Old Skia (Using Transform)

old.mp4

New Impeller (Using fragment shader)

new.mp4

Pre-launch Checklist

If you need help, consider asking for advice on the #hackers-new channel on Discord.

@github-actions github-actions bot added tool Affects the "flutter" command-line tool. See also t: labels. framework flutter/packages/flutter repository. See also f: labels. f: material design flutter/packages/flutter/material repository. f: scrolling Viewports, list views, slivers, etc. labels May 22, 2025
@flutter-dashboard
Copy link

Golden file changes have been found for this pull request. Click here to view and triage (e.g. because this is an intentional change).

If you are still iterating on this change and are not ready to resolve the images on the Flutter Gold dashboard, consider marking this PR as a draft pull request above. You will still be able to view image results on the dashboard, commenting will be silenced, and the check will not try to resolve itself until marked ready for review.

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.

Changes reported for pull request #169293 at sha 3c6f85a

@flutter-dashboard flutter-dashboard bot added the will affect goldens Changes to golden files label May 22, 2025
@MTtankkeo MTtankkeo marked this pull request as draft May 22, 2025 20:38
@MTtankkeo MTtankkeo marked this pull request as ready for review May 22, 2025 21:01
@flutter-dashboard
Copy link

Golden file changes are available for triage from new commit, Click here to view.

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.

Changes reported for pull request #169293 at sha 8b26ebc

@MTtankkeo
Copy link
Contributor Author

😭 Hi @justinmc, @dkwingsmt, @Piinks, could you please review this PR? Thanks! 😭

Copy link
Contributor

@Piinks Piinks left a comment

Choose a reason for hiding this comment

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

Hi @MTtankkeo thanks for the contribution! This type of change would involve some changes in the engine I think.

@MTtankkeo MTtankkeo marked this pull request as draft May 23, 2025 18:35
@flutter-dashboard
Copy link

This pull request has been changed to a draft. The currently pending flutter-gold status will not be able to resolve until a new commit is pushed or the change is marked ready for review again.

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.

@dkwingsmt
Copy link
Contributor

After an internal discussion between @Piinks, a couple other folks, and I, we've come to agree with the current direction to add the shader to the framework as long as it aligns with how we implement the ink sparkle. We'll take a more detailed review at this PR soon, but I just want to let you know ASAP so you don't have to look into the engine code. Sorry for the confusion!

@MTtankkeo MTtankkeo marked this pull request as ready for review May 23, 2025 19:22
@flutter-dashboard
Copy link

Golden file changes are available for triage from new commit, Click here to view.

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.

Changes reported for pull request #169293 at sha 93ad7c2

@MTtankkeo MTtankkeo requested a review from chunhtai May 26, 2025 17:45
Copy link
Contributor

@chunhtai chunhtai left a comment

Choose a reason for hiding this comment

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

Code mostly looks good to me just left some minor comment.

@MTtankkeo MTtankkeo requested review from a team and matanlurey as code owners May 27, 2025 20:21
@github-actions github-actions bot added a: tests "flutter test", flutter_test, or one of our tests a: text input Entering text in a text field or keyboard related problems c: contributor-productivity Team-specific productivity, code health, technical debt. platform-android Android applications specifically platform-ios iOS applications specifically engine flutter/engine related. See also e: labels. labels May 27, 2025
@MTtankkeo
Copy link
Contributor Author

I’ve tried to engage constructively and move this forward, but I need your response to make progress.

@MTtankkeo
Copy link
Contributor Author

Just a quick follow-up — I've proposed a resolution to the concern at https://github.com/flutter/flutter/pull/169293/files#r2165791595 with a StretchEffect abstraction. If there's no objection, I'll proceed with that implementation and mark the thread as resolved.

Please let me know if you have any blockers. Otherwise, I’ll consider the discussion resolved and move forward.

@dkwingsmt
Copy link
Contributor

dkwingsmt commented Jul 30, 2025

I still haven't seen https://github.com/flutter/flutter/pull/169293/files#r2165791595 addressed.

@dkwingsmt I suggested something in response to your review — did you get a chance to read my comment?

Ah, my apology. I probably have missed the reply. Can you find me the link to your reply (since there are too many items above)?

@MTtankkeo
Copy link
Contributor Author

I still haven't seen https://github.com/flutter/flutter/pull/169293/files#r2165791595 addressed.

@dkwingsmt I suggested something in response to your review — did you get a chance to read my comment?

Ah, my apology. I probably have missed the reply. Can you find me the link to your reply (since there are too many items above)?

That comment is outdated.

Comment

@dkwingsmt @Piinks considering the concerns around making StretchOverscrollEffect public due to its renderer dependency, what do you think about introducing a new widget like StretchEffect?

This widget would act as a safe abstraction, internally switching between StretchOverscrollEffect (when supported) and a fallback like Transform.

That way we can still expose a reusable, scroll-independent stretch effect as @Piinks suggested, while encapsulating renderer-specific logic and preventing misuse — and this structure also allows us to make StretchOverscrollEffect private, as you suggested.

I think this could be a good way to address both of your concerns. I'd love to hear your thoughts on it.

Example

class StretchEffect extends StatelessWidget {
  const StretchEffect({
    super.key,
    this.stretchStrength = 0.0,
    required this.axis,
    required this.child,
  });

  final double stretchStrength;
  final Axis axis;
  final Widget child;

  @override
  Widget build(BuildContext context) {
    if (ImageFilter.isShaderFilterSupported) {
      return _StretchOverscrollEffect(...);
    } else {
      return Transform(transform: ...)
    }
  }
}

// private
class _StretchOverscrollEffect {}

@dkwingsmt
Copy link
Contributor

dkwingsmt commented Jul 30, 2025

I see, and you have moved forward with it. It looks good to me at a first glance, but let me take a closer look!

Copy link
Contributor

@dkwingsmt dkwingsmt left a comment

Choose a reason for hiding this comment

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

Looking good in general.

@flutter-dashboard
Copy link

Golden file changes are available for triage from new commit, Click here to view.

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.

Changes reported for pull request #169293 at sha f7f1129

@MTtankkeo
Copy link
Contributor Author

Sorry, my reply was in a pending state. You should be able to see it now!

Copy link
Contributor

@dkwingsmt dkwingsmt left a comment

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!

@flutter-dashboard
Copy link

Golden file changes are available for triage from new commit, Click here to view.

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.

Changes reported for pull request #169293 at sha c97605a

@Piinks
Copy link
Contributor

Piinks commented Aug 14, 2025

Triaged images 👍

Thank you again for contributing this!

@matanlurey
Copy link
Contributor

reason for revert: Does not work on Metal (iOS/macOS):

The following _Exception was thrown running a test:
Exception: Asset 'shaders/stretch_effect.frag' does not contain appropriate runtime stage data for current backend (Metal).

@justinmc
Copy link
Contributor

@MTtankkeo Can you open a new PR to try to reland this when you get a chance? The best way is probably to press the "Revrt" button on #173865. We do still want to solve this!

We're trying to figure out what caused the error posted above. Probably it's a configuration thing and not related to your shader code.

@MTtankkeo
Copy link
Contributor Author

MTtankkeo commented Aug 15, 2025

@justinmc new PR: #173885

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

f: scrolling Viewports, list views, slivers, etc. framework flutter/packages/flutter repository. See also f: labels. tool Affects the "flutter" command-line tool. See also t: labels. will affect goldens Changes to golden files

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Re-implement stretch overscroll behavior as a custom shader

7 participants