Skip to content

"Stream" scenes to improve parallelization between UI and raster threads #145712

@loic-sharma

Description

@loic-sharma

Part of #142845

Background

Rendering is parallelized across the UI and raster threads. These two threads communicate using the "frame pipeline", a thread-safe queue:

  1. The framework renders a scene onto each view
  2. Once all views have been rendered, the engine submits the frame to the frame pipeline.
  3. The raster thread receives the frame and rasterizes it

Today, this parallelization is limited to workloads between separate frames.

For example, let's say we have a frame budget of 16ms, and rendering and rasterizing each view takes 5ms. If I render 2 views:

Time                        5ms                   10ms                      15ms                       20ms
UI thread        | -- Render view 1 -- | | -- Render view 2 -- |
Raster thread                                                    | -- Rasterize view 1 -- | | -- Rasterize view 2 -- |

This example would take 20ms, we would exceed our frame budget.

"Streaming" scenes

We can improve parallelization by rasterizing views as soon as they have been rendered. The UI thread would "stream" scenes to the raster thread instead of "batching" them.

Updated example:

Time                        5ms                     10ms                      15ms
UI thread        | -- Render view 1 -- | | --   Render view 2  -- |
Raster thread                            | -- Rasterize view 1 -- | | -- Rasterize view 2 -- |

This now takes 15ms, we would meet our frame budget.

However, note that this optimization doesn't help in scenarios where the raster thread is fully saturated:

Time                            5ms                                  10ms                               15ms                              20ms
UI thread        | --   Frame 1, render view 1 -- | | --   Frame 1, render view 2  -- |
Raster thread    | -- Frame 0 rasterize view 1 -- | | -- Frame 0, rasterize view 2 -- | | -- Frame 1 rasterize view 1 -- | | -- Frame 1, rasterize view 2 -- |

If the raster thread is already busy, "streaming" scenes won't reduce the total rendering time.

Rendering a subset of views

Normally the engine submits a frame pipeline item once the onDrawFrame callback exits. This is problematic as the framework does potentially expensive cleanup work at the end of the onDrawFrame callback.

The engine has an optimization where it submits a frame to the raster thread immediately once FlutterView.render has been called on all views. However, this optimization doesn't help if the framework chooses to not render all views in a frame. "Streaming" views would allow us to replace this optimization.

Metadata

Metadata

Assignees

No one assigned

    Labels

    P3Issues that are less important to the Flutter projecta: multi windowIssues related to multi window supportengineflutter/engine related. See also e: labels.team-engineOwned by Engine teamtriaged-engineTriaged by Engine team

    Type

    No type

    Projects

    Status

    No status

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions