autokap 1.3.13 → 1.3.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/browser.js +47 -16
  2. package/package.json +1 -1
package/dist/browser.js CHANGED
@@ -822,28 +822,29 @@ export class Browser {
822
822
  const baseArgs = (process.platform === 'linux' && !isLinuxWithGpu)
823
823
  ? CHROMIUM_ARGS
824
824
  : CHROMIUM_ARGS.filter(arg => arg !== '--disable-gpu' && arg !== '--disable-gpu-sandbox');
825
- // Pin ANGLE to the platform's native graphics API. Chrome's default
826
- // backend is OpenGL on macOS, which is far slower than Metal for the
827
- // compositor (measured 4 FPS vs 32 FPS at 2880×1800 on a heavy React UI).
828
- // Same story on Windows where D3D11 is the native fast path. Cloud Run
829
- // L4 routes through ANGLE→OpenGL using NVIDIA's libGL/libEGL (mounted at
830
- // /usr/local/nvidia/lib64). We tried `--use-angle=vulkan` first but
831
- // Cloud Run does not bind-mount the NVIDIA Vulkan ICD, so vulkaninfo
832
- // resolves to llvmpipe (software fallback). The OpenGL path goes through
833
- // the EGL/GLX libs that ARE mounted, hitting the L4 directly.
825
+ // Pin GPU backend to each platform's native graphics API:
826
+ // - macOS: Metal (compositor 4→32 fps boost at 2880×1800 vs OpenGL).
827
+ // - Windows: D3D11.
828
+ // - Cloud Run Linux: ANGLE/Vulkan binding NVIDIA L4. The Dockerfile
829
+ // ships /usr/share/vulkan/icd.d/nvidia_icd.json (Cloud Run does NOT
830
+ // bind-mount it) so Vulkan loader resolves to libGLX_nvidia.so.0
831
+ // instead of llvmpipe. Verified flag set comes from Musixmatch's
832
+ // production K8s recipe and davesnider's Playwright benchmark.
834
833
  const angleArg = process.platform === 'darwin' ? '--use-angle=metal'
835
834
  : process.platform === 'win32' ? '--use-angle=d3d11'
836
- : isLinuxWithGpu ? '--use-angle=gl'
835
+ : isLinuxWithGpu ? '--use-angle=vulkan'
837
836
  : null;
838
- // Cloud Run NVIDIA L4: GPU rasterization + zero-copy upload via the GL
839
- // backend. `--ignore-gpu-blocklist` bypasses Chromium's hardcoded driver
840
- // blocklist (it doesn't know about Cloud Run's mounted NVIDIA driver).
841
- // These flags target the throughput wins for backdrop-filter, blur, and
842
- // full-viewport repaints the modal-open scenario that defeats software
843
- // rasterization at ~1 fps.
837
+ // Cloud Run NVIDIA L4: ANGLE/Vulkan + GPU rasterization + zero-copy upload.
838
+ // `--ignore-gpu-blocklist` bypasses Chromium's hardcoded blocklist (it has
839
+ // no entry for Cloud Run's mounted NVIDIA driver). `--enable-features=Vulkan`
840
+ // is required so Chromium uses the Vulkan compositor instead of falling
841
+ // back through HARDWARE_GL SWIFTSHADER. These flags target the throughput
842
+ // wins for backdrop-filter, blur, and full-viewport repaints — the modal
843
+ // scenario that pinned software rasterization at ~1 fps.
844
844
  const cloudGpuArgs = isLinuxWithGpu
845
845
  ? [
846
846
  '--use-gl=angle',
847
+ '--enable-features=Vulkan',
847
848
  '--ignore-gpu-blocklist',
848
849
  '--enable-gpu-rasterization',
849
850
  '--enable-zero-copy',
@@ -895,6 +896,36 @@ export class Browser {
895
896
  }
896
897
  }, { styleId: CAPTURE_HIDE_STYLE_ID, css: getCaptureHideCSS() });
897
898
  instance.page = await instance.context.newPage();
899
+ // Cloud Run only: query the WebGL UNMASKED_RENDERER_WEBGL string once
900
+ // per browser launch and log it. This is the source of truth for which
901
+ // GPU backend Chromium picked — flag combinations alone are not enough,
902
+ // because Chromium silently steps down the fallback chain
903
+ // (HARDWARE_VULKAN → HARDWARE_GL → SWIFTSHADER → DISPLAY_COMPOSITOR)
904
+ // when a backend fails to initialize. A renderer string containing
905
+ // "NVIDIA" confirms hardware; "SwiftShader" or "llvmpipe" means
906
+ // software fallback. Cheap (~50ms) and only runs in cloud mode.
907
+ if (isCloudRunner) {
908
+ try {
909
+ const gpuInfo = await instance.page.evaluate(() => {
910
+ const canvas = document.createElement('canvas');
911
+ const gl = (canvas.getContext('webgl2') || canvas.getContext('webgl'));
912
+ if (!gl)
913
+ return { error: 'no webgl context' };
914
+ const ext = gl.getExtension('WEBGL_debug_renderer_info');
915
+ if (!ext)
916
+ return { error: 'no debug_renderer_info extension' };
917
+ return {
918
+ vendor: gl.getParameter(ext.UNMASKED_VENDOR_WEBGL),
919
+ renderer: gl.getParameter(ext.UNMASKED_RENDERER_WEBGL),
920
+ version: gl.getParameter(gl.VERSION),
921
+ };
922
+ });
923
+ console.info('[gpu-check] WebGL renderer:', JSON.stringify(gpuInfo));
924
+ }
925
+ catch (err) {
926
+ console.warn('[gpu-check] WebGL query failed:', err.message);
927
+ }
928
+ }
898
929
  return instance;
899
930
  }
900
931
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "autokap",
3
- "version": "1.3.13",
3
+ "version": "1.3.15",
4
4
  "description": "AI-powered CLI tool for capturing clean screenshots of websites",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",