[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:
parent
eeb81b9a8a
commit
2cf78c5583
@ -8,51 +8,72 @@
|
|||||||
mergeInto(LibraryManager.library, {
|
mergeInto(LibraryManager.library, {
|
||||||
$skwasm_support_setup__postset: 'skwasm_support_setup();',
|
$skwasm_support_setup__postset: 'skwasm_support_setup();',
|
||||||
$skwasm_support_setup: function() {
|
$skwasm_support_setup: function() {
|
||||||
// This value represents the difference between the time origin of the main
|
if (Module["skwasmSingleThreaded"]) {
|
||||||
// thread and whichever web worker this code is running on. This is so that
|
_skwasm_isSingleThreaded = function() {
|
||||||
// when we report frame timings, that they are in the same time domain
|
return true;
|
||||||
// regardless of whether they are captured on the main thread or the web
|
|
||||||
// worker.
|
|
||||||
let timeOriginDelta = 0;
|
|
||||||
skwasm_registerMessageListener = function(threadId, listener) {
|
|
||||||
const eventListener = function({data}) {
|
|
||||||
const skwasmMessage = data.skwasmMessage;
|
|
||||||
if (!skwasmMessage) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (skwasmMessage == 'syncTimeOrigin') {
|
|
||||||
timeOriginDelta = performance.timeOrigin - data.timeOrigin;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
listener(data);
|
|
||||||
};
|
};
|
||||||
if (!threadId) {
|
|
||||||
addEventListener("message", eventListener);
|
let messageListener;
|
||||||
} else {
|
// In single threaded mode, we simply invoke the message listener as a
|
||||||
_wasmWorkers[threadId].addEventListener("message", eventListener);
|
// microtask, as it's much cheaper than doing a full postMessage
|
||||||
_wasmWorkers[threadId].postMessage({
|
skwasm_registerMessageListener = function(threadId, listener) {
|
||||||
skwasmMessage: 'syncTimeOrigin',
|
messageListener = listener;
|
||||||
timeOrigin: performance.timeOrigin,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
};
|
skwasm_getCurrentTimestamp = function() {
|
||||||
skwasm_getCurrentTimestamp = function() {
|
return performance.now();
|
||||||
return performance.now() + timeOriginDelta;
|
};
|
||||||
};
|
skwasm_postMessage = function(message, transfers, threadId) {
|
||||||
skwasm_postMessage = function(message, transfers, threadId) {
|
// If we're in single-threaded mode, we shouldn't use postMessage, as
|
||||||
if (threadId) {
|
// it ends up being quite expensive. Instead, just queue a microtask.
|
||||||
_wasmWorkers[threadId].postMessage(message, transfers);
|
queueMicrotask(() => messageListener(message));
|
||||||
} else {
|
};
|
||||||
postMessage(message, transfers);
|
} 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
|
||||||
|
// regardless of whether they are captured on the main thread or the web
|
||||||
|
// worker.
|
||||||
|
let timeOriginDelta = 0;
|
||||||
|
skwasm_registerMessageListener = function(threadId, listener) {
|
||||||
|
const eventListener = function({data}) {
|
||||||
|
const skwasmMessage = data.skwasmMessage;
|
||||||
|
if (!skwasmMessage) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (skwasmMessage == 'syncTimeOrigin') {
|
||||||
|
timeOriginDelta = performance.timeOrigin - data.timeOrigin;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
listener(data);
|
||||||
|
};
|
||||||
|
if (!threadId) {
|
||||||
|
addEventListener("message", eventListener);
|
||||||
|
} else {
|
||||||
|
_wasmWorkers[threadId].addEventListener("message", eventListener);
|
||||||
|
_wasmWorkers[threadId].postMessage({
|
||||||
|
skwasmMessage: 'syncTimeOrigin',
|
||||||
|
timeOrigin: performance.timeOrigin,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
skwasm_getCurrentTimestamp = function() {
|
||||||
|
return performance.now() + timeOriginDelta;
|
||||||
|
};
|
||||||
|
skwasm_postMessage = function(message, transfers, threadId) {
|
||||||
|
if (threadId) {
|
||||||
|
_wasmWorkers[threadId].postMessage(message, { transfer: transfers } );
|
||||||
|
} else {
|
||||||
|
postMessage(message, { transfer: transfers });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
const handleToCanvasMap = new Map();
|
const handleToCanvasMap = new Map();
|
||||||
const associatedObjectsMap = new Map();
|
const associatedObjectsMap = new Map();
|
||||||
|
|
||||||
_skwasm_isSingleThreaded = function() {
|
|
||||||
return Module["skwasmSingleThreaded"];
|
|
||||||
};
|
|
||||||
_skwasm_setAssociatedObjectOnThread = function(threadId, pointer, object) {
|
_skwasm_setAssociatedObjectOnThread = function(threadId, pointer, object) {
|
||||||
skwasm_postMessage({
|
skwasm_postMessage({
|
||||||
skwasmMessage: 'setAssociatedObject',
|
skwasmMessage: 'setAssociatedObject',
|
||||||
|
Loading…
x
Reference in New Issue
Block a user