Skip to content

Switch the WebGPU Canvas Interop to be WebGPU first #53

Description

@greggman

IIUC, there is a proposal to allow canvas to transferToWebGPU

This seems like it has several issues.

  • The canvas might not be compatible with the WebGPU device. In this case, a copy is needed to transfer the canvas's contents into the WebGPU device and back.
  • The canvas might be the wrong texture format. (app can't choose like it can with WebGPU)
  • The canvas format might change on each transfer requiring the app to be built around checking and remaking resources on demand. (Mozilla confirmed this is an issue)
  • Setting the canvas.width,height after transferring to WebGPU is strange.
  • Texture management is too magic.

Instead of starting with canvas2d and transfering to WebGPU, would it be better to start with WebGPU and transfer to canvas 2d?

const device = await (await navigator.gpu.requestAdapter()).requestDevice({
  canvas2DCompatible: true,  // Give the implementataion a chance to
                             // add any features it needs the device to have
));

// Create a 2D context for this device
const ctx = CanvasRenderingContext2D.createFromWebGPUDevice(device);

// Make textures in WebGPU as normal
const texture = device.createTexture({
  size: [200, 300],
  format: 'rgba8unorm',
  usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.TEXTURE_BINDING,
});

// Draw to a texture using the 2D context
ctx.transferWebGPUTextureToContext(texture);  // texture is now unusable by WebGPU
ctx.beginPath();
ctx.arc(100, 150, 75, 0, Math.PI * 2);
ctx.fill();
ctx.removeWebGPUTextureFromContext();  // texture is now usable by WebGPU again and 2d draw commands submitted. (maybe this should take device or device.queue)

Advantages:

  • Can draw to any texture in supported formats. Not just some magic canvas texture but any texture created by WebGPU (assuming the format is compatible with the 2d rendering context API)
  • texture ownership is clear. The WebGPU app owns the texture
  • displaying the texture works as normal. Call webgpuContext.getCurrentTexture() if you want a texture displayed in a canvas then transfer it to the context.
  • No copy is ever needed. Since the WebGPU app is making the textures they're guarenteed to be compatible with the device.
  • No sizing issues. (the ctx is not connected to a canvas so you can't change the size)
  • No magic

I'm not saying the above API is perfect. I'm just trying to throw out the ideas that it might be more useful to start at WebGPU instead of starting at Canvas2D. In particular, being able to render to any texture, not just a "canvas texture" seems useful. It also seems like a more interesting model, that a Canvas2DRenderingContext is just a API that draws to a texture, any texture, not just canvas blessed textures.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions