Skip to content

Reland: Only render views that need to be rendered - #192128

Merged
knopp merged 54 commits into
flutter:masterfrom
knopp:fix_multiview_repaint
Sep 24, 2026
Merged

knopp merged 54 commits into
flutter:masterfrom
knopp:fix_multiview_repaint

Conversation

@knopp

@knopp knopp commented Sep 1, 2026 •

Copy link
Copy Markdown
Member

This relands #179874, reverted in #191252.

The reason for revert was stalled web benchmarks (#191251). Stalling was caused by _autoUpdateBenchmarkPhase inside macrobenchmarks/lib/src/web/recorder.dart expecting certain number of preroll_frame and apply_frame events. These events are only published for frames that are composited (ui.Scene being rendered), but some of the web benchmarks request frame without making any render objects dirty, which after #191252 did not result on view being composited.

The fix is to force view composition on every frame when the benchmarks are running.

cc @yjbanov regarding the changes in recorder.dart.

Pre-launch Checklist

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

If this change needs to override an active code freeze, provide a comment explaining why. The code freeze workflow can be overridden by code reviewers. See pinned issues for any active code freezes with guidance.

Note: The Flutter team is currently trialing the use of Gemini Code Assist for GitHub. Comments from the gemini-code-assist bot should not be taken as authoritative feedback from the Flutter team. If you find its comments useful you can update your code accordingly, but if you are unsure or disagree with the feedback, please feel free to wait for a Flutter team member's review for guidance on which automated comments should be addressed.

@knopp
knopp requested a review from a team as a code owner September 1, 2026 19:41
@knopp
knopp requested review from reidbaker and removed request for a team September 1, 2026 19:41
@flutter-dashboard flutter-dashboard Bot added the CICD Run CI/CD label Sep 1, 2026
@github-actions github-actions Bot added platform-android Android applications specifically framework flutter/packages/flutter repository. See also f: labels. engine flutter/engine related. See also e: labels. platform-web Web applications specifically team-android Owned by Android platform team team-web Owned by Web platform team labels Sep 1, 2026
@knopp
knopp requested a review from yjbanov September 1, 2026 19:41

@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 introduces onTextureFrameAvailable and onMarkAllViewsNeedRender callbacks to PlatformDispatcher across native, web, and Android embedding to notify the framework when a texture has a new frame or when all views need to be re-rendered. RendererBinding and TextureBox are updated to handle these events, optimizing rendering by marking views and texture boxes as needing paint or compositing only when necessary. The review feedback suggests optimizing handleTextureFrameAvailable in RendererBinding with an early return when no callbacks are registered, and using the private backing field _onMarkAllViewsNeedRender in EnginePlatformDispatcher for consistency.

Comment thread packages/flutter/lib/src/rendering/binding.dart
@justinmc
justinmc self-requested a review September 1, 2026 22:20

@chunhtai chunhtai 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.

I run the pr through agent, it points out several issue which i think is valid

Comment thread packages/flutter/lib/src/rendering/texture.dart
Comment thread packages/flutter/test/rendering/rendering_tester.dart
for (final PipelineOwner child in _children) {
child.flushPaint();
}
onFlushedPaint?.call(dirtyNodes.isNotEmpty);

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.

a child pipeline owner may be responsible for drawing a section on part of the flutterview. for example https://gist.github.com/chunhtai/abb5fea62500a3ced1074cc241d66825

a child pipeline owner may be doing expansive calculation to draw the subscreen to not block the parent pipeline owner.

In this case, the dirty node in child pipeline will not notify the parent pipeline owner.

This is a niche case though

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Should we recursively ask there whether the child pipeline owners have any dirty nodes?

@loic-sharma loic-sharma Sep 5, 2026 •

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Should we recursively ask there whether the child pipeline owners have any dirty nodes?

I lean towards not doing this.

In the ViewAnchor case (eg, a child window), the child view has a separate child pipeline owner. Ideally if the child view repaints, that does not cause a re-render of the parent view.

I think we do support this scenario of multiple pipeline owners for a single view. If you manually create a pipeline owner, you can pass in a PipelineOwner.onFlushPaint callback that invokes RenderView.markNeedsCompositeFrame on the shared view.

fml::TaskRunner::RunNowOrPostTask(task_runners_.GetUITaskRunner(),
[engine = engine_->GetWeakPtr()]() {
if (engine) {
engine->ScheduleFrame(false);

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.

ScheduleFrame(false) actually trigger a shortcircuit in Animator::RequestFrame to DrawLastLayerTrees, which completely bypass the dart

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Yes. That is not a problem. The problem only occurs when engine->ScheduleFrame(false); is called and something else triggers layer tree regeneration. This is fixed by the preceding call to engine->NotifyTextureFrameAvailable(texture_id);.

@knopp
knopp force-pushed the fix_multiview_repaint branch 2 times, most recently from b4f6460 to 0477100 Compare September 8, 2026 18:20
@knopp

knopp commented Sep 9, 2026

Copy link
Copy Markdown
Member Author

This is ready for re-review.

@knopp
knopp force-pushed the fix_multiview_repaint branch 2 times, most recently from c91c984 to 28f856c Compare September 18, 2026 15:13
@flutter-dashboard

Copy link
Copy Markdown

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 #192128 at sha 3bad5ab

@flutter-dashboard flutter-dashboard Bot added the will affect goldens Changes to golden files label Sep 18, 2026
@knopp
knopp force-pushed the fix_multiview_repaint branch from 3bad5ab to 731ec75 Compare September 18, 2026 19:56
@loic-sharma

Copy link
Copy Markdown
Member

@knopp Do we need to update this guy to pass a onFlushedPaint callback that invokes renderView.markNeedsCompositeFrame()?

@override
PipelineOwner createRootPipelineOwner() {
return PipelineOwner(
onSemanticsOwnerCreated: () {
renderView.scheduleInitialSemantics();
},
onSemanticsUpdate: (SemanticsUpdate update) {
renderView.updateSemantics(update);
},
onSemanticsOwnerDisposed: () {
renderView.clearSemantics();
},
);
}

Merged via the queue into flutter:master with commit 6d2efe7 Sep 24, 2026
18 checks passed
@knopp
knopp deleted the fix_multiview_repaint branch September 24, 2026 05:01
elliette added a commit to elliette/flutter that referenced this pull request Sep 24, 2026
loic-sharma pushed a commit to elliette/flutter that referenced this pull request Sep 24, 2026
@elliette

Copy link
Copy Markdown
Member

Reason for revert: broke flutter -> packages autoroller

@elliette elliette added the revert Autorevert PR (with "Reason for revert:" comment) label Sep 25, 2026
@flutteractionsbot

Copy link
Copy Markdown
Contributor

Successfully created revert PR: #193360

@flutteractionsbot flutteractionsbot removed the revert Autorevert PR (with "Reason for revert:" comment) label Sep 25, 2026
elliette added a commit to elliette/flutter that referenced this pull request Sep 25, 2026
elliette added a commit to elliette/flutter that referenced this pull request Sep 25, 2026
elliette added a commit to elliette/flutter that referenced this pull request Sep 28, 2026
elliette added a commit to elliette/flutter that referenced this pull request Sep 28, 2026
github-merge-queue Bot pushed a commit that referenced this pull request Sep 28, 2026
Reverts: [Reland: Only render views that need to be rendered
](#192128)

Initiated by: @elliette

Reason for reverting: broke flutter -> packages autoroller

Original PR Author: @knopp

Reviewed By: @loic-sharma

The original PR description is provided below:

This relands #179874, reverted in
#191252.

The reason for revert was stalled web benchmarks
(#191251). Stalling was caused
by `_autoUpdateBenchmarkPhase` inside
`macrobenchmarks/lib/src/web/recorder.dart` expecting certain number of
`preroll_frame` and `apply_frame` events. These events are only
published for frames that are composited (ui.Scene being rendered), but
some of the web benchmarks request frame without making any render
objects dirty, which after
#191252 did not result on view
being composited.

The fix is to force view composition on every frame when the benchmarks
are running.

cc @yjbanov regarding the changes in `recorder.dart`.

## Pre-launch Checklist

- [x] I read the [Contributor Guide] and followed the process outlined
there for submitting PRs.
- [x] I read the [AI contribution guidelines] and understand my
responsibilities, or I am not using AI tools.
- [x] I read the [Tree Hygiene] wiki page, which explains my
responsibilities.
- [x] I read and followed the [Flutter Style Guide], including [Features
we expect every widget to implement].
- [x] I signed the [CLA].
- [x] I listed at least one issue that this PR fixes in the description
above.
- [x] I updated/added relevant in-code documentation (doc comments with
`///`).
- [x] If this PR introduces a new feature or capability, I created and
linked a website documentation issue or PR in [flutter/website] (or
verified none is needed).
- [x] I added new tests to check the change I am making, or this PR is
[test-exempt].
- [x] I followed the [breaking change policy] and added [Data Driven
Fixes] where supported.
- [x] All existing and new tests are passing.

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

If this change needs to override an active code freeze, provide a
comment explaining why. The code freeze workflow can be overridden by
code reviewers. See pinned issues for any active code freezes with
guidance.

**Note**: The Flutter team is currently trialing the use of [Gemini Code
Assist for
GitHub](https://developers.google.com/gemini-code-assist/docs/review-github-code).
Comments from the `gemini-code-assist` bot should not be taken as
authoritative feedback from the Flutter team. If you find its comments
useful you can update your code accordingly, but if you are unsure or
disagree with the feedback, please feel free to wait for a Flutter team
member's review for guidance on which automated comments should be
addressed.

<!-- Links -->
[Contributor Guide]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview
[AI contribution guidelines]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#ai-contribution-guidelines
[Tree Hygiene]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md
[test-exempt]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests
[Flutter Style Guide]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md
[Features we expect every widget to implement]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement
[CLA]: https://cla.developers.google.com/
[flutter/tests]: https://github.com/flutter/tests
[flutter/website]: https://github.com/flutter/website
[breaking change policy]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes
[Discord]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md
[Data Driven Fixes]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md

Co-authored-by: Elliott Brooks <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CICD Run CI/CD d: examples Sample code and demos engine flutter/engine related. See also e: labels. framework flutter/packages/flutter repository. See also f: labels. platform-android Android applications specifically platform-web Web applications specifically team-android Owned by Android platform team team-web Owned by Web platform team will affect goldens Changes to golden files

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants