Uploaded image for project: 'Qt'
  1. Qt
  2. QTBUG-80498

Calling QQuickWindow::update() on the render thread leads to unnecessary rendering of an extra frame with QSG_RHI=1

    XMLWordPrintable

Details

    • Bug
    • Resolution: Done
    • P2: Important
    • 5.15
    • 5.14, 5.15
    • Qt RHI, Quick: SceneGraph
    • None
    • 8c0fb7679c34281b7ed48e466a7eb72885c088e7

    Description

      When using Qt Quick 3D with Qt Quick's RHI-based rendering path enabled, it looks like the threaded render loop renders an extra frame every time QQuickWindow::update() is called on the render thread in Viewport3D's updatePaintNode() (thus reducing frame rate due to throttling to vsync). The basic render loop has no such problem.

      This is not something exercised in a typical Qt Quick application, but is a perfectly valid use case, in QQuickFramebufferObject, and any other custom item that wants to ensure that slots connected to signals like beforeRendering() get invoked due to rendering a frame even when the synchronizing step resulted in no changes in the scenegraph.

      This is only visible on a system where there is a lenghier blocking happening in beginFrame() - the problem is not necessarily noticeable with different scheduling.

      This is with the direct OpenGL rendering path and looks as expected (prepare, render, prepare, render, ...) and notice the blockedForSync=28 and similar lines.

      qt.scenegraph.time.renderloop: Frame rendered with 'threaded' renderloop in 9ms, sync=1, render=7, swap=0 - (on render thread)
      qt.scenegraph.time.renderloop: Frame prepared with 'threaded' renderloop, polish=0, lock=0, blockedForSync=10, animations=0 - (on Gui thread) QQuickView(0x7ffee36874d0 exposed, visibility=QWindow::Windowed, flags=QFlags<Qt::WindowType>(Window), geometry=28,85 1024x768)
      qt.scenegraph.time.renderloop: Frame rendered with 'threaded' renderloop in 2ms, sync=0, render=2, swap=0 - (on render thread)
      qt.scenegraph.time.renderloop: Frame rendered with 'threaded' renderloop in 16ms, sync=0, render=16, swap=0 - (on render thread)
      qt.scenegraph.time.renderloop: Frame prepared with 'threaded' renderloop, polish=0, lock=0, blockedForSync=19, animations=0 - (on Gui thread) QQuickView(0x7ffee36874d0 exposed, visibility=QWindow::Windowed, flags=QFlags<Qt::WindowType>(Window), geometry=28,85 1024x768)
      qt.scenegraph.time.renderloop: Frame prepared with 'threaded' renderloop, polish=0, lock=0, blockedForSync=0, animations=0 - (on Gui thread) QQuickView(0x7ffee36874d0 active exposed, visibility=QWindow::Windowed, flags=QFlags<Qt::WindowType>(Window), geometry=28,85 1024x768)
      qt.scenegraph.time.renderloop: Frame rendered with 'threaded' renderloop in 16ms, sync=0, render=16, swap=0 - (on render thread)
      qt.scenegraph.time.renderloop: Frame prepared with 'threaded' renderloop, polish=0, lock=0, blockedForSync=10, animations=0 - (on Gui thread) QQuickView(0x7ffee36874d0 active exposed, visibility=QWindow::Windowed, flags=QFlags<Qt::WindowType>(Window), geometry=28,85 1024x768)
      qt.scenegraph.time.renderloop: Frame rendered with 'threaded' renderloop in 16ms, sync=0, render=16, swap=0 - (on render thread)
      qt.scenegraph.time.renderloop: Frame prepared with 'threaded' renderloop, polish=0, lock=0, blockedForSync=11, animations=0 - (on Gui thread) QQuickView(0x7ffee36874d0 active exposed, visibility=QWindow::Windowed, flags=QFlags<Qt::WindowType>(Window), geometry=28,85 1024x768)
      qt.scenegraph.time.renderloop: Frame rendered with 'threaded' renderloop in 16ms, sync=0, render=16, swap=0 - (on render thread)
      qt.scenegraph.time.renderloop: Frame prepared with 'threaded' renderloop, polish=0, lock=0, blockedForSync=11, animations=0 - (on Gui thread) QQuickView(0x7ffee36874d0 active exposed, visibility=QWindow::Windowed, flags=QFlags<Qt::WindowType>(Window), geometry=28,85 1024x768)
      qt.scenegraph.time.renderloop: Frame rendered with 'threaded' renderloop in 16ms, sync=0, render=16, swap=0 - (on render thread)
      qt.scenegraph.time.renderloop: Frame prepared with 'threaded' renderloop, polish=0, lock=0, blockedForSync=11, animations=0 - (on Gui thread) QQuickView(0x7ffee36874d0 active exposed, visibility=QWindow::Windowed, flags=QFlags<Qt::WindowType>(Window), geometry=28,85 1024x768)
      qt.scenegraph.time.renderloop: Frame rendered with 'threaded' renderloop in 16ms, sync=0, render=16, swap=0 - (on render thread)
       

      This is with QSG_RHI=1 QSG_RHI_BACKEND=vulkan and looks odd (prepare, render, render, prepare, render, render, ...)

      qt.scenegraph.time.renderloop: Frame rendered with 'threaded' renderloop in 42ms, sync=2, render=39, swap=0 - (on render thread)
      qt.scenegraph.time.renderloop: Frame prepared with 'threaded' renderloop, polish=0, lock=0, blockedForSync=61, animations=0 - (on Gui thread) QQuickView(0x7ffd454ce760 exposed, visibility=QWindow::Windowed, flags=QFlags<Qt::WindowType>(Window), geometry=28,85 1024x768)
      qt.scenegraph.time.renderloop: Frame rendered with 'threaded' renderloop in 0ms, sync=0, render=0, swap=0 - (on render thread)
      qt.scenegraph.time.renderloop: Frame rendered with 'threaded' renderloop in 2ms, sync=1, render=0, swap=1 - (on render thread)
      qt.scenegraph.time.renderloop: Frame prepared with 'threaded' renderloop, polish=0, lock=0, blockedForSync=2, animations=0 - (on Gui thread) QQuickView(0x7ffd454ce760 exposed, visibility=QWindow::Windowed, flags=QFlags<Qt::WindowType>(Window), geometry=28,85 1024x768)
      qt.scenegraph.time.renderloop: Frame prepared with 'threaded' renderloop, polish=0, lock=0, blockedForSync=0, animations=0 - (on Gui thread) QQuickView(0x7ffd454ce760 active exposed, visibility=QWindow::Windowed, flags=QFlags<Qt::WindowType>(Window), geometry=28,85 1024x768)
      qt.scenegraph.time.renderloop: Frame rendered with 'threaded' renderloop in 1ms, sync=0, render=0, swap=1 - (on render thread)
      qt.scenegraph.time.renderloop: Frame rendered with 'threaded' renderloop in 15ms, sync=14, render=0, swap=0 - (on render thread)
      qt.scenegraph.time.renderloop: Frame prepared with 'threaded' renderloop, polish=0, lock=0, blockedForSync=26, animations=0 - (on Gui thread) QQuickView(0x7ffd454ce760 active exposed, visibility=QWindow::Windowed, flags=QFlags<Qt::WindowType>(Window), geometry=28,85 1024x768)
      qt.scenegraph.time.renderloop: Frame rendered with 'threaded' renderloop in 16ms, sync=15, render=0, swap=0 - (on render thread)
      qt.scenegraph.time.renderloop: Frame rendered with 'threaded' renderloop in 16ms, sync=15, render=0, swap=0 - (on render thread)
      qt.scenegraph.time.renderloop: Frame prepared with 'threaded' renderloop, polish=0, lock=0, blockedForSync=28, animations=0 - (on Gui thread) QQuickView(0x7ffd454ce760 active exposed, visibility=QWindow::Windowed, flags=QFlags<Qt::WindowType>(Window), geometry=28,85 1024x768)
      qt.scenegraph.time.renderloop: Frame rendered with 'threaded' renderloop in 17ms, sync=16, render=0, swap=1 - (on render thread)
      qt.scenegraph.time.renderloop: Frame rendered with 'threaded' renderloop in 16ms, sync=15, render=0, swap=1 - (on render thread)
      qt.scenegraph.time.renderloop: Frame prepared with 'threaded' renderloop, polish=0, lock=0, blockedForSync=27, animations=0 - (on Gui thread) QQuickView(0x7ffd454ce760 active exposed, visibility=QWindow::Windowed, flags=QFlags<Qt::WindowType>(Window), geometry=28,85 1024x768)
      qt.scenegraph.time.renderloop: Frame rendered with 'threaded' renderloop in 16ms, sync=15, render=0, swap=1 - (on render thread)
      qt.scenegraph.time.renderloop: Frame rendered with 'threaded' renderloop in 16ms, sync=15, render=0, swap=0 - (on render thread)
      qt.scenegraph.time.renderloop: Frame prepared with 'threaded' renderloop, polish=0, lock=0, blockedForSync=28, animations=0 - (on Gui thread) QQuickView(0x7ffd454ce760 active exposed, visibility=QWindow::Windowed, flags=QFlags<Qt::WindowType>(Window), geometry=28,85 1024x768)
      qt.scenegraph.time.renderloop: Frame rendered with 'threaded' renderloop in 17ms, sync=16, render=0, swap=1 - (on render thread)
      qt.scenegraph.time.renderloop: Frame rendered with 'threaded' renderloop in 15ms, sync=15, render=0, swap=0 - (on render thread)
      qt.scenegraph.time.renderloop: Frame prepared with 'threaded' renderloop, polish=0, lock=0, blockedForSync=27, animations=0 - (on Gui thread) QQuickView(0x7ffd454ce760 active exposed, visibility=QWindow::Windowed, flags=QFlags<Qt::WindowType>(Window), geometry=28,85 1024x768)
      qt.scenegraph.time.renderloop: Frame rendered with 'threaded' renderloop in 16ms, sync=16, render=0, swap=0 - (on render thread)
      qt.scenegraph.time.renderloop: Frame rendered with 'threaded' renderloop in 17ms, sync=16, render=0, swap=1 - (on render thread)
      qt.scenegraph.general: animation driver switched to timer mode
      qt.scenegraph.time.renderloop: Frame prepared with 'threaded' renderloop, polish=0, lock=0, blockedForSync=28, animations=0 - (on Gui thread) QQuickView(0x7ffd454ce760 active exposed, visibility=QWindow::Windowed, flags=QFlags<Qt::WindowType>(Window), geometry=28,85 1024x768)
      qt.scenegraph.time.renderloop: Frame rendered with 'threaded' renderloop in 16ms, sync=15, render=0, swap=1 - (on render thread)
      qt.scenegraph.time.renderloop: Frame rendered with 'threaded' renderloop in 16ms, sync=15, render=0, swap=0 - (on render thread)
      

      Attachments

        Issue Links

          No reviews matched the request. Check your Options in the drop-down menu of this sections header.

          Activity

            People

              lagocs Laszlo Agocs
              lagocs Laszlo Agocs
              Votes:
              0 Vote for this issue
              Watchers:
              3 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved:

                Gerrit Reviews

                  There are no open Gerrit changes