Accelerated Canvas2D without ANGLE (macOS default on release/beta): canvas drawn with putImageData is never painted (Intel UHD 630)
Categories
(Core :: Graphics: Canvas2D, defect)
Tracking
()
| Tracking | Status | |
|---|---|---|
| firefox-esr153 | --- | unaffected |
| firefox158 | --- | wontfix |
| firefox159 | --- | verified |
| firefox160 | --- | verified |
People
(Reporter: matthias.cullmann, Assigned: jnicol)
References
(Regression)
Details
(Keywords: regression, testcase)
Attachments
(7 files, 2 external files)
Steps to reproduce
User Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:157.0) Gecko/20100101 Firefox/157.0
- Firefox 157 release or 158 beta on macOS (Intel UHD 630), default prefs:
gfx.canvas.accelerated = true,webgl.disable-angle = true. - Open the attached
repro.html. Each card draws the same 200x200 pattern into a canvas.
Simplest failing case (card G):
const c = document.createElement('canvas'); c.width = c.height = 200;
document.body.append(c);
const ctx = c.getContext('2d');
const img = ctx.createImageData(200, 200); /* fill with a pattern */
ctx.putImageData(img, 0, 0);
The other cards vary the sequence used by the widely used node-qrcode / angularx-qrcode libraries (canvas drawn before or after being appended, resized after getContext, toDataURL readback) — all fail the same way. repro-dialog.html mimics the real-world dialog (scrolling modal, render after a button click).
Actual results
Every canvas drawn with putImageData stays blank (white) — cards A, B, C, D, G, and also H, where putImageData is followed by a 1x1 fillRect. Stable across reloads and "Run again"; also not painted after scrolling it into view, waiting, or hovering. The same pattern drawn with fillRect only (card E) renders. repro-dialog.html also stays blank.
The canvas content is correct:
getImageData()returns the pattern (the page prints the number of dark pixels under each canvas)elementFromPoint()at the canvas centre returns the canvas itself- computed styles are normal (display inline, visibility visible, opacity 1, no filter/mask/clip-path/transform)
- copying the same pixels into an
<img>viacanvas.toDataURL()displays correctly - Firefox's own screenshot feature (right-click > "Take Screenshot") captures all canvases correctly, also the blank ones — on the real site and in repro.html. Only the live on-screen output is blank, so the canvas content is intact and the problem is in presenting it to the compositor.
No console errors.
Expected results
The canvas shows the pattern, as it does in Chrome and Safari, and in Firefox with gfx.canvas.accelerated = false or webgl.disable-angle = false.
Additional information
Cause narrowed down: the bug is in the non-ANGLE (CGL/OpenGL) WebGL path that accelerated Canvas2D uses on macOS release/beta.
mozregression --find-fix(automated with a screenshot-based probe,detect.html+probe.py, attached) from 2026-08-15 (bad) to 2026-09-24 (good) ends at the autoland push for bug 2072535 "Enable Metal ANGLE for WebGL on Nightly": https://hg.mozilla.org/integration/autoland/pushloghtml?fromchange=041d1aaf8c5776b41028e481ccea4a73183f6022&tochange=c9f9a67f54c76e2c690952d12564b1b7f8d46c3a
That change only flipswebgl.disable-angleto false on macOS Nightly — it hides the bug rather than fixing it, which is why Beta 158 is still affected.- Confirmed both ways with the probe:
| Build | webgl.disable-angle | Result |
|---|---|---|
| 157.0.1 | false | painted |
| 158.0b5 | false | painted |
| 160.0a1 | true | blank |
- Reproduces in 157.0.1 (also with a fresh profile, so not profile/extension related), 158.0b5, and Nightlies 156/157/158 before bug 2072535 landed. Nightly 160 renders correctly only because of the ANGLE default.
- Workarounds:
gfx.canvas.accelerated = false, orwebgl.disable-angle = false. - Found on a real site: the 2FA "add authenticator app" dialog of a utility customer portal (Angular 22 + angularx-qrcode, elementType "canvas"). The QR code never appeared, making 2FA enrolment impossible without the workaround.
- Impact: until Metal ANGLE ships to release, macOS users on this path see blank canvases for putImageData content (e.g. all angularx-qrcode / node-qrcode QR codes).
- Hardware: Mac mini 2018 (Macmini8,1), Intel UHD Graphics 630, 16 GB, LG HDR 4K display (3840x2160, devicePixelRatio 2), macOS 15.8.1 (24H32). about:support attached.
- Possibly related: bug 1939995 (blank canvases fixed by gfx.canvas.accelerated=false, Windows).
| Reporter | ||
Comment 1•1 month ago
|
||
| Reporter | ||
Comment 2•1 month ago
|
||
| Reporter | ||
Comment 3•1 month ago
|
||
Screenshots taken with macOS screencapture (Firefox's own "Take Screenshot" re-renders and would show every canvas). The page is detect.html (attached next): left canvas = solid magenta via putImageData, right canvas = solid cyan via fillRect.
- Firefox 157.0.1, default prefs: left canvas missing.
- Nightly 160.0a1, default prefs (Metal ANGLE): both painted.
| Reporter | ||
Comment 4•1 month ago
|
||
| Reporter | ||
Comment 5•1 month ago
|
||
| Reporter | ||
Comment 6•1 month ago
|
||
Bisection command used (exit 0 = painted = "good"):
mozregression --find-fix --bad 2026-08-15 --good 2026-09-24 --command 'python probe.py "{binary}"'
probe.py <binary> webgl.disable-angle=true|false was used for the pref cross-check. Needs Pillow and Screen Recording permission for the terminal.
| Reporter | ||
Updated•1 month ago
|
Updated•1 month ago
|
Comment 7•1 month ago
|
||
./mach mozregression --good 2026-07-19 --bad 2026-08-13 -a "https://bug2080436.bmoattachments.org/attachment.cgi?id=9657227"
gives
https://hg-edge.mozilla.org/integration/autoland/pushloghtml?fromchange=5ab718c5a32c093f8846931b1c2a9fcf92c37058&tochange=c9c78ae99215d977e1b6c17377637ae04f81275f
Comment 8•1 month ago
|
||
Set release status flags based on info from the regressing bug 2055839
:jnicol, since you are the author of the regressor, bug 2055839, could you take a look? Also, could you set the severity field?
For more information, please visit BugBot documentation.
Updated•1 month ago
|
| Assignee | ||
Comment 9•1 month ago
|
||
Using the shared PBO upload path can result in broken rendering when
with the native macOS GL driver on Intel GPUs. We therefore avoid
it. Rendering when using ANGLE is unaffected.
Updated•1 month ago
|
Comment 10•1 month ago
|
||
Comment 11•1 month ago
|
||
| bugherder | ||
Updated•1 month ago
|
Comment 12•1 month ago
|
||
The patch landed in nightly and beta is affected.
:jnicol, please make an uplift decision for beta:
- For beta, nominate the patch for beta uplift approval if the fix should be included in this release, or set
status-firefox159towontfixif the fix can wait for the next release.
See Requesting an Uplift for documentation on how to request an uplift.
For more information, please visit BugBot documentation.
| Assignee | ||
Comment 13•1 month ago
|
||
Using the shared PBO upload path can result in broken rendering when
with the native macOS GL driver on Intel GPUs. We therefore avoid
it. Rendering when using ANGLE is unaffected.
Original Revision: https://phabricator.services.mozilla.com/D332840
Updated•1 month ago
|
Comment 14•1 month ago
|
||
firefox-beta Uplift Approval Request
- User impact if declined/Reason for urgency: Broken canvas2d rendering for macOS users
- Code covered by automated testing?: no
- Fix verified in Nightly?: yes
- Needs manual QE testing?: no
- Steps to reproduce for manual QE testing:
- Risk associated with taking this patch: low
- Explanation of risk level: Reverts to texture upload path used prior to bug 2055839 landing (in 155) for affected devices
- String changes made/needed?: N/A
- Is Android affected?: no
Updated•1 month ago
|
Updated•1 month ago
|
Comment 15•1 month ago
|
||
| uplift | ||
| Assignee | ||
Updated•1 month ago
|
Updated•24 days ago
|
Updated•23 days ago
|
Comment 16•19 days ago
|
||
I reproduced the issue with test case from comment 0 and comment 1 using Firefox 157.0, on macOS 15.
The issue is verified as fixed on latest Beta 160.0b1 and Release 159.0 under macOS 15.
Description
•