A worker OffscreenCanvas encodes the pixels it reads back
In a worker, an OffscreenCanvas's getImageData and the decoded PNG from its convertToBlob agree on every channel. Information only (severity: info).
What a detector infers
A canvas has more than one way out. getImageData hands pixels straight to script; convertToBlob encodes the same pixels into a file, and with PNG, which is lossless, decoding that file has to give back exactly what getImageData returned. canvas-todataurl-vs-getimagedata makes this comparison on the page's main thread.
This row makes it inside a dedicated worker, on an OffscreenCanvas, which has its own exits: a perturbation has to cover both of them in every realm, and one applied to the worker's getImageData but not to its convertToBlob — or the reverse — makes the decoded file and the direct readback disagree. The drawing is opaque and contains no text, so neither alpha premultiplication nor font rendering can introduce a legitimate difference.
Measured on every stock browser tested: no differing channel. Only that side is measured — no spoof tested here produced a disagreement — so the row is information only until a failing case has been observed. N/A where workers or OffscreenCanvas are unavailable.
How to resolve it
Apply any canvas perturbation at the point every exit reads from, in every realm, or not at all. Covering one OffscreenCanvas exit in a worker and not the other leaves a lossless encode that no longer matches the pixels.
Nearby checks in Render & GPU
- A Direct3D 11 renderer reports the caps ANGLE's D3D11 backend fixes
webgl-d3d11-fixed-capsWhen ANGLE runs WebGL on Direct3D 11 at feature level 11 — the renderer string reads Direct3D11 vs_5_0 ps_5_0 — it does not ask the driver… - Every extension WebGL hands out is one it advertises
webgl-gettable-is-advertisedIn Chrome, getSupportedExtensions() and getExtension() read the same set: an extension the context can hand out is one it lists, and one it… - WebGL state reads back what the page just set
webgl-state-reads-backSome WebGL parameters are not capabilities but state the page itself controls. - readPixels writes only the pixels it was asked to read
webgl-readpixels-sentinelreadPixels writes into an array the page supplies, and the WebGL specification is precise about the edges: when the requested rectangle… - WebGPU's preferred canvas format belongs to the claimed OS
webgpu-canvas-format-vs-osnavigator.gpu.getPreferredCanvasFormat() returns the texture format the platform's compositor wants to be handed, and Chrome on Windows and… - A WebGPU device accepts every limit and feature its adapter advertises
webgpu-device-honours-adapterA WebGPU adapter advertises limits and features, and the device it creates is validated against them by Dawn, Chrome's WebGPU… - WebGL renderer (software vs hardware)
webgl-not-softwareThe audit reads UNMASKED_RENDERER through the WEBGL_debug_renderer_info extension and matches it against SwiftShader, llvmpipe and Software. - WebGPU vendor coheres with WebGL vendor
webgl-webgpu-vendorTwo independent graphics stacks in the same browser are backed by the same physical adapter: this check lowercases the WebGL UNMASKED_VENDOR…
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 offscreen-canvas-exits-agree belongs to.
