When optimizing page performance using SharedWorker + OffscreenCanvas, it was discovered that the first 50 frames of the Canvas on macOS freeze and fail to refresh. This is the issue described here: https://issues.chromium.org/396460819.
The issue arises because in the first 50 frames, the CanvasResource is not sent to the Placeholder, keeping its reference count at 1. This causes the CanvasResourceProviderSharedImage to operate in non-copy-on-write mode, which uses the same SharedImage to update the Canvas content each time. This mechanism is used to enable the Canvas's low-latency mode (desynchronized=true), also known as SingleBuffer mode in CanvasResourceProvider. However, the non-copy-on-write mode currently doesn't work on Mac. Resolving this issue should allow Mac to support low-latency mode.
The non-copy-on-write mode requires a SharedImage to be both written by the Canvas and read by the viz compositor for display, may leading to the following issues:
If the SharedImage is written again before the viz compositor reads it, display correctness issues may occur.
If the SharedImage is directly used as an overlay, subsequent writes might be displayed without going through SubmitCompositorFrame. For example, on Mac, dragging a window can immediately reflect changes to the UI when using the same IOSurface.
On macOS with Metal enabled, the SharedImage used by the Canvas has an IOSurfaceImageBacking backend, which doesn't support concurrent read/write under Metal. However, non-copy-on-write heavily relies on concurrent read/write.
On macOS, most CompositorFrames can be displayed via the overlay mechanism. In this case, if the Canvas keeps drawing on the same IOSurface, the UI won't refresh.
If the user sets desynchronized=true, issues 1 and 2 can be considered acceptable. Therefore, the key to enabling non-copy-on-write on Mac lies in solving issues 3 and 4.
For issue 3:
The code can simply remove the blocking of concurrent read/write in IOSurfaceImageBackingFactory, but the issue https://anglebug.com/7626 needs to be re-evaluated.
For issue 4:
Some workarounds include setting CALayer.content to nil before each frame commit or creating a new CALayer to carry the IOSurface each time.
I have submitted a prototype CL to demonstrate potential solutions for issues 3 and 4: https://chromium-review.googlesource.com/c/chromium/src/+/6301417.
Thus, to make low-latency mode work on Mac, we need to discuss issues 3 and 4, or any other unknown factors.
Special thanks to Colin Blundell, without whose encouragement this email would not have been possible.
Thanks!