Signal · signalsVersion 5

webgl_renderer

The GPU name the browser reports through WebGL, often with the graphics back end.

webgl_renderer at a glance (from the library code, signalsVersion 5)
Component namewebgl_renderer
In the visitorIdyes
structuredId groupgpu (graphics)
Hashingplain value; a digest only when longer than 128 characters or not printable ASCII
Excluded underFirefox resistFingerprinting and Tor Browser (firefox_rfp)
Inner timeout1000 ms
Added insignalsVersion 1
In plain words

Browsers can tell a page which graphics chip draws its 3D content, for example “Apple M2” or a model of Intel, AMD or NVIDIA GPU, often wrapped in the name of the browser’s graphics layer. WhiskerJS reads that name as text. It is one of the most readable device details there is, and it also shows when there is no GPU at all.

What it reads

From the shared WebGL 1 context:

  • in browsers other than Firefox, WhiskerJS asks for the WEBGL_debug_renderer_info extension and, when it exists, reads UNMASKED_RENDERER_WEBGL with getParameter();
  • if that gives nothing (no extension, or an empty answer), it reads the plain gl.RENDERER value instead;
  • in Firefox (browser class firefox or firefox_rfp) the extension is not requested at all: Firefox prints a deprecation warning in the console when it is, and its plain RENDERER already carries the unmasked string. WhiskerJS writes nothing to the console, so it avoids that call.

An empty result is unavailable / no_value.

How the technique works

The browser’s “masked” renderer value is often a generic word such as “WebKit WebGL”. The debug extension exposes the underlying string the graphics driver reports. Chromium browsers usually wrap it in ANGLE, the translation layer they use, for example ANGLE (Apple, ANGLE Metal Renderer: Apple M2, Unspecified Version). The string is reported as is unless it is longer than 128 characters or not printable ASCII, in which case it is hashed like any other value.

The raw string is also kept, inside the library only, for the software_renderer check, which fires when it names SwiftShader, llvmpipe, softpipe, a “software rasterizer”, the “basic render driver” or Mesa offscreen.

Why it helps

It names the GPU family and often the model and graphics back end (Metal, Direct3D, OpenGL, Vulkan). That separates devices clearly and, read together with the platform and the user agent your server sees, can expose inconsistencies such as a desktop GPU on a phone user agent. It is in the gpu group.

Stability

Stable until the browser or driver changes how the GPU is described, or a different GPU is used (an external display on a laptop with two GPUs, or hardware acceleration switched off). Browser updates sometimes change the ANGLE wrapping text.

Browser support and what blocks it

Privacy

It reveals the graphics hardware, which is device information and can be personal data together with the rest of the result. It is read without any permission or prompt and nothing is sent by WhiskerJS. Long or unusual strings leave only as a digest.

How WhiskerJS handles noise and failures

Status ruleId When
ok none plain text, or a digest when long or not printable ASCII
unavailable no_value both the unmasked and the plain value were empty
unavailable no_document, no_api, no_context no document, no getContext, no WebGL
unavailable no_digest the string needed hashing and Web Crypto is missing
blocked security_error, threw getParameter threw
excluded firefox_rfp, caller_excluded exclusion table or your exclude list
timed_out timeout, aborted 1000 ms inner timeout, overall budget, abort

Example value

From a headless Chromium test browser in a container, drawing in software:

"webgl_renderer": {
  "status": "ok",
  "value": "ANGLE (Google, Vulkan 1.3.0 (SwiftShader Device (LLVM 10.0.0) (0x0000C0DE)), SwiftShader driver)",
  "hashed": false
}

That run also had the software_renderer flag. On a typical Mac with Chrome the docs show ANGLE (Apple, ANGLE Metal Renderer: Apple M2, Unspecified Version).

Questions and answers

Why does my renderer say SwiftShader or llvmpipe?

The browser is drawing in software instead of on a GPU: hardware acceleration is off, the GPU is blocklisted, or the machine is a server, container or virtual machine. WhiskerJS then also sets the software_renderer integrity flag.

Is the renderer string ever hashed?

Only when it is longer than 128 characters or contains a character outside printable ASCII. Otherwise it is reported as plain text with hashed false.

Why is it excluded under Firefox resistFingerprinting?

That mode replaces the WebGL strings with placeholders, so the value would not describe the device. The exclusion table reports excluded with ruleId firefox_rfp.