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

Qt 3D renderer design not suitable for proper Qt Quick integration

    XMLWordPrintable

    Details

    • Type: Suggestion
    • Status: Open
    • Priority: P2: Important
    • Resolution: Unresolved
    • Affects Version/s: 5.11, 5.12
    • Fix Version/s: None
    • Component/s: Qt3D
    • Labels:
      None

      Description

      The render loop logic in Qt 3D has to be redesigned since what we have there today (and used by Scene3D and Studio3D) is broken when it comes to Qt Quick or widget integration (Q3DSWidget works similarly to Scene3D and Studio3D).

      Proper Qt Quick integration means that when we call renderSynchronous(), Qt 3D must render the next frame. Neither not doing anything nor waiting for any N > 0 time is acceptable since renderSyncronous is called when Qt Quick renders a frame, meaning there will be a swap and vsync throttling afterwards - if there is no 3D content generated in that frame then it means there is just no way to get a 60 FPS 3D view that runs in lockstep with the 2D content.

      Various Qt 3D Studio scenes are busted due to this and run with varying degrees of smoothness - it is not unlikely to get a !queueIsComplete or even a queueIsEmpty. The blocking mode is useless (the Qt Quick render thread (which may be the main thread) must not be blocked, it does not handle queueEmpty, and arbitrary timeouts are fragile anyway)

      Consider this. Here we are running with a Studio3D and the 'windows' render loop so Qt Quick and the renderSynchronous() calls are made on the main thread. The GL impl is NVIDIA which presumably throttles in GL calls (not on swapBuffers) hece the render 15 and swap 0 in the scenegraph logs. That's fine.

      FrameAction
      doRender
      hasCleanedQueueAndProceeded true queueIsComplete true queueIsEmpty false
      renderSynchronous took 15 ms
      qt.scenegraph.time.renderloop: Frame rendered with 'windows' renderloop in: 16ms, polish=0, sync=0, render=15, swap=0 - QQuickView(0x498b0ff860 active exposed, visibility=QWindow::Visibility(Windowed), flags=QFlags<Qt::WindowType>(Window), title="Qt 3D Studio Layers-as-Quick-items Example", geometry=320,160 1280x720)
      qt.scenegraph.time.renderloop: animations ticked in 0ms
      
      // !!!
      FrameAction
      renderSynchronous did nothing
      hasCleanedQueueAndProceeded false queueIsComplete false queueIsEmpty true
      renderSynchronous took 0 ms
      qt.scenegraph.time.renderloop: Frame rendered with 'windows' renderloop in: 14ms, polish=0, sync=0, render=14, swap=0 - QQuickView(0x498b0ff860 active exposed, visibility=QWindow::Visibility(Windowed), flags=QFlags<Qt::WindowType>(Window), title="Qt 3D Studio Layers-as-Quick-items Example", geometry=320,160 1280x720)
      qt.scenegraph.time.renderloop: animations ticked in 0ms
      
      // !!! no FrameAction??
      doRender
      hasCleanedQueueAndProceeded true queueIsComplete true queueIsEmpty false
      renderSynchronous took 16 ms
      qt.scenegraph.time.renderloop: Frame rendered with 'windows' renderloop in: 16ms, polish=0, sync=0, render=16, swap=0 - QQuickView(0x498b0ff860 active exposed, visibility=QWindow::Visibility(Windowed), flags=QFlags<Qt::WindowType>(Window), title="Qt 3D Studio Layers-as-Quick-items Example", geometry=320,160 1280x720)
      qt.scenegraph.time.renderloop: animations ticked in 0ms
      
      FrameAction
      ...
      

      The bad things are: why does renderSynchronous take 15-16 ms (when it actually does something) when it then gets followed by Qt Quick's rendering that takes the same (we need to block somewhere to vsync true but together that's like 33 ms...)? Why do we skip invoking frame actions? And that we skip 3D rendering in some frames, as outlined above.

      In the end we end up with something like the following. Note the min and max values below the avg and the graph.

      (no threaded render loop)

      (threaded render loop, the default on most systems)

      the behavior is definitely different here as renderSynchronous does not take 15-16 ms in this setup (when it's on the dedicated Quick render thread) yet we still lose time on the main thread somewhere.

        Attachments

          Issue Links

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

            Activity

              People

              Assignee:
              dragly Svenn-Arne Dragly
              Reporter:
              lagocs Laszlo Agocs
              Votes:
              6 Vote for this issue
              Watchers:
              15 Start watching this issue

                Dates

                Created:
                Updated:

                  Gerrit Reviews

                  There are no open Gerrit changes