Действительно, вы не можете передать ArrayBuffer, который используется внутри WebAssembly, через postMessage() с опцией transfer. Это происходит потому, что в этом случае браузер пытается оторвать буфер от исходного контекста и присоединить его к новому контексту (в данном случае, от worker'а к основному потоку). Однако ArrayBuffer, связанный с памятью, используемой внутри WebAssembly, не может быть оторван и перенесен в другой контекст.
Есть несколько вариантов, как можно передать данные между основным потоком и worker'ом без копирования.
1. Использовать SharedArrayBuffer вместо ArrayBuffer. Однако, как вы уже заметили, у SharedArrayBuffer есть ограничения на использование в некоторых браузерах. Кроме того, не все платформы поддерживают SharedArrayBuffer (например, некоторые мобильные устройства iOS). Чтобы использовать SharedArrayBuffer в вашем случае, вы можете создать его в основном потоке и передать его в worker через postMessage(). Затем вы можете использовать этот SharedArrayBuffer внутри вашего WebAssembly модуля.
2. Вы можете использовать Transferable Objects для передачи данных без копирования. В вашем случае, если память внутри WebAssembly модуля уже инициализирована, вы можете передать указатель на начало памяти через Transferable Objects. Например:
Основной поток:
const mem = instance.exports.memory.buffer;
const ptr = instance.exports.getPixelDataPtr();
worker.postMessage({mem, ptr}, [mem]);
Web Worker:
self.onmessage = (event) => {
const {mem, ptr} = event.data;
const pixels = new Uint8Array(mem, ptr, numPixels * 4);
// делаем что-то с пикселями
}
В этом случае, вы передаете указатель на начало памяти вместе с буфером, но не копируете саму память. Вы можете использовать TypedArray для доступа к данным в памяти. Обратите внимание, что в вашем WebAssembly модуле должна быть функция, которая возвращает указатель на начало памяти, который вы можете передать в worker.
Однако, если вы измените данные в памяти на стороне worker'а, эти изменения не будут отражены в памяти, используемой внутри WebAssembly модуля.