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

Skip to content

[performance] Process dirty nodes from top to bottom during paint to avoid unnecessary layer tree walks #98219

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 2 commits into from
Feb 11, 2022

Conversation

goderbauer
Copy link
Member

@goderbauer goderbauer commented Feb 10, 2022

Prior to this change, the flushPaint method was the odd one out of all the flush methods on PipelineOwner as it would process dirty nodes from bottom to top instead of top to bottom. Some historic digging shows that the flushPaint processing order was changed to that in 654fc73#diff-d06e00032e4d722205a2189ffbab26c1d8f5e13652efebc849583d0a1359fec9R612. Unfortunately, the exact reason is lost to history. Presumably it was for performance, but no scenario where this order would be beneficial has been identified. Instead, this order of processing causes additional walks of the layer tree during paint that would be avoided with top to bottom processing. Therefore, this PR is changing the order back to top to bottom.

Regressions? If this change causes any performance regression it should be rolled back immediately and the scenario where bottom to top processing is beneficial should be documented in flushPaint (or even better: encoded in a test).

@flutter-dashboard flutter-dashboard bot added the framework flutter/packages/flutter repository. See also f: labels. label Feb 10, 2022
@goderbauer
Copy link
Member Author

FYI @chunhtai since you recently also run into trouble with the upside down processing order in paint.

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.

LGTM, the only thing that prevented me from doing this was that I am not sure if some mechanism may depend on the paint order. If this change was introduced as a result of performance improvement, I think it is probably obsolete.

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.

Let the great experiment begin!

@fluttergithubbot fluttergithubbot merged commit 8cd540f into flutter:master Feb 11, 2022
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Feb 11, 2022
engine-flutter-autoroll added a commit to engine-flutter-autoroll/plugins that referenced this pull request Feb 11, 2022
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Feb 11, 2022
@goderbauer goderbauer deleted the paintOrderDeepestFirst branch February 11, 2022 17:29
goderbauer added a commit that referenced this pull request Feb 15, 2022
…aint to avoid unnecessary layer tree walks (#98219)"

This reverts commit 8cd540f.
@goderbauer
Copy link
Member Author

goderbauer commented Feb 18, 2022

Figured out why this was breaking a test in Google3. A widget there is making brittle assumptions about the order in which nodes are processed during paint. The Render tree looks basically like this:

Overlay
  OverlayEntryA
     UninterestingRenderObject
        RenderObjectA
  OverlayEntryB
    RenderObjectB

RenderObjectA and RenderObjectB share some data via a shared object. When RenderObjectA paints it sets some data on that sharedObject, that RenderObjectB is supposed to use during its paint. This is assuming that A paints before B (if B paints first it will use outdated data as A didn't have a chance to update the sharedObject yet). Prior to this PR, we would paint the deepest RenderObject first and since A is deeper in the tree it was guaranteed to paint first. This PR is switching this order around and now B is painting first missing the updated data that A is producing during its paint.

Seems a little brittle to rely on paint order like that. It only works because A happens to be deeper in the tree.

@Hixie
Copy link
Contributor

Hixie commented Feb 18, 2022

That is definitely an invalid assumption. It's perfectly acceptable for siblings to be painted in any arbitrary order.

@goderbauer
Copy link
Member Author

Actually, what I describe above is not some custom internal widget. Turns out, it's our Material Slider widget that has this problematic reliance on node processing order during paint. Filed #98770 for that with more details. We should also add a test for the slider to the framework that would have caught the breakage this caused in google3 earlier on this PR.

clocksmith pushed a commit to clocksmith/flutter that referenced this pull request Mar 8, 2022
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.

5 participants