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. Performance of QQuickWidget
QtWS25 Last Chance

Performance of QQuickWidget

Scheduled Pinned Locked Moved General and Desktop
slowperformancerenderingpaintingrepaint
16 Posts 2 Posters 8.3k Views
  • 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.
  • Z Offline
    Z Offline
    zepfan
    wrote on 27 Jun 2015, 12:53 last edited by
    #1

    Hi,

    I've created a small application using a C++ class that derives from QQuickWidget, and this launches a qml file. The qml file has a Repeater and creates 20 VU meters. The VU meter is contained inside its own qml file and has a timer which changes the height of a clip rectangle using a random number......so the meter is being constantly repainted.

    However, if I have 20 meters visible, but only one of these is getting its height changed the CPU usage is the same as when all 20 are getting their height changed. Why is this? I would have thought that the CPU usage would be much lower because the other 19 meters are not getting their height changed, and are therefore not being repainted?

    Any advice / tips is appreciated!

    Thanks.

    P 1 Reply Last reply 27 Jun 2015, 13:45
    0
    • Z zepfan
      27 Jun 2015, 12:53

      Hi,

      I've created a small application using a C++ class that derives from QQuickWidget, and this launches a qml file. The qml file has a Repeater and creates 20 VU meters. The VU meter is contained inside its own qml file and has a timer which changes the height of a clip rectangle using a random number......so the meter is being constantly repainted.

      However, if I have 20 meters visible, but only one of these is getting its height changed the CPU usage is the same as when all 20 are getting their height changed. Why is this? I would have thought that the CPU usage would be much lower because the other 19 meters are not getting their height changed, and are therefore not being repainted?

      Any advice / tips is appreciated!

      Thanks.

      P Offline
      P Offline
      p3c0
      Moderators
      wrote on 27 Jun 2015, 13:45 last edited by
      #2

      Hi @zepfan, I don't have the exact reason as I don’t have enough experience with using QQuickWidget but the documentation mentions few points related to performance hit that may occur. Check out the 3 notes under that topic. Can you try using QQuickView and createWindowContainer() as according to this blog too:

      Well, unless there is a very good reason for using it and you know what you are doing. If the stacking and other limitations do not apply and the application is targeting desktop platforms only and the platform in question is able to use the Qt Quick Scenegraph’s threaded render loop, then having a QQuickView embedded via createWindowContainer() will always lead to better performance when compared to QQuickWidget

      157

      1 Reply Last reply
      0
      • Z Offline
        Z Offline
        zepfan
        wrote on 27 Jun 2015, 17:58 last edited by
        #3

        Thanks for the response. I tried using a QQuickView and yes the performance is better, but it still uses the same CPU % whether there is one meter active or if there are 20 active. So it seems there is still unnecessary repainting happening on the other 19 meters. Is there a way to prevent repainting of elements that don't need it?

        Thanks.

        P 1 Reply Last reply 28 Jun 2015, 04:52
        0
        • Z zepfan
          27 Jun 2015, 17:58

          Thanks for the response. I tried using a QQuickView and yes the performance is better, but it still uses the same CPU % whether there is one meter active or if there are 20 active. So it seems there is still unnecessary repainting happening on the other 19 meters. Is there a way to prevent repainting of elements that don't need it?

          Thanks.

          P Offline
          P Offline
          p3c0
          Moderators
          wrote on 28 Jun 2015, 04:52 last edited by
          #4

          @zepfan

          So it seems there is still unnecessary repainting happening on the other 19 meters.

          Are you sure they are repainted everytime ? How did you check ?
          Is this VU meter a C++ class derived from QQuickPaintedItem ?

          157

          1 Reply Last reply
          0
          • Z Offline
            Z Offline
            zepfan
            wrote on 28 Jun 2015, 11:35 last edited by
            #5

            No I'm not sure that they're getting repainted, but if I have just one active meter visible and nothing else, the CPU % goes down. But if I have 20 visible and only one active then the CPU is much higher. Since the other 19 shouldn't be getting repainted why would the CPU still be higher? The 19 meters that are inactive just have a black opaque background.
            The VU meters are built just using qml. Only the QQuickView derived class is C++ and it has basically nothing in it. This is just a small test app I've built with no frills.

            Any ideas?

            Thanks.

            P 1 Reply Last reply 28 Jun 2015, 13:28
            0
            • Z zepfan
              28 Jun 2015, 11:35

              No I'm not sure that they're getting repainted, but if I have just one active meter visible and nothing else, the CPU % goes down. But if I have 20 visible and only one active then the CPU is much higher. Since the other 19 shouldn't be getting repainted why would the CPU still be higher? The 19 meters that are inactive just have a black opaque background.
              The VU meters are built just using qml. Only the QQuickView derived class is C++ and it has basically nothing in it. This is just a small test app I've built with no frills.

              Any ideas?

              Thanks.

              P Offline
              P Offline
              p3c0
              Moderators
              wrote on 28 Jun 2015, 13:28 last edited by
              #6

              @zepfan I guess there could be some other problem then. May be some connections or properties that are getting updated. Even if it gets repainted I think CPU usage wont go that much high as QML uses scenegraph which in turn uses OpenGL so most of the rendering is done by the hardware.
              Can you post a complete minimal runnable example to test ?

              157

              1 Reply Last reply
              0
              • Z Offline
                Z Offline
                zepfan
                wrote on 28 Jun 2015, 17:45 last edited by p3c0
                #7

                Here is the qml file that defines the meter. I use a Repeater to create multiple instances of these and give each one a unique index (meterIndex).
                In the code you can see I check to see if it is the first meter (meterIndex = 0) and if so then only that one's clip rectangle is active. I've since realised that setting the rest to invisible actually brings down the CPU %. But if I leave them visible then the CPU increases, even though there's no activity. Is it normal to set items to invisible if you don't want anything rendered for them?

                import QtQuick 2.0
                
                Rectangle {
                  id: myMeter
                  width: 20
                  height: 100
                  property int meterIndex: 0
                
                  color: "black"
                
                  Rectangle {
                    id: clipRect
                    width: parent.width
                    height: 0
                    clip: true
                
                    Timer {
                      id: myTimer
                      interval: 20
                      repeat: true
                      running: true
                      triggeredOnStart: true
                      onTriggered: {
                        if(myMeter.meterIndex == 0) {
                          clipRect.height = myMeter.height * Math.random();
                        }
                        else {
                          clipRect.visible = false;
                          myTimer.stop();
                        }
                      }
                    }
                    color: "blue"
                  }
                }
                
                P 1 Reply Last reply 29 Jun 2015, 06:06
                0
                • Z zepfan
                  28 Jun 2015, 17:45

                  Here is the qml file that defines the meter. I use a Repeater to create multiple instances of these and give each one a unique index (meterIndex).
                  In the code you can see I check to see if it is the first meter (meterIndex = 0) and if so then only that one's clip rectangle is active. I've since realised that setting the rest to invisible actually brings down the CPU %. But if I leave them visible then the CPU increases, even though there's no activity. Is it normal to set items to invisible if you don't want anything rendered for them?

                  import QtQuick 2.0
                  
                  Rectangle {
                    id: myMeter
                    width: 20
                    height: 100
                    property int meterIndex: 0
                  
                    color: "black"
                  
                    Rectangle {
                      id: clipRect
                      width: parent.width
                      height: 0
                      clip: true
                  
                      Timer {
                        id: myTimer
                        interval: 20
                        repeat: true
                        running: true
                        triggeredOnStart: true
                        onTriggered: {
                          if(myMeter.meterIndex == 0) {
                            clipRect.height = myMeter.height * Math.random();
                          }
                          else {
                            clipRect.visible = false;
                            myTimer.stop();
                          }
                        }
                      }
                      color: "blue"
                    }
                  }
                  
                  P Offline
                  P Offline
                  p3c0
                  Moderators
                  wrote on 29 Jun 2015, 06:06 last edited by p3c0
                  #8

                  @zepfan I see you are starting a Timer of interval 20 and it seems you are starting it for all the other remaining meters. A Timer of such a low interval and that too for 20 items is ofcourse going to be CPU intensive. I would suggest here to not start the Timer for the rest in first place. You can add s condition like:

                  Timer {
                    running: myMeter.meterIndex == 0
                  }
                  

                  So the Timer will start only for the Item with meterIndex = 0

                  Is it normal to set items to invisible if you don't want anything rendered for them?

                  Yes it reduces the cost of drawing again. See over-drawing-and-invisible-elements.

                  157

                  1 Reply Last reply
                  0
                  • Z Offline
                    Z Offline
                    zepfan
                    wrote on 29 Jun 2015, 09:39 last edited by
                    #9

                    So if I have other elements on screen but they have not changed, does that mean they will be re-rendered every time also? I can't change them to (visible: false) as obviously I need to see them!

                    Is there a flag/setting that you can set that will make sure only items that are 'dirty' will be rendered?

                    Thanks

                    P 1 Reply Last reply 29 Jun 2015, 09:45
                    0
                    • Z zepfan
                      29 Jun 2015, 09:39

                      So if I have other elements on screen but they have not changed, does that mean they will be re-rendered every time also? I can't change them to (visible: false) as obviously I need to see them!

                      Is there a flag/setting that you can set that will make sure only items that are 'dirty' will be rendered?

                      Thanks

                      P Offline
                      P Offline
                      p3c0
                      Moderators
                      wrote on 29 Jun 2015, 09:45 last edited by
                      #10

                      @zepfan No change no rendering again.

                      Is there a flag/setting that you can set that will make sure only items that are 'dirty' will be rendered?

                      I'm not aware of any such in QML.
                      But as I explained earlier your timer is eating the CPU. Even if Item is invisible timer will be active. 20 ms timeout for 20 items is CPU intensive.

                      157

                      Z 1 Reply Last reply 29 Jun 2015, 10:16
                      0
                      • P p3c0
                        29 Jun 2015, 09:45

                        @zepfan No change no rendering again.

                        Is there a flag/setting that you can set that will make sure only items that are 'dirty' will be rendered?

                        I'm not aware of any such in QML.
                        But as I explained earlier your timer is eating the CPU. Even if Item is invisible timer will be active. 20 ms timeout for 20 items is CPU intensive.

                        Z Offline
                        Z Offline
                        zepfan
                        wrote on 29 Jun 2015, 10:16 last edited by
                        #11

                        @p3c0 said:

                        But as I explained earlier your timer is eating the CPU. Even if Item is invisible timer will be active. 20 ms timeout for 20 items is CPU intensive.

                        True, but if I only have the timer running for one meter there is still quite a difference in CPU % between having the idle meters' clipRect visible or not visible. If they're not being repainted (since they're not active) then there shouldn't be a difference in CPU %?

                        P 1 Reply Last reply 29 Jun 2015, 10:20
                        0
                        • Z zepfan
                          29 Jun 2015, 10:16

                          @p3c0 said:

                          But as I explained earlier your timer is eating the CPU. Even if Item is invisible timer will be active. 20 ms timeout for 20 items is CPU intensive.

                          True, but if I only have the timer running for one meter there is still quite a difference in CPU % between having the idle meters' clipRect visible or not visible. If they're not being repainted (since they're not active) then there shouldn't be a difference in CPU %?

                          P Offline
                          P Offline
                          p3c0
                          Moderators
                          wrote on 29 Jun 2015, 10:20 last edited by
                          #12

                          @zepfan How much CPU is being utilized on your system ? Can you post a complete example test it out ?

                          157

                          1 Reply Last reply
                          0
                          • Z Offline
                            Z Offline
                            zepfan
                            wrote on 30 Jun 2015, 09:35 last edited by p3c0
                            #13

                            If you use the code above for the actual Meter (MyMeter), and here is its parent which uses a Repeater to construct 20 of them. Try having the timer just running in the first meter, compared with having the timer running in all of them. I don't notice much change in CPU when having one of them getting its clipRect.height changed or having all of them get their clipRect.height changed.

                            I should state that the reason I've made this test application is because I'm doing something similar in work (which I obviously can't post) and am getting similar results. My suspicion is that the whole scene is getting re-rendered rather than just the item that needs it.

                            import QtQuick 2.0
                            
                            Rectangle {
                              visible: true
                              width: 900
                              height: 700
                              color: "green"
                            
                              Column {
                                id: myColumn
                                spacing: 10
                            
                                Repeater {
                                  model: 2
                            
                                  Row {
                                    id: myRow
                                    x: 50
                                    y: 50
                                    spacing: 40
                                    property int rowIndex: index
                            
                                    Repeater {
                                      id: innerRepeater
                                      model: 10
                            
                                      MyMeter {
                                        objectName: "Meter " + (index + (myRow.rowIndex * innerRepeater.model))
                                        meterIndex: (index + (myRow.rowIndex * innerRepeater.model))
                            
                                        width: 15
                                        height: 150
                                      }
                                    }
                                  }
                                }
                              }
                            }
                            
                            P 1 Reply Last reply 30 Jun 2015, 09:52
                            0
                            • Z zepfan
                              30 Jun 2015, 09:35

                              If you use the code above for the actual Meter (MyMeter), and here is its parent which uses a Repeater to construct 20 of them. Try having the timer just running in the first meter, compared with having the timer running in all of them. I don't notice much change in CPU when having one of them getting its clipRect.height changed or having all of them get their clipRect.height changed.

                              I should state that the reason I've made this test application is because I'm doing something similar in work (which I obviously can't post) and am getting similar results. My suspicion is that the whole scene is getting re-rendered rather than just the item that needs it.

                              import QtQuick 2.0
                              
                              Rectangle {
                                visible: true
                                width: 900
                                height: 700
                                color: "green"
                              
                                Column {
                                  id: myColumn
                                  spacing: 10
                              
                                  Repeater {
                                    model: 2
                              
                                    Row {
                                      id: myRow
                                      x: 50
                                      y: 50
                                      spacing: 40
                                      property int rowIndex: index
                              
                                      Repeater {
                                        id: innerRepeater
                                        model: 10
                              
                                        MyMeter {
                                          objectName: "Meter " + (index + (myRow.rowIndex * innerRepeater.model))
                                          meterIndex: (index + (myRow.rowIndex * innerRepeater.model))
                              
                                          width: 15
                                          height: 150
                                        }
                                      }
                                    }
                                  }
                                }
                              }
                              
                              P Offline
                              P Offline
                              p3c0
                              Moderators
                              wrote on 30 Jun 2015, 09:52 last edited by
                              #14

                              @zepfan Just tested. I do notice change in CPU %. For single Meter running it is around 3-3.5% while with all meters running it is around 7.5-8.3%.
                              How much on your system ?

                              157

                              1 Reply Last reply
                              0
                              • Z Offline
                                Z Offline
                                zepfan
                                wrote on 30 Jun 2015, 16:56 last edited by
                                #15

                                I don't have the exact figure on me at the moment, but the figure itself isn't relevant. For my test app the figure wasn't too high, but my concern is that the CPU % doesn't change much whether I have one meter active or 20 meters active. Once they are all visible it's pretty much the same. And obviously this affects the real project I'm working on even more.
                                I've actually also just posted in the QtQuick forum just to see if anyone has any thoughts on rendering performance/improvements.

                                Thanks

                                P 1 Reply Last reply 1 Jul 2015, 05:25
                                0
                                • Z zepfan
                                  30 Jun 2015, 16:56

                                  I don't have the exact figure on me at the moment, but the figure itself isn't relevant. For my test app the figure wasn't too high, but my concern is that the CPU % doesn't change much whether I have one meter active or 20 meters active. Once they are all visible it's pretty much the same. And obviously this affects the real project I'm working on even more.
                                  I've actually also just posted in the QtQuick forum just to see if anyone has any thoughts on rendering performance/improvements.

                                  Thanks

                                  P Offline
                                  P Offline
                                  p3c0
                                  Moderators
                                  wrote on 1 Jul 2015, 05:25 last edited by p3c0 7 Jan 2015, 05:26
                                  #16

                                  @zepfan As told earlier the rendering is all done by OpenGL which in turn is handled by the GPU so that wont matter. The Timer is what is affecting the CPU.
                                  QtQuick renderer is capable of handling thousands of items at a time. Please check it here. Also here are some benchmark examples.
                                  Extremetable example loads 100000 items as and when required.
                                  Anyway here are some more link that you may fine useful:
                                  http://doc.qt.io/qt-5/qtquick-performance.html
                                  http://www.sletta.org/apps/blog/show/42708211-looking-at-throughput-in-qt-quick
                                  http://doc.qt.io/qt-5/qtquick-visualcanvas-scenegraph-renderer.html
                                  Try profiling your example.

                                  157

                                  1 Reply Last reply
                                  0

                                  10/16

                                  29 Jun 2015, 09:45

                                  • Login

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