You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
textImage2D does not accept OffscreenCanvas anymore as a pixel source for texture #1180
Describe the bug
Since the last macOS and Safari version, textImage2D does not accept OffscreenCanvas anymore as a pixel source for texture. Passing directly a OffscreenCanvas element will throw a Type Error exception.
Device:
OS: macOS 13.3
Browser: Safari 16.4
melonJS Version: 14.0 and higher
Solution
This was fixed in the 15.1 release by using transfertToBitmapImage() when the pixels source is an Offscreen Canvas.
Unfortunately, that led to another issue when using Offscreencanvas and system font rendering in WebGL, with the converted BitmapImage producing some garbaged pixel soup :
Internal use of OffscreenCanvas when rendering text was then also disabled in the same fix, to restore the previous behaviour :
In conclusion, the issue is fixed for now, but I'm creating this issue, because I'm not sure if this is actually the expected behaviour as per the W3C/WebGL standard or a bug with the current version of Safari (other browsers are still fine with using OffscreenCanvas as a pixel source).
If anyone has any additional insight on this, I'm definitely interested !
changed the title [-]`textImage2D` does not accept OffscreenCanvas anymore as a pixel source for the texture[/-][+]`textImage2D` does not accept OffscreenCanvas anymore as a pixel source for texture[/+]on Mar 30, 2023
The workaround using transferToImageBitmap() has been stable since v15.1. OffscreenCanvas is also still explicitly disabled for text rendering in WebGL mode (text.js:176-178).
Per the WebGL 2.0 spec, OffscreenCanvas is a valid TexImageSource for texImage2D. However, Safari's implementation remains unreliable.
Flutter's tracking issue for the same problem is still open: flutter/flutter#150801. From that issue:
Safari_ 17+ supports OffscreenCanvas with WebGL, but only on macOS Sonoma and iOS 17+ derivatives. Not earlier versions of the platforms with Safari 17.
There's also a separate WebKit bug (WebKit#267291) affecting texImage2D with OffscreenCanvas, and as noted in the Flutter issue:
There's`_ no good way to check for this capability now.
Keeping this open until Safari/WebKit fully stabilizes their OffscreenCanvas + texImage2D support, at which point we can re-enable OffscreenCanvas for text rendering and potentially remove the transferToImageBitmap() workaround.
Closing as resolved. The reported bug (passing an OffscreenCanvas to texImage2D throwing on Safari, and the garbled-pixel-soup that the transferToImageBitmap() workaround then caused for WebGL text) has been fixed for users since v15.1: the transferToImageBitmap() workaround is stable, and OffscreenCanvas is explicitly disabled for text rendering (src/renderable/text/text.js — CanvasRenderTarget(..., { offscreenCanvas: false })). No user is impacted on any browser today. The underlying defect is an upstream WebKit bug (WebKit#267291), not a melonJS one.
The only thing this issue was holding open was "re-enable OffscreenCanvas for text once Safari stabilizes, and drop the workaround." After review, that's a deliberate non-goal, for three independent reasons:
1. We can't safely detect when it's available.
The capability is gated on the OS version, not the browser version — per the Flutter tracking issue, Safari 17 works on macOS Sonoma / iOS 17 but the same Safari 17 is broken on older macOS. Safari freezes the macOS version in the UA string (Mac OS X 10_15_7 regardless of the real OS), so on macOS — exactly where this was reported — you can't read the OS to form the (browser, OS) pair you'd need. UA gating also misclassifies WebKit-based non-Safari iOS browsers (CriOS/FxiOS/EdgiOS) and in-app WKWebViews. A false positive there ships garbled text to real users — strictly worse than today. A runtime upload+readPixels capability probe would be robust, but it adds a startup GPU stall and a second code path.
2. The performance upside is ~zero anyway. OffscreenCanvas's real benefit is rasterizing off the main thread in a Web Worker — melonJS renders text on the main thread, so that doesn't apply. On the main thread, OffscreenCanvas vs. the detached<canvas> we already use is the same 2D rasterization engine (the detached canvas already has no DOM/layout cost), and the texImage2D upload costs the same. Text is also rasterized on change and cached as a texture, not re-rasterized per frame — so it isn't even a hot path. Net measurable gain in a real scene: none.
3. The workaround has to stay regardless.
Even if WebKit fully fixes this tomorrow, users on older Safari/OS versions keep the bug, so the transferToImageBitmap() path can't be removed for backward compatibility.
So there's no actionable, worthwhile work here. If WebKit ever ships a clean fix with a detectable capability and there's a concrete perf motivation (e.g. worker-based rendering), that's a fresh, well-scoped enhancement to file at that point with current data — not a reason to keep a 2023 bug open indefinitely.
Activity
[-]`textImage2D` does not accept OffscreenCanvas anymore as a pixel source for the texture[/-][+]`textImage2D` does not accept OffscreenCanvas anymore as a pixel source for texture[/+]obiot commentedon Mar 14, 2026
Status update (March 2026)
The workaround using transferToImageBitmap() has been stable since v15.1.
OffscreenCanvasis also still explicitly disabled for text rendering in WebGL mode (text.js:176-178).Per the WebGL 2.0 spec,
OffscreenCanvasis a valid TexImageSource for texImage2D. However, Safari's implementation remains unreliable.Flutter's tracking issue for the same problem is still open: flutter/flutter#150801. From that issue:
There's also a separate WebKit bug (WebKit#267291) affecting texImage2D with OffscreenCanvas, and as noted in the Flutter issue:
Keeping this open until Safari/WebKit fully stabilizes their OffscreenCanvas + texImage2D support, at which point we can re-enable OffscreenCanvas for text rendering and potentially remove the transferToImageBitmap() workaround.
Clean up TODO/FIXME/XXX comments across codebase
obiot commentedon Jun 29, 2026
Closing as resolved. The reported bug (passing an
OffscreenCanvastotexImage2Dthrowing on Safari, and the garbled-pixel-soup that thetransferToImageBitmap()workaround then caused for WebGL text) has been fixed for users since v15.1: thetransferToImageBitmap()workaround is stable, andOffscreenCanvasis explicitly disabled for text rendering (src/renderable/text/text.js—CanvasRenderTarget(..., { offscreenCanvas: false })). No user is impacted on any browser today. The underlying defect is an upstream WebKit bug (WebKit#267291), not a melonJS one.The only thing this issue was holding open was "re-enable
OffscreenCanvasfor text once Safari stabilizes, and drop the workaround." After review, that's a deliberate non-goal, for three independent reasons:1. We can't safely detect when it's available.
The capability is gated on the OS version, not the browser version — per the Flutter tracking issue, Safari 17 works on macOS Sonoma / iOS 17 but the same Safari 17 is broken on older macOS. Safari freezes the macOS version in the UA string (
Mac OS X 10_15_7regardless of the real OS), so on macOS — exactly where this was reported — you can't read the OS to form the(browser, OS)pair you'd need. UA gating also misclassifies WebKit-based non-Safari iOS browsers (CriOS/FxiOS/EdgiOS) and in-app WKWebViews. A false positive there ships garbled text to real users — strictly worse than today. A runtime upload+readPixelscapability probe would be robust, but it adds a startup GPU stall and a second code path.2. The performance upside is ~zero anyway.
OffscreenCanvas's real benefit is rasterizing off the main thread in a Web Worker — melonJS renders text on the main thread, so that doesn't apply. On the main thread,OffscreenCanvasvs. the detached<canvas>we already use is the same 2D rasterization engine (the detached canvas already has no DOM/layout cost), and thetexImage2Dupload costs the same. Text is also rasterized on change and cached as a texture, not re-rasterized per frame — so it isn't even a hot path. Net measurable gain in a real scene: none.3. The workaround has to stay regardless.
Even if WebKit fully fixes this tomorrow, users on older Safari/OS versions keep the bug, so the
transferToImageBitmap()path can't be removed for backward compatibility.So there's no actionable, worthwhile work here. If WebKit ever ships a clean fix with a detectable capability and there's a concrete perf motivation (e.g. worker-based rendering), that's a fresh, well-scoped enhancement to file at that point with current data — not a reason to keep a 2023 bug open indefinitely.