WebGL and WebGPU agree on whether this device clears uniformly
Check id webgl-webgpu-readback-agree
What an ordinary browser yields
Both APIs report the same verdict on uniformity: either both clear to exactly one colour, or neither does.
What a detector infers
One clear, two GPU APIs, one adapter. WebGL paints a flat colour and reads it back with readPixels; WebGPU renders the same clear into a texture and copies it into a mapped buffer. Those are different stacks — different entry points, different memory paths — but they sit on the same physical device, so they cannot disagree about whether that device is able to paint a single colour uniformly. What this adds over the plain uniformity row above it is a CONTROL on the same hardware. A single-API uniformity test always leaves one excuse standing: perhaps this driver simply does not clear cleanly, and the audit has no reference for what this particular GPU ought to do. Asking the other API settles it without any reference at all. If WebGPU renders the identical clear as one colour on the identical adapter, the hardware demonstrably can do it, and a WebGL readback carrying seven colours was therefore altered on the way out rather than produced that way. The check fires symmetrically, so the reverse case — WebGPU perturbed while WebGL is honest — reads the same. Measured on a shipping stealth browser: WebGL returned six, six and seven distinct colours across three launches while WebGPU returned exactly one every time, on the same adapter in the same session. Both APIs must be available for the comparison to mean anything, and WebGPU is frequently absent — no adapter, an older build, a headless or software configuration — so the row declines rather than guesses whenever either side cannot answer.
How to resolve it
readPixels and copyTextureToBuffer are separate stacks over one adapter, so a clear that is uniform through one has to be uniform through the other. Anything perturbing GPU readback as a defence against render fingerprinting therefore has to cover both APIs to stay self-consistent — and covering only WebGL is the natural mistake, because WebGL is the older surface and the one that fingerprinting scripts have historically read. The uncovered API then becomes a free control for the covered one, which is a strictly worse position than not perturbing at all: it does not merely reveal that something was changed, it demonstrates on the spot that the hardware could have answered honestly.
Read in the wild by
CloakBrowser (measured)
WebGL readback carried six to seven distinct colours for a flat clear while WebGPU, asked for the same clear on the same adapter in the same session, returned exactly one — on every launch measured. Because the WebGPU path is untouched, it doubles as proof that the device clears cleanly, which is what turns the WebGL result from an oddity into an alteration.
3/3 launches: WebGL 6, 6 and 7 distinct colours over 64×64 (dominant 4088/4087/4086 px); WebGPU exactly 1 distinct colour ("255,102,0,255", 4096/4096) in each of the same sessions. Stock Chrome and Clearcote on the same machine: 1 distinct through both APIs.
CloakBrowser (measured)Every attribution traces to a published artifact. See the sources and their limits.
Nearby checks in Render & GPU
- 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. - a WebGL framebuffer reads back the same through readPixels and toDataURL
webgl-readpixels-vs-todataurlreadPixels and toDataURL both read the drawing buffer of one WebGL canvas, and PNG is lossless, so decoding the data URL has to reproduce… - 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. - ink extent and advance width grow by the same step
text-ink-extent-vs-advanceTextMetrics reports two numbers produced by different parts of the engine. width is the sum of the glyph advances the shaper accumulated…
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-webgpu-readback-agree belongs to.