Bug 82275

Summary: WebGL content swapped at wrong time in threaded compositing mode
Product: WebKit Reporter: James Robinson <jamesr>
Component: New BugsAssignee: James Robinson <jamesr>
Status: RESOLVED FIXED    
Severity: Normal CC: cc-bugs, dino, enne, gman, joone.hur, kbr, mrobinson, nduca, reveman, senorblanco, simon.fraser, staikos, twiz, webkit.review.bot, zmo
Priority: P2    
Version: 528+ (Nightly build)   
Hardware: Unspecified   
OS: Unspecified   
Bug Depends on: 80459    
Bug Blocks:    
Attachments:
Description Flags
Patch
none
mac build fix
none
Patch
none
Patch
none
Patch kbr: review+

James Robinson
Reported 2012-03-26 17:55:02 PDT
WebGL content swapped at wrong time in threaded compositing mode
Attachments
Patch (28.89 KB, patch)
2012-03-26 17:57 PDT, James Robinson
no flags
mac build fix (28.89 KB, patch)
2012-03-26 18:23 PDT, James Robinson
no flags
Patch (33.21 KB, patch)
2012-03-26 18:53 PDT, James Robinson
no flags
Patch (59.65 KB, patch)
2012-04-05 16:04 PDT, James Robinson
no flags
Patch (59.71 KB, patch)
2012-04-06 11:01 PDT, James Robinson
kbr: review+
James Robinson
Comment 1 2012-03-26 17:57:50 PDT
James Robinson
Comment 2 2012-03-26 18:01:04 PDT
Ken said he'd take a look at this. I've modified other DrawingBuffer implementations based on inspection and they all seem fine except for Blackberry, which seems to be clearly non-compiling on ToT so I've mostly left it alone.
Build Bot
Comment 3 2012-03-26 18:13:36 PDT
Kenneth Russell
Comment 4 2012-03-26 18:22:24 PDT
Comment on attachment 133947 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=133947&action=review Looks good overall. One minor comment. The Mac build failure is probably a minor issue. r=me > Source/WebCore/platform/graphics/gpu/DrawingBuffer.h:58 > + static PassRefPtr<DrawingBuffer> create(GraphicsContext3D*, const IntSize&, bool seperateBackingTexture, bool alpha); Typo: seperateBackingTexture -> separateBackingTexture. Should we define an enum instead of adding another anonymous bool argument to the constructor? Perhaps also retrofit the separateBackingTexture argument with one?
James Robinson
Comment 5 2012-03-26 18:23:01 PDT
Created attachment 133955 [details] mac build fix
James Robinson
Comment 6 2012-03-26 18:26:26 PDT
Oops, I think I accidentally killed your review flag. I'm going to let EWS check that I didn't explode any other ports before landing.
Kenneth Russell
Comment 7 2012-03-26 18:28:57 PDT
Comment on attachment 133955 [details] mac build fix No problem. The change to the Mac port looks OK, but consider the comments from the previous review.
James Robinson
Comment 8 2012-03-26 18:53:16 PDT
James Robinson
Comment 9 2012-03-26 18:54:18 PDT
(In reply to comment #4) > Typo: seperateBackingTexture -> separateBackingTexture. Should we define an enum instead of adding another anonymous bool argument to the constructor? Perhaps also retrofit the separateBackingTexture argument with one? Good idea. I've switched both to enums - I struggled a bit on the name, but decided they were both requirements that the caller was making of creation. Let me know if that works for you.
Kenneth Russell
Comment 10 2012-03-26 18:57:13 PDT
Comment on attachment 133959 [details] Patch Thanks, that's a nice cleanup. r=me still.
James Robinson
Comment 11 2012-03-26 19:02:42 PDT
Awesome, holding off on cq+ until the other EWSen cycle.
James Robinson
Comment 12 2012-03-27 16:13:52 PDT
This patch breaks the antialiased display path (which appears to not break any layout tests). Investigating both...
Kenneth Russell
Comment 13 2012-03-27 16:24:16 PDT
Apologies that the layout tests don't exercise multisampling. I thought they would, based on memory and code inspection, but I haven't traced through DRT and in-process command buffer implementation to understand what's going on. Please feel free to file a new bug about that and assign it to me.
James Robinson
Comment 14 2012-03-27 16:58:11 PDT
Comment on attachment 133959 [details] Patch Clearing flags - this breaks the multisampled path on Chromium because FBOs aren't shared between contexts so we can't bind + blit from context other than the WebGL context. I'll leave the resolve in paint..() and make sure that we always double buffer the color attachment and do either a swap or a copy in updateCompositorResources(). I'll also file a bug about why this isn't caught by running layout tests, since the multisampled output path is the default.
James Robinson
Comment 15 2012-04-05 16:04:43 PDT
James Robinson
Comment 16 2012-04-05 16:07:09 PDT
This ended up being a bit larger than I had hoped, but I believe it works. A few things to note: 1.) mesa doesn't support multisampling, so the pixel expectations for DRT are not multisampled. I've run this test manually to confirm that multisampling still works as expected. 2.) I've updated other DrawingBuffer implementations in a best-effort way, but it's pretty clear that many of these do not even compile with current code. 3.) This *still* doesn't swap at exactly the right time in the face of incremental uploads (canvas 2d has the same bug). I'll address this for WebGL and canvas 2d in a follow-up patch since it'll only impact chromium code.
Kenneth Russell
Comment 17 2012-04-05 18:31:10 PDT
Comment on attachment 135924 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=135924&action=review Overall this looks very good. Nice work. There's only one small issue, but I feel pretty strongly that it should be taken care of (and re-testing done), thus the r-. > Source/WebCore/ChangeLog:29 > + since we're shadowing the relevant GL state on the WebGLRenderingContext anyway. This one change concerns me. Noting that FECustomFilter.cpp is using DrawingBuffer, it is not a good idea to assume that the WebGLRenderingContext is the caller of DrawingBuffer::clearFramebuffer(). Minimally, this change should be split off from the rest of this patch, but I also think it should just not be done. > Source/WebCore/platform/graphics/filters/FECustomFilter.cpp:145 > + m_drawingBuffer = DrawingBuffer::create(m_context.get(), contextSize, DrawingBuffer::Discard, DrawingBuffer::Alpha); Because this class uses DrawingBuffer I think it is not a good idea to assume that the WebGLRenderingContext will preserve all of the needed state during calls to DrawingBuffer::clearFramebuffer(). > LayoutTests/fast/canvas/webgl/webgl-composite-modes-repaint.html:4 > +This test is only useful as a pixel test. You should see two rows with 4 canvases in each. The top row of canvases should have a black background, the bottom row should have a pink background. Is the comment about the pink background accurate in this test and the other one?
James Robinson
Comment 18 2012-04-06 10:52:27 PDT
FECustomFilter doesn't use clearFramebuffer(), so I'm not sure what code or testing change you are proposing. Do you want me to just delete the comment? Presumably if somebody adds a call to clearFramebuffer() they will read the comment and do whatever they need to do to maintain their GL state invariant. The pink comment in the layout test is out of date (I changed the background color to darkblue to make it more obvious if antialiasing was happening or not). Will update.
Kenneth Russell
Comment 19 2012-04-06 10:55:37 PDT
(In reply to comment #18) > FECustomFilter doesn't use clearFramebuffer(), so I'm not sure what code or testing change you are proposing. Do you want me to just delete the comment? No, I'd like you to restore the state saving and restoring code in DrawingBuffer::clearFramebuffer().
James Robinson
Comment 20 2012-04-06 10:58:12 PDT
(In reply to comment #19) > (In reply to comment #18) > > FECustomFilter doesn't use clearFramebuffer(), so I'm not sure what code or testing change you are proposing. Do you want me to just delete the comment? > > No, I'd like you to restore the state saving and restoring code in DrawingBuffer::clearFramebuffer(). Why?
James Robinson
Comment 21 2012-04-06 11:01:10 PDT
Kenneth Russell
Comment 22 2012-04-06 11:35:44 PDT
(In reply to comment #20) > (In reply to comment #19) > > (In reply to comment #18) > > > FECustomFilter doesn't use clearFramebuffer(), so I'm not sure what code or testing change you are proposing. Do you want me to just delete the comment? > > > > No, I'd like you to restore the state saving and restoring code in DrawingBuffer::clearFramebuffer(). > > Why? Because if other callers than WebGL start using the DrawingBuffer class, then having clearFramebuffer() destroy context state will be surprising and unexpected. I don't think there will be a huge performance improvement from eliminating these state queries. If there is, we can figure out alternatives.
Kenneth Russell
Comment 23 2012-04-06 11:38:00 PDT
Comment on attachment 136043 [details] Patch The state saving and restoring code has still been removed in DrawingBuffer::clearFramebuffer.
James Robinson
Comment 24 2012-04-06 12:09:17 PDT
(In reply to comment #22) > (In reply to comment #20) > > (In reply to comment #19) > > > (In reply to comment #18) > > > > FECustomFilter doesn't use clearFramebuffer(), so I'm not sure what code or testing change you are proposing. Do you want me to just delete the comment? > > > > > > No, I'd like you to restore the state saving and restoring code in DrawingBuffer::clearFramebuffer(). > > > > Why? > > Because if other callers than WebGL start using the DrawingBuffer class, then having clearFramebuffer() destroy context state will be surprising and unexpected. I don't think there will be a huge performance improvement from eliminating these state queries. If there is, we can figure out alternatives. It's in the header. Pretty much every other operation on the DrawingBuffer (creating, reset(), commit(), bind(), createSecondaryBuffers(), paintRenderingResultsToImageData()) destroys context state. It's far more surprising that clearFramebuffer() attempts to restore state currently when nothing else does and every caller is shadowing this state anyway.
Kenneth Russell
Comment 25 2012-04-06 12:17:11 PDT
(In reply to comment #24) > Pretty much every other operation on the DrawingBuffer (creating, reset(), commit(), bind(), createSecondaryBuffers(), paintRenderingResultsToImageData()) destroys context state. It's far more surprising that clearFramebuffer() attempts to restore state currently when nothing else does and every caller is shadowing this state anyway. All right, I hadn't realized that none of the other operations tried to preserve state. r=me then, and thanks for fixing this.
James Robinson
Comment 26 2012-04-06 14:16:07 PDT
Note You need to log in before you can comment on or make changes to this bug.