-
Notifications
You must be signed in to change notification settings - Fork 6k
Try rasterizing each picture and layer at most once. Apply a consistent caching treshold to layers and pictures. #16545
Conversation
cbracken
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
|
@ignatz do you have any preliminary numbers on the performance effect here? (We collect them on post-submit in the engine-framework roll either way) |
|
Hmm -- this is consistently (three runs in a row) failing the |
Adrian has exact numbers but to paraphrase him: this change helps measurably but the frame drops don't significantly improve since the dominating factor is still the high render cost on the gpu thread. This change helps only indirectly by reducing the opportunity cost of not rasterizing other elements on screen. The gains heavily depend on "rasterizations-per-frame" (peaking at one, i.e. nothing else gets rasterized while unrasterizable elements are on screen) and the relative savings for the other elements. |
I have a suspicion. In the test I create a large SkPicture to make it fail rasterization. Which works fine on my workstation given enough memory but might be to greedy for the more constraint CI environment. Maybe you know of another nifty way to make rasterization fail? Otherwise, I'm also happy to experiment with more conservative numbers tomorrow. |
I did update the test. Hopefully it passes now within the memory limits. Generally the testing approach is kinda brittle, since the renderable bounds depend on the environment. That said, I don't have a better approach. A mockable skia api would be nice. Seems to be still failing :/ Note, since your last review I piggy bagged a semantic change into this PR. Previously we would always cache layers and not respect any access thresholds. The fewest layer types actually use the cache. However, I've seen per-frame re-rasterizations of text during opacity animations. I added a test but can totally understand if you'd like me to pull the changes apart. Just let me know |
Turns out I optimized the wrong way. Concretely, I made the bounds smaller in the test rather than bigger. The problem seems to have been that while my workstation was failing with more conservative bounds the CI environment wans't, which lead the CI environment to actually allocate the memory and in turn exceeded the container limits. |
|
ping |
|
/cc @liyuqian for further review. |
liyuqian
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM with one nit. I'd also love to see a companion flutter/flutter pull request that adds a performance test of this so we can quantify the improvement. Although this may not directly affect the Opal dropped frame metrics since there are other bottlenecks as #16545 (comment) suggested, I'm pretty sure that the frame_rasterization_time_millis in Flutter's performance test would capture some improvement of this PR.
If this PR is not urgent, it's also better to land that performance test PR first so our dashboard would record the numbers before and after this improvement. I'm very happy to provide help writing the performance test. My goal is let more and more people feel comfortable at writing Flutter performance tests.
This is certainly not the most high-impact improvement. Urgency is relative, would be good to have an ETA. It would still be a nice to have change, since not keep rasterizing non-rasterizable items seems like a strict improvement. The effective performance gain will depend on:
Note that I'd only expect a measurable improvement if the mentioned test induces failed rasterizations. Depending on that it might not even be worth waiting for it.
Right, the main problem here is probably that it's non-trivial and brittle to set up failed rasterizations from flutter. I'm aware of only one way. I think any such performance test would be super helpful going forward to avoid future regressions. For this specific change, it would just state the obvious: less work more better :). Independently note that there are still some test infra failures because of the test that tries to achieve failed rasterizations by creating an absurdly large image. Unfortunately, this is brittle since it can depend on your rendering environment. What do you suggest, are you aware of a better way to fail rasterization, can we disable the test in certain environments (e.g. preprocessor defines), or any other ideas? |
|
@ignatz by looking at our code, having a super large cull rect seems the only way other than subclassing |
…ation fails. Further enforce the same access threshold on layers as on Pictures. Previously layers would always be cached. The latter is a semantic change.
Happy to hear \o/. Rebased |
…rasterization fails. Further enforce the same access threshold on layers as on Pictures. Previously layers would always be cached. The latter is a semantic change. (flutter/engine#16545)
… rasterization fails. Further enforce the same access threshold on layers as on Pictures. Previously layers would always be cached. The latter is a semantic change. (#16545)" (#16889) This caused regression in several benchmarks, including: animated_placeholder_perf. Regression tracked in flutter/flutter#51776. This reverts commit 01a52b9.
…rasterization fails. Further enforce the same access threshold on layers as on Pictures. Previously layers would always be cached. The latter is a semantic change. (flutter/engine#16545)
* 9beac71 Add support for software text editing controls (flutter/engine#15560) * ab9f83f Roll fuchsia/sdk/core/linux-amd64 from RYDur... to bgFop... (flutter/engine#16855) * 62d0c08 Roll src/third_party/dart dda5bcee00d3..4dad6d77ba50 (6 commits) (flutter/engine#16856) * 76d12d2 Roll src/third_party/skia 03d9e8af0d25..262796edeba6 (11 commits) (flutter/engine#16857) * 01a52b9 Try rasterizing images and layers only once, even when their rasterization fails. Further enforce the same access threshold on layers as on Pictures. Previously layers would always be cached. The latter is a semantic change. (flutter/engine#16545) * 3b0d1a8 script for fetching correct flutter version (flutter/engine#16818) * 9746ddb Roll src/third_party/dart 4dad6d77ba50..6708f6d4c7df (15 commits) (flutter/engine#16860) * 90736bb Roll src/third_party/skia 262796edeba6..54cb21430ccb (23 commits) (flutter/engine#16861) * 142882e Roll src/third_party/skia 54cb21430ccb..e1ae9c4bcf2e (4 commits) (flutter/engine#16863) * 7192356 Manual roll of Dart 09bbd3cca5...6708f6d4c7 (flutter/engine#16864) * fae5ff6 Roll src/third_party/skia e1ae9c4bcf2e..5d1c3e2ead61 (2 commits) (flutter/engine#16865) * c6525a4 Roll src/third_party/skia 5d1c3e2ead61..59b160f99106 (2 commits) (flutter/engine#16866) * 755e2b5 Roll src/third_party/skia 59b160f99106..71a20b2685c6 (1 commits) (flutter/engine#16867) * 93d0eff Roll src/third_party/skia 71a20b2685c6..ecbb0fb2d5bc (1 commits) (flutter/engine#16869) * bfee5ae Roll fuchsia/sdk/core/linux-amd64 from bgFop... to F_Ihm... (flutter/engine#16871) * ca29b47 Roll fuchsia/sdk/core/mac-amd64 from K26F5... to 79I0C... (flutter/engine#16872) * 708ca2c Roll src/third_party/skia ecbb0fb2d5bc..666707336e07 (1 commits) (flutter/engine#16873) * 78ea291 Roll fuchsia/sdk/core/mac-amd64 from 79I0C... to NoQzJ... (flutter/engine#16874) * 7b43bb8 Roll fuchsia/sdk/core/linux-amd64 from F_Ihm... to 22R78... (flutter/engine#16875) * 75c9c62 Roll src/third_party/skia 666707336e07..231f1bf56556 (1 commits) (flutter/engine#16876) * 7a86b83 Roll src/third_party/dart 09bbd3cca5d4..860dca93ea42 (1 commits) (flutter/engine#16877) * d0c87e2 Roll src/third_party/skia 231f1bf56556..d6205322cdc5 (1 commits) (flutter/engine#16878) * b4c5854 Roll src/third_party/skia d6205322cdc5..6729496a037f (1 commits) (flutter/engine#16879) * 03f0ee5 Roll src/third_party/skia 6729496a037f..367dbff98555 (1 commits) (flutter/engine#16880) * d84b968 Roll fuchsia/sdk/core/mac-amd64 from NoQzJ... to q2DAy... (flutter/engine#16881) * 4490e7c Roll fuchsia/sdk/core/linux-amd64 from 22R78... to 9NHsJ... (flutter/engine#16882) * a39e7ac Roll src/third_party/skia 367dbff98555..986680240f81 (1 commits) (flutter/engine#16884) * 62b1e50 Roll src/third_party/dart 860dca93ea42..fbe9f6115d2f (9 commits) (flutter/engine#16885) * 5e474ee Roll src/third_party/skia 986680240f81..9dd0bd78b2d7 (2 commits) (flutter/engine#16886)
|
@ignatz : the regression suggests that there's something that we missed in this PR since this should be a strict improvement. To figure out what we missed, run the performance test with a locally built engine:
|
|
@ignatz : thanks to @flar , we now believed that regression flutter/flutter#51776 of this PR is caused by changing layer raster cache's behaviors. Before this PR, we'll always raster cache a layer if possible. This PR unexpectedly introduces the picture raster cache access threshold to the layer raster cache in https://github.com/flutter/engine/pull/16545/files#diff-d94c1943874763e8d6cc9eed9f1ab7eaR130. I unfortunately missed that line (and the title of this PR) during the code review, as I thought this PR only fixes how we increase the layer raster cache access count without actually enforcing the threshold. @ignatz : would you like to reland this patch without forcing the threshold on the layer raster cache? You might want to change |

If Rasterization fails, i.e. image.is_valid() is false, the cache might try rasterizing the image again on the next frame. Not only is this wasteful put might also prevent other pictures to be cached within the current frame budget.
CC @cbracken