partial interface GPUDevice {
GPUSurface createSurface(GPUSurfaceDescriptor descriptor);
};
interface GPUSurface : GPUTexture {
ImageBitmap transferToImageBitmap();
};
dictionary GPUSurfaceDescriptor : GPUObjectDescriptorBase {
ImageBitmapRenderingContext context;
GPUExtent3D size;
required GPUTextureFormat format;
GPUTextureUsageFlags usage = 0x10; // GPUTextureUsage.OUTPUT_ATTACHMENT
};Either context or size is required (not both).
If context is specified, then its canvas's size is used.
The surface may be optimized for display to that canvas.
Note:
For example, this may mean the surface points at an image in an IDXGISwapChain created for this canvas.
However, such optimizations are not observable.
An ImageBitmap created from a GPUSurface can be used just like any other ImageBitmap, regardless of the context specified.
The ImageBitmapRenderingContext can still receive any ImageBitmap.
Internally, any necessary copies-on-write or moves-on-write will occur.
For example, on D3D12/DXGI, with a canvas that has had control transferred to an OffscreenCanvas,
and an ImageBitmapRenderingContext ibrc created from it:
- A
GPUSurfacescould be allocated inside a swap chain buffer. - An
ImageBitmapibcreated fromswould still point at the same allocation.
If this is done, then:
- Transferring
ibintoibrcwould cause a swap chain present. - Transferring another unrelated
ImageBitmap,ib2, intoibrcwould causeibto be moved into a new backing store andib2to be copied into the swap chain and presented. - Consuming
ibin another way would cause the swap chain buffer to be freed for reuse by another surface. - Using
ibin a non-consuming way would just read-back from its allocation in the swap chain buffer. - Creating another
GPUSurfaces2would do a normal allocation (not inside the swap chain buffer, because that space is already used).
Any deoptimization cases could issue warnings.
Also note that any canvas which is synchronized with DOM rendering (i.e. any non-transferred-to-offscreen canvas)
cannot be presented via IDXGISwapChain, because IDXGISwapChain::Present does not guarantee which frame the result will appear on.
[1] refers to the "swap chain's zero-index buffer", which seems to be wrong with D3D12 since it doesn't renumber the swap chain buffers on present.
[3] says that only FLIP_SEQUENTIAL can be used, but we are using DISCARD already in Dawn.
Austin's alternative idea:
requestNextTextureis sort of likerequestAnimationFramein that it calls the provided callback when theGPUSurfacehas the next swapchain image available. If an application does not present frames and theGPUSurfaceis backed by a native swapchain, then it will not callrequestNextTextureuntil swapchain images are presented or detached.Unlike
requestAnimationFrame,requestNextTexturemay call the callback inline immediately if there is a swapchain image available.Advantages
Applications can always stay on the fast path for presentation. The
requestNextTexturecallback allows applications to record frames ahead of time and decouples GPU command execution from presentation.Disadvantages
It's harder for an application to do rendering that is not tied to a swapchain. ex.) Rendering to 10 ImageBitmaps to transfer to image elements.
Simple usage:
Advanced Usage: