[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Public WebGL] inconsistent clear behavior for preserveDrawingBuffer: false (the default)

On Sat, Jun 9, 2012 at 6:50 AM, Benoit Jacob <bjacob@mozilla.com> wrote:

On Fri, Jun 1, 2012 at 2:14 PM, Benoit Jacob <bjacob@mozilla.com> wrote:

I was trying to repo an error mentioned in another thread

Here's my test

The spec says

WebGL presents its drawing buffer to the HTML page compositor immediately before a compositing operation, but only if the drawing buffer has been modified since the last compositing operation. 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.

In the sample I clear the drawing buffer to green. Then 1 second later I issue some GL commands to see what happens.  These 6 commands should not effect what is displayed

        gl.bindTexture(gl.TEXTURE_2D, gl.createTexture());
        gl.bindFramebuffer(gl.FRAMEBUFFER, null);
        var p = new Uint8Array(4);
        gl.readPixels(0,0,1,1,gl.RGBA,gl.UNSIGNED_BYTE, p);

What I find is Firefox ends up reflecting that the backbuffer has been cleared if I call gl.readPixels. On other words it recomposites the page with the cleared drawing buffer. As far as I can tell from the spec that's a bug. The drawing buffer has not been modified so  it should not be composited again.
In Mozilla's implementation, readPixel checks if the backbuffer needs a clear (which is the case if preserveDrawingBuffer is false and the drawing buffer hasn't been cleared since it was last presented). If it does find that it needs a clear, then it clears it and requests it to be composited again.

How else should it behave?

It should perhaps make a copy and of the backbuffer to use for composition, if necessary, and clear the WebGL-visible backbuffer. This is what WebKit does, though I realize it's a real pain to do. 
I really hope that that isn't required by the WebGL spec; if it were, I would argue that developers probably wouldn't want that if they knew that it caused that inefficiency.

Anyway: in Mozilla's implementation, readPixels is clearing the backbuffer as if it were a draw-operation. If I remove this clearing, Gregg's testcase succeeds (stays green) and the conformance tests still pass. So I guess it was just a bug that readPixels was clearing the backbuffer as a draw-op and that's all we need to fix here?

That's all firefox needed to fix I believe.

We'll fix webkit to follow the new clearer spec.
I wonder, then, why WebKit is making this copy?
I'm not sure. If things are anti-aliased though I think we have to do a resolve which makes a copy.
Filed https://bugzilla.mozilla.org/show_bug.cgi?id=763190



A runnable testcase could be very useful here.


On Chrome if I call gl.drawArrays(gl.TRIANGLE, 0, 0) the drawing buffer is not recomposited. That could be argued either way. The drawing buffer did not get modified but it's a special case. I could easily call gl.drawArrays with a real program and real data that doesn't actually end up modifying the drawing buffer.  I think this means the spec should be more clear. Instead of saying "but only if the drawing buffer has been modified since the last compositing operation" it should be specific and say " but only if clear, drawArrays or drawElements have been called since the last compositing operation".


Unfortunately there is no way to write conformance tests for these cases. In all cases the drawing buffer is cleared correctly and so calling readPixels to verify will pass on all browsers. This is only something browser vendors can test themselves with screen captures or other browser specific test.