QOpenGLWidget immediate OpenGL repaint
-
In our 3D application we are now using QOpenGLWidget to paint OpenGL stuff into the window.
However this is not refreshing the window as often as possible - e.g. when dragging the model drawn in the viewport - the drag is non-smooth -> model jumps a lot.
After each mouse move event a translation is done, then repaint() is called which should repaint the window immediatelly. However that is not done.
The constructor is using following code to disable V-sync:
setUpdateBehavior(QOpenGLWidget::NoPartialUpdate);
auto format = QSurfaceFormat::defaultFormat();
format.setSwapInterval(0);
setFormat(format);The FPS for my test model is at least 50. Measured by timer with glFlush() after all draw before taking values.
So what else needs to be done to have smooth behavior????
In Qt 4 QGlWidget implementation this is working for us correctly to note.Also QWidgetBackingStore::sendUpdateRequest() with UpdateNow update time is still checking refresh rate even when setSwapInterval() is set to 0. Is this a bug?
-
QWidgetBackingStore::sendUpdateRequest() is not deferring immediate updates in case setSwapInterval() is 0. So there is not a bug as I originally meant.
However putting timing to frameSwapped() signal shows that swap is not happening more than 30 times a second (there is at least 33 ms interval).
The swap is on Windows implemented in: QPlatformBackingStore::composeAndFlush(). Which is composing the final picture from all texture targets - in our case a single texture.
Is this method called somehow periodically with refresh rate of monitor? How can this be disabled, so it's also called immediatelly??? -
I have resolved all problems - things to pay attention to:
- When QCoreApplication::setAttribute(Qt::AA_ShareOpenGLContexts); is used the default format needs to be set before construction of QApplication:
auto format = QSurfaceFormat::defaultFormat();
format.setSwapInterval(0);
QSurfaceFormat::setDefaultFormat(format);This turns down vertical sync just releasing the main GUI thread from waiting to vertical sync to happen.
- Too many immediate redraws are not good - in our case there were 2 immediate redraws just cutting the real FPS to half (Without FPS counter in redrawing noticing this ofc :-) )
- There are still standard redraws interleaved from system events marking regions of application dirty, but this is hopefully ok. The problem with this is that during script processing we want to see redraws immediately, so standard redraws through event loop are not "fast" enough (as blocked until whole script is done).