User:Roc/ScreenCaptureAPI
Screen Capture API
Add an API to <iframe> that takes a screenshot asynchronously:
Promise createScreenshot();
The Promise returns an ImageBitmap. This can be transferred to an HTMLImageElement (see [[1]]) for rendering. It can also be drawn to a 2D canvas for postprocessing; e.g. the data retrieved by JS using getImageData or converted to an encoded image (off the main thread) using canvas.toBlob. More APIs can be added to ImageBitmap if necessary.
The ImageBitmap size is not easily predictable since it depends on the size of the <iframe> after zooming. It will be a snapshot of what is visible in the <iframe>'s viewport (including the scrollbar, if any), some time between requesting and receiving the screenshot.
Implementation
createScreenshot forces construction of a layer in the subdocument frame if there isn't already one. It allocates a screenshot request ID and attaches the request to the layer. Display list construction sets up dirty rects to ensure that everything in the iframe's viewport is considered visible. The request ID is transmitted to the compositor using layers IPC. We should probably only support one screenshot request on a layer at a time, to simplify things.
When the compositor sees a screenshot request on a layer, it forces construction of an intermediate surface for the layer. Content is composited to the layer. Instead of destroying the intermediate surface, we save it to a list. At the end of composition, we do some IPC magic to transfer ownership of the intermediate surfaces to the IPC client owning the screenshot request. The surface is exposed to the layers client as a layers Image in the callback reply to the screenshot request.
The layers Image is wrapped in a DOM ImageBitmap and used to fulfill the Promise.