You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WSL2中PyQtWebEngine及GLX创建GL上下文失败求助

WSL2 Ubuntu 22.04中PyQtWebEngine程序GL上下文创建失败问题

问题描述

在Windows 11的WSL2(Ubuntu 22.04)实例中运行基于PyQt6 PyQtWebEngine的浏览器程序时出现崩溃,错误提示GL上下文创建失败。后续用C++代码复现了相同的GL上下文创建问题。

Python复现代码

import sys
from PyQt6.QtCore import *
from PyQt6.QtWidgets import *
from PyQt6.QtGui import QAction
from PyQt6.QtWebEngineWidgets import QWebEngineView

class BrowserApp(QMainWindow):

    def __init__(self):
        super().__init__()

        # Set up the browser
        self.browser = QWebEngineView()
        self.browser.setUrl(QUrl("https://www.google.com"))

        self.setCentralWidget(self.browser)
        self.showMaximized()

        # navigation bar
        navbar = QToolBar()
        self.addToolBar(navbar)

        back_btn = QAction("Back", self)
        back_btn.triggered.connect(self.browser.back)
        navbar.addAction(back_btn)

        forward_btn = QAction("Forward", self)
        forward_btn.triggered.connect(self.browser.forward)
        navbar.addAction(forward_btn)

        reload_btn = QAction("Reload", self)
        reload_btn.triggered.connect(self.browser.reload)
        navbar.addAction(reload_btn)

        home_btn = QAction("Home", self)
        home_btn.triggered.connect(self.navigate_home)
        navbar.addAction(home_btn)

        self.url_bar = QLineEdit()
        self.url_bar.returnPressed.connect(self.navigate_to_url)
        navbar.addWidget(self.url_bar)

        self.browser.urlChanged.connect(self.update_url)

    def navigate_home(self):
        self.browser.setUrl(QUrl("https://www.google.com"))

    def navigate_to_url(self):
        url = self.url_bar.text()
        self.browser.setUrl(QUrl(url))

    def update_url(self, q: QUrl):
        self.url_bar.setText(q.toString())

app = QApplication(sys.argv)
window = BrowserApp()
sys.exit(app.exec())

Python程序运行错误信息

D3D12: Removing Device.
[68941:68967:0907/170452.006866:ERROR:gl_context_egl.cc(370)] eglCreateContext failed with error EGL_BAD_ALLOC
[68941:68967:0907/170452.006913:ERROR:gpu_channel_manager.cc(888)] Failed to create GLES3 context, fallback to GLES2.
Segmentation fault

系统配置

  • 操作系统:Microsoft Windows 11
  • CPU:13th Gen Intel(R) Core(TM) i7-13700 @ 2100 MHz
  • GPU:Intel(R) UHD Graphics 770

C++复现代码

#include <iostream>
#include <GL/glx.h>
#include <X11/Xlib.h>

int IgnoreX11Errors(Display *display, XErrorEvent *error) {
    return 0;  // Ignore errors
}

int main() {
    Display* display = XOpenDisplay(nullptr);
    if (!display) {
        std::cerr << "Unable to open X display." << std::endl;
        return -1;
    }

    static int visualAttribs[] = {
        GLX_X_RENDERABLE, True,
        GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT,
        GLX_RENDER_TYPE, GLX_RGBA_BIT,
        GLX_X_VISUAL_TYPE, GLX_TRUE_COLOR,
        GLX_RED_SIZE, 8,
        GLX_GREEN_SIZE, 8,
        GLX_BLUE_SIZE, 8,
        GLX_ALPHA_SIZE, 8,
        GLX_DEPTH_SIZE, 24,
        GLX_STENCIL_SIZE, 8,
        GLX_DOUBLEBUFFER, True,
        None
    };

    int numConfigs;
    GLXFBConfig* fbConfigs = glXChooseFBConfig(display, DefaultScreen(display), visualAttribs, &numConfigs);
    if (!fbConfigs) {
        std::cerr << "Failed to retrieve framebuffer configs." << std::endl;
        XCloseDisplay(display);
        return -1;
    }

    GLXFBConfig config = fbConfigs[0];
    XFree(fbConfigs);

    PFNGLXCREATECONTEXTATTRIBSARBPROC glXCreateContextAttribsARB = 
        (PFNGLXCREATECONTEXTATTRIBSARBPROC) glXGetProcAddressARB((const GLubyte*) "glXCreateContextAttribsARB");

    if (!glXCreateContextAttribsARB) {
        std::cerr << "glXCreateContextAttribsARB is not available." << std::endl;
        XCloseDisplay(display);
        return -1;
    }

    int contextAttribs[] = {
        GLX_CONTEXT_MAJOR_VERSION_ARB, 4,
        GLX_CONTEXT_MINOR_VERSION_ARB, 5,
        None
    };

    auto old_error_handler = XSetErrorHandler(IgnoreX11Errors);
    GLXContext context = glXCreateContextAttribsARB(display, config, 0, True, contextAttribs);
    XSetErrorHandler(old_error_handler);

    if (!context) {
        std::cerr << "Failed to create GL context with glXCreateContextAttribsARB." << std::endl;
        XCloseDisplay(display);
        return -1;
    }

    std::cout << "GL context created successfully." << std::endl;

    glXDestroyContext(display, context);
    XCloseDisplay(display);
    return 0;
}

C++代码编译命令

g++ tmp.cpp -o tmp -lGL -lX11

C++程序运行错误信息

Failed to create GL context with glXCreateContextAttribsARB.

排查思路与解决建议

1. 降低GL上下文版本要求

程序尝试创建GL 4.5上下文失败,WSLg对高版本GL的支持可能有限。

  • 修改C++代码中的上下文版本为3.2或更低,测试能否创建成功:
    int contextAttribs[] = {
        GLX_CONTEXT_MAJOR_VERSION_ARB, 3,
        GLX_CONTEXT_MINOR_VERSION_ARB, 2,
        None
    };
    
  • 对PyQtWebEngine,可通过环境变量强制使用低版本GL或禁用GPU加速:
    # 强制使用桌面GL并忽略GPU黑名单
    export QTWEBENGINE_CHROMIUM_FLAGS="--use-gl=desktop --ignore-gpu-blacklist --disable-gpu-driver-bug-workarounds"
    # 直接禁用GPU加速
    export QTWEBENGINE_CHROMIUM_FLAGS="--disable-gpu"
    
    运行Python程序时带上该环境变量即可。

2. 更新WSL2与GPU驱动

  • 执行wsl --update更新WSL2内核及组件,确保WSLg功能处于最新状态
  • 前往Intel官网下载并安装最新版UHD Graphics 770驱动,Windows侧的GPU驱动版本直接影响WSLg的GL支持

3. 检查WSLg配置

确保WSLg的GPU加速功能正常启用:

  • 查看或创建~/.wslconfig文件,添加以下配置:
    [wsl2]
    guiApplications=true
    drmRenderDevice=/dev/dri/renderD128
    
  • 执行wsl --shutdown关闭WSL实例,重新启动后生效

4. 验证基础GL支持

安装mesa-utils工具查看WSL中支持的GL版本:

sudo apt install mesa-utils
glxinfo | grep "OpenGL version"

如果输出的版本低于4.5,说明当前WSLg不支持高版本GL,只能降级程序的GL要求。

5. 测试无GPU加速模式

直接禁用PyQtWebEngine的GPU加速运行程序:

QTWEBENGINE_CHROMIUM_FLAGS="--disable-gpu" python your_script.py

若程序能正常运行,说明问题根源在GPU加速的GL上下文创建环节。

内容的提问来源于stack exchange,提问作者Tokubara

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 14:38:10