[CP-beta][skwasm] Use queueMicrotask instead of postMessage when single-threaded (#167154)

This pull request is created by [automatic cherry pick workflow](https://github.com/flutter/flutter/blob/main/docs/releases/Flutter-Cherrypick-Process.md#automatically-creates-a-cherry-pick-request)

### Issue Link:
https://github.com/flutter/flutter/issues/166905

### Changelog Description:
* [flutter/166905](https://github.com/flutter/flutter/issues/166905) Fixes a performance regression in skwasm when running in single-threaded mode.

### Impact Description:
This fixes a significant regression in the skwasm renderer when running single-thraaded (i.e. in a non-`crossOriginIsolated` browsing context)

### Workaround:
Is there a workaround for this issue?

The only workaround is to run skwasm in a multi-threaded context or to disable skwasm.

### Risk:
What is the risk level of this cherry-pick?

  - [ x ] Low

This essentially returns the single-threaded renderer to the previous message passing strategy.

### Test Coverage:
Are you confident that your fix is well-tested by automated tests?

  - [ x ] Yes

### Validation Steps:
What are the steps to validate that this fix works?

Built the Wonderous app and take a Chrome profile.
This commit is contained in:
flutteractionsbot 2025-04-15 18:09:26 -07:00 committed by GitHub
parent eeb81b9a8a
commit 2cf78c5583
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -8,6 +8,30 @@
mergeInto(LibraryManager.library, {
$skwasm_support_setup__postset: 'skwasm_support_setup();',
$skwasm_support_setup: function() {
if (Module["skwasmSingleThreaded"]) {
_skwasm_isSingleThreaded = function() {
return true;
};
let messageListener;
// In single threaded mode, we simply invoke the message listener as a
// microtask, as it's much cheaper than doing a full postMessage
skwasm_registerMessageListener = function(threadId, listener) {
messageListener = listener;
}
skwasm_getCurrentTimestamp = function() {
return performance.now();
};
skwasm_postMessage = function(message, transfers, threadId) {
// If we're in single-threaded mode, we shouldn't use postMessage, as
// it ends up being quite expensive. Instead, just queue a microtask.
queueMicrotask(() => messageListener(message));
};
} else {
_skwasm_isSingleThreaded = function() {
return false;
};
// This value represents the difference between the time origin of the main
// thread and whichever web worker this code is running on. This is so that
// when we report frame timings, that they are in the same time domain
@ -41,18 +65,15 @@ mergeInto(LibraryManager.library, {
};
skwasm_postMessage = function(message, transfers, threadId) {
if (threadId) {
_wasmWorkers[threadId].postMessage(message, transfers);
_wasmWorkers[threadId].postMessage(message, { transfer: transfers } );
} else {
postMessage(message, transfers);
postMessage(message, { transfer: transfers });
}
};
}
const handleToCanvasMap = new Map();
const associatedObjectsMap = new Map();
_skwasm_isSingleThreaded = function() {
return Module["skwasmSingleThreaded"];
};
_skwasm_setAssociatedObjectOnThread = function(threadId, pointer, object) {
skwasm_postMessage({
skwasmMessage: 'setAssociatedObject',