Qml界面渲染机制



  • 渲染层次:

    0_1531798264848_48a56a99-a2a7-4a1e-8d0e-f12d889d74a1-image.png

    渲染循环分三种,basic, windows, and threaded,其中Basic和Windows是单线程的,threaded在单独线程里面渲染场景,qt会根据平台自动选择一种,我电脑上已经验证是threaded

    qt.scenegraph.general: threaded render loop qt.scenegraph.general: Using sg animation driver qt.scenegraph.general: Animation Driver: using vsync: 16.67 ms

    同时可以知道画面垂直同步是16.67 ms,理论60Hz

    线程渲染循环中如何完成一帧

    0_1531798407892_935d0c1f-554a-4cbb-999a-a0966484548d-image.png

    1. A change occurs in the QML scene, causing QQuickItem::update() to be called. This can be the result of for instance an animation or user input. An event is posted to the render thread to initiate a new frame.
    2. The render thread prepares to draw a new frame and makes the OpenGL context current and initiates a block on the GUI thread.
    3. While the render thread is preparing the new frame, the GUI thread calls QQuickItem::updatePolish() to do final touch-up of items before they are rendered.
    4. GUI thread is blocked.
    5. The QQuickWindow::beforeSynchronizing() signal is emitted. Applications can make direct connections (using Qt::DirectConnection) to this signal to do any preparation required before calls to QQuickItem::updatePaintNode().
    6. Synchronization of the QML state into the scene graph. This is done by calling the QQuickItem::updatePaintNode() function on all items that have changed since the previous frame. This is the only time the QML items and the nodes in the scene graph interact.
    7. GUI thread block is released.
    8. The scene graph is rendered:
    9. The QQuickWindow::beforeRendering() signal is emitted. Applications can make direct connections (using Qt::DirectConnection) to this signal to use custom OpenGL calls which will then stack visually beneath the QML scene.
    10. Items that have specified QSGNode::UsePreprocess, will have their QSGNode::preprocess() function invoked.
    11. The renderer processes the nodes and calls OpenGL functions.
    12. The QQuickWindow::afterRendering() signal is emitted. Applications can make direct connections (using Qt::DirectConnection) to this signal to use custom OpenGL calls which will then stack visually over the QML scene.
    13. The rendered frame is swapped and QQuickWindow::frameSwapped() is emitted.
    14. While the render thread is rendering, the GUI is free to advance animations, process events, etc.
      The threaded renderer is currently used by default on Windows with opengl32.dll, Linux with non-Mesa based drivers, macOS, mobile platforms, and Embedded Linux with EGLFS but this is subject to change. It is possible to force use of the threaded renderer by setting QSG_RENDER_LOOP=threaded in the environment.

    非线程渲染

    0_1531798434302_91612780-f2cf-4fdb-b5a1-aeb004a1e7a2-image.png

    查看渲染方式:

    QLoggingCategory::setFilterRules(QStringLiteral("qt.scenegraph.general=true")); qSetMessagePattern("%{category}: %{message}");



  • @青山白云 对,Qt Quick内部实现还是根据屏幕的刷新率来的。不这么做的话,在不同平台上使用Animator做动画速度会出现不一致的现象。所以Qt的Animation Driver也是按照这样的思路规定16.67ms。


Log in to reply
 

走马观花

最近的回复

  • 诶 没有Linux吗??

    read more
  • 萌梦 男孩,女孩,和蛋

    menghome.png

    read more
  • 设计模式-工厂模式

    使用qt/qml来演示设计模式效果,便于学习理解

    1)定义创建对象的接口,封装对象的创建
    2)使具体化类的工作延迟到工厂子类中

    bg.png
    image.png

    1. 工厂类

    createProduct使用了参数来选择要创建哪个产品

    #ifndef FACTORY_H #define FACTORY_H #include <QObject> class Product; class QString; class Factory: public QObject { Q_OBJECT public: virtual ~Factory() = 0; virtual Product* createProduct(QString type) = 0; protected: Factory(); }; class ConcreteFactory: public Factory { Q_OBJECT public: ~ConcreteFactory(); ConcreteFactory(); public slots: Product* createProduct(QString type); }; #endif // FACTORY_H #include "factory.h" #include "product.h" #include <QtQml/qqml.h> Factory::~Factory() { } Factory::Factory() { qmlRegisterType<Product>("Product", 1, 0, "Product"); } ConcreteFactory::~ConcreteFactory() { } ConcreteFactory::ConcreteFactory() { } Product *ConcreteFactory::createProduct(QString type) { if(type == "boy") return static_cast<Product *>(new ConcreteProduct1()); else if(type == "girl") return static_cast<Product *>(new ConcreteProduct2()); return static_cast<Product *>(new ConcreteProduct1()); } 2 产品类

    一个产品是萌梦男,一个产品是萌梦女

    #ifndef PRODUCT_H #define PRODUCT_H #include <QObject> class Product: public QObject { Q_OBJECT public: virtual ~Product() = 0; Q_PROPERTY(QString icon READ icon NOTIFY iconChanged) QString m_icon; QString icon() const { return m_icon; } signals: void iconChanged(QString icon); protected: Product(); signals: public slots: }; class ConcreteProduct1: public Product { Q_OBJECT public: ~ConcreteProduct1(); ConcreteProduct1(); }; class ConcreteProduct2: public Product { Q_OBJECT public: ~ConcreteProduct2(); ConcreteProduct2(); }; #endif // PRODUCT_H #include "product.h" Product::~Product() { } Product::Product() { } ConcreteProduct1::~ConcreteProduct1() { } ConcreteProduct1::ConcreteProduct1() { m_icon = "qrc:/images/boy.png"; } ConcreteProduct2::~ConcreteProduct2() { } ConcreteProduct2::ConcreteProduct2() { m_icon = "qrc:/images/girl.png"; } 3. main.qml

    使用timer,canvas,listview等实现一个自动化生产的动画效果

    源代码

    Fork me on Gitee

    read more
  • blender建模 章鱼
    捕获2.PNG 😵

    read more

关注我们

微博
QQ群