-
Notifications
You must be signed in to change notification settings - Fork 6k
Trace calls to Canvas::saveLayer #29444
Conversation
|
@flar AFAICT, I don't want to add these to the dispatchers for DisplayList, since that would duplicate tracing. Please let me know if I'm misunderstanding anything there. |
| if (canvas()) { | ||
| if (needs_save_layer) { | ||
| FML_LOG(INFO) << "Using SaveLayer to protect non-readback surface"; | ||
| TRACE_EVENT0("flutter", "Canvas::saveLayer"); |
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.
The cost of the save layer is not just isolated to this scope. There will be significant time taken in the flush waiting on the GPU to service this workload. So, perhaps a more actionable metric is to have a counter that tracks the number of save layers?
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.
TRACE_COUNTER instead of TRACE_EVENT I mean.
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.
Counters won't show up in systracing. My idea here is that devtools could manually count these, and developers would be able to more easily see what callstacks were resulting in them. Then we'd want something like debugging the SKP that resulted and you could visually see what parts of the draw used a savelayer.
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.
(so yes, these trace events will be very small, but devtools will be able to scan for them and know they result in more expensive operations later)
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.
It's not just that the bulk of the work happens in a different phase of the pipeline (i.e. flush vs LayerTree.Paint), it's that even the saveLayer call itself doesn't really do the work. It remembers a few items you told it, then later the restore applies that work. So there are many reasons why this timed event isn't capturing any real work.
Why doesn't devtools scan for the counter events? They are just another type of event in the Chrome Tracing.
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.
Why doesn't devtools scan for the counter events?
Discussing this in person, it looks like devtools should be able to detect counter events. systrace is an issue though and I am investigating if counters are not supported by systrace or whether this is a limitation with our trace logger to systrace. In any case, it looks like our use case ought to be address by just tracing to the timeline.
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.
it would be great to switch this to a counter as these events are adding noise to the trace right now without clear user value.
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.
We didn't use counters because it wouldn't be seen by users. The action a user should take is to turn on debugTracePaintEnabled and remove or rewrite the render object adding this call.
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.
... without clear user value.
I don't remember the full context of this discussion---if these are trace events we explicitly added for the benefit of end-users, then we should certainly try to make them more useful---but in general, it's been our practice to add trace events as needed to assist Engine developers in zeroing in on issues, be they performance issues or otherwise. So (in general, maybe not for this specific case) if a trace event is too noisy, the corrective action would be to filter it before an end-user sees it.
|
Can we add an arg to these trace events "devtoolsTag" args are added for shader events currently. |
saveLayer calls captured in a DisplayList aren't duplicates of any other saveLayer that appears in the rest of the source code. |
I'm speaking specifically about calls in https://github.com/flutter/engine/blob/master/flow/display_list_canvas.cc |
|
Talked with Chinmay offline a bit, I'll look at getting this set up as a counter. @kenzieschmoll do you still need special args there for counters? |
|
We may not need a "devtoolsTag" arg then. Will the counter event be sent for each call to saveLayer? Or will the saveLayer call count be included in the event args? See https://docs.google.com/document/d/1CvAClvFfyA5R-PhYUmn5OOQtYMH4h6I0nSsKchNAySU/preview#heading=h.msg3086636uq for an example with "cats" and "dogs" |
Ideally, it would be sent once per frame after the rasterization. This should significantly reduce the trace size and also be easier to collect. |
|
I've updated this to emit an I should ideally write several more tests for individual components of this rather than the integration-type test I wrote in Dart. Before I do that I'd like to make sure this approach seems reasonable to @chinmaygarde and @kenzieschmoll will be able to consume it properly in devtools. The event comes out in the timeline looking like this: {
"name":"LayerTree::SaveLayerCount",
"cat":"Embedder",
"tid":10755,
"pid":32564,
"ts":293539251550,
"ph":"C",
"args":{
"count":"2"
}
}, |
49760a8 to
b3e71cc
Compare
|
Looks good to me. Offline, we spoke about potentially using a |
|
One thing that would be very helpful from the DevTools side is if we can add the frame number to the event args. This will allow us to link this counter event with the proper frame it belongs to. We already have access to this frame number somewhere in the engine and pass it to a couple other events as a "frame_number" arg. |
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.
After looking at this amount of plumbing I feel as if we should be using the events instead.
There is too much disruption of various systems and the accounting is wrong in some places in ways that fixing will only add a lot more accounting. Prepare on a layer, for instance, could end up just doing a touch on the cache entry, or it could find that the cache entry is already populated and do no work at all, or it could try to populate the cache and fail due to conditions deeper in the code. Adding a save layer count on every call to prepare is more often to be over-accounting than anything.
The accounting for save layers in the flutter::Picture object would end up being redundant for display lists who could easily tell you how many save layers they have directly or even do the savelayer events themselves at the site where they invoke it.
SkPicture may not do all of those saveLayers because peephole optimizations may delete them, or RTree code may bypass them.
All in all I think the events were far simpler. As far as trying to measure the duration of the saveLayer events - which is a meaningless exercise, there are instantaneous trace events which do not measure a duration and those would be reasonable to use for the saveLayers. Using (non-duration) events would also show you where in the timeline they happened rather than just the count.
flow/layers/image_filter_layer.cc
Outdated
| // from frame to frame so we try to cache the layer itself | ||
| // for maximum performance. | ||
| TryToPrepareRasterCache(context, this, matrix); | ||
| context->save_layer_count += 1; |
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.
What saveLayer is this counting for?
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.
Rasterizing this layer for the cache is effectively a saveLayer - although your point about this possibly touching the cache without updating the image is well taken.
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.
I can imagine that the hit rate on this specific count being true is probably very low. But it can vary case by case.
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.
Also, this increment only accounts for the saveLayer in this layer's own Paint() call. Consider that this layer has children and those children can also contain saveLayer calls and this increment of 1 can't even hope to account for all of those.
While we could design another accounting workaround for that issue, this is perhaps yet another reason that using trace events localized at the sites of the saveLayer calls would greatly improve the accuracy of these metrics in a less convoluted way.
|
This may be a better mechanism than duration events or counts: Line 119 in bbc4615
|
After looking at the new code I don't think "easier to collect" rang true in the end. Tagging the sites with instant events looks a lot less invasive to the architecture. |
|
The main problem with instant events is that they definitely do not show up in systracing, and it would be a shame to lose this information when using systracing. That was the real reason for using the duration based events, rather than to actually capture any timing information. See https://github.com/dart-lang/sdk/blob/56e7532f99f85150968bed6b54f3301960a1bcd3/runtime/vm/timeline_android.cc#L61-L90 Perhaps a fix for that would be to have Dart emit instant events as B/E couples with the same or some trivially small timestamp in the systrace recorder? Instant events tend to be hard to see though. As far as optimizations removing saveLayer - it'd be nice if we could capture those, but I'm mainly concerned with making it clearer to developers when their app is using saveLayer for a particular frame so that they can find and eliminate it, rather than relying on an optimization that may stop working due to seemingly unrelated changes in their application. |
|
The "easier to collect" part was also referring to how devtools would collect this information, now to how the engine would :) |
|
Ah, yes, devtools would have to look for them as it scans the events, but I'm presuming it already scans the events anyway, so that is just adding another case to the scanner? I looked for the documentation of the systrace format, but couldn't find anything. Having a zero length event should be fine - or we could wrap the call to canvas->saveLayer like was done before even if that isn't very meaningful, it would disrupt our code less to not have to "find" a place to increment a counter from every location that uses saveLayer. |
flow/layers/image_filter_layer.cc
Outdated
| // switch during the Paint phase even if they are not stable. | ||
| // This benefit is seen most during animations. | ||
| TryToPrepareRasterCache(context, GetCacheableChild(), matrix); | ||
| context->save_layer_count += 1; |
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.
I just noticed this. Even though I am pushing for switching back to tagging the saveLayer calls themselves with events as it is more accurate and less disruptive, I thought I'd point out a problem with this specific change if for no other reason than to educate.
This call is preparing the children for a cache entry. There is not an implicit saveLayer involved when those children are rasterized like there is when "this" is cached. So, this specific increment is incorrect in all cases.
f7d6f75 to
d90de5d
Compare
|
Per offline discussion:
|
|
I also believe that this version will not double-count or incorrectly count raster caching as a save layer, unless the save layer call actually happens in |
* 422b15a Roll Skia from d9d9e21b311c to a8d38078a4f3 (1 revision) (flutter/engine#29521) * afe1c98 Roll Fuchsia Mac SDK from SfdmlzXiU... to nkHhPcy3q... (flutter/engine#29522) * b7f4651 Roll Fuchsia Linux SDK from 5-RB9TzQH... to m90mMA37b... (flutter/engine#29523) * 15d5a23 [Web] Fix BMP encoder (flutter/engine#29448) * 3f55aec Fix FlutterPresentInfo struct_size doc string (flutter/engine#29524) * b991af9 Roll Skia from a8d38078a4f3 to 7368c6d00b7c (5 revisions) (flutter/engine#29525) * 93666e2 Fix isolate_configuration typo (flutter/engine#29318) * 91033b9 Roll Skia from 7368c6d00b7c to a5030e9090e8 (3 revisions) (flutter/engine#29527) * c2090c2 [iOS] Make sure spawnee's isGpuDisabled is set correctly when FlutterEngine spawn (flutter/engine#29361) * e071f1d Roll Skia from a5030e9090e8 to 37afdbc22e89 (4 revisions) (flutter/engine#29528) * ca1710a Roll Skia from 37afdbc22e89 to a05d3029ac65 (4 revisions) (flutter/engine#29532) * 3364409 Reland Display Features support (Foldable and Cutout) (flutter/engine#29447) * 4684d23 [fuchsia] Add more logging for error cases. (flutter/engine#29397) * 5cf7c39 Remove D3D9 fallback path (flutter/engine#29533) * 98d31de [raster_cache] Increment access_count on Touch (flutter/engine#29529) * cc6fc4a Re-enable A11yTreeIsConsistent with higher timeout (flutter/engine#29367) * fb20916 Roll Skia from a05d3029ac65 to 37da672b14b7 (1 revision) (flutter/engine#29534) * d229ec8 use SkMatrix.invert() instead of MatrixDecomposition to validate cache matrices (flutter/engine#29530) * a92aebb Roll Clang Linux from 5N9a1nYj5... to UtjvZhwws... (flutter/engine#29535) * 47dab8a Roll Dart SDK from 3b11f88c96a5 to f38618d5d0c0 (7 revisions) (flutter/engine#29537) * 83ccad7 FragmentProgram constructed asynchronously (flutter/engine#29513) * 2078baf Roll Fuchsia Linux SDK from m90mMA37b... to Ci-Vji1rx... (flutter/engine#29546) * 6bf8093 Roll Fuchsia Mac SDK from nkHhPcy3q... to emi7COLIo... (flutter/engine#29547) * 290d179 Roll Skia from 37da672b14b7 to cf8daf79e710 (9 revisions) (flutter/engine#29548) * 197ca59 [iOS] Fixes press key message leaks (flutter/engine#29354) * 986b8d8 Roll Skia from cf8daf79e710 to ae67f07a58a2 (1 revision) (flutter/engine#29549) * 11010f0 Roll Skia from ae67f07a58a2 to 17616469ddf8 (1 revision) (flutter/engine#29551) * dadc7b2 Roll Skia from 17616469ddf8 to 4322c7fec7e4 (3 revisions) (flutter/engine#29552) * ed66091 don't build flutter SDK artifacts for armv7 (flutter/engine#28016) * 484cc5c Roll Dart SDK from f38618d5d0c0 to 05febe0a7860 (5 revisions) (flutter/engine#29539) * 387563a Roll Skia from 4322c7fec7e4 to 1800d410df16 (1 revision) (flutter/engine#29553) * 05ceba2 Roll Skia from 1800d410df16 to 725705f6630b (1 revision) (flutter/engine#29555) * 2b142ef Roll Dart SDK from 05febe0a7860 to 38e7078fa2b7 (5 revisions) (flutter/engine#29556) * 29da91f Roll Fuchsia Linux SDK from Ci-Vji1rx... to kHXT3xnTG... (flutter/engine#29557) * da02a4b Roll Fuchsia Mac SDK from emi7COLIo... to 6BYh8qaYo... (flutter/engine#29558) * 71fb575 Roll Skia from 725705f6630b to deb9386be146 (3 revisions) (flutter/engine#29559) * c5f572a [Linux keyboard] Fix logical keys of up events are not regularized (flutter/engine#29550) * 988ea43 Roll Dart SDK from 38e7078fa2b7 to d464cd3f2dc8 (5 revisions) (flutter/engine#29561) * fdee74d Trace calls to Canvas::saveLayer (flutter/engine#29444) * 953f718 ios test script checks for `ios_test_flutter` artifacts (flutter/engine#29554) * 145d890 Roll Skia from deb9386be146 to 37bef2d300e4 (6 revisions) (flutter/engine#29563) * cc9b174 Fix race condition introduced by background platform channels (flutter/engine#29377) * 79b5e3c Roll Dart SDK from d464cd3f2dc8 to 996ef242a2c9 (1 revision) (flutter/engine#29564) * 3eb6e15 fuchsia: Enable integration tests (flutter/engine#29565) * ffa8b25 Roll Skia from 37bef2d300e4 to 2417872a9993 (1 revision) (flutter/engine#29567) * 9af2de9 Roll Dart SDK from 996ef242a2c9 to 5ccf755b37a4 (1 revision) (flutter/engine#29568) * 16d6d18 Roll Fuchsia Linux SDK from kHXT3xnTG... to uP2kJIngK... (flutter/engine#29569) * 321bc56 Roll Fuchsia Mac SDK from 6BYh8qaYo... to W9UXc2Fwx... (flutter/engine#29570) * f0a8d4e Roll Dart SDK from 5ccf755b37a4 to f6a43e5eb71d (1 revision) (flutter/engine#29571) * 0be0303 Hide a11y elements when resigning active (flutter/engine#29566) * 9a3195a Roll Fuchsia Linux SDK from uP2kJIngK... to aD3d4Kqmy... (flutter/engine#29572) * b3cbee5 Roll Fuchsia Mac SDK from W9UXc2Fwx... to rIpW1050J... (flutter/engine#29573) * df686d2 Revert "Reland Display Features support (Foldable and Cutout) (#29447)" (flutter/engine#29574) * e812731 Revert dart to 38e7078fa2b7 (flutter/engine#29575) * 049074e Roll Skia from 2417872a9993 to cd7220e7686c (2 revisions) (flutter/engine#29577) * e6a51a4 Roll Fuchsia Mac SDK from rIpW1050J... to TOmxgL3av... (flutter/engine#29578) * 8f272d9 Roll Fuchsia Linux SDK from aD3d4Kqmy... to ZniYyCw7U... (flutter/engine#29579) * 469d6f1 Revert "[Web] Fix BMP encoder (#29448)" (flutter/engine#29580)
| if (!canvas_) { | ||
| return; | ||
| } | ||
| TRACE_EVENT0("flutter", "Canvas::saveLayer"); |
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.
This is incorrect. This line is only recording a saveLayer and has nothing to do with the execution of saveLayers.
The recorded picture can be reused on every single frame from here on and it won't be recorded (there's not much that can be done for that with SkP, but DL could record them as they execute).
The recorded picture could be a mistake and never used even once.
This trace will appear on the build thread, not the raster thread.
There is everything wrong with this event.
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.
I know that this record won't be enough, but in most cases it will provide signal about where in developer code someone actually triggered a saveLayer. My more recent concern is that it might not be enough, since things like drawColor and drawPaint might also trigger a saveLayer.
How would you suggest achieving this?
|
Where are the trace events on the auto save layers used in other layers? Also, DL should be tracing the events in the canvas adapter in display_list_canvas.cc. |
|
The AutoSaveLayer tracing is definitely missing here. I was under the impression that tracing it in the canvas adapter in display_list_canvas.cc would be duplicating events - e.g. that UI's |
|
canvas.cc records a request that may be executed anywhere from 0 to 1000 times (or more). It is basically throwing stats at the wall. dl_canvas.cc has a 1:1 ratio of times it calls saveLayer to times when we actually do saveLayer work. (The only caveat is that Skia might elide some of them due to culling, but that should be rare and the same thing could be said about any other way of accounting them.) Calling the latter a duplicate doesn't really ring true to me. The naive call site in canvas.cc should be considered the duplicate call site compared to dl_canvas.cc. While it is true that this might leave us with no accounting at all if DL is disabled, when DL is enabled we have a 100% (99.9%?) accurate count. If we were coding for SkPicture, I would count the saveLayer calls while recording and remember them in the Picture and have picture_layer try to do something with that (dl_layer can ignore the count if dl_canvas.cc does the events). If DL remains enabled by default, that code would never get used, though. |
|
Another thing to consider is that calling saveLayer on an SkRecorder canvas might eventually be elided due to peephole optimizers (ignoring how many times the Picture gets used). We eventually want to add a similar capability to DL as well. In that case, calling saveLayer in canvas.cc will literally disappear before it ever gets to the point of asking Skia for real work to be done (and regardless of how many times the Picture is reused). |
|
Part of the goal here is for developers to have a way to know what parts of their application code are resulting in saveLayers. I'm fine with tracing at the The idea here is still not to say "this call is intrinsically expensive," but to say that it will result in expense later and there's something you can do about it. I still believe this tracing/mechanism can be refined further of course, but I do not think we should drop the tracing in canvas.cc. I suspect that rather than tracing when the DisplayListBuilder actually adds it to Skia, we probably want to surface Skia's trace of |
|
Then we should use 2 mechanisms. And how is emitting an event going to accomplish your associativity goal? Events are already something that is delivered asynchronously so I would think it would be really hard to trace an event from the timeline into calls they are making. If you want them to know when saveLayer calls are being used in their widgets, why not have this show up in the widget/RO dumps that they request when debugging the app? |
Yes, that is the plan :) More information is forthcoming.
We're not there yet. But, emitting the event here will mean that when they turn on https://api.flutter.dev/flutter/rendering/debugProfilePaintsEnabled.html, they will see exactly which RenderObject was painting when saveLayer was called. This probably isn't enough though, since |
|
And with this trace, even without turning on that flag for now, @goderbauer and I will be able to more clearly see in CI generated traces on low end phones how many times these events are emitted and whether they're involved in the worst raster times we're seeing. |
|
This is really simple to fix. Change the name of the event in canvas.cc to something indicating that a saveLayer is being recorded. That not only makes it more accurate, it prevents it from being confused with the calls in the raster code which are not the same kind of action. One is recording a request for a call, the other is actually doing the saveLayer. Add 2 event calls to AutoSaveLayer and dl_canvas.cc which will bring the code to nearly 100% accounting for all saveLayers being executed during rasterization. You get all of the utility of having the ui.Canvas calls tagged without having to worry about "duplicate calls which are not duplicates at all and in fact have different countability" while achieving greater accuracy for the "how many saveLayers executed in this frame" justification in the original description. |
|
I drafted the fix as #29598 |
* 422b15a Roll Skia from d9d9e21b311c to a8d38078a4f3 (1 revision) (flutter/engine#29521) * afe1c98 Roll Fuchsia Mac SDK from SfdmlzXiU... to nkHhPcy3q... (flutter/engine#29522) * b7f4651 Roll Fuchsia Linux SDK from 5-RB9TzQH... to m90mMA37b... (flutter/engine#29523) * 15d5a23 [Web] Fix BMP encoder (flutter/engine#29448) * 3f55aec Fix FlutterPresentInfo struct_size doc string (flutter/engine#29524) * b991af9 Roll Skia from a8d38078a4f3 to 7368c6d00b7c (5 revisions) (flutter/engine#29525) * 93666e2 Fix isolate_configuration typo (flutter/engine#29318) * 91033b9 Roll Skia from 7368c6d00b7c to a5030e9090e8 (3 revisions) (flutter/engine#29527) * c2090c2 [iOS] Make sure spawnee's isGpuDisabled is set correctly when FlutterEngine spawn (flutter/engine#29361) * e071f1d Roll Skia from a5030e9090e8 to 37afdbc22e89 (4 revisions) (flutter/engine#29528) * ca1710a Roll Skia from 37afdbc22e89 to a05d3029ac65 (4 revisions) (flutter/engine#29532) * 3364409 Reland Display Features support (Foldable and Cutout) (flutter/engine#29447) * 4684d23 [fuchsia] Add more logging for error cases. (flutter/engine#29397) * 5cf7c39 Remove D3D9 fallback path (flutter/engine#29533) * 98d31de [raster_cache] Increment access_count on Touch (flutter/engine#29529) * cc6fc4a Re-enable A11yTreeIsConsistent with higher timeout (flutter/engine#29367) * fb20916 Roll Skia from a05d3029ac65 to 37da672b14b7 (1 revision) (flutter/engine#29534) * d229ec8 use SkMatrix.invert() instead of MatrixDecomposition to validate cache matrices (flutter/engine#29530) * a92aebb Roll Clang Linux from 5N9a1nYj5... to UtjvZhwws... (flutter/engine#29535) * 47dab8a Roll Dart SDK from 3b11f88c96a5 to f38618d5d0c0 (7 revisions) (flutter/engine#29537) * 83ccad7 FragmentProgram constructed asynchronously (flutter/engine#29513) * 2078baf Roll Fuchsia Linux SDK from m90mMA37b... to Ci-Vji1rx... (flutter/engine#29546) * 6bf8093 Roll Fuchsia Mac SDK from nkHhPcy3q... to emi7COLIo... (flutter/engine#29547) * 290d179 Roll Skia from 37da672b14b7 to cf8daf79e710 (9 revisions) (flutter/engine#29548) * 197ca59 [iOS] Fixes press key message leaks (flutter/engine#29354) * 986b8d8 Roll Skia from cf8daf79e710 to ae67f07a58a2 (1 revision) (flutter/engine#29549) * 11010f0 Roll Skia from ae67f07a58a2 to 17616469ddf8 (1 revision) (flutter/engine#29551) * dadc7b2 Roll Skia from 17616469ddf8 to 4322c7fec7e4 (3 revisions) (flutter/engine#29552) * ed66091 don't build flutter SDK artifacts for armv7 (flutter/engine#28016) * 484cc5c Roll Dart SDK from f38618d5d0c0 to 05febe0a7860 (5 revisions) (flutter/engine#29539) * 387563a Roll Skia from 4322c7fec7e4 to 1800d410df16 (1 revision) (flutter/engine#29553) * 05ceba2 Roll Skia from 1800d410df16 to 725705f6630b (1 revision) (flutter/engine#29555) * 2b142ef Roll Dart SDK from 05febe0a7860 to 38e7078fa2b7 (5 revisions) (flutter/engine#29556) * 29da91f Roll Fuchsia Linux SDK from Ci-Vji1rx... to kHXT3xnTG... (flutter/engine#29557) * da02a4b Roll Fuchsia Mac SDK from emi7COLIo... to 6BYh8qaYo... (flutter/engine#29558) * 71fb575 Roll Skia from 725705f6630b to deb9386be146 (3 revisions) (flutter/engine#29559) * c5f572a [Linux keyboard] Fix logical keys of up events are not regularized (flutter/engine#29550) * 988ea43 Roll Dart SDK from 38e7078fa2b7 to d464cd3f2dc8 (5 revisions) (flutter/engine#29561) * fdee74d Trace calls to Canvas::saveLayer (flutter/engine#29444) * 953f718 ios test script checks for `ios_test_flutter` artifacts (flutter/engine#29554) * 145d890 Roll Skia from deb9386be146 to 37bef2d300e4 (6 revisions) (flutter/engine#29563) * cc9b174 Fix race condition introduced by background platform channels (flutter/engine#29377) * 79b5e3c Roll Dart SDK from d464cd3f2dc8 to 996ef242a2c9 (1 revision) (flutter/engine#29564) * 3eb6e15 fuchsia: Enable integration tests (flutter/engine#29565) * ffa8b25 Roll Skia from 37bef2d300e4 to 2417872a9993 (1 revision) (flutter/engine#29567) * 9af2de9 Roll Dart SDK from 996ef242a2c9 to 5ccf755b37a4 (1 revision) (flutter/engine#29568) * 16d6d18 Roll Fuchsia Linux SDK from kHXT3xnTG... to uP2kJIngK... (flutter/engine#29569) * 321bc56 Roll Fuchsia Mac SDK from 6BYh8qaYo... to W9UXc2Fwx... (flutter/engine#29570) * f0a8d4e Roll Dart SDK from 5ccf755b37a4 to f6a43e5eb71d (1 revision) (flutter/engine#29571) * 0be0303 Hide a11y elements when resigning active (flutter/engine#29566) * 9a3195a Roll Fuchsia Linux SDK from uP2kJIngK... to aD3d4Kqmy... (flutter/engine#29572) * b3cbee5 Roll Fuchsia Mac SDK from W9UXc2Fwx... to rIpW1050J... (flutter/engine#29573) * df686d2 Revert "Reland Display Features support (Foldable and Cutout) (flutter#29447)" (flutter/engine#29574) * e812731 Revert dart to 38e7078fa2b7 (flutter/engine#29575) * 049074e Roll Skia from 2417872a9993 to cd7220e7686c (2 revisions) (flutter/engine#29577) * e6a51a4 Roll Fuchsia Mac SDK from rIpW1050J... to TOmxgL3av... (flutter/engine#29578) * 8f272d9 Roll Fuchsia Linux SDK from aD3d4Kqmy... to ZniYyCw7U... (flutter/engine#29579) * 469d6f1 Revert "[Web] Fix BMP encoder (flutter#29448)" (flutter/engine#29580)
These calls tend to be expensive on rasterization. Adding traces can make it easier to tell how many times they're happening per frame on expensive-to-rasterize frames
Fixes flutter/flutter#92840
/cc @kenzieschmoll @jacob314