chromedp: WebGL is not working using headless shell

What versions are you running?

$ go list -m github.com/chromedp/chromedp
v0.8.2
$ google-chrome-stable --version
Google Chrome 101.0.4951.64 (desktop, Arch Linux)
Chrome/102.0.5005.63 (headless shell)
$ go version
go version go1.18.2 linux/amd64

What did you do? Include clear steps.

docker run -p 9222:9222 --rm --name headless-shell chromedp/headless-shell

[0530/182008.253071:INFO:content_main_runner_impl.cc(1144)] Chrome is running in full browser mode.

DevTools listening on ws://0.0.0.0:9222/devtools/browser/5d1cb0e4-bcd0-4547-b976-f5bdedc86c31
[0530/182008.258946:WARNING:child_process_launcher_helper_posix.cc(83)] Ignoring invalid file snapshot_blob.bin
[0530/182008.260614:ERROR:gl_context_egl.cc(355)] eglCreateContext failed with error EGL_BAD_ATTRIBUTE
[0530/182008.260743:ERROR:gpu_init.cc(481)] Passthrough is not supported, GL is angle, ANGLE is swiftshader
[0530/182008.260808:ERROR:gl_context_egl.cc(355)] eglCreateContext failed with error EGL_BAD_ATTRIBUTE
[0530/182008.260865:ERROR:gpu_info_collector.cc(93)] gl::init::CreateGLContext failed
[0530/182008.260909:ERROR:gpu_info_collector.cc(348)] Could not create context for info collection.
[0530/182008.260963:ERROR:gpu_init.cc(86)] CollectGraphicsInfo failed.
[0530/182008.262619:ERROR:viz_main_impl.cc(186)] Exiting GPU process due to errors during initialization
[0530/182008.263289:WARNING:child_process_launcher_helper_posix.cc(83)] Ignoring invalid file snapshot_blob.bin
[0530/182008.269225:ERROR:gl_context_egl.cc(355)] eglCreateContext failed with error EGL_BAD_ATTRIBUTE
[0530/182008.269310:ERROR:gpu_init.cc(481)] Passthrough is not supported, GL is angle, ANGLE is swiftshader
[0530/182008.269383:ERROR:gl_context_egl.cc(355)] eglCreateContext failed with error EGL_BAD_ATTRIBUTE
[0530/182008.269428:ERROR:gpu_info_collector.cc(93)] gl::init::CreateGLContext failed
[0530/182008.269463:ERROR:gpu_info_collector.cc(348)] Could not create context for info collection.
[0530/182008.269540:ERROR:gpu_init.cc(86)] CollectGraphicsInfo failed.
[0530/182008.270843:ERROR:viz_main_impl.cc(186)] Exiting GPU process due to errors during initialization
[0530/182008.274135:ERROR:gl_context_egl.cc(355)] eglCreateContext failed with error EGL_BAD_ATTRIBUTE
[0530/182008.274225:ERROR:gpu_init.cc(481)] Passthrough is not supported, GL is angle, ANGLE is swiftshader
[0530/182008.274309:ERROR:gl_context_egl.cc(355)] eglCreateContext failed with error EGL_BAD_ATTRIBUTE
[0530/182008.274350:ERROR:gpu_info_collector.cc(93)] gl::init::CreateGLContext failed
[0530/182008.274381:ERROR:gpu_info_collector.cc(348)] Could not create context for info collection.
[0530/182008.274417:ERROR:gpu_init.cc(86)] CollectGraphicsInfo failed.
[0530/182008.275892:ERROR:viz_main_impl.cc(186)] Exiting GPU process due to errors during initialization
[0530/182008.278231:ERROR:gpu_init.cc(481)] Passthrough is not supported, GL is disabled, ANGLE is

I then have a Go code using chromedp that waits for an element to be visible, this element is visible once a canvas is successfully rendered with Three.js. I then render the webpage to a PDF file.

With chromedp’s headless shell running in Docker, it doesn’t work and hangs waiting for my element to become visible.

If I use my desktop browser launched with google-chrome-stable --headless --use-gl=swiftshader --remote-debugging-port=9222, it starts flawlessly and everything works. (--no-sandbox flag doesn’t change anything)

What did you expect to see?

No GL initialization error.

What did you see instead?

GL initialization errors. This is the root cause of my problem but I can provide a minimal working example if needed.

About this issue

  • Original URL
  • State: closed
  • Created 2 years ago
  • Comments: 16 (11 by maintainers)

Commits related to this issue

Most upvoted comments

Thank you for confirming!

--use-vulkan=native --use-angle=vulkan works with chromedp/headless-shell:102.0.5005.115, but in a way that we don’t understand. The error messages do not look good.

--use-vulkan=native --use-angle=vulkan does not work with zeke/headless-shell:102.0.5005.115. But I think this is expected. Because hardware GPU is not supported yet according to https://bugs.chromium.org/p/chromium/issues/detail?id=765284.

I think we can go with --use-gl=angle --use-angle=swiftshader for now, and review the options after hardware GPU support is landed.

Thanks for jumping in.

I worked on that issue for hours and came up with a minimal working example:

package main

import (
	"context"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
	"testing"
	"time"

	"github.com/chromedp/cdproto/page"
	"github.com/chromedp/chromedp"
)

func getWSurl(addr string) (string, error) {
	request, err := http.NewRequest(http.MethodGet, fmt.Sprintf("http://%s/json/version", addr), nil)
	if err != nil {
		return "", err
	}

	response, err := http.DefaultClient.Do(request)
	if err != nil {
		return "", err
	}

	result := &struct {
		WebSockerDebuggerURL string `json:"webSocketDebuggerUrl"`
	}{}
	if err := json.NewDecoder(response.Body).Decode(&result); err != nil {
		return "", err
	}

	return result.WebSockerDebuggerURL, nil
}

func TestWebGL(t *testing.T) {
	wsURL, err := getWSurl("localhost:9222")
	if err != nil {
		t.Fatal(err)
	}

	parentCtx, cancelParent := chromedp.NewRemoteAllocator(context.Background(), wsURL)
	defer cancelParent()

	ctx, cancel := chromedp.NewContext(parentCtx)
	defer cancel()

	var result []byte
	tasks := chromedp.Tasks{
		chromedp.Navigate("https://get.webgl.org/"),
		chromedp.Sleep(2 * time.Second),
		chromedp.ActionFunc(func(ctx context.Context) error {
			var err error
			result, _, err = page.PrintToPDF().WithPrintBackground(false).Do(ctx)
			return err
		}),
	}

	if err := chromedp.Run(ctx, tasks); err != nil {
		t.Fatal(err)
	}

	if err := ioutil.WriteFile("out.pdf", result, 0644); err != nil {
		t.Fatal(err)
	}
}

Using docker run -p 9222:9222 chromedp/headless-shell, I get:

Hmm. While your browser seems to support WebGL, it is disabled or unavailable. If possible, please ensure that you are running the latest drivers for your video card.

And no WebGL canvas. So it’s definitely not working.

If I use docker run -p 9222:9222 --rm --name headless-shell chromedp/headless-shell:101.0.4947.3, here is what I get upon starting:

[0531/090805.491158:INFO:content_main_runner_impl.cc(1172)] Chrome is running in full browser mode.

DevTools listening on ws://0.0.0.0:9222/devtools/browser/58c5180e-3758-42f4-8dd7-fb2f6d0be506
[0531/090805.497365:WARNING:child_process_launcher_helper_posix.cc(83)] Ignoring invalid file snapshot_blob.bin
[0531/090805.500463:ERROR:gpu_init.cc(481)] Passthrough is not supported, GL is angle, ANGLE is swiftshader
[0531/090805.500930:WARNING:child_process_launcher_helper_posix.cc(83)] Ignoring invalid file snapshot_blob.bin

The PDF reports that WebGL is working:

Your browser supports WebGL You should see a spinning cube. If you do not, please visit the support site for your browser.

But the canvas is blank and I don’t see the cube.

However I was finally able to render my Three.js canvas thanks to this Chromium issue: https://bugs.chromium.org/p/chromium/issues/detail?id=765284

With docker run -p 9222:9222 chromedp/headless-shell --use-vulkan=native --use-angle=vulkan, I’m finally able to render the cube 🎉

I still get initialization errors:

[0531/091121.473789:INFO:content_main_runner_impl.cc(1144)] Chrome is running in full browser mode.

DevTools listening on ws://0.0.0.0:9222/devtools/browser/a62cb7de-5fd8-4f3c-9c36-b0d93f2626e2
[0531/091121.479610:WARNING:child_process_launcher_helper_posix.cc(83)] Ignoring invalid file snapshot_blob.bin
[0531/091121.483288:WARNING:child_process_launcher_helper_posix.cc(83)] Ignoring invalid file snapshot_blob.bin
[0531/091121.483667:ERROR:gpu_init.cc(481)] Passthrough is not supported, GL is angle, ANGLE is vulkan
[0531/091121.486852:ERROR:vulkan_instance.cc(103)] Failed to load vulkan:libvulkan.so.1: cannot open shared object file: No such file or directory
[0531/091121.486964:ERROR:gpu_init.cc(941)] Failed to create and initialize Vulkan implementation.
[0531/091129.723209:WARNING:child_process_launcher_helper_posix.cc(83)] Ignoring invalid file snapshot_blob.bin

But everything is working as expected.

We might want to update the Dockerfile’s entrypoint or give recommandation on the README to get chromedp/headless-shell WebGL rendering to work. At this point I still do not know if Chrome is really using Vulkan for WebGL rendering or falling back to a working default…

Here are the rendered PDFs: webgl-unsupported.pdf webgl-supported-no-cube-101.0.4947.3.pdf vulkan-working.pdf