Thanks to visit codestin.com
Credit goes to github.com

Skip to content

fix fade_transition issue #157663

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 14 commits into from
Dec 11, 2024
Merged

Conversation

yiiim
Copy link
Member

@yiiim yiiim commented Oct 26, 2024

Fixes: #157312

A simpler way to reproduce this issue:

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatefulWidget {
  const MyApp({super.key});

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> with SingleTickerProviderStateMixin {
  late AnimationController controller = AnimationController(
    duration: const Duration(seconds: 2),
    value: 1,
    vsync: this,
  );
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: Center(
          child: FadeTransition(
            opacity: controller,
            child: Builder(
              builder: (context) {
                return GestureDetector(
                  onTap: () {
                    controller.value = 0.5;
                    context.findRenderObject()?.markNeedsPaint();
                    controller.value = 0;
                  },
                  child: Text("Click"),
                );
              },
            ),
          ),
        ),
      ),
    );
  }
}

The main reason is that updating the opacity with markNeedsCompositedLayerUpdate followed by markNeedsPaint causes it to be added to owner!._nodesNeedingPaint twice.

Pre-launch Checklist

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

@github-actions github-actions bot added the framework flutter/packages/flutter repository. See also f: labels. label Oct 26, 2024
Copy link
Contributor

@nate-thegrate nate-thegrate left a comment

Choose a reason for hiding this comment

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

LGTM with a couple of tiny suggestions :)

Thanks for the fix and the well-structured test!

@github-actions github-actions bot added the a: text input Entering text in a text field or keyboard related problems label Oct 29, 2024
@yiiim
Copy link
Member Author

yiiim commented Oct 29, 2024

LGTM with a couple of tiny suggestions :)

Thanks for the fix and the well-structured test!

Thank you for leaving a comment. I am concerned about the changes to markNeedsPaint, and we might need someone more familiar with RenderObject to review it.

@chunhtai chunhtai requested a review from dkwingsmt November 5, 2024 23:15
@justinmc
Copy link
Contributor

justinmc commented Nov 14, 2024

@dkwingsmt Is this something you would be up for reviewing?

@dkwingsmt
Copy link
Contributor

dkwingsmt commented Nov 15, 2024

Thanks for the contribution. The change seems reasonable to me. But since this involves a change to RenderObject, I think we should add a test for RenderObject so that this fix is verified even if AnimatedOpacity is gone.

Also cc @jonahwilliams who worked on related code 3 years ago and should be more knowledgeable than me.

Side note

It took me a while to understand the relationship between markNeedsCompositedLayerUpdate and markNeedsPaint:

markNeedsPaint markNeedsCompositedLayerUpdate
First few lines Skip if _needsPaint, then set _needsPaint Skip if _needsCompositedLayerUpdate || _needsPaint, then set _needsCompositedLayerUpdate
Behavior if it is and was a boundary Adds itself to owner!._nodesNeedingPaint and request visual update Adds itself to owner!._nodesNeedingPaint and request visual update
Behavior (a lot of things) Same as markNeedsPaint

So basically, other than the first few lines, the rest of the two functions are identical. I suggest we refactor it somehow to indicate it more clearly. (It doesn't have to be done in this PR.)

Copy link
Member

@jonahwilliams jonahwilliams left a comment

Choose a reason for hiding this comment

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

Change seems reasonable to me, thank you for tracking this one down

LGTM

@github-actions github-actions bot removed the a: text input Entering text in a text field or keyboard related problems label Nov 15, 2024
@yiiim
Copy link
Member Author

yiiim commented Nov 15, 2024

But since this involves a change to RenderObject, I think we should add a test for RenderObject so that this fix is verified even if AnimatedOpacity is gone.

@dkwingsmt Tests for RenderObject have been added, feel free to review.

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

@dkwingsmt dkwingsmt added the autosubmit Merge PR when tree becomes green via auto submit App label Nov 15, 2024
@auto-submit auto-submit bot removed the autosubmit Merge PR when tree becomes green via auto submit App label Nov 15, 2024
Copy link
Contributor

auto-submit bot commented Nov 15, 2024

auto label is removed for flutter/flutter/157663, due to - The status or check suite Google testing has failed. Please fix the issues identified (or deflake) before re-applying this label.

@nate-thegrate
Copy link
Contributor

BTW – I've learned that Google testing can have a hard time understanding merge commits, so it might be better to do a rebase here

https://github.com/flutter/flutter/blob/master/docs/contributing/Tree-hygiene.md#using-git

@yiiim
Copy link
Member Author

yiiim commented Nov 18, 2024

@dkwingsmt Did the Google testing fail because of this assertion?

@dkwingsmt
Copy link
Contributor

dkwingsmt commented Nov 18, 2024

Yeah it was. But I don't think we can remove this assertion, otherwise it means this change will change the logic of existing apps. Let me see if I can find why it was triggered.

I wonder if it's because markNeedsPaint is called after _nodesNeedingPaint is used before _needsCompositedLayerUpdate is reset.

Edit: I found that a handful of tests are broken and seem to be caused by the exactly same widget. I'll look more into it.

@dkwingsmt
Copy link
Contributor

dkwingsmt commented Nov 28, 2024

I took a look and propose a different fix:

// object.dart, L2964
-       owner?._nodesNeedingPaint.remove(this);
+       owner?._nodesNeedingPaint.removeWhere((RenderObject t) => t == this);

This fix works for both your unit test and the internal tests.

Analysis: The reason why adding the object to owner!._nodesNeedingPaint twice causes the problem is because while flushCompositingBits is supposed to clean up all objects that have become non-compositing, the job fails because only the first encounter is removed. Therefore flushPaint unexpectedly encounters non-compositing objects.

And the reason why I think the current approach might not be the best is because the system is so complicated that we can't assume _needsCompositedLayerUpdate == true is equivalent to owner!._nodesNeedingPaint.contains(this).

And it seems _nodesNeedingPaint is designed to allow duplicates, since flushPaint checks whether a node still _needsPaint on each iteration afresh.

If you use this approach, maybe we should add a comment to _nodesNeedingPaint to explain that there might be duplicate nodes.

@yiiim
Copy link
Member Author

yiiim commented Nov 28, 2024

I have committed the solution you proposed, If _nodesNeedingPaint allows duplicates, then we can handle it this way.

@dkwingsmt
Copy link
Contributor

@jonahwilliams Would you like to take another look, since we've changed the approach?

@dkwingsmt
Copy link
Contributor

I'll wait until after the US thanksgiving holiday to settle this PR. Thanks for your patience.

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

@dkwingsmt dkwingsmt added the autosubmit Merge PR when tree becomes green via auto submit App label Dec 10, 2024
Copy link
Contributor

auto-submit bot commented Dec 10, 2024

auto label is removed for flutter/flutter/157663, due to - The status or check suite Windows build_tests_1_9 has failed. Please fix the issues identified (or deflake) before re-applying this label.

@auto-submit auto-submit bot removed the autosubmit Merge PR when tree becomes green via auto submit App label Dec 10, 2024
@dkwingsmt dkwingsmt added the autosubmit Merge PR when tree becomes green via auto submit App label Dec 11, 2024
@auto-submit auto-submit bot added this pull request to the merge queue Dec 11, 2024
Merged via the queue into flutter:master with commit 7814641 Dec 11, 2024
80 checks passed
@flutter-dashboard flutter-dashboard bot removed the autosubmit Merge PR when tree becomes green via auto submit App label Dec 11, 2024
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Dec 11, 2024
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Dec 11, 2024
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Dec 11, 2024
@reidbaker reidbaker mentioned this pull request Dec 13, 2024
11 tasks
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Feb 12, 2025
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Feb 13, 2025
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Feb 13, 2025
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Mar 6, 2025
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Mar 7, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
framework flutter/packages/flutter repository. See also f: labels.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Rapidly switching with AnimatedSwitcher causes error:Failed assertion: line 1191 pos 20: 'node.isRepaintBoundary': is not true.
5 participants