| Summary: | REGRESSION(r289580): Canvas: putImageData sometimes draws nothing | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|
| Product: | WebKit | Reporter: | Bart Corremans <bart.corremans> | ||||||||
| Component: | Canvas | Assignee: | Said Abou-Hallawa <sabouhallawa> | ||||||||
| Status: | RESOLVED FIXED | ||||||||||
| Severity: | Normal | CC: | dino, rackler, sabouhallawa, webkit-bug-importer | ||||||||
| Priority: | P2 | Keywords: | InRadar | ||||||||
| Version: | Safari Technology Preview | ||||||||||
| Hardware: | Mac (Apple Silicon) | ||||||||||
| OS: | macOS 12 | ||||||||||
| See Also: | https://bugs.webkit.org/show_bug.cgi?id=236305 | ||||||||||
| Bug Depends on: | |||||||||||
| Bug Blocks: | 236305 | ||||||||||
| Attachments: |
|
||||||||||
|
Description
Bart Corremans
2022-05-23 08:32:50 PDT
Note that if opening the index.html file directly, you will need to enable Develop -> Disable Local File Restrictions. If you are serving using a web server, this is not needed. Thanks for reporting this bug. In the attached test case, putImageData() is the only drawing operation which is applied to the target context. r289580 made PutPixelBuffer an ImageBuffer message not a display list item. So the flag RemoteDisplayListRecorderProxy::m_needsFlush is never set to true because no StreamConnection message is sent from the target canvas. So RemoteImageBufferProxy::flushDrawingContextAsync() never returns true because m_remoteDisplayList::needsFlush() always returns false. This makes flushDrawingContext() return always without waiting. When drawing the target canvas to the page we copy its backend to a NativeImage in WebProcess. This happens while the last PutPixelBuffer message is being processed by GPUProcess. Calling getImageData() as a workaround forces GPUProcess to flush all the drawing items before returning the image data. After receiving the data from GPUProcess, if we copy the backend to NativeImage in WebProcess, we will be getting valid pixels. Another workaround is to draw dummy anything to the target canvas. This will fix the drawing issue. Instead of using: target.getImageData(0, 0, canvasWidth, canvasHeight); We can use something like this: target.fillRect(0, 0, 0, 0); This will set RemoteDisplayListRecorderProxy::m_needsFlush() to true. So when copyNativeImage() is called, flushDrawingContext() will wait until a DidFlush message is received. Pull request: https://github.com/WebKit/WebKit/pull/1003 Created attachment 459745 [details]
simpler test case
*** Bug 240735 has been marked as a duplicate of this bug. *** Committed r294928 (251039@main): <https://commits.webkit.org/251039@main> Reviewed commits have been landed. Closing PR #1003 and removing active labels. Thank you for the explanation and quick resolution! I can confirm my original issue is also fixed using the latest WebKit build. Reopening to attach new patch. Created attachment 459823 [details]
Patch
Pull request: https://github.com/WebKit/WebKit/pull/1206 Committed r295132 (251223@main): <https://commits.webkit.org/251223@main> Reviewed commits have been landed. Closing PR #1206 and removing active labels. |