Repository navigation
[Impeller] Avoid heap-allocating std::function captures per draw - #192679
Conversation
UberSDF and circle contents build callbacks per draw that capture the sampler binding and geometry result by value; these captures exceed the small-buffer optimization and heap-allocate. DrawGeometry invokes the callbacks synchronously within the call, so capture by reference is safe and removes two allocations per draw. test-exempt: capture-by-ref only; DrawGeometry remains synchronous. Measured on Apple M1 (Metal, release), interleaved medians of primitive_rendering_benchmarks: BM_DrawOval/AAFilled/ImpellerMetalSDF/16 -5.9% CPU, BM_DrawRect/AAFilled/ImpellerMetalSDF/16 -1.5% CPU.
|
@artemkulyk Is this PR still in progress, or is it ready for review? |
|
@b-luk , It is ready for review, but I cannot open it, because I have two other PRs open. |
|
/gemini review |
There was a problem hiding this comment.
Code Review
This pull request modifies CircleContents and UberSDFContents in Impeller to capture local variables by reference instead of moving them by value into lambda callbacks. Comments have been added to explain that capturing by reference is safe because the callbacks are executed before DrawGeometry returns. Additionally, the optional header was included in uber_sdf_contents.h. I have no feedback to provide.
| // DrawGeometry invokes this before returning, so capturing locals by | ||
| // reference is safe. |
There was a problem hiding this comment.
I don't think we need an explicit comment about this. Other pipeline Contents files do not have this comment, so leaving this out would be consistent with the rest of the files.
There was a problem hiding this comment.
Removed. Keeping it consistent with the other Contents.
| // geometry_result by reference is safe. | ||
| [&geometry_result](const ContentContext& renderer, const Entity& entity, | ||
| RenderPass& pass, | ||
| const Geometry* geometry) { return geometry_result; }); |
There was a problem hiding this comment.
Can we omit create_geom_callback completely? It has a default of DefaultCreateGeometryCallback:
flutter/engine/src/flutter/impeller/entity/contents/color_source_contents.h
Lines 117 to 118 in a638a66
which is what both CircleContents and UberSDFContents both are passing in.
/*force_stencil=*/false is also the default and could be omitted.
Most other pipeline Contents' Render functions already omit these and use the defaults, e.g. SolidColorContents
so removing these from CircleContents and UberSDFContents makes them more similar to the other ones.
There was a problem hiding this comment.
Done in both. Default makes the same call, both geometries are kNormal, so no behavior change.
…ntents CircleContents and UberSDFContents were the only contents passing a custom create_geom_callback, and it only returned a precomputed GetPositionBuffer result. The default callback performs the same call, and neither CircleGeometry nor UberSDFGeometry overrides GetResultMode (both are kNormal). force_stencil was false as well, so the stencil-then-cover path never engaged. This also removes the now-unused geometry_result precompute. test-exempt: refactor with no behavior change; existing golden tests cover both pipelines.
|
Applied in 24489a0. Thanks! |
|
/gemini review |
There was a problem hiding this comment.
Code Review
This pull request simplifies the rendering pipeline setup in CircleContents and UberSDFContents by removing the manual retrieval of the geometry position buffer and the associated create_geom_callback argument. Additionally, the lambda capture for sampler_binding in UberSDFContents has been simplified to capture by reference, and an include for was added to its header file. There are no review comments, and I have no feedback to provide.
This PR seems fine to me. You can switch one of your other open PRs to draft so that you can mark this one as ready. |
b-luk
left a comment
There was a problem hiding this comment.
LGTM
I don't know if this will have any meaningful impact on performance. But the simplified code is a benefit.
|
Thanks! Earlier isolated A/B runs on M1 Metal showed about 2% lower CPU time for SDF rectangles; oval and circle results were within noise. I haven't remeasured after the callback cleanup, so I wouldn't claim a broad performance improvement. |
There was a problem hiding this comment.
Code Review
This pull request simplifies the rendering implementation in CircleContents and UberSDFContents by removing redundant geometry position buffer retrievals and custom geometry callbacks. It also refactors lambda captures in UberSDFContents and adds the header to uber_sdf_contents.h. There are no review comments, and I have no feedback to provide.
|
autosubmit label was removed for flutter/flutter/192679, because This PR has not met approval requirements for merging. The PR author is not a member of flutter-hackers and needs 1 more review(s) in order to merge this PR.
|
|
@gaaclarke for second review |
gaaclarke
left a comment
There was a problem hiding this comment.
lgtm, getting the position buffer and passing it in should be the same as passing in that geometry
UberSDF and circle contents build per-draw callbacks that capture the sampler binding and geometry result by value. Those captures exceed the std::function small-buffer optimization and heap-allocate on every draw.
DrawGeometry invokes the callbacks before returning, so capturing by reference is valid and removes those allocations.
Fixes #192673
Related to #164607
test-exempt: capture-by-ref only; DrawGeometry remains synchronous
Pre-launch Checklist
///).If you need help, consider asking for advice on the #hackers-new channel on Discord.
If this change needs to override an active code freeze, provide a comment explaining why. The code freeze workflow can be overridden by code reviewers. See pinned issues for any active code freezes with guidance.
Note: The Flutter team is currently trialing the use of Gemini Code Assist for GitHub. Comments from the
gemini-code-assistbot should not be taken as authoritative feedback from the Flutter team. If you find its comments useful you can update your code accordingly, but if you are unsure or disagree with the feedback, please feel free to wait for a Flutter team member's review for guidance on which automated comments should be addressed.Made with Cursor