Skip to content

Commit

Permalink
Properly transfer objects between the main thread and web worker. (#4…
Browse files Browse the repository at this point in the history
…6061)

We need to make sure to add objects to the transfer list when we send them across the ui thread/web worker boundary. Otherwise, they get copied, which is very expensive.

On my M1 MacBook Pro, I took measurements of scrolling in the material 3 demo. Before this change, the work on the web worker thread was taking about 25-40ms per frame. After the change, it's around 2ms.
  • Loading branch information
eyebrowsoffire authored Sep 19, 2023
1 parent 3171f20 commit 556c613
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 7 deletions.
13 changes: 7 additions & 6 deletions lib/web_ui/skwasm/library_skwasm_support.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ mergeInto(LibraryManager.library, {
skwasmMessage: 'setAssociatedObject',
pointer,
object,
});
}, [object]);
};
_skwasm_getAssociatedObject = function(pointer) {
return associatedObjectsMap.get(pointer);
Expand All @@ -34,11 +34,12 @@ mergeInto(LibraryManager.library, {
associatedObjectsMap.set(data.pointer, data.object);
return;
case 'disposeAssociatedObject':
const object = { data };
const pointer = data.pointer;
const object = associatedObjectsMap.get(pointer);
if (object.close) {
object.close();
}
associatedObjectsMap.delete(data.pointer);
associatedObjectsMap.delete(pointer);
return;
default:
console.warn(`unrecognized skwasm message: ${skwasmMessage}`);
Expand Down Expand Up @@ -81,7 +82,7 @@ mergeInto(LibraryManager.library, {
surface: surfaceHandle,
callbackId,
imageBitmap,
});
}, [imageBitmap]);
};
_skwasm_createGlTextureFromTextureSource = function(textureSource, width, height) {
const glCtx = GL.currentContext.GLctx;
Expand All @@ -98,10 +99,10 @@ mergeInto(LibraryManager.library, {
GL.textures[textureId] = newTexture;
return textureId;
};
_skwasm_disposeAssociatedObjectOnThread = function(threadId, object) {
_skwasm_disposeAssociatedObjectOnThread = function(threadId, pointer) {
PThread.pthreads[threadId].postMessage({
skwasmMessage: 'disposeAssociatedObject',
object,
pointer,
});
};
},
Expand Down
12 changes: 11 additions & 1 deletion lib/web_ui/test/ui/image_golden_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -319,7 +319,17 @@ Future<void> testMain() async {
await completer.future;

final DomImageBitmap bitmap = (await createImageBitmap(image).toDart)! as DomImageBitmap;
return renderer.createImageFromImageBitmap(bitmap);

expect(bitmap.width.toDartInt, 150);
expect(bitmap.height.toDartInt, 150);
final ui.Image uiImage = await renderer.createImageFromImageBitmap(bitmap);

if (isSkwasm) {
// Skwasm transfers the bitmap to the web worker, so it should be disposed/consumed.
expect(bitmap.width.toDartInt, 0);
expect(bitmap.height.toDartInt, 0);
}
return uiImage;
});
}

Expand Down

0 comments on commit 556c613

Please sign in to comment.