Details
Description
A Qt 6.6.0 QML app that uses WebView hangs on startup when using an NVIDIA graphics driver. If I use the NVIDIA control panel to switch to "Integrated graphics", the lockup doesn't happen, and the app runs fine.
This is not a problem in Qt 6.5.3, so it has been newly introduced in 6.6.0.
This issue appears to be very similar to QTBUG-56020 and QTBUG-52954, which were fixed in Qt 5.7.1.
It's easy to reproduce, for me at least - just build and run the Qt Quick WebView example app. If I'm using the NVIDIA graphics driver, the app hangs before any UI is shown; with the "Integrated graphics" driver, the app runs OK.
The code is locking up in QWindowsOpenGLTester::testDesktopGL(), in qwindowsopengltester.cpp, when it calls MakeCurrent (which is actually a call to wglMakeCurrent()). I've captured the call stacks when stopped on a breakpoint just before the call to MakeCurrent(), in both Qt 6.5.3 and Qt 6.6.0.
In Qt 6.5.3, which works fine, the call stack looks like this:
QWindowsOpenGLTester::testDesktopGL qwindowsopengltester.cpp 375 QWindowsOpenGLTester::detectSupportedRenderers qwindowsopengltester.cpp 256 QWindowsOpenGLTester::supportedRenderers qwindowsopengltester.cpp 293 QWindowsStaticOpenGLContext::doCreate qwindowsintegration.cpp 434 QWindowsStaticOpenGLContext::create qwindowsintegration.cpp 455 QWindowsIntegration::staticOpenGLContext qwindowsintegration.cpp 514 QWindowsIntegration::createPlatformOpenGLContext qwindowsintegration.cpp 460 QOpenGLContext::create qopenglcontext.cpp 354 qAddPreRoutine qcoreapplication.cpp 267 QtWebEngineQuick::initialize qtwebenginequickglobal.cpp 49 QWebEngineWebViewPlugin::prepare qwebenginewebviewplugin.cpp 23 initializeImpl qtwebviewfunctions.cpp 35 qt_call_pre_routines qcoreapplication.cpp 306 QCoreApplicationPrivate::init qcoreapplication.cpp 912 QGuiApplicationPrivate::init qguiapplication.cpp 1581 QGuiApplication::QGuiApplication qguiapplication.cpp 643 main main.cpp 36
You can see that the OpenGL initialization is being done from the main() function, which appears to be the right way to do it.
In Qt 6.6.0, which locks up, the call stack looks like this:
QWindowsOpenGLTester::testDesktopGL qwindowsopengltester.cpp 375 QWindowsOpenGLTester::detectSupportedRenderers qwindowsopengltester.cpp 256 QWindowsOpenGLTester::supportedRenderers qwindowsopengltester.cpp 293 QWindowsStaticOpenGLContext::doCreate qwindowsintegration.cpp 422 QWindowsStaticOpenGLContext::create qwindowsintegration.cpp 443 QWindowsIntegration::staticOpenGLContext qwindowsintegration.cpp 502 QWindowsIntegration::createPlatformOpenGLContext qwindowsintegration.cpp 448 QOpenGLContext::create qopenglcontext.cpp 355 QWebEnginePage::setUrlRequestInterceptor Qt6WebEngineCored qAddPreRoutine qcoreapplication.cpp 267 QWebEnginePage::setUrlRequestInterceptor Qt6WebEngineCored QWebEnginePage::setUrlRequestInterceptor Qt6WebEngineCored QWebEnginePage::setUrlRequestInterceptor Qt6WebEngineCored initterm ucrtbased QWebEnginePage::setUrlRequestInterceptor Qt6WebEngineCored QWebEnginePage::setUrlRequestInterceptor Qt6WebEngineCored QWebEnginePage::setUrlRequestInterceptor Qt6WebEngineCored QWebEnginePage::setUrlRequestInterceptor Qt6WebEngineCored RtlActivateActivationContextUnsafeFast ntdll LdrGetProcedureAddressEx ntdll LdrGetProcedureAddressEx ntdll LdrGetProcedureAddressEx ntdll LdrGetProcedureAddressEx ntdll RtlSwitchedVVI ntdll RtlGetFullPathName_UstrEx ntdll RtlDosPathNameToNtPathName_U ntdll LdrLoadDll ntdll LoadLibraryExW KERNELBASE PGHookFunction PGHook QLibraryPrivate::load_sys qlibrary_win.cpp 63 QLibraryPrivate::load qlibrary.cpp 523 QLibraryPrivate::loadPlugin qlibrary.cpp 575 QLibraryPrivate::pluginInstance qlibrary.cpp 496 QFactoryLoader::instance qfactoryloader.cpp 374 QWebViewFactory::getPlugin qwebviewfactory.cpp 123 initializeImpl qtwebviewfunctions.cpp 31 qt_call_pre_routines qcoreapplication.cpp 306 QCoreApplicationPrivate::init qcoreapplication.cpp 912 QGuiApplicationPrivate::init qguiapplication.cpp 1577 QGuiApplication::QGuiApplication qguiapplication.cpp 643 main main.cpp 36
In this case the OpenGL initialization is being done in the DLL loading sequence for the WebEngine plugin. There is a strong hint in QTBUG-56020 that this is problematic, as the Gerrit reviews for that Jira say "Do not call QOpenGLContext::openGLModuleType() from MainDll".
There is a workaround. If I add this code in the main.cpp module, then that forces the OpenGL initialization to be done directly from main(), and the lockup doesn't happen:
#include <QOpenGLContext>
static void initialize()
{
QOpenGLContext context;
context.create();
}
Q_COREAPP_STARTUP_FUNCTION(initialize)
Attachments
Issue Links
- duplicates
-
QTBUG-117882 Qt 6.6.0rc QWebView on Windows locks
- Closed
- relates to
-
QTBUG-52954 WebEngine hangs when loaded in a plugin with AMD Radeon display adapter
- Closed
-
QTBUG-56020 WebEngine hangs when loaded in a plugin with Nvidia Geforce GTX 660 display adapter
- Closed
-
QTBUG-117882 Qt 6.6.0rc QWebView on Windows locks
- Closed