Reputation: 1834
I would like to disable vsync
from the QOpenGLContext format in order to facilitate the integration of a third party rendering system.
QSurfaceFormat::swapInterval
seems to be the only related parameter in Qt.
I tried several ways to implement this, but even if I set the QSurfaceFormat::swapInterval(0)
at an early stage (before the QMainWindow
construction), then the QOpenGLContext::create()
call is restoring it.
// at application startup, before creating the Qt windows (or in MyQWindow constructor)
QSurfaceFormat format;
format.setSwapBehavior(QSurfaceFormat::DoubleBuffer);
format.setRedBufferSize(8);
format.setGreenBufferSize(8);
format.setBlueBufferSize(8);
format.setAlphaBufferSize(8);
format.setDepthBufferSize(24);
format.setStencilBufferSize(8);
format.setSwapInterval(0);
QSurfaceFormat::setDefaultFormat(format);
QMainWindow *w = new QMainWindow;
w->show();
// at QWindow with QOpenGLContext creation, at the first frame update (or at the constructor)
MyQWindow::initialization() {
WbOpenGLContext *c = new WbOpenGLContext(this);
c->setFormat(requestedFormat());
qDebug() << "requested format:" << c->format();
c->create();
qDebug() << "actual format:" << c->format();
}
# output
requested format: QSurfaceFormat(
version 2.0,
options QFlags(),
depthBufferSize 24,
redBufferSize 8,
greenBufferSize 8,
blueBufferSize 8,
alphaBufferSize 8,
stencilBufferSize 8,
samples -1,
swapBehavior 2,
swapInterval 0,
profile 0
)
context format: QSurfaceFormat(
version 3.0,
options QFlags(0x4),
depthBufferSize 24,
redBufferSize 8,
greenBufferSize 8,
blueBufferSize 8,
alphaBufferSize 8,
stencilBufferSize 8,
samples 0,
swapBehavior 2,
swapInterval 1, # Not what I asked
profile 0
)
Is there a way to force vsync to be disabled?
Upvotes: 4
Views: 4437
Reputation: 275
If you want to disable vsync, please take the QSurfaceFormat you created, and call QSurfaceFormat::setDefaultFormat(format)
before you create your QApplication object.
The documentation for QOpenGLWidget
indicates that calling QSurfaceFormat::setDefaultFormat(format)
before QApplication construction is mandatory on some platforms, including macOS, when an OpenGL Core Profile context is requested:
Note: Calling QSurfaceFormat::setDefaultFormat() before constructing the QApplication instance is mandatory on some platforms (for example, macOS) when an OpenGL core profile context is requested. This is to ensure that resource sharing between contexts stays functional as all internal contexts are created using the correct version and profile.
Additionally,the documentation for QSurfaceFormat::setDefaultFormat(format)
indicates that you should call it before QApplication otherwise you may have some issues with context sharing:
void QSurfaceFormat::setDefaultFormat(const QSurfaceFormat &format) Sets the global default surface format.
This format is used by default in QOpenGLContext, QWindow, QOpenGLWidget and similar classes.
It can always be overridden on a per-instance basis by using the class in question's own setFormat() function. However, it is often more convenient to set the format for all windows once at the start of the application. It also guarantees proper behavior in cases where shared contexts are required, because settings the format via this function guarantees that all contexts and surfaces, even the ones created internally by Qt, will use the same format.
Note: When setting Qt::AA_ShareOpenGLContexts, it is strongly recommended to place the call to this function before the construction of the QGuiApplication or QApplication. Otherwise format will not be applied to the global share context and therefore issues may arise with context sharing afterwards.
This function was introduced in Qt 5.4.
See also defaultFormat().
I have found that it is also needed for vsync.
So, given that, your first code block should look something like this now:
// at application startup, before creating the Qt windows (or in MyQWindow constructor)
QSurfaceFormat format;
format.setSwapBehavior(QSurfaceFormat::DoubleBuffer);
format.setRedBufferSize(8);
format.setGreenBufferSize(8);
format.setBlueBufferSize(8);
format.setAlphaBufferSize(8);
format.setDepthBufferSize(24);
format.setStencilBufferSize(8);
format.setSwapInterval(0);
QSurfaceFormat::setDefaultFormat(format);
QApplication app(arc, argv);
QMainWindow *w = new QMainWindow;
w->show();
app.exec();
Upvotes: 1
Reputation: 1834
As peppe is suggesting in the comments of the question, the QSurfaceFormat format of the QOpenGLContext instance after its creation is unfortunately not matching the actual format used internally.
This means that the code I implemented is probably working, but the second debug statement displays wrong values.
Upvotes: 3