a WebGL framebuffer reads back the same through readPixels and toDataURL
Check id webgl-readpixels-vs-todataurl
What an ordinary browser yields
Every channel identical between readPixels and the decoded PNG (severity: warn).
What a detector infers
readPixels and toDataURL both read the drawing buffer of one WebGL canvas, and PNG is lossless, so decoding the data URL has to reproduce the bytes readPixels already returned. The only adjustment is orientation -- readPixels is bottom-up while the canvas is top-down, so rows are flipped before comparing -- and no reference image exists anywhere in the comparison. It earns a place beside webgl-readback-flat-uniform because that row reads readPixels only, and WebGL fingerprinting scripts overwhelmingly hash canvas.toDataURL() after rendering rather than calling readPixels. A build that perturbs the export path while leaving readPixels honest therefore satisfies every existing WebGL pixel check, which is exactly the gap 2D canvas had until its dual-exit row. Measured on a clean browser across all three alpha configurations -- alpha off, alpha with premultiplication, and alpha without -- zero differing channels of 4096 in every one. Premultiplication was the confound worth checking and it does not bite, because the browser applies the same conversion to both exits.
How to resolve it
readPixels and toDataURL read the same drawing buffer, so a lossless encode has to reproduce what readPixels returned. Perturbing only the export path leaves readPixels-based checks satisfied while the two exits disagree with each other. Perturb both identically, or neither.
Nearby checks in Render & GPU
- one flat fill reads back as exactly one colour
canvas-flat-fill-uniformThis is the area form of the 1×1 canvas probe, and it exists because that probe is easy to pass by accident. - one pixel reads the same through a full read and a windowed read
canvas-subrect-consistencyThe same pixels, asked for twice through different windows. A full-canvas read and an inner 16×16 read overlap on 256 pixels, and those are… - a canvas reads back the same through toDataURL and getImageData
canvas-todataurl-vs-getimagedatatoDataURL and getImageData are two exits from one canvas, and PNG is lossless, so decoding the data URL back into pixels has to reproduce… - one WebGL clear reads back as exactly one colour
webgl-readback-flat-uniformA single glClear writes one colour into every pixel of the framebuffer, so reading that framebuffer back must yield exactly one colour. - WebGL and WebGPU agree on whether this device clears uniformly
webgl-webgpu-readback-agreeOne clear, two GPU APIs, one adapter. WebGL paints a flat colour and reads it back with readPixels; WebGPU renders the same clear into a… - canvas measureText widths on the 1/512 sub-pixel grid
measuretext-gridChrome's 2D text metrics are quantised: advance widths are computed in fixed-point and land on a dyadic 1/512-pixel grid. - text metrics are not a uniform multiple of the engine's own grid
text-metrics-uniform-scaleThis is the sub-pixel grid check asked one question deeper. That check reports THAT widths have left Blink's 1/512-pixel grid; this one asks… - N copies of a glyph measure exactly N times one copy
text-advance-additivityThe advance width of N copies of a single glyph is exactly N times the advance of one copy.
Clearcote is a browser built for fingerprint coherence
It is a Chromium fork, maintained by the same people who wrote this reference. It ships as a compiled browser rather than as a stealth script injected into someone else's — which is a description of how it is built, and is not an argument about how it behaves on this check.
This audit takes no position on how Clearcote scores on Render & GPU checks, on this one, or anywhere else. It has no baseline corpus of other people's fingerprints to rank you against and no vendor scoreboard — nearly every check is self-referential, asking one browser the same question through two independent APIs and reporting whether both answers can be true at once. It runs identically on any browser, including ours. Run it on yours and read the result yourself.
See the other checks in Render & GPU — the family webgl-readpixels-vs-todataurl belongs to.