Skip to content

Consider disabling picture complexity based raster caching in Skia backend. #131206

Closed

Description

@jonahwilliams

The Flutter engine will attempt to estimate the "cost" of the pictures that it renders. When this cost exceeds a threshold and the picture itself is stable, the engine will create a "raster cache" entry for that picture. The raster cache essentially replace the display/canvas operations with a texture containing the rasterized elements which will be reused on subsequent frames. The idea being that this will be cheaper and lead to more performant applications.

There are a few serious problems with the current raster cache complexity based scoring:

  • Failure to measure tradeoffs

The benchmarking infrastructure was designed to capture the cost of the cache removing the raster ops on the devices CPU. It did not measure the potentially increased GPU load from texture sampling/loading from video memory. From some local investigations, texture sampling can be multiple times slower than executing the original shaders.

There is also an additional memory cost to holding these raster images. They are only stored in native resolution and can add severals 10s of MB to video memory usages.

  • Unpredictable performance

Sometimes developers will inadvertantly create extremely expensive pictures, perhaps by doing something like emulating a paint application with stacked drawing + clears. The performance of this application will likely ping pong between smooth (as hundreds of draw ops are replaced with a texture) to janky once a new drawing operation is appended. This performance is likely to be less intuitive than if we were consistently slow. At least then they might look to developing their own caching strategy that didn't pingpong.

  • Unmaintainable herustics

The herustics used to populate the complexity scoring mechanism were developed by a never productionized one time script. From investigation, we know that several of these metrics are likely wrong. For example, there is no advantage to replacing large text blobs with a raster cache entry, as the text blobs are already drawn from sampled textures.

Because of these issues, we've previously decided not to port the raster cache to Impeller. This issue considers the case of also removing this from the Skia backend.

Experimental results

On Friday July 21, I disabled the picture complexity based raster cache heuristics in the engine. There were really only two benchmark changes of note:

  1. The complex layout scroll perf 90% time regressed by 2.5 MS

https://flutter-flutter-perf.skia.org/e/?begin=1689935934&end=1690044312&keys=X837961e90618ea0b4da8b84f85cdcb0a&selected=commit%3D35908%26name%3D%252Carch%253Dintel%252Cbranch%253Dmaster%252Cconfig%253Ddefault%252Cdevice_type%253DSM-A025V%252Cdevice_version%253Dnone%252Chost_type%253Dlinux%252Csub_result%253D90th_percentile_frame_rasterizer_time_millis%252Ctest%253Dcomplex_layout_scroll_perf__timeline_summary%252C&xbaroffset=35908

  1. The worst frame time of the textfield perf microbenchmark improved by 325ms

https://flutter-flutter-perf.skia.org/e/?queries=test%3Dfullscreen_textfield_perf&selected=commit%3D35908%26name%3D%252Carch%253Dintel%252Cbranch%253Dmaster%252Cconfig%253Ddefault%252Cdevice_type%253DMoto_G__4_%252Cdevice_version%253Dnone%252Chost_type%253Dlinux%252Csub_result%253D99th_percentile_frame_rasterizer_time_millis%252Ctest%253Dfullscreen_textfield_perf%252C

Activity

  1. added
    P1High-priority issues at the top of the work list
    on Jul 24, 2023
  2. jonahwilliams commented on Jul 24, 2023

    @jonahwilliams
    ContributorAuthor

    For the benchmark that regressed, I looked at GPU captures from current ToT (no raster caching) and last stable (with raster caching)

    Stable

    image

    ToT

    image

    Without raster caching the GPU workload is faster and uses less memory.

    However raster times did increase, notably because we are spending a bit more time in Skia canvas dispatching per frame.

  3. changed the title [-]Disable picutre complexity based raster caching in Skia backend.[/-] [+]Consider disabling picture complexity based raster caching in Skia backend.[/+] on Jul 25, 2023
  4. dnfield commented on Jul 26, 2023

    @dnfield
    Contributor

    Without raster caching the GPU workload is faster and uses less memory.

    However raster times did increase, notably because we are spending a bit more time in Skia canvas dispatching per frame

    What's the numeric difference between GPU time/CPU time with and without? It looks like with this change we're saving >1ms of GPU time per frame but we lost ~2.5ms on CPU time?

  5. jonahwilliams commented on Jul 26, 2023

    @jonahwilliams
    ContributorAuthor

    On the complex layout benchmark, yes
    on the gallery benchmarks there was no change
    on the textfield benchmark, there was a 250ms+ improvement (because the heuristics don't measure tradeoff costs and are just wrong sometime)

  6. dnfield commented on Jul 26, 2023

    @dnfield
    Contributor

    ...this seems like a good reason to disable it? Although it'd be good to understand what's going on in the complex layout benchmark more fully, and good to see if we can somehow get measurments of GPU time in our tests.

  7. jonahwilliams commented on Jul 26, 2023

    @jonahwilliams
    ContributorAuthor

    unfortunately the complex layout benchmark is just ... slow to encode in the SkPicture. So reducing the number of commands helps, disproportionately :(

  8. dnfield commented on Jul 26, 2023

    @dnfield
    Contributor

    Is it because there's a large number of commands? Or because there are particularly expensive ones?

    We went from a heuristic that was super simple and probably not right, to one that was very complicated and definitely not right.

    Should we be measuring the time it takes to encode the SkPicture and go from there?

  9. removed their assignment
    on Jul 27, 2023
  10. flutter-triage-bot commented on Feb 21, 2024

    @flutter-triage-bot

    This issue is marked P1 but has had no recent status updates.

    The P1 label indicates high-priority issues that are at the top of the work list. This is the highest priority level a bug can have if it isn't affecting a top-tier customer or breaking the build. Bugs marked P1 are generally actively being worked on unless the assignee is dealing with a P0 bug (or another P1 bug). Issues at this level should be resolved in a matter of months and should have monthly updates on GitHub.

    Please consider where this bug really falls in our current priorities, and label it or assign it accordingly. This allows people to have a clearer picture of what work is actually planned. Thanks!

  11. jonahwilliams commented on Feb 26, 2024

    @jonahwilliams
    ContributorAuthor

    I don't think we're going to have time to work on this. We should remove the complexity scoring when we turn on Impeller.

  12. github-actions commented on Mar 11, 2024

    @github-actions

    This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new bug, including the output of flutter doctor -v and a minimal reproduction of the issue.

  13. locked as resolved and limited conversation to collaborators on Mar 11, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    P1High-priority issues at the top of the work listteam-engineOwned by Engine teamtriaged-engineTriaged by Engine team

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions