import puppeteer from 'puppeteer'; const b = await puppeteer.launch({ args:['--no-sandbox','--disable-setuid-sandbox','--use-gl=angle','--enable-unsafe-swiftshader','--ignore-gpu-blocklist'] }); const p = await b.newPage(); await p.setViewport({width:800,height:600}); await p.goto('about:blank',{waitUntil:'load'}); await new Promise(r=>setTimeout(r,300)); const r = await p.evaluate(()=>{ const cv=document.createElement('canvas'); cv.width=64; cv.height=64; document.body.appendChild(cv); const gl=cv.getContext('webgl2'); if(!gl) return {webgl2:false}; const vs=`#version 300 es\nin vec4 a_position; void main(){ gl_Position=a_position; }`; const fs=`#version 300 es\nprecision mediump float; out vec4 o; void main(){ o=vec4(1.0,0.3,0.0,1.0); }`; const mk=(s)=>{const sh=gl.createShader(s.includes('main(){ gl_Position')?gl.VERTEX_SHADER:gl.FRAGMENT_SHADER);gl.shaderSource(sh,s);gl.compileShader(sh);return {sh,ok:gl.getShaderParameter(sh,gl.COMPILE_STATUS),log:gl.getShaderInfoLog(sh)};}; const v=mk(vs), f=mk(fs); const prog=gl.createProgram(); gl.attachShader(prog,v.sh); gl.attachShader(prog,f.sh); gl.linkProgram(prog); const linked=gl.getProgramParameter(prog,gl.LINK_STATUS); gl.useProgram(prog); const buf=gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER,buf); gl.bufferData(gl.ARRAY_BUFFER,new Float32Array([-1,-1,1,-1,-1,1,-1,1,1,-1,1,1]),gl.STATIC_DRAW); const loc=gl.getAttribLocation(prog,'a_position'); gl.enableVertexAttribArray(loc); gl.vertexAttribPointer(loc,2,gl.FLOAT,false,0,0); gl.clearColor(0,0,0,1); gl.clear(gl.COLOR_BUFFER_BIT); gl.drawArrays(gl.TRIANGLES,0,6); const px=new Uint8Array(4); gl.readPixels(32,32,1,1,gl.RGBA,gl.UNSIGNED_BYTE,px); return { webgl2:true, vsOk:v.ok, fsOk:f.ok, fsLog:f.log, linked, center:Array.from(px) }; }); console.log(JSON.stringify(r,null,1)); await b.close();