render: expose WebGL as unavailable without backend

This commit is contained in:
SGavrl
2026-07-26 11:14:43 +00:00
parent 7618b3276a
commit 29d0bce3f5
2 changed files with 36 additions and 45 deletions

View File

@@ -7279,51 +7279,12 @@ Element.prototype.getContext = function getContext(type) {
return this._ctx;
}
if (type === 'webgl' || type === 'experimental-webgl' || type === 'webgl2') {
return {
canvas: this,
MAX_VIEWPORT_DIMS: 0x0D33,
MAX_TEXTURE_SIZE: 0x0D33,
MAX_RENDERBUFFER_SIZE: 0x84E8,
MAX_TEXTURE_MAX_ANISOTROPY_EXT: 0x84EA,
MAX_DRAW_BUFFERS_WEBGL: 0x8824,
getContextAttributes() { return { alpha: true, antialias: true, depth: true, failIfMajorPerformanceCaveat: false, powerPreference: "default", premultipliedAlpha: true, preserveDrawingBuffer: false, stencil: true, desynchronized: false }; },
uniform2f() {},
getExtension(name) {
if (name === 'WEBGL_debug_renderer_info') return { UNMASKED_VENDOR_WEBGL: 0x9245, UNMASKED_RENDERER_WEBGL: 0x9246 };
return null;
},
getParameter(pname) {
if (pname === 0x9245) return _fp('gpuVendor');
if (pname === 0x9246) return _fp('gpu');
if (pname === 0x1F01) return 'WebKit WebGL'; // GL_RENDERER
if (pname === 0x1F00) return 'WebKit'; // GL_VENDOR
if (pname === 0x1F02) return 'OpenGL ES 3.0 (ANGLE)'; // GL_VERSION
if (pname === 0x8B8C) return 'WebGL GLSL ES 3.00 (ANGLE)'; // GL_SHADING_LANGUAGE_VERSION
if (pname === undefined) return [0, 0];
// Some properties like MAX_VIEWPORT_DIMS return arrays
if (pname === 0x0D33) return [8192, 8192];
if (pname === 0x8A2A) return [8192, 8192];
return 0;
},
getSupportedExtensions() { return ['WEBGL_debug_renderer_info','EXT_texture_filter_anisotropic','WEBGL_compressed_texture_s3tc','WEBGL_lose_context']; },
getShaderPrecisionFormat() { return { rangeMin: 127, rangeMax: 127, precision: 23 }; },
createBuffer() { return {}; }, createShader() { return {}; }, createProgram() { return {}; },
shaderSource() {}, compileShader() {}, attachShader() {}, linkProgram() {},
getProgramParameter() { return true; }, useProgram() {}, deleteShader() {},
bindBuffer() {}, bufferData() {}, enableVertexAttribArray() {}, vertexAttribPointer() {},
drawArrays() {}, drawElements() {}, viewport() {}, clear() {}, clearColor() {},
enable() {}, disable() {}, blendFunc() {}, depthFunc() {},
getUniformLocation() { return {}; }, getAttribLocation() { return 0; },
uniform1f() {}, uniform1i() {}, uniformMatrix4fv() {},
createTexture() { return {}; }, bindTexture() {}, texImage2D() {}, texParameteri() {},
activeTexture() {}, pixelStorei() {}, generateMipmap() {},
createFramebuffer() { return {}; }, bindFramebuffer() {}, framebufferTexture2D() {},
readPixels(x,y,w,h,f,t,d) { if(d) for(let i=0;i<d.length;i++) d[i]=Math.floor(Math.random()*256); },
VERTEX_SHADER: 0x8B31, FRAGMENT_SHADER: 0x8B30, LINK_STATUS: 0x8B82,
ARRAY_BUFFER: 0x8892, STATIC_DRAW: 0x88E4, FLOAT: 0x1406,
TRIANGLES: 0x0004, COLOR_BUFFER_BIT: 0x4000, DEPTH_BUFFER_BIT: 0x100,
TEXTURE_2D: 0x0DE1, RGBA: 0x1908, UNSIGNED_BYTE: 0x1401,
};
// Context creation is allowed to fail, and that is the only truthful
// behavior until the renderer has a real WebGL backend. The former shim
// reported successful shader/program creation while every draw call was a
// no-op. Feature-detecting applications consequently selected their WebGL
// path, hid their HTML/image fallback, and produced a blank canvas.
return null;
}
return null;
};

View File

@@ -2794,6 +2794,36 @@ mod tests {
assert_eq!(result, serde_json::json!([1, 1, true, ""]));
}
#[test]
fn unavailable_webgl_context_does_not_claim_success() {
let mut rt = setup_runtime("<html><body><canvas></canvas></body></html>");
let result = rt
.evaluate(
r#"
(() => {
const canvas = document.querySelector('canvas');
const fallback = document.createElement('p');
if (!canvas.getContext('webgl')) {
fallback.textContent = 'static fallback';
document.body.appendChild(fallback);
}
return [
canvas.getContext('webgl'),
canvas.getContext('webgl2'),
canvas.getContext('experimental-webgl'),
fallback.isConnected,
fallback.textContent,
];
})()
"#,
)
.unwrap();
assert_eq!(
result,
serde_json::json!([null, null, null, true, "static fallback"])
);
}
#[test]
fn test_script_execution() {
let mut rt = setup_runtime("<ul><li>A</li><li>B</li></ul>");