Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. What causes QSGRenderThread to have constant CPU usage on a static scene?

What causes QSGRenderThread to have constant CPU usage on a static scene?

Scheduled Pinned Locked Moved Solved QML and Qt Quick
3 Posts 2 Posters 1.4k 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.
  • DiracsbracketD Offline
    DiracsbracketD Offline
    Diracsbracket
    wrote on last edited by Diracsbracket
    #1

    Hi.
    I'm experiencing weird occurences of constant CPU usage by the QSGRenderThread even when the scene is static. It uses about 22~25% of one of the 4 cores.

    It seems to happen after the first scene update following the presentation of the default stack item to the user.

    It occurs more often than not, but not always, and sometimes goes away for some reason, maybe by pushing and popping some other item on the StackView.

    I tried to confirm that the QSG is not constantly rendering by adding the following debug messages in my main.qml:

    Connections {
        target: mainWindow   
        function onBeforeSynchronizing() { console.debug("onBeforeSynchronizing") }
        function onAfterSynchronizing() { console.debug("onAfterSynchronizing") }
    }
    

    But that seems to work as expected: the debug messages are only printed when the scene changes.

    What is happening here?
    I found the old bug report about this situation, but got none the wiser, as it was closed and marked as solved with no explanation.

    Thanks for any insights you may provide on how to tackle this problem ~

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

      Hi,

      Sorry I do not have an answer for that but you might want to give more information about your hardware and Qt version.

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

      DiracsbracketD 1 Reply Last reply
      0
      • SGaistS SGaist

        Hi,

        Sorry I do not have an answer for that but you might want to give more information about your hardware and Qt version.

        DiracsbracketD Offline
        DiracsbracketD Offline
        Diracsbracket
        wrote on last edited by Diracsbracket
        #3

        Thanks, @SGaist
        I have isolated the problem.
        As for:

        you might want to give more information about your hardware and Qt version.

        It is on Pi OS Lite Linux raspberrypi 5.4.72-v7l+ on Pi 4B with Qt 5.15.2 but also can be reproduced on Debian Buster:

        Linux buster 4.19.0-9-amd64 #1 SMP Debian 4.19.118-2 (2020-04-29) x86_64 GNU/Linux
        

        The problem lies with the use of BusyIndicator when the interval between setting running to true then to false again is too short.

        The following minimal example reproduces the problem, both on my Pi and my Debian Buster VM build host (in my app, the running property is controlled by the status of a FolderListModel):

        import QtQuick 2.15
        import QtQuick.Controls 2.15
        import QtQuick.Window 2.15
        
        Window {
            id: root
            visible: true
            property int winWidth: 640
            property int winHeight: 480
        
            width: winWidth
            height: winHeight
        
            title: qsTr("Minimal QML")
        
            Button {
                width: 300
                height: 100
                anchors.centerIn: parent
                text: "Start/Stop"
                font.pixelSize: 48
                onClicked: {
                    //Forcing running to false only does work to stop
                    //the high cpu usage. It must be started/stopped here.
                    busyIndicator.running = !busyIndicator.running
                }
            }
        
            BusyIndicator {
                id: busyIndicator
                width: 170
                height: 170
                running: false
                anchors.centerIn: parent
                anchors.verticalCenterOffset: -35
                clip: false
        
                property string color: "blue"
                palette.dark: color
        
                onRunningChanged: {
                    busyText.text = running ? "running" : ""
                    console.debug("BusyIndicator: ", running)
                }
        
                Text {
                    id: busyText
                    visible: busyIndicator.running
                    font.pixelSize: 64
                    color: busyIndicator.color
                    anchors.horizontalCenter: parent.horizontalCenter
                    anchors.top: busyIndicator.bottom
                    anchors.topMargin: 10
                }
            }
        
            Timer {
                id: timer
                interval: 5
                repeat: false
                onTriggered: busyIndicator.running = false
            }
        
            Component.onCompleted: {
                busyIndicator.running = true
                timer.start()
            }
        }
        

        At program startup, we get the following debug output:

        qml: BusyIndicator:  true
        qml: BusyIndicator:  false
        

        But from then on, QGSRenderThread cpu usage stays high:

        f2ea5366-3caf-4692-97bb-4bb7c698c910-image.png

        The only way to stop it is to press the button twice to start/stop it;
        setting only running = false upon button press does not work to stop the high CPU usage.

        I suspect that in the above use case non-interactive case, the interval between the start/stop states is too short to display anything, and somehow messes up the state of the BusyIndicator animation or so. It only seems to work correctly if the animation has effectively been shown on-screen for some time, as achieved with the Start/Stop button.

        Setting the timer interval to e.g. 50 briefly flashes the busy indicator, and then QSGRenderThread reverts back to 0 activity.

        EDIT: Apparently, this is a reported bug.
        https://bugreports.qt.io/browse/QTBUG-85860?jql=text ~ "BusyIndicator"

        If I use a custom BusyIndicator such as the following, the problem does not occur, even for
        running intervals as short as 1ms.

        //BusyIndicator.qml
        //This is essentially what the Controls 1 version of BusyIndicator does:
        
        import QtQuick 2.15
        
        Item {
            id: root   
            property bool running: true
        
            Image {
                id: image
                anchors.fill: parent
        
                opacity: root.running ? 1 : 0
                Behavior on opacity { OpacityAnimator { duration: 250 } }
        
                source: "busyindicator.png"
        
                RotationAnimator on rotation {
                    from: 0
                    to: 360
                    duration: 6000
                    loops: Animation.Infinite
                    running: image.visible && (root.running || image.opacity > 0)
                }
            }
        }
        
        1 Reply Last reply
        2

        • Login

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