RESOLVED FIXED 34719
WebGL rendering results must be made available to Canvas.toDataURL and 2D drawImage
https://bugs.webkit.org/show_bug.cgi?id=34719
Summary WebGL rendering results must be made available to Canvas.toDataURL and 2D dra...
Kenneth Russell
Reported 2010-02-08 13:01:19 PST
Rendering into one Canvas element using WebGL and then drawing that Canvas into another using CanvasRenderingContext2D.drawImage() does not always work. Appropriate hooks need to be placed in the Canvas implementation to force the WebGL context to prepare its contents for drawing via the 2D Canvas APIs.
Attachments
patch (18.75 KB, patch)
2010-07-03 16:40 PDT, Zhenyao Mo
simon.fraser: review-
simon.fraser: commit-queue-
revised patch: responding to Simon Fraser's review (18.78 KB, patch)
2010-07-04 14:57 PDT, Zhenyao Mo
simon.fraser: review+
simon.fraser: commit-queue-
revised patch: responding to Simon Fraser and kbr's review (22.54 KB, patch)
2010-07-10 12:30 PDT, Zhenyao Mo
zmo: commit-queue-
revised patch: fix a bug (30.29 KB, patch)
2010-07-10 17:47 PDT, Zhenyao Mo
zmo: commit-queue-
revised patch: resolving svn merge conflicts (29.63 KB, patch)
2010-07-10 18:35 PDT, Zhenyao Mo
zmo: commit-queue-
revised patch: deal with Qt part of GraphicsContext3D (34.68 KB, patch)
2010-07-13 18:15 PDT, Zhenyao Mo
no flags
revised patch: fix a ChangeLog issue (30.96 KB, patch)
2010-07-13 18:18 PDT, Zhenyao Mo
no flags
revised patch: fix the Qt bug (31.07 KB, patch)
2010-07-13 18:42 PDT, Zhenyao Mo
no flags
revised patch (30.98 KB, patch)
2010-07-13 19:13 PDT, Zhenyao Mo
no flags
revised patch (30.29 KB, patch)
2010-07-15 13:44 PDT, Zhenyao Mo
japhet: review-
revised patch (31.56 KB, patch)
2010-07-15 16:49 PDT, Zhenyao Mo
japhet: review+
Patch fixing compiler warning (2.73 KB, patch)
2010-07-19 14:58 PDT, Kenneth Russell
japhet: review+
kbr: commit-queue-
Kenneth Russell
Comment 1 2010-06-08 11:23:41 PDT
The same problem exists with Canvas.toDataURL(). Both of these APIs must respect the premultipliedAlpha flag in the WebGLContextAttributes.
Zhenyao Mo
Comment 2 2010-07-03 16:40:08 PDT
Created attachment 60461 [details] patch Tested in both Safari and Chrome in Mac in Release mode.
Simon Fraser (smfr)
Comment 3 2010-07-03 22:30:01 PDT
Comment on attachment 60461 [details] patch paintRenderingResultsToCanvas is leaking 'pixels'.
Zhenyao Mo
Comment 4 2010-07-04 14:57:52 PDT
Created attachment 60482 [details] revised patch: responding to Simon Fraser's review Use OwnArrayPtr for pixels to avoid leak.
Simon Fraser (smfr)
Comment 5 2010-07-06 13:01:04 PDT
Comment on attachment 60482 [details] revised patch: responding to Simon Fraser's review WebCore/platform/graphics/mac/GraphicsContext3DMac.mm:256 + // BEGIN: the same code as in WebGraphicsContext3DDefaultImpl.cpp::readBackFramebuffer Either share the code, or remove the comment. As-is, the comment is not useful. Can you share code with GraphicsContext3D::readPixels()? WebCore/platform/graphics/mac/GraphicsContext3DMac.mm:290 + CGImageRef cgImage = CGImageCreate(m_currentWidth, You should use RetainPtr for the dataProvider, colorSpace and cgImage. Do you need to save/restore the state in the imageBuffer->context()? WebCore/platform/graphics/mac/GraphicsContext3DMac.mm:307 + // We want to completely overwrite the previous frame's rendering results. Is that described in a spec anywhere? r=me
Kenneth Russell
Comment 6 2010-07-07 19:10:04 PDT
Comment on attachment 60482 [details] revised patch: responding to Simon Fraser's review Generally looks good, but one high-level comment about code refactoring which I would prefer be done. WebCore/platform/graphics/GraphicsContext3D.h:711 + void paintRenderingResultsToCanvas(WebGLRenderingContext*context); Formatting: WebGLRenderingContext* context WebCore/platform/graphics/mac/GraphicsContext3DMac.mm:256 + // BEGIN: the same code as in WebGraphicsContext3DDefaultImpl.cpp::readBackFramebuffer The CG portions of this code should be refactored rather than duplicated. Given that the original code came from GraphicsContext3D.cpp in WebKit/chromium/src, it should be possible to refactor it into WebCore/platform/graphics/cg/GraphicsContext3DCG.cpp. It might be necessary to split it into two routines (before/after readback), or pass a callback function. If it seems reasonable to do the refactoring, please do so.
Kenneth Russell
Comment 7 2010-07-07 19:14:28 PDT
(In reply to comment #5) > WebCore/platform/graphics/mac/GraphicsContext3DMac.mm:307 > + // We want to completely overwrite the previous frame's rendering results. > > Is that described in a spec anywhere? The comment refers to the fact that the kCGBlendModeCopy blend mode is used, so that transparent pixels aren't blended with any content previously in the image.
Simon Fraser (smfr)
Comment 8 2010-07-07 19:22:15 PDT
(In reply to comment #7) > (In reply to comment #5) > > WebCore/platform/graphics/mac/GraphicsContext3DMac.mm:307 > > + // We want to completely overwrite the previous frame's rendering results. > > > > Is that described in a spec anywhere? > > The comment refers to the fact that the kCGBlendModeCopy blend mode is used, so that transparent pixels aren't blended with any content previously in the image. I realize that, but where is that behavior spec'd? I imagine this affect the outcome of mixing a 2D and 2D context on the same canvas, but I'd hope that transparent pixels in the 3D context wouldn't clobber earlier 2D drawing.
Kenneth Russell
Comment 9 2010-07-07 19:33:57 PDT
(In reply to comment #8) > (In reply to comment #7) > > (In reply to comment #5) > > > WebCore/platform/graphics/mac/GraphicsContext3DMac.mm:307 > > > + // We want to completely overwrite the previous frame's rendering results. > > > > > > Is that described in a spec anywhere? > > > > The comment refers to the fact that the kCGBlendModeCopy blend mode is used, so that transparent pixels aren't blended with any content previously in the image. > > I realize that, but where is that behavior spec'd? I imagine this affect the outcome of mixing a 2D and 2D context on the same canvas, but I'd hope that transparent pixels in the 3D context wouldn't clobber earlier 2D drawing. There have been some changes pending to the HTML Canvas specification for some time now regarding mixing of contexts, and I believe the latest resolution is that using the 2D and 3D contexts simultaneously will be explicitly disallowed in the spec. Regardless, even if you're just using the 3D context, it's still necessary to completely overwrite the rendering results. Consider the case where you draw one 3D scene with a certain set of pixels as transparent, and then perform a drawImage call with that canvas as source. Then draw a different 3D scene with a different set of transparent pixels, and perform another similar drawImage call (into a second, clean, canvas). It would be an error if portions of the first scene were visible where the pixels are transparent in the second scene because the data read back from the graphics card was blended with the previously read back data.
Simon Fraser (smfr)
Comment 10 2010-07-07 20:41:43 PDT
Fair enough.
Simon Fraser (smfr)
Comment 11 2010-07-08 22:44:28 PDT
This may also fix bug 30722.
Zhenyao Mo
Comment 12 2010-07-10 12:28:12 PDT
(In reply to comment #5) > (From update of attachment 60482 [details]) > > WebCore/platform/graphics/mac/GraphicsContext3DMac.mm:256 > + // BEGIN: the same code as in WebGraphicsContext3DDefaultImpl.cpp::readBackFramebuffer > Either share the code, or remove the comment. As-is, the comment is not useful. Removed. > > Can you share code with GraphicsContext3D::readPixels()? readPixels() logic is different. Here we always read from backbuffer, whereas readPixels might read from user created fbo. > > WebCore/platform/graphics/mac/GraphicsContext3DMac.mm:290 > + CGImageRef cgImage = CGImageCreate(m_currentWidth, > You should use RetainPtr for the dataProvider, colorSpace and cgImage. > > Do you need to save/restore the state in the imageBuffer->context()? Done. > > WebCore/platform/graphics/mac/GraphicsContext3DMac.mm:307 > + // We want to completely overwrite the previous frame's rendering results. > > Is that described in a spec anywhere? > > r=me
Zhenyao Mo
Comment 13 2010-07-10 12:28:48 PDT
(In reply to comment #6) > (From update of attachment 60482 [details]) > Generally looks good, but one high-level comment about code refactoring which I would prefer be done. > > > WebCore/platform/graphics/GraphicsContext3D.h:711 > + void paintRenderingResultsToCanvas(WebGLRenderingContext*context); > Formatting: WebGLRenderingContext* context Done. > > WebCore/platform/graphics/mac/GraphicsContext3DMac.mm:256 > + // BEGIN: the same code as in WebGraphicsContext3DDefaultImpl.cpp::readBackFramebuffer > The CG portions of this code should be refactored rather than duplicated. Given that the original code came from GraphicsContext3D.cpp in WebKit/chromium/src, it should be possible to refactor it into WebCore/platform/graphics/cg/GraphicsContext3DCG.cpp. It might be necessary to split it into two routines (before/after readback), or pass a callback function. If it seems reasonable to do the refactoring, please do so. Done.
Zhenyao Mo
Comment 14 2010-07-10 12:30:02 PDT
Created attachment 61159 [details] revised patch: responding to Simon Fraser and kbr's review
Zhenyao Mo
Comment 15 2010-07-10 17:47:42 PDT
Created attachment 61170 [details] revised patch: fix a bug in WebGLRenderingContext::markedContextChanged(), always set the dirty flag when context has changed. Also, add another test canvas-test.html for this change. (This test is copied from WebGL conformance tests with minor modifications).
Zhenyao Mo
Comment 16 2010-07-10 18:27:53 PDT
Yike, this patch is so out-of-date. CanvasSurface.h/cpp is gone. Have to manually merge. Add jamesr@chromium.org to cc list since he did the code refactoring.
Zhenyao Mo
Comment 17 2010-07-10 18:35:15 PDT
Created attachment 61172 [details] revised patch: resolving svn merge conflicts
Zhenyao Mo
Comment 18 2010-07-13 18:15:56 PDT
Created attachment 61447 [details] revised patch: deal with Qt part of GraphicsContext3D Try my luck!
Zhenyao Mo
Comment 19 2010-07-13 18:18:19 PDT
Created attachment 61449 [details] revised patch: fix a ChangeLog issue
Early Warning System Bot
Comment 20 2010-07-13 18:27:43 PDT
Zhenyao Mo
Comment 21 2010-07-13 18:42:56 PDT
Created attachment 61451 [details] revised patch: fix the Qt bug
Zhenyao Mo
Comment 22 2010-07-13 19:13:15 PDT
Created attachment 61457 [details] revised patch Seems like Qt/Gtk/Win bots failure may have nothing to do with CG stuff. Revert the changes I made based on the blame-CG assumption.
Zhenyao Mo
Comment 23 2010-07-15 13:44:11 PDT
Created attachment 61712 [details] revised patch Using kbr's script to sync the two tests in this patch with khronos conformance tests. No other changes,
Kenneth Russell
Comment 24 2010-07-15 14:12:35 PDT
Comment on attachment 61712 [details] revised patch Looks good. Thanks for waiting and keeping the tests in sync.
Nate Chapin
Comment 25 2010-07-15 15:44:00 PDT
Comment on attachment 61712 [details] revised patch > +#if ENABLE(3D_CANVAS) > + if (sourceCanvas->is3D()) { > + WebGLRenderingContext* context3d = reinterpret_cast<WebGLRenderingContext*>(sourceCanvas->renderingContext()); > + context3d->paintRenderingResultsToCanvas(); > + } > +#endif > + We probably shouldn't be doing 3D things in CanvasRenderingContext2D. > + intervalId = window.setInterval(function() { If there's any way to make this test work without setInterval, please do so, lest it be slow and flaky.
Zhenyao Mo
Comment 26 2010-07-15 16:49:51 PDT
Created attachment 61747 [details] revised patch
Kenneth Russell
Comment 27 2010-07-15 16:53:47 PDT
Comment on attachment 61747 [details] revised patch This looks better to me. I think the setInterval call is needed in the test (I'm not the test author but there's probably a reason it was used), but the modifications that have been made should prevent any flakiness.
Nate Chapin
Comment 28 2010-07-15 16:58:30 PDT
Comment on attachment 61747 [details] revised patch Alright, sounds good.
Zhenyao Mo
Comment 29 2010-07-15 18:01:14 PDT
Zoltan Herczeg
Comment 30 2010-07-19 00:27:52 PDT
This patch does not builds on mac-leopard: /Users/hzoli/WebKitHZ/WebCore/platform/graphics/mac/GraphicsContext3DMac.mm: In member function 'void WebCore::GraphicsContext3D::paintRenderingResultsToCanvas(WebCore::WebGLRenderingContext*)': /Users/hzoli/WebKitHZ/WebCore/platform/graphics/mac/GraphicsContext3DMac.mm:257: warning: 'mustRestoreFBO' may be used uninitialized in this function I think it should be false by default, isn't it?
Kenneth Russell
Comment 31 2010-07-19 14:57:07 PDT
(In reply to comment #30) > This patch does not builds on mac-leopard: > > /Users/hzoli/WebKitHZ/WebCore/platform/graphics/mac/GraphicsContext3DMac.mm: In member function 'void WebCore::GraphicsContext3D::paintRenderingResultsToCanvas(WebCore::WebGLRenderingContext*)': > /Users/hzoli/WebKitHZ/WebCore/platform/graphics/mac/GraphicsContext3DMac.mm:257: warning: 'mustRestoreFBO' may be used uninitialized in this function > > I think it should be false by default, isn't it? Yes, you're right. I'll upload a patch fixing this. Not sure why it wasn't caught by the bots.
Kenneth Russell
Comment 32 2010-07-19 14:58:18 PDT
Created attachment 61996 [details] Patch fixing compiler warning From the ChangeLog: Fixed compiler warning introduced by original patch. No new tests; covered by existing tests.
Kenneth Russell
Comment 33 2010-07-19 18:45:47 PDT
Simon Fraser (smfr)
Comment 34 2010-07-19 20:24:37 PDT
Does this fix bug 30722?
Kenneth Russell
Comment 35 2010-07-20 09:59:35 PDT
(In reply to comment #34) > Does this fix bug 30722? I'm not sure (and Mo is on vacation this week). Was there a test case for 30722?
Simon Fraser (smfr)
Comment 36 2010-07-22 15:08:24 PDT
This caused bug 42852.
Simon Fraser (smfr)
Comment 37 2010-07-22 17:43:24 PDT
(In reply to comment #35) > (In reply to comment #34) > > Does this fix bug 30722? > > I'm not sure (and Mo is on vacation this week). Was there a test case for 30722? See bug 42862.
Note You need to log in before you can comment on or make changes to this bug.