Rendering WebGL image in headless chrome without a GPU

James Hollingworth picture James Hollingworth · Dec 28, 2017 · Viewed 11.1k times · Source

I'm trying to export an image rendered with WebGL on a linux server without a GPU. To do this I'm using headless Chrome however the exported image is black (example exported image, taking a screenshot of page shows its just canvas that is black). I was hoping for some help figuring out why this is happening.

To export the image I render the image into a canvas, export data via canvas.toDataURL('image/jpeg') and then post the data to the server. I'm using Pixi.js for rendering, if I use canvas renderer then everything works on the server; It's WebGL rendering thats not working. It's worth noting the WebGL render works fine in Chrome 63 on a Macbook.

To control Chrome I'm using Puppeteer. All I'm doing is opening a page, waiting a second, and then closing it again:

puppeteer
  .launch({
    args: [
      '--no-sandbox',
      '--disable-setuid-sandbox',
    ],
  })
  .then(browser => {
    return browser.newPage().then(page => {
      return page
        .goto(url)
        .then(() => page.waitFor(1000))
        .then(() => browser.close())
        .catch(err => console.error('Failed', err));
    });
  })

These are the arguments puppeteer passes to Chrome:

[
  '--disable-background-networking',
  '--disable-background-timer-throttling',
  '--disable-client-side-phishing-detection',
  '--disable-default-apps',
  '--disable-extensions',
  '--disable-hang-monitor',
  '--disable-popup-blocking',
  '--disable-prompt-on-repost',
  '--disable-sync',
  '--disable-translate',
  '--metrics-recording-only',
  '--no-first-run',
  '--remote-debugging-port=0',
  '--safebrowsing-disable-auto-update',
  '--enable-automation',
  '--password-store=basic',
  '--use-mock-keychain',
  '--user-data-dir=/tmp/puppeteer_dev_profile-GhEAXZ',
  '--headless',
  '--disable-gpu',
  '--hide-scrollbars',
  '--mute-audio',
  '--no-sandbox',
  '--disable-setuid-sandbox'
]

The swiftshader author said in June headless WebGL rendering is possible and it seems to be confirmed by this Chromium issue so I guess I'm missing something. Has anyone got any ideas what I'm doing wrong?

A couple of things I've tried:

  • Not passing in --disable-gpu
  • --use-gl=swiftshader-webgl, --use-gl=swiftshader, --use-gl=osmesa
  • Taking a full screen screenshot to see if its just canvas. Whole screen is just black.

Versions

  • Chrome: linux-515411
  • puppeteer: 0.13.0
  • node: 8.2.1
  • Linux: CentOS 7

This is what I needed to install on my server to get chrome to run (Source)

yum install cups-libs dbus-glib libXrandr libXcursor libXinerama cairo cairo-gobject pango ffmpeg
rpm -ivh --nodeps http://mirror.centos.org/centos/7/os/x86_64/Packages/atk-2.22.0-3.el7.x86_64.rpm
rpm -ivh --nodeps http://mirror.centos.org/centos/7/os/x86_64/Packages/at-spi2-atk-2.22.0-2.el7.x86_64.rpm
rpm -ivh --nodeps http://mirror.centos.org/centos/7/os/x86_64/Packages/at-spi2-core-2.22.0-1.el7.x86_64.rpm
rpm -ivh --nodeps http://dl.fedoraproject.org/pub/archive/fedora/linux/releases/20/Fedora/x86_64/os/Packages/g/GConf2-3.2.6-7.fc20.x86_64.rpm
rpm -ivh --nodeps http://dl.fedoraproject.org/pub/archive/fedora/linux/releases/20/Fedora/x86_64/os/Packages/l/libXScrnSaver-1.2.2-6.fc20.x86_64.rpm
rpm -ivh --nodeps http://dl.fedoraproject.org/pub/archive/fedora/linux/releases/20/Fedora/x86_64/os/Packages/l/libxkbcommon-0.3.1-1.fc20.x86_64.rpm
rpm -ivh --nodeps http://dl.fedoraproject.org/pub/archive/fedora/linux/releases/20/Fedora/x86_64/os/Packages/l/libwayland-client-1.2.0-3.fc20.x86_64.rpm
rpm -ivh --nodeps http://dl.fedoraproject.org/pub/archive/fedora/linux/releases/20/Fedora/x86_64/os/Packages/l/libwayland-cursor-1.2.0-3.fc20.x86_64.rpm
rpm -ivh --nodeps http://dl.fedoraproject.org/pub/archive/fedora/linux/releases/20/Fedora/x86_64/os/Packages/g/gtk3-3.10.4-1.fc20.x86_64.rpm
rpm -ivh --nodeps http://dl.fedoraproject.org/pub/archive/fedora/linux/releases/16/Fedora/x86_64/os/Packages/gdk-pixbuf2-2.24.0-1.fc16.x86_64.rpm

Answer

Nicolas Capens picture Nicolas Capens · Jan 2, 2018

There's an open bug which affects systems without X11 libraries: crbug.com/swiftshader/79. It prevents Chrome OS from running with SwiftShader, but the same issue would also happen on a headless Linux system which has no X11 support.

Fortunately it should be feasible to install X11 and get things running. I'm not 100% sure which packages provide the necessary libraries, but try these: xorg xserver-xorg xvfb libx11-dev libxext-dev libxext-dev:i386

Eventually the SwiftShader bug will be fixed so it doesn't require X11 whatsoever.