[skwasm] Use transferToImageBitmap
instead of createImageBitmap
(#163251)
Harry had investigated that on the CanvasKit side, that this was a bit a faster than the `createImageBitmap` approach when dealing with multiple DOM canvases. Also, it appears that Safari is significantly faster at `transferToImageBitmap` compared to `createImageBitmap`, so this might make porting skwasm to Safari a bit more feasible. Either way, we should validate the performance and make sure this doesn't actually make anything slower.
This commit is contained in:
parent
9ffdd3a0ec
commit
7d22606cda
@ -113,14 +113,13 @@ mergeInto(LibraryManager.library, {
|
||||
canvas.width = width;
|
||||
canvas.height = height;
|
||||
};
|
||||
_skwasm_captureImageBitmap = function(contextHandle, width, height, imagePromises) {
|
||||
if (!imagePromises) imagePromises = Array();
|
||||
_skwasm_captureImageBitmap = function(contextHandle, images) {
|
||||
if (!images) images = Array();
|
||||
const canvas = handleToCanvasMap.get(contextHandle);
|
||||
imagePromises.push(createImageBitmap(canvas, 0, 0, width, height));
|
||||
return imagePromises;
|
||||
images.push(canvas.transferToImageBitmap());
|
||||
return images;
|
||||
};
|
||||
_skwasm_resolveAndPostImages = async function(surfaceHandle, imagePromises, rasterStart, callbackId) {
|
||||
const imageBitmaps = imagePromises ? await Promise.all(imagePromises) : [];
|
||||
_skwasm_postImages = async function(surfaceHandle, imageBitmaps, rasterStart, callbackId) {
|
||||
const rasterEnd = skwasm_getCurrentTimestamp();
|
||||
skwasm_postMessage({
|
||||
skwasmMessage: 'onRenderComplete',
|
||||
@ -136,7 +135,7 @@ mergeInto(LibraryManager.library, {
|
||||
const newTexture = glCtx.createTexture();
|
||||
glCtx.bindTexture(glCtx.TEXTURE_2D, newTexture);
|
||||
glCtx.pixelStorei(glCtx.UNPACK_PREMULTIPLY_ALPHA_WEBGL, true);
|
||||
|
||||
|
||||
glCtx.texImage2D(glCtx.TEXTURE_2D, 0, glCtx.RGBA, width, height, 0, glCtx.RGBA, glCtx.UNSIGNED_BYTE, textureSource);
|
||||
|
||||
glCtx.pixelStorei(glCtx.UNPACK_PREMULTIPLY_ALPHA_WEBGL, false);
|
||||
@ -193,8 +192,8 @@ mergeInto(LibraryManager.library, {
|
||||
skwasm_resizeCanvas__deps: ['$skwasm_support_setup'],
|
||||
skwasm_captureImageBitmap: function () {},
|
||||
skwasm_captureImageBitmap__deps: ['$skwasm_support_setup'],
|
||||
skwasm_resolveAndPostImages: function () {},
|
||||
skwasm_resolveAndPostImages__deps: ['$skwasm_support_setup'],
|
||||
skwasm_postImages: function () {},
|
||||
skwasm_postImages__deps: ['$skwasm_support_setup'],
|
||||
skwasm_createGlTextureFromTextureSource: function () {},
|
||||
skwasm_createGlTextureFromTextureSource__deps: ['$skwasm_support_setup'],
|
||||
skwasm_dispatchDisposeSurface: function() {},
|
||||
@ -204,4 +203,3 @@ mergeInto(LibraryManager.library, {
|
||||
skwasm_postRasterizeResult: function() {},
|
||||
skwasm_postRasterizeResult__deps: ['$skwasm_support_setup'],
|
||||
});
|
||||
|
@ -28,13 +28,11 @@ extern void skwasm_dispatchRenderPictures(unsigned long threadId,
|
||||
extern uint32_t skwasm_createOffscreenCanvas(int width, int height);
|
||||
extern void skwasm_resizeCanvas(uint32_t contextHandle, int width, int height);
|
||||
extern SkwasmObject skwasm_captureImageBitmap(uint32_t contextHandle,
|
||||
int width,
|
||||
int height,
|
||||
SkwasmObject imagePromises);
|
||||
extern void skwasm_resolveAndPostImages(Skwasm::Surface* surface,
|
||||
SkwasmObject imagePromises,
|
||||
double rasterStart,
|
||||
uint32_t callbackId);
|
||||
extern void skwasm_postImages(Skwasm::Surface* surface,
|
||||
SkwasmObject imageBitmaps,
|
||||
double rasterStart,
|
||||
uint32_t callbackId);
|
||||
extern unsigned int skwasm_createGlTextureFromTextureSource(
|
||||
SkwasmObject textureSource,
|
||||
int width,
|
||||
|
@ -99,9 +99,9 @@ void Surface::_init() {
|
||||
|
||||
// Worker thread only
|
||||
void Surface::_resizeCanvasToFit(int width, int height) {
|
||||
if (!_surface || width > _canvasWidth || height > _canvasHeight) {
|
||||
_canvasWidth = std::max(width, _canvasWidth);
|
||||
_canvasHeight = std::max(height, _canvasHeight);
|
||||
if (!_surface || width != _canvasWidth || height != _canvasHeight) {
|
||||
_canvasWidth = width;
|
||||
_canvasHeight = height;
|
||||
_recreateSurface();
|
||||
}
|
||||
}
|
||||
@ -124,7 +124,7 @@ void Surface::renderPicturesOnWorker(sk_sp<SkPicture>* pictures,
|
||||
double rasterStart) {
|
||||
// This is populated by the `captureImageBitmap` call the first time it is
|
||||
// passed in.
|
||||
SkwasmObject imagePromiseArray = __builtin_wasm_ref_null_extern();
|
||||
SkwasmObject imageBitmapArray = __builtin_wasm_ref_null_extern();
|
||||
for (int i = 0; i < pictureCount; i++) {
|
||||
sk_sp<SkPicture> picture = pictures[i];
|
||||
SkRect pictureRect = picture->cullRect();
|
||||
@ -138,11 +138,9 @@ void Surface::renderPicturesOnWorker(sk_sp<SkPicture>* pictures,
|
||||
canvas->drawColor(SK_ColorTRANSPARENT, SkBlendMode::kSrc);
|
||||
canvas->drawPicture(picture, &matrix, nullptr);
|
||||
_grContext->flush(_surface.get());
|
||||
imagePromiseArray =
|
||||
skwasm_captureImageBitmap(_glContext, roundedOutRect.width(),
|
||||
roundedOutRect.height(), imagePromiseArray);
|
||||
imageBitmapArray = skwasm_captureImageBitmap(_glContext, imageBitmapArray);
|
||||
}
|
||||
skwasm_resolveAndPostImages(this, imagePromiseArray, rasterStart, callbackId);
|
||||
skwasm_postImages(this, imageBitmapArray, rasterStart, callbackId);
|
||||
}
|
||||
|
||||
// Worker thread only
|
||||
|
Loading…
x
Reference in New Issue
Block a user