-
Notifications
You must be signed in to change notification settings - Fork 5.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Use a single OffscreenCanvas for rendering in CanvasKit #42672
Use a single OffscreenCanvas for rendering in CanvasKit #42672
Conversation
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. |
Golden file changes are available for triage from new commit, Click here to view. |
Golden file changes are available for triage from new commit, Click here to view. |
So this is an interesting approach, it seems to use a single canvas to render each layer, and then use canvas to canvas drawing operations to output it to a non webgl canvas. The goals of this change, I believe, are to avoid the multiple webGL context limit enforced by the browser. Some observations: This still doesn't actually solve the root problems related to too many layers when HTML elements get introduced into the DOM and we need overlay canvases. Instead of the browsers built-in error limit, now we have a new software defined overlay canvas limit (maximumOverlays), which is 7 vs the browsers 16 (and flutter's current 8?). Am I missing something, or will every case that would fail before still fail under this proposed approach, with the caveat that in theory you can make that number whatever you want (if it's exposed) and avoid the hard cap of the browser, but in return we need to do tons of bitmap copy operations which might blow up perf (Firefox and Safari I'm looking at you). I guess the proof is in the perf as to whether this is an improvement or not (I understand there might be other values to an offscreen canvas being used like rendering off the main thread which could be worth it), but how does it solve the problems behind #37890 and the other related issues if it doesn't reduce the number of overlays required and has an even lower limit of overlays due to the perf required for the copies? The proposal in #41562 solves the problem that leads to the additional overlays being needed for things like video elements and image elements. Do we need to resurrect that even if this change gets merged? Instead of going through all this work, or maybe as part of this work, why not just allow the overlays to render themselves into the canvas? The open issues related to Video and Image elements causing canvases to be created would require a lot less copying if they could just paint their media element directly into the canvas instead of copying around everything besides them. Skia supports it already so no reason it can't be supported with a special image constructor in web_ui that accepts an HTMLMediaElement. |
@jezell I have a follow-up change which reduces the overlays induced by HTML elements which uses the algorithm here: https://docs.google.com/document/d/1aCIOEEYe31HqCaCGUKsAmUu9T0U6o2zUMGpqdPEdJoQ/edit#heading=h.kj5jgtvn1u89 |
@jezell Also, if all you're looking for is a way to create a You can use |
@harryterkelsen @eyebrowsoffire awesome news! |
@harryterkelsen you can in many cases make a further optimization and reduce the required platform views to one as I did in #41562. As long as the platform views are rectangular, opaque, and ignore pointer events, you can place them behind the canvas and render their region with a clear operation. While some platform views might not meet these conditions, many commonly problematic ones such as camera / video feeds or jpegs do. To the viewer, it appears that they are sitting in the correct location because the things that would have been rendered on top (because they are moved behind the canvas z-index) get erased during the drawing operation instead of creating a new canvas. I believe his approach is superior in these cases as it completely eliminates the need for the overlays when these constraints hold true. |
@jezell We have actually discussed the "cutout" approach in the past, but as you've already described it only works on completely opaque rectangular views, so we cannot use it as a general purpose solution for platform views. To help reassure a bit, we have done benchmarking of this change and haven't found any major issues with the performance of this strategy. This is also roughly equivalent to the strategy we are using in the experimental Skwasm renderer, which has proven to be quite performant so far. The amount of copying happening under the hood is actually quite a bit less than you might imagine, as The main thing here is that practically speaking, there are hard limits and very real perf ramifications to creating multiple GL contexts, but those same limitations do not apply to making The main thing we achieve from having a single GL context is that we can safely use the same GPU-side resources across multiple overlays. Right now, having multiple GL contexts is unfortunately pretty error prone and has performance cliffs when we have to move resources from one context to another. Anyway, we really appreciate your engagement (and your patience) on these issues. I'm hoping the new |
@eyebrowsoffire I agree that the ImageBitmap approach is the best general purpose solution, looking forward to giving it a shot. Should solve a lot of the cases for us that get us into trouble. Is the video_player web package being updated to use it? I'll work with the flutter_webrtc guys and see if we can get them to move over to it as well. I believe it should be good enough to solve our current blockers. |
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! One small comment.
Golden file changes are available for triage from new commit, Click here to view. |
…)" This reverts commit c5ba843.
) Reverts #42672 This is causing breakages in the Framework roller on golden tests: flutter/flutter#134583
…134597) flutter/engine@c90fadf...7c78ea2 2023-09-12 zanderso@users.noreply.github.com Revert "Lazily allocate RasterCacheItems only when caching is enabled" (flutter/engine#45734) 2023-09-12 1961493+harryterkelsen@users.noreply.github.com Revert "Use a single OffscreenCanvas for rendering in CanvasKit" (flutter/engine#45744) 2023-09-12 chinmaygarde@google.com [Impeller] Patch the compiler to account for subpass inputs and PSO metadata. (flutter/engine#45739) 2023-09-12 chinmaygarde@google.com [Impeller] Fix swapchain recreation for non-polling cases. (flutter/engine#45740) 2023-09-12 skia-flutter-autoroll@skia.org Roll Fuchsia Mac SDK from QgAHx3BtJfN3TmodS... to UCa49z8fu0hD9cypj... (flutter/engine#45738) 2023-09-12 ychris@google.com [ios] upload extension safe artifacts (flutter/engine#45664) 2023-09-12 30870216+gaaclarke@users.noreply.github.com Added test to assert the vulkan embedder threadsafe vkqueue usage (flutter/engine#45732) 2023-09-12 chinmaygarde@google.com [Impeller] If validations are enabled but not found, still create the VK context. (flutter/engine#45674) 2023-09-12 skia-flutter-autoroll@skia.org Roll Skia from 211d63b1e1f5 to 2d295711337c (7 revisions) (flutter/engine#45729) 2023-09-12 1961493+harryterkelsen@users.noreply.github.com Use a single OffscreenCanvas for rendering in CanvasKit (flutter/engine#42672) Also rolling transitive DEPS: fuchsia/sdk/core/mac-amd64 from QgAHx3BtJfN3 to UCa49z8fu0hD If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/flutter-engine-flutter-autoroll Please CC bdero@google.com,rmistry@google.com,zra@google.com on the revert to ensure that a human is aware of the problem. To file a bug in Flutter: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://bugs.chromium.org/p/skia/issues/entry?template=Autoroller+Bug Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md
…lutter#134597) flutter/engine@c90fadf...7c78ea2 2023-09-12 zanderso@users.noreply.github.com Revert "Lazily allocate RasterCacheItems only when caching is enabled" (flutter/engine#45734) 2023-09-12 1961493+harryterkelsen@users.noreply.github.com Revert "Use a single OffscreenCanvas for rendering in CanvasKit" (flutter/engine#45744) 2023-09-12 chinmaygarde@google.com [Impeller] Patch the compiler to account for subpass inputs and PSO metadata. (flutter/engine#45739) 2023-09-12 chinmaygarde@google.com [Impeller] Fix swapchain recreation for non-polling cases. (flutter/engine#45740) 2023-09-12 skia-flutter-autoroll@skia.org Roll Fuchsia Mac SDK from QgAHx3BtJfN3TmodS... to UCa49z8fu0hD9cypj... (flutter/engine#45738) 2023-09-12 ychris@google.com [ios] upload extension safe artifacts (flutter/engine#45664) 2023-09-12 30870216+gaaclarke@users.noreply.github.com Added test to assert the vulkan embedder threadsafe vkqueue usage (flutter/engine#45732) 2023-09-12 chinmaygarde@google.com [Impeller] If validations are enabled but not found, still create the VK context. (flutter/engine#45674) 2023-09-12 skia-flutter-autoroll@skia.org Roll Skia from 211d63b1e1f5 to 2d295711337c (7 revisions) (flutter/engine#45729) 2023-09-12 1961493+harryterkelsen@users.noreply.github.com Use a single OffscreenCanvas for rendering in CanvasKit (flutter/engine#42672) Also rolling transitive DEPS: fuchsia/sdk/core/mac-amd64 from QgAHx3BtJfN3 to UCa49z8fu0hD If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/flutter-engine-flutter-autoroll Please CC bdero@google.com,rmistry@google.com,zra@google.com on the revert to ensure that a human is aware of the problem. To file a bug in Flutter: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://bugs.chromium.org/p/skia/issues/entry?template=Autoroller+Bug Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md
This changes CanvasKit's rendering model. Previously, each overlay canvas induced a new WebGL context and SkSurface. Now, there is only ever one SkSurface (backed by an OffscreenCanvas), and the overlays are HTML canvases with a bitmaprenderer context. The content is rendered using the SkSurface and passed to the overlays using
transferToImageBitmap
. This way, there is only one WebGL context in the lifetime of the app.Pre-launch Checklist
///
).If you need help, consider asking for advice on the #hackers-new channel on Discord.