Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Render/Layout performance very slow. High CPU usage for only 20 QLabels in 30fps
Forum Updated to NodeBB v4.3 + New Features

Render/Layout performance very slow. High CPU usage for only 20 QLabels in 30fps

Scheduled Pinned Locked Moved Unsolved General and Desktop
22 Posts 3 Posters 11.5k Views 2 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • mrjjM Offline
    mrjjM Offline
    mrjj
    Lifetime Qt Champion
    wrote on last edited by
    #12

    Wondering:
    Those in Created ID etc
    are the labels ?

    1 Reply Last reply
    0
    • mrjjM Offline
      mrjjM Offline
      mrjj
      Lifetime Qt Champion
      wrote on last edited by
      #13

      Just for test
      Seems to use 6-8% on windows
      alt text

      1 Reply Last reply
      0
      • M Offline
        M Offline
        marcj
        wrote on last edited by
        #14

        The thing is, the prototype that has most of the stuff already is implemented in TypeScript/HTML5 (no OpenGL here), and we have at 15fps roughly the same CPU usage as QT has with displaying 20 QLabels at 30fps. We wanted to pump it up to 60 fps to get a very smooth running GUI, but that would have cost one CPU core using the HTML5 engine, so I gave QT a try. I'm afraid QT's CPU usage goes through the roof when I implement it using TableView and way more QLabels, Buttons, SelectBox etc as well.

        So strictly speaking, I thought we could go the native approach to save a LOT cpu circles, but it seems Chromium's HTML engine is already highly optimised as we can compare directly the CPU usage here. I see however an incredible huge CPU usage difference when I compare QT/Chromium with imGUI, so I still have the hope that I can get the same performance using QT. 😎

        "Create ID" It's actually a simple table grid, just text. First row has special styling due to be the table header with some onclick events.

        1 Reply Last reply
        0
        • mrjjM Offline
          mrjjM Offline
          mrjj
          Lifetime Qt Champion
          wrote on last edited by mrjj
          #15

          Hi
          Give it a day more so other timezones come online.
          Some user knows far more about Qt on mac than me.

          Im pretty sure it can get better but i agree with you that
          it doesn't look as it will scale well.

          I have seen reports on QWidgets and macOS having not optimal performance especially
          with retina displays but im not using macOS so im not sure what current status is.

          1 Reply Last reply
          0
          • M Offline
            M Offline
            marcj
            wrote on last edited by
            #16

            Thanks MrJJ, much appreciated.

            mrjjM 1 Reply Last reply
            1
            • M marcj

              Thanks MrJJ, much appreciated.

              mrjjM Offline
              mrjjM Offline
              mrjj
              Lifetime Qt Champion
              wrote on last edited by
              #17

              @marcj
              Np. i wish you good luck with project. Looks very nice. ( im GUI lover)

              1 Reply Last reply
              0
              • SGaistS Offline
                SGaistS Offline
                SGaist
                Lifetime Qt Champion
                wrote on last edited by
                #18

                Hi,

                If you want something fancy and with OpenGL then @mrjj's recommendation of QtQuick is the way to go. QtQuick is OpenGL rendered by default.

                Qt Widgets have never been hardware accelerated and likely won't be any time soon. They allow you to build applications for system with lower specs.

                As the warning of QGraphicsProxyWidget states, that class should not be used in hight performance scenarios which your application is.

                As for Apple's OpenGL stack, AFAIK, it's known to not be most recent or up to date regarding the standard, so beware of that when comparing to other systems.

                On an unrelated note, it's Qt, QT stands for Apple QuickTime which you are likely not using even if developing on macOS.

                Interested in AI ? www.idiap.ch
                Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                1 Reply Last reply
                1
                • M Offline
                  M Offline
                  marcj
                  wrote on last edited by marcj
                  #19

                  Alright, I played more with QPainter, and made my own custom QWidget that uses paintEvent() to call painter->drawText directly. That should be the fastest I can get, right? Indeed, it was roughly twice the speed (8% vs 17%). However, there's no automatic geometric calculation yet for the layout manager.

                  My code:

                  // main.cpp
                  #include <QtWidgets/QApplication>
                  #include <QTimer>
                  #include <QGraphicsScene>
                  #include <QGraphicsView>
                  #include <QGridLayout>
                  #include <QtOpenGL>
                  #include <QOpenGLWidget>
                  #include <QDebug>
                  
                  class MyWidget: public QWidget {
                  
                  
                  public:
                      QString text;
                      QSize size;
                  
                      MyWidget() : QWidget() {
                          setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
                          size.setWidth(100);
                          size.setHeight(15);
                      }
                  
                      void paintEvent(QPaintEvent *event) override {
                          QPainter painter(this);
                          painter.setPen(Qt::black);
                          painter.setFont(QFont("Helvetica", 14));
                          painter.drawText(0, 14, text);
                      }
                  
                      QSize sizeHint() const
                      {
                          return size;
                      }
                  
                      void setPlainText(QString text) {
                          this->text = text;
                          update();
                      }
                  
                  };
                  
                  int main(int argc, char *argv[]) {
                      QCoreApplication::setAttribute(Qt::AA_UseOpenGLES);
                      QApplication app(argc, argv);
                  
                      const int labelsCount = 200;
                      const int cols = 10;
                      QGraphicsScene scene;
                  
                      QGridLayout *layout = new QGridLayout();
                  
                      QGraphicsView view(&scene);
                      view.setLayout(layout);
                  
                      //regarding documentation, this enabled OpengGL
                      //and in fact, the rendered font looks different when having this line active
                      view.setViewport(new QOpenGLWidget()); //helps a lot the more draws we have
                  //    view.setViewport(new QGLWidget()); //doesnt work on OSX
                  
                      QVarLengthArray<MyWidget, labelsCount> labels(labelsCount);
                  
                      for (int i =0; i < labelsCount; i++ ){
                          labels[i].setPlainText(QString("Hallo %1").arg(i));
                          layout->addWidget(&labels[i], floor(i / cols), i % cols);
                      }
                  
                      QTimer *timer = new QTimer();
                      timer->setInterval(1000/30);
                  
                      int counter = 0;
                      QObject::connect(timer, &QTimer::timeout, [&] {
                          counter++;
                          for (int i =0; i < labelsCount; i++ ){
                              auto text = QStringLiteral("(%1): %3").arg(i).arg(counter);
                              labels[i].setPlainText(text);
                          }
                      });
                  
                      timer->start();
                      view.show();
                  
                      return app.exec();
                  }
                  

                  After this good news I tested with a more realistic scenario: Having 200 labels updating in real-time (30fps). Screenshot:

                  0_1527716563882_Screen Shot 2018-05-30 at 23.42.26.png

                  At the bottom you see my HTOP Cpu utilization from that process. Unfortunately, still at 50% of a Intel i7 with over 3Ghz. The GPU isn't the bottleneck either, since I got a NVIDIA Titan Xp with 12GB RAM - no retina Display.

                  I'm running out of ideas here since I've never used QT until today and probably lack some fundamentals. I actually can't believe that printing directly with the QPainter is so darn slow. so there must be something I'm currently missing . Does anyone have an idea what else I could do? (except to leave QT behind)

                  1 Reply Last reply
                  0
                  • M Offline
                    M Offline
                    marcj
                    wrote on last edited by marcj
                    #20

                    I tried further to see where the bottleneck is. My next example shows how 200 very simple progress-bars perform. Result is that it renders way faster, only 13% CPU usage (30fps). However, drawing such OpenGL primitives is in other GUI abstraction an extremely easy task and costs almost zero CPU.

                    Code:

                    // main.cpp
                    #include <QtWidgets/QApplication>
                    #include <QTimer>
                    #include <QGraphicsScene>
                    #include <QGraphicsView>
                    #include <QGridLayout>
                    #include <QtOpenGL>
                    #include <QOpenGLWidget>
                    #include <QDebug>
                    
                    class MyWidget: public QWidget {
                    
                    
                    public:
                        QString text;
                        int value = 0; //0 -> 100
                        QSize size;
                    
                        MyWidget() : QWidget() {
                            setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
                            size.setWidth(100);
                            size.setHeight(15);
                        }
                    
                        void paintEvent(QPaintEvent *event) override {
                            QPainter painter(this);
                            painter.fillRect(QRect(0, 0, value % 100, 14), Qt::black);
                        }
                    
                        QSize sizeHint() const
                        {
                            return size;
                        }
                    
                        void setValue(int value) {
                            this->value = value;
                            update();
                        }
                    
                    };
                    
                    int main(int argc, char *argv[]) {
                        QCoreApplication::setAttribute(Qt::AA_UseOpenGLES);
                        QApplication app(argc, argv);
                    
                        const int labelsCount = 200;
                        const int cols = 10;
                        QGraphicsScene scene;
                    
                        QGridLayout *layout = new QGridLayout();
                    
                        QGraphicsView view(&scene);
                        view.setLayout(layout);
                    
                        //regarding documentation, this enabled OpengGL
                        //and in fact, the rendered font looks different when having this line active
                        view.setViewport(new QOpenGLWidget()); //helps a lot the more draws we have
                    
                        QVarLengthArray<MyWidget, labelsCount> labels(labelsCount);
                    
                        for (int i =0; i < labelsCount; i++ ){
                            layout->addWidget(&labels[i], floor(i / cols), i % cols);
                        }
                    
                        QTimer *timer = new QTimer();
                        timer->setInterval(1000/30);
                    
                        int counter = 0;
                        QObject::connect(timer, &QTimer::timeout, [&] {
                            counter++;
                            for (int i =0; i < labelsCount; i++ ){
                                labels[i].setValue(counter);
                            }
                        });
                    
                        timer->start();
                        view.show();
                    
                        return app.exec();
                    }
                    

                    Screen:

                    0_1527717767958_Screen Shot 2018-05-31 at 00.01.37.png


                    I also just made sure it's really not my hardware and implemented in another GUI library almost the same case: 200 progress-bars (although in this example it shows also text). Result is 4% CPU usage, but with a major difference that it renders at 100fps. If I go 100 fps in Qt example above, I get 50% cpu usage. If I add text right next to the rect I get probably 100%.

                    Screen of the other GUI lib:

                    0_1527718484641_Screen Shot 2018-05-31 at 00.14.28.png

                    So I guess there must be something in QT where I can have more direct access to the OpenGL abstraction.

                    1 Reply Last reply
                    0
                    • M Offline
                      M Offline
                      marcj
                      wrote on last edited by marcj
                      #21

                      I tried now as you guys suggested the QT Quick Widgets, which should be rendered with OpenGL and with performance in mind (I mean it should run on mobile devices right?). Result is not really satisfying, I guess even worse. 100 labels, 30fps -> 33% CPU burn.

                      0_1527725605455_Screen Shot 2018-05-31 at 02.13.11.png

                      Code for that:

                      //main.cpp
                      #include <QGuiApplication>
                      #include <QTimer>
                      #include <QQuickItem>
                      #include <QQmlApplicationEngine>
                      
                      int main(int argc, char *argv[])
                      {
                          QGuiApplication app(argc, argv);
                      
                          QQmlApplicationEngine engine;
                          engine.load(QUrl(QStringLiteral("main.qml")));
                      
                          QQuickItem *list = engine.rootObjects()[0]->findChild<QQuickItem *>(QString("list"),
                                                                                               Qt::FindChildrenRecursively);
                      
                          QTimer *timer = new QTimer();
                          timer->setInterval(1000/30);
                          int counter = 0;
                      
                          QObject::connect(timer, &QTimer::timeout, [&] {
                              counter++;
                              for(auto const& item: list->childItems()) {
                                  item->setProperty("text", QString("WTF %1").arg(counter));
                              }
                          });
                      
                          timer->start();
                      
                          return app.exec();
                      }
                      
                      import QtQuick 2.6
                      import QtQuick.Controls 2.0
                      
                      ApplicationWindow {
                          id: root
                          width: 600
                          height: 500
                          visible: true
                      
                          Grid {
                              objectName: "list"
                              rows: 50
                              columns: 10
                              spacing: 10
                      
                              Repeater {
                                  model: 100;
                                  objectName: "repeater"
                                  Label {
                                      text: "Hello world"
                                      width: 60
                                      objectName: "label" + index
                                  }
                              }
                          }
                      }
                      
                      1 Reply Last reply
                      0
                      • SGaistS Offline
                        SGaistS Offline
                        SGaist
                        Lifetime Qt Champion
                        wrote on last edited by
                        #22

                        If you'd like to go on with raw OpenGL, then the Qt OpenGL and GUI modules are what you want to look at, they provide everything you need to write OpenGL application.

                        Interested in AI ? www.idiap.ch
                        Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                        1 Reply Last reply
                        1

                        • Login

                        • Login or register to search.
                        • First post
                          Last post
                        0
                        • Categories
                        • Recent
                        • Tags
                        • Popular
                        • Users
                        • Groups
                        • Search
                        • Get Qt Extensions
                        • Unsolved