Windows10下Qt 5.11.1开发的Qt/QML应用与OpenGL程序同开性能下降问询
可能的原因
- Windows OpenGL上下文调度优先级问题:GLUT应用默认会抢占更高的GPU渲染时间片,Qt 5.11的QtQuick默认没有设置OpenGL上下文的优先级属性,系统会优先分配GPU资源给优先级更高的GL上下文,即使总GPU占用只有50%也会出现这个情况。笔记本的双显卡切换机制也可能加剧这个问题,QtQuick默认跑在核显、GLUT应用跑在独显的情况下,跨显卡的资源同步也会导致QML渲染卡顿。
- QtQuick渲染线程阻塞:Qt 5.11版本的QtQuick默认是渲染线程和GUI线程分离,但如果GLUT应用占用了Windows的WGL共享资源锁,会导致QtQuick的渲染线程每次提交渲染指令时都要等待锁释放,出现频繁的阻塞,表现就是刷新滞后。
- 垂直同步(VSync)冲突:两个OpenGL应用同时开启垂直同步的情况下,Windows的合成管理器会强制将两个应用的渲染帧对齐到显示器刷新率,如果其中一个应用的帧渲染耗时更长,会拖慢另一个应用的帧输出速率,即使两个应用的GPU占用都没到上限。
- QtQuick的渲染后端适配问题:Qt 5.11的默认QtQuick后端是桌面OpenGL,部分笔记本显卡驱动对多OpenGL上下文的共享资源处理有bug,会优先保障全屏或者前台的OpenGL应用的渲染资源,后台的QtQuick应用会被限制渲染速率。
可参考的排查方向
- 验证渲染后端影响:在QML应用的
QApplication初始化前添加强制渲染后端的参数,测试不同后端的表现:
如果切换到ANGLE后端后卡顿消失,基本可以确定是原生OpenGL上下文调度的问题。// 软渲染后端,排除GPU调度问题 QCoreApplication::setAttribute(Qt::AA_UseSoftwareOpenGL); // 或者用ANGLE的D3D转译后端,绕开原生OpenGL调度 QCoreApplication::setAttribute(Qt::AA_UseOpenGLES); - 调整QtQuick渲染优先级:在QQuickView或者QQuickWindow实例化后,设置渲染线程优先级:
同时可以添加window->setRenderPriority(QQuickWindow::HighRenderPriority);QCoreApplication::setAttribute(Qt::AA_DontCreateNativeWidgetSiblings)属性,避免不必要的原生上下文切换。 - 关闭垂直同步测试:在QML应用启动时添加环境变量关闭垂直同步:
如果关闭后卡顿缓解,就是VSync冲突导致的,可后续根据需求调整VSync策略。// 切换到单线程渲染循环 qputenv("QSG_RENDER_LOOP", "basic"); // 关闭垂直同步 qputenv("QSG_VSYNC", "0"); - 定位具体瓶颈:开启QML调试器的性能面板,或者添加环境变量
QSG_VISUALIZE=overdraw查看过度绘制情况,同时用Windows任务管理器的GPU面板查看两个应用分别占用的GPU引擎(3D、复制、视频编码等),确认是否存在某个细分引擎被占满的情况,不要只看总GPU占用率。 - 测试窗口状态影响:将QtQuick窗口设置为置顶、或者和GLUT应用同时显示在前台,观察卡顿是否消失,如果消失说明是系统对后台OpenGL应用的渲染限制,可通过设置窗口的
Qt::WindowStaysOnTopHint属性或者调用Windows API调整窗口的渲染优先级规避。
内容的提问来源于stack exchange,提问作者Sebastian
相关产品推荐
相关产品推荐

