A user account is required in order to edit this wiki, but we've had to disable public user registrations due to spam.
To request an account, ask an autoconfirmed user on Chat (such as one of these permanent autoconfirmed members).
OffscreenCanvas: Difference between revisions
(→Web IDL: use promise) |
Kenrussell (talk | contribs) (→Web IDL: Updated Web IDL with results of WebGL working group discussion) |
||
Line 34: | Line 34: | ||
== Web IDL == | == Web IDL == | ||
[Constructor(unsigned long width, unsigned long height)] | [Constructor(unsigned long width, unsigned long height), | ||
Exposed=(Window,Worker)] | |||
interface WorkerCanvas { | interface WorkerCanvas { | ||
attribute unsigned long width; | attribute unsigned long width; | ||
attribute unsigned long height; | attribute unsigned long height; | ||
RenderingContext? getContext(DOMString contextId, any... arguments); | RenderingContext? getContext(DOMString contextId, any... arguments); | ||
Promise<Blob> toBlob(optional DOMString type, any... arguments); | Promise<Blob> toBlob(optional DOMString type, any... arguments); | ||
ImageBitmap transferToImageBitmap(); | ImageBitmap transferToImageBitmap(); | ||
}; | }; | ||
Line 50: | Line 51: | ||
}; | }; | ||
// The new ImageBitmapRenderingContext is a canvas rendering context | |||
void | // which only provides the functionality to replace the canvas's | ||
// contents with the given ImageBitmap. Its context id (the first argument | |||
// to getContext) is "bitmaprenderer". | |||
[Exposed=(Window,Worker)] | |||
interface ImageBitmapRenderingContext { | |||
// Displays the given ImageBitmap in the canvas associated with this | |||
// rendering context. Ownership of the ImageBitmap is transferred to | |||
// the canvas. The caller may not use its reference to the ImageBitmap | |||
// after making this call. (This semantic is crucial to enable prompt | |||
// reclamation of expensive graphics resources, rather than relying on | |||
// garbage collection to do so.) | |||
// | |||
// The ImageBitmap conceptually replaces the canvas's bitmap, but | |||
// it does not change the canvas's intrinsic width or height. | |||
// | |||
// The ImageBitmap, when displayed, is clipped to the rectangle | |||
// defined by the canvas's instrinsic width and height. Pixels that | |||
// would be covered by the canvas's bitmap which are not covered by | |||
// the supplied ImageBitmap are rendered transparent black. Any CSS | |||
// styles affecting the display of the canvas are applied as usual. | |||
void transferImageBitmap(ImageBitmap bitmap); | |||
}; | }; | ||
Revision as of 02:46, 7 April 2015
- Provides more control over how canvases are rendered. This is a follow-on to the WorkerCanvas proposal and will be merged once agreement is reached.
Use Case Description
Feedback from web application authors using canvases have shown the need for the following controls:
- (From ShaderToy, Sketchfab, Verold): need to be able to render to multiple regions on the page efficiently using a single canvas context. 3D model warehouse sites desire to show multiple live interactive models on the page, but creating multiple WebGL contexts per page is too inefficient. A single context should be able to render to multiple regions on the page.
- (From Google Maps): need to be able to render WebGL from a worker, transfer the rendered image to the main thread without making any copy of it, and composite it with other HTML on the page, guaranteeing that the updates are all seen in the same rendered frame.
- (From Mozilla and partners using Emscripten and asm.js): need to be able to render WebGL entirely asynchronously from a worker, displaying the results in a canvas owned by the main thread, without any synchronization with the main thread. In this mode, the entire application runs in the worker. The main thread only receives input events and sends them to the worker for processing.
- (From adopters of the Push API): need to be able to dynamically create images to use as notification icons, such as compositing avatars, or adding an unread count
Current Limitations
- CanvasProxy does not provide sufficient control to allow synchronization between workers' rendering and DOM updates on the main thread. Keeping this rendering in sync is a requirement from Google's Maps team.
- CanvasInWorkers does not allow a worker to render directly into a canvas on the main thread without running code on the main thread. Allowing completely unsynchronized rendering is a requirement from Mozilla and users of Emscripten such as Epic Games and Unity, in which the desire is to execute all of the game's rendering on a worker thread.
- WorkerCanvas addresses these two use cases, but the specific mechanism for displaying the rendering results (in image elements) was not palatable to some implementers in recent face-to-face meetings.
Current Usage and Workarounds
WebGL in Web Workers details some work attempted in the Emscripten toolchain to address the lack of WebGL in workers. Due to the high volume of calls and large amount of data that is transferred to the graphics card in a typical high-end WebGL application, this approach is not sustainable. It's necessary for workers to be able to call the WebGL API directly, and present those results to the screen in a manner that does not introduce any copies of the rendering results.
Benefits
Making canvas rendering contexts available to workers will increase parallelism in web applications, leading to increased performance on multi-core systems.
Requests for this Feature
See the abovementioned use cases:
- Google's Maps team
- Emscripten users such as Epic Games and Unity
- Many others
Web IDL
[Constructor(unsigned long width, unsigned long height), Exposed=(Window,Worker)] interface WorkerCanvas { attribute unsigned long width; attribute unsigned long height; RenderingContext? getContext(DOMString contextId, any... arguments); Promise<Blob> toBlob(optional DOMString type, any... arguments); ImageBitmap transferToImageBitmap(); }; WorkerCanvas implements Transferable; ImageBitmap implements Transferable; partial interface HTMLCanvasElement { WorkerCanvas transferControlToWorker(); }; // The new ImageBitmapRenderingContext is a canvas rendering context // which only provides the functionality to replace the canvas's // contents with the given ImageBitmap. Its context id (the first argument // to getContext) is "bitmaprenderer". [Exposed=(Window,Worker)] interface ImageBitmapRenderingContext { // Displays the given ImageBitmap in the canvas associated with this // rendering context. Ownership of the ImageBitmap is transferred to // the canvas. The caller may not use its reference to the ImageBitmap // after making this call. (This semantic is crucial to enable prompt // reclamation of expensive graphics resources, rather than relying on // garbage collection to do so.) // // The ImageBitmap conceptually replaces the canvas's bitmap, but // it does not change the canvas's intrinsic width or height. // // The ImageBitmap, when displayed, is clipped to the rectangle // defined by the canvas's instrinsic width and height. Pixels that // would be covered by the canvas's bitmap which are not covered by // the supplied ImageBitmap are rendered transparent black. Any CSS // styles affecting the display of the canvas are applied as usual. void transferImageBitmap(ImageBitmap bitmap); };
Proposed Solutions
My Solution
- Brief description of the solution and of how it address the problem at hand.
Processing Model
- Explanation of the changes introduced by this solution. It explains how the document is processed, and how errors are handled. This should be very clear, including things such as event timing if the solution involves events, how to create graphs representing the data in the case of semantic proposals, etc.
Limitations
- Cases not covered by this solution in relation to the problem description; other problems with this solution, if any.
Implementation
- Description of how and why browser vendors would take advantage of this feature.
Adoption
- Reasons why page authors would use this solution.