Unable to render WebGL with Xvfb


#1

I am trying to render my app which has a WebGL dependency in Electron on my Linux PC, but nothing is rendering on the page, except for the CSS background color. When I remove the WebGL dependency, which is MapboxGL, then everything renders normally.

I am using X Virtual Frame Buffer, which seems necessary for a Linux environment, as described here: https://electronjs.org/docs/tutorial/testing-on-headless-ci

I am running Xvfb using this command:

Xvfb :99 -screen 0 1024x768x24 > xvfblog.txt 2>&1 &

I am not sure if this is relevant, but Xvfb starts up with the following messages:

The XKEYBOARD keymap compiler (xkbcomp) reports:
> Warning:          Unsupported high keycode 372 for name <I372> ignored
>                   X11 cannot support keycodes above 255.
>                   This warning only shows for the first high keycode.
> Internal error:   Could not resolve keysym XF86WWAN
> Internal error:   Could not resolve keysym XF86RFKill
> Internal error:   Could not resolve keysym XF86Keyboard
Errors from xkbcomp are not fatal to the X server

I also noticed that when I test my app using Electron on a Macbook, Xvfb is not required, and my WebGL app renders just fine.

I am a bit stumped here. Are there any suggestions about what could be wrong, or what I can investigate for a fix?


#2

I was able to resolve this issue by configuring Xvfb to work with WebGL as follows:

Xvfb :99 -screen 0 1024x768x24 +extension GLX +render > xvfblog.txt 2>&1 &

Where I added the +extension GLX +render flags.

I also had to start electron with the ignore-gpu-blacklist flag. I found this article helpful with that: https://medium.com/social-tables-tech/how-we-test-webgl-on-continuous-integration-37a1ead55fd7

Also note that I am using the “electron” npm package, and I had to add the following flags to my BrowserWindow object:

const win = new BrowserWindow({
  show: false,
  webPreferences: {
    webgl: true,
    webSecurity: false,
    experimentalFeatures: true,
    experimentalCanvasFeatures: true,
    offscreen: true
  }
})

I hope this helps someone.