Skip to content

Stand-alone widget tree with multiple render trees to enable multi-view rendering#125003

Merged
auto-submit[bot] merged 115 commits intoflutter:masterfrom
goderbauer:rawview
Jul 17, 2023
Merged

Stand-alone widget tree with multiple render trees to enable multi-view rendering#125003
auto-submit[bot] merged 115 commits intoflutter:masterfrom
goderbauer:rawview

Conversation

@goderbauer
Copy link
Member

@goderbauer goderbauer commented Apr 17, 2023

Part of #121573.

This change enables Flutter to generate multiple Scenes to be rendered into separate FlutterViews from a single widget tree. Each Scene is described by a separate render tree, which are all associated with the single widget tree.

This PR implements the framework-side mechanisms to describe the content to be rendered into multiple views. Separate engine-side changes are necessary to provide these views to the framework and to draw the framework-generated Scene into them.

Summary of changes

The details of this change are described in flutter.dev/go/multiple-views. Below is a high-level summary organized by layers.

Rendering layer changes

  • The RendererBinding no longer owns a single renderView. In fact, it doesn't OWN any RenderViews at all anymore. Instead, it offers an API (addRenderView/removeRenderView) to add and remove RenderViews that then will be MANAGED by the binding. The RenderView itself is now owned by a higher-level abstraction (e.g. the RawView Element of the widgets layer, see below), who is also in charge of adding it to the binding. When added, the binding will interact with the RenderView to produce a frame (e.g. by calling compositeFrame on it) and to perform hit tests for incoming pointer events. Multiple RenderViews can be added to the binding (typically one per FlutterView) to produce multiple Scenes.
  • Instead of owning a single pipelineOwner, the RendererBinding now owns the root of the PipelineOwner tree (exposed as rootPipelineOwner on the binding). Each PipelineOwner in that tree (except for the root) typically manages its own render tree typically rooted in one of the RenderViews mentioned in the previous bullet. During frame production, the binding will instruct each PipelineOwner of that tree to flush layout, paint, semantics etc. A higher-level abstraction (e.g. the widgets layer, see below) is in charge of adding PipelineOwners to this tree.
  • Backwards compatibility: The old renderView and pipelineOwner properties of the RendererBinding are retained, but marked as deprecated. Care has been taken to keep their original behavior for the deprecation period, i.e. if you just call runApp, the render tree bootstrapped by this call is rooted in the deprecated RendererBinding.renderView and managed by the deprecated RendererBinding.pipelineOwner.

Widgets layer changes

  • The WidgetsBinding no longer attaches the widget tree to an existing render tree. Instead, it bootstraps a stand-alone widget tree that is not backed by a render tree. For this, RenderObjectToWidgetAdapter has been replaced by RootWidget.
  • Multiple render trees can be bootstrapped and attached to the widget tree with the help of the View widget, which internally is backed by a RawView widget. Configured with a FlutterView to render into, the RawView creates a new PipelineOwner and a new RenderView for the new render tree. It adds the new RenderView to the RendererBinding and its PipelineOwner to the pipeline owner tree.
  • The View widget can only appear in certain well-defined locations in the widget tree since it bootstraps a new render tree and does not insert a RenderObject into an ancestor. However, almost all Elements expect that their children insert RenderObjects, otherwise they will not function properly. To produce a good error message when the View widget is used in an illegal location, the debugMustInsertRenderObjectIntoSlot method has been added to Element, where a child can ask whether a given slot must insert a RenderObject into its ancestor or not. In practice, the View widget can be used as a child of the RootWidget, inside the view slot of the ViewAnchor (see below) and inside a ViewCollection (see below). In those locations, the View widget may be wrapped in other non-RenderObjectWidgets (e.g. InheritedWidgets).
  • The new ViewAnchor can be used to create a side-view inside a parent View. The child of the ViewAnchor widget renders into the parent View as usual, but the view slot can take on another View widget, which has access to all inherited widgets above the ViewAnchor. Metaphorically speaking, the view is anchored to the location of the ViewAnchor in the widget tree.
  • The new ViewCollection widget allows for multiple sibling views as it takes a list of Views as children. It can be used in all the places that accept a View widget.

Google3

As of July 5, 2023 this change passed a TAP global presubmit (TGP) in google3: tap/OCL:544707016:BASE:545809771:1688597935864:e43dd651

Note to reviewers

This change is big (sorry). I suggest focusing the initial review on the changes inside of packages/flutter first. The majority of the changes describe above are implemented in (listed in suggested review order):

  • rendering/binding.dart
  • widgets/binding.dart
  • widgets/view.dart
  • widgets/framework.dart

All other changes included in the PR are basically the fallout of what's implemented in those files. Also note that a lot of the lines added in this PR are documentation and tests.

I am also very happy to walk reviewers through the code in person or via video call, if that is helpful.

I appreciate any feedback.

Feedback to address before submitting ("TODO")

  • PipelineOwner tree should implement DiagnosticableTree
  • ViewHooksScope should be private
  • Disallow setting root node on default root pipeline owner

@flutter-dashboard flutter-dashboard bot added a: accessibility Accessibility, e.g. VoiceOver or TalkBack. (aka a11y) a: animation Animation APIs a: tests "flutter test", flutter_test, or one of our tests a: text input Entering text in a text field or keyboard related problems d: examples Sample code and demos f: focus Focus traversal, gaining or losing focus f: gestures flutter/packages/flutter/gestures repository. f: material design flutter/packages/flutter/material repository. f: routes Navigator, Router, and related APIs. framework flutter/packages/flutter repository. See also f: labels. f: integration_test The flutter/packages/integration_test plugin c: contributor-productivity Team-specific productivity, code health, technical debt. labels Apr 17, 2023
@goderbauer goderbauer force-pushed the rawview branch 2 times, most recently from b53331d to b4f9996 Compare April 25, 2023 13:01
@goderbauer goderbauer force-pushed the rawview branch 4 times, most recently from 8993887 to c6dd65f Compare May 10, 2023 11:59
@goderbauer goderbauer force-pushed the rawview branch 3 times, most recently from 478a36b to 43a9a19 Compare May 18, 2023 18:22
@github-actions github-actions bot removed the a: animation Animation APIs label Jun 7, 2023
@github-actions github-actions bot removed f: material design flutter/packages/flutter/material repository. a: text input Entering text in a text field or keyboard related problems f: routes Navigator, Router, and related APIs. labels Jun 7, 2023
@goderbauer goderbauer force-pushed the rawview branch 3 times, most recently from 9b1458e to 7c92446 Compare June 10, 2023 01:01
@goderbauer goderbauer mentioned this pull request Jul 13, 2023
@goderbauer goderbauer added the autosubmit Merge PR when tree becomes green via auto submit App label Jul 17, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

a: accessibility Accessibility, e.g. VoiceOver or TalkBack. (aka a11y) a: tests "flutter test", flutter_test, or one of our tests autosubmit Merge PR when tree becomes green via auto submit App c: contributor-productivity Team-specific productivity, code health, technical debt. d: examples Sample code and demos f: focus Focus traversal, gaining or losing focus f: integration_test The flutter/packages/integration_test plugin framework flutter/packages/flutter repository. See also f: labels.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants