Qt Quick绘制非常缓慢

4
我刚开始学习Qt Quick,有一个非常基本的程序,基本上与启动Qt Quick Controls应用程序项目时相同。
问题是当我尝试调整窗口大小时,它需要很长时间才能完成。可以在下面的.gif文件中看到。

Problem

我在网上找到的有关类似问题的唯一信息是,您可以使用QML分析器查找引起延迟的位置,有时是由于调试器原因。因此,下面您可以看到QML分析器,gif是在发布模式下记录的。

enter image description here

据我所知,动画正在锁定GUI线程,导致渲染或重绘变慢,但我不确定是什么原因导致的。
我很感激任何解决问题的帮助。
代码并不多。

Test.pro

QT += qml quick
CONFIG += c++11
SOURCES += main.cpp
RESOURCES += qml.qrc
QML_IMPORT_PATH =
QML_DESIGNER_IMPORT_PATH =
DEFINES += QT_DEPRECATED_WARNINGS
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target

main.cpp

#include <QGuiApplication>
#include <QQmlApplicationEngine>

int main(int argc, char *argv[])
{
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
    QGuiApplication app(argc, argv);

    QQmlApplicationEngine engine;
    engine.load(QUrl(QLatin1String("qrc:/main.qml")));
    if (engine.rootObjects().isEmpty())
        return -1;

    return app.exec();
}

main.qml

import QtQuick 2.7
import QtQuick.Controls 2.0
import QtQuick.Layouts 1.3

ApplicationWindow {
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World")

    SwipeView {
        id: swipeView
        anchors.fill: parent
        currentIndex: tabBar.currentIndex

        Page1 {
            Label {
                text: qsTr("First page")
                anchors.centerIn: parent
            }
        }

        Page {
            Label {
                text: qsTr("Second page")
                anchors.centerIn: parent
            }
        }

        Page {
            Label {
                text: qsTr("Third page")
                anchors.centerIn: parent
            }
        }
    }

    footer: TabBar {
        id: tabBar
        currentIndex: swipeView.currentIndex
        TabButton {
            text: qsTr("First")
        }
        TabButton {
            text: qsTr("Second")
        }
        TabButton {
            text: qsTr("Third")
        }
    }
}

Page1.qml

import QtQuick 2.7

Page1Form {
    button1.onClicked: {
        console.log("Button Pressed. Entered text: " + textField1.text);
    }
}

Page1Form.ui.qml

import QtQuick 2.7
import QtQuick.Controls 2.0
import QtQuick.Layouts 1.3

Item {
    property alias textField1: textField1
    property alias button1: button1

    RowLayout {
        anchors.horizontalCenter: parent.horizontalCenter
        anchors.topMargin: 20
        anchors.top: parent.top

        TextField {
            id: textField1
            placeholderText: qsTr("Text")
        }

        Button {
            id: button1
            text: qsTr("Press Me")
        }
    }
}

规格:Windows 10,Qt 5.9,MSVC 2017


Qt论坛交叉发布


我没有像你遇到的那样的问题。窗口调整大小非常平滑。你可能需要仔细检查其他东西。我正在使用Qt5.9和Visual Studio 2015。 - CroCo
@CroCo 好的。谢谢。那很奇怪。我想知道 Visual Studio 版本是否会影响它。 - Dan
不确定但调整窗口大小的功能是一件常见的事情。我怀疑QML无法支持此功能。此外,您正在使用的应用程序非常简单,即使是极其简单的API也不会出现这种症状。有些问题出现了。 - CroCo
3个回答

2

谢谢你的回答。我下班后一定会研究一下这个。 - Dan
遗憾的是,这对我似乎没有起作用。然而,这可能是因为我的设置有误。您知道如何在默认项目上创建一个 ANGLED3D9 项目,该默认项目显然是一个 D3D11 项目吗? - Dan

0

我认为你遇到这个问题是因为在幕后使用了软件渲染,所以需要相当长的时间。为了启用硬件渲染,你需要安装ANGLE驱动程序。你的性能分析图片显示交换操作占据了所有时间,这实际上是将所有像素从CPU复制到GPU,这就是为什么你看到这种滞后的原因。我不同意@dtech的看法,认为这不会对你有所帮助。我在Windows上使用ANGLE驱动程序渲染相当复杂的GL 3D场景,所以QT也能做到,我确信。


0

当窗口大小调整时,QML必须重新评估大小的绑定。因此,所有更改大小或具有锚定属性的元素都需要重新计算。 据我所知,QT使用openGL作为默认渲染器。在窗口大小调整时,openGL渲染的缓冲区也需要调整大小,并且整个场景图需要重新绘制。但在此之前,如果它们的大小发生了变化,则需要首先重新渲染单个元素。Qml将可见元素存储在纹理中,因此随着元素的调整,必须重新创建纹理...

可能还会发生更多情况,这取决于您使用的元素、场景图的构建方式或批次的组成方式。

如果要调试场景图,可以通过设置环境变量来实现。 例如,您可以通过设置使更改以随机颜色闪烁:

QSG_VISUALIZE=changes

在这里了解有关Qt Quick场景图渲染器的更多信息。


好的。那你知道我怎么能加快这个过程吗? - Dan
1
听起来有些傻,但不要调整窗口大小,也不要使用具有动态尺寸的元素。除此之外,我自己还没有找到任何解决方案... - SigSegOwl
好的,谢谢。你知道ANGLE是否是一个可行的替代方案吗? - Dan
1
不确定,当然你可以尝试,但我建议先更仔细地识别问题。你可以将QSG_RENDER_TIMING=1设置为环境变量,查看调整大小时的时间,这样你就可以确定渲染确实是一个问题。此外,请查看我上面发布的场景图链接以获取性能提示! - SigSegOwl
ANGLE很可能不会改变任何事情,甚至可能更糟。问题不在图形性能上,而且因为它基本上是仿真,所以ANGLE不会改善它。 - dtech

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接