业务中有跟原生端对齐的功能,比如上报设备的硬件信息,之前一直以为是无法实现的,无意间看到 https://hardwaretester.com/gpu 是可以获取到 gpu 信息的,就扒了一下网页源代码
gpu 信息 rank
测试 MAC
测试 Windows
chrome 关闭硬件加速
chrome 开启硬件加速
核心代码
基于 webgl 获取到设备的 renderer(渲染器)信息,其中就包括了 gpu 信息,代码如下:
const canvas = document.createElement('canvas');
const gl = canvas.getContext('webgl2') || canvas.getContext('webgl') || canvas.getContext('experimental-webgl');
const renderer = gl.getParameter(gpuInfo.UNMASKED_RENDERER_WEBGL);
// ANGLE (Apple, ANGLE Metal Renderer: Apple M2 Pro, Unspecified Version)
https://hardwaretester.com/gpu 源代码
这个网站访问量还是很大的,这段源码是经得起测试的,整理成可读代码如下:
const getRendererText = () => {
try {
const canvas = document.createElement('canvas');
const gl = canvas.getContext('webgl') || canvas.getContext('experimental-webgl');
if (!gl) {
return 'Unknown';
}
const gpuInfo = gl.getExtension('WEBGL_debug_renderer_info');
if (!gpuInfo) {
return 'Unknown';
}
const renderer = gl.getParameter(gpuInfo.UNMASKED_RENDERER_WEBGL);
return renderer || 'Unknown';
} catch (error) {
return 'Unknown';
}
};
const EM = (e) => {
let t = [],
n = e.split("");
for (let r = 0; r < n.length; r++)
if (n[r] === "(") t.push(r);
else if (n[r] === ")") {
let i = t.pop();
i !== void 0 && (n.splice(i, r - i + 1), r = i - 1)
}
return n.join("")
}
const El = (e) => {
return EM(e).replace(/\/PCIe\/SSE2/g, "").replace(/\s+/g, " ").trim()
}
// 获取 GPU 信息
const gpuText = (renderText) => {
try {
if (/, or similar$/.test(renderText)) return 'Unknown';
if (/SwiftShader/.test(renderText)) return 'Unknown';
if (/^ANGLE/.test(renderText)) {
let t = renderText.match(/\((.+)\)$/)[1],
n = t.split(/,\s*/g),
[_, info] = n;
if (/^ANGLE Metal Renderer: /.test(info)) {
info = renderText.split(": ")[1].split(",")[0];
}
if (n.length === 1) {
info = n[0].split(" ").slice(1).join(" ");
}
// 如果 i 包含 "Direct3D",则将 i 重置为相应的值
if (/Direct3D/.test(info)) {
info = info.split("Direct3D")[0].trim();
}
return info;
}
} catch(err) {
console.log('err: ', err);
}
return El(renderText);
}
const rendererText = getRendererText();
const gpuText = getGpuText(rendererText);
console.log('rendererText: ', rendererText);
console.log('gpuText: ', gpuText);
``