Uploaded image for project: 'Qt'
  1. Qt
  2. QTBUG-119183

Qt 6.6.0 WebView app hangs on startup with NVIDIA graphics driver

    XMLWordPrintable

Details

    • Bug
    • Resolution: Unresolved
    • P2: Important
    • None
    • 6.6.0
    • WebView
    • None
    • Dell Latitude 5521 laptop
      Windows 10 Pro
      NVIDIA GeForce MX450 graphics card
    • Windows

    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

          No reviews matched the request. Check your Options in the drop-down menu of this sections header.

          Activity

            People

              stromme Christian
              roballan Rob Allan
              Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

              Dates

                Created:
                Updated:

                Gerrit Reviews

                  There are no open Gerrit changes