[Public WebGL] Updating the Spec W.R.T. preserveDrawingBuffer = false

Gregg Tavares [email protected]
Fri Jun 7 00:05:58 PDT 2013

I think we should revisit or maybe just clarify the spec with regards to
what happens when you call a function that uses the contents of a canvas.

The specific functions are

  context2d.drawImage(canvas, ...);
  gl.texImage2D(...., canvas)
  gl.texSubImage2D(..., canvas);

The current text of the spec says

WebGL presents its drawing buffer to the HTML page compositor immediately
before a compositing operation, but only if clear, drawArrays or
drawElements have been called since the last compositing operation, while
the drawing buffer is the currently bound framebuffer. Before the drawing
buffer is presented for compositing the implementation shall ensure that
all rendering operations have been flushed to the drawing buffer. *By
default, after compositing the contents of the drawing buffer shall be
cleared to their default values, as shown in the table above.*

This default behavior can be changed by setting the preserveDrawingBuffer
attribute of the WebGLContextAttributes object. If this flag is true, the
contents of the drawing buffer shall be preserved until the author either
clears or overwrites them.* If this flag is false, attempting to perform
operations using this context as a source image after the rendering
function has returned can lead to undefined behavior. This includes
readPixels or toDataURL calls, or using this context as the source image of
another context's texImage2D or drawImage call.*

I'd like to suggest it does not make a lot of scene to have this undefined.
Specifically I think toDataURL, drawImage and texImage2D should change so
that until drawing commands are issued after a composite the pixels being
composited will be used.

It seems strange that I can fill a canvas with pixels. Once filled with
pixels I can transform it, rotate it, move it around in the DOM. I can even
print it. But if I ask what's in it with one of those 4 functions it will
tell me "0,0,0,0"

To be more specific I'm suggesting every canvas effectively has a
"drawing_buffer_to_copy_from" reference to a DrawingBuffer. When a draw
command is issued "drawing_buffer_to_copy_from" is set to the DrawingBuffer
being drawn to. (the back buffer)

If preserveDrawingBuffer = false then when compositing happens conceptually
DrawingBuffers are swapped. "drawing_buffer_to_copy_from" is NOT updated to
point to the new buffer (it's only updated by calling a drawing function).

This means until a drawing function is called,
toDataURL/drawImage/texImage2D would give the contents of the canvas.

readPixels on the other hand always gives data from the current
DrawingBuffer so its behavior would not change. The DrawingBuffers are
swapped at composite time. readPixels always reads from the current
DrawingBuffer (backbuffer).

It seems like this would make more intuitive sense. If I see a canvas on
the screen with an image in and I use it with one of those 4 functions I'll
get what I see.

This would also enable screenshot apis to work with WebGL. Currently they
can't work without co-operation from the app. For example this one

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://khronos.org/pipermail/public_webgl_khronos.org/attachments/20130607/b9c83e9e/attachment.html>

More information about the public_webgl mailing list