Details
-
Suggestion
-
Resolution: Unresolved
-
P2: Important
-
None
-
5.11, 5.12
-
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
- is required for
-
QT3DS-1032 Q3DSWidget locked to ~30 FPS at best and is flickering
- Closed
- relates to
-
QTBUG-69985 Scene3D (and Studio3D) needs a way to determine if the Qt 3D scene changes
- Closed
-
QT3DS-2437 New Qt3D Render Aspect
- Closed
-
QTBUG-70885 OnDemandRendering broken wrt expose events
- Open
-
QT3DS-660 Qt 3D bugs and features required for Runtime 2
- Withdrawn