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. Debug functions to assert which phase the render thread and main thread are in

Debug functions to assert which phase the render thread and main thread are in

Scheduled Pinned Locked Moved Unsolved QML and Qt Quick
4 Posts 1 Posters 347 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.
  • J Offline
    J Offline
    Jarrod
    wrote on 16 Aug 2022, 02:19 last edited by
    #1

    In more complex applications it would make code easier to reason about and guard against regressions to be able to do things like this in debug builds:

    Q_ASSERT(QSG::isGuiBlocked());
    Q_ASSERT(QSG::isRenderThread());
    
    Q_ASSERT(QSG::isUpdatingPaintNodes());
    Q_ASSERT(QQuickItem::isUpdating());
    Q_ASSERT(QQuickItem::isUpdatingPolish());
    

    Regarding thread detection, currently AFAIK we can only robustly detect the Qt UI thread, not the render thread. I have this:

    inline bool isQtUI() { return QCoreApplication::instance() && QThread::currentThread() == QCoreApplication::instance()->thread(); }
    

    I think there should also be a standard function for this in the Qt API, at least in debug.

    08157921-b6bc-4708-9057-f1b18e5f8e87-image.png

    Just wanted to double check if there is anything like these functions already before I consider adding my own solution. I would especially like to be able to robustly assert that the render thread is current.

    1 Reply Last reply
    0
    • J Offline
      J Offline
      Jarrod
      wrote on 17 Aug 2022, 05:34 last edited by Jarrod
      #2

      I did this as a workable but not ideal solution to checking if we are on the render thread...

      #define QT_REQUIRE_RENDER_THREAD() Q_ASSERT(util::thread::isQtRender())
      
      constexpr auto kRenderThreadName = "Qt Render Thread";
      
      inline bool isQtRender() {
          Q_ASSERT(QThread::currentThread()); 
          return QThread::currentThread()->objectName() == kRenderThreadName;
      }
      
      class NameRenderThreadJob : public QRunnable
      {
      public:
          void run() override
          {
              QThread::currentThread()->setObjectName(kRenderThreadName);
          }
      };
      

      And add this to the constructor of our QQuickWindow / QQuickView subclasses, which thankfully in our project are used in all cases:

      scheduleRenderJob(new util::thread::NameRenderThreadJob(), QQuickWindow::BeforeSynchronizingStage);
      

      So just manually naming the Qt Render Thread QObject and crossing my fingers that none of the asserts will be checked before the name is set.

      1 Reply Last reply
      0
      • J Offline
        J Offline
        Jarrod
        wrote on 17 Aug 2022, 06:06 last edited by Jarrod
        #3

        I think NoStage is actually a better choice than BeforeSynchronizingStage for this:
        https://doc.qt.io/qt-6/qquickwindow.html#scheduleRenderJob

        Update: No, use BeforeSynchronizingStage.

        If stage is NoStage, job will be run at the earliest opportunity whenever the render thread is not busy rendering a frame.

        So I thought perhaps NoStage would cause the render job to run earlier than with BeforeSynchronizingStage. But in my tests this was not the case. Probably this is key: "whenever the render thread is not busy".

        1 Reply Last reply
        0
        • J Offline
          J Offline
          Jarrod
          wrote on 17 Aug 2022, 07:26 last edited by
          #4

          Better solution using metaObject():

              constexpr auto kQtRenderThreadClassName = "QSGRenderThread";
          
              bool util::thread::isQtRender()
              {
                  Q_ASSERT(QThread::currentThread()); 
                  QString threadName { QThread::currentThread()->metaObject()->className() };
                  return threadName == kQtRenderThreadClassName;
              }
          
          1 Reply Last reply
          0

          4/4

          17 Aug 2022, 07:26

          • Login

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