summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/gui/opengl/qopenglextensions_p.h5
-rw-r--r--src/gui/opengl/qopenglfunctions.cpp32
-rw-r--r--src/widgets/kernel/qopenglwidget.cpp6
3 files changed, 39 insertions, 4 deletions
diff --git a/src/gui/opengl/qopenglextensions_p.h b/src/gui/opengl/qopenglextensions_p.h
index aa2f784d86..ff5d79566c 100644
--- a/src/gui/opengl/qopenglextensions_p.h
+++ b/src/gui/opengl/qopenglextensions_p.h
@@ -135,6 +135,8 @@ public:
QOpenGLES3Helper *gles3Helper();
+ void flushShared();
+
private:
static bool isInitialized(const QOpenGLFunctionsPrivate *d) { return d != 0; }
};
@@ -158,6 +160,9 @@ public:
GLsizei width, GLsizei height);
void (QOPENGLF_APIENTRYP GetBufferSubData)(GLenum target, qopengl_GLintptr offset, qopengl_GLsizeiptr size, GLvoid *data);
void (QOPENGLF_APIENTRYP DiscardFramebuffer)(GLenum target, GLsizei numAttachments, const GLenum *attachments);
+
+ bool flushVendorChecked;
+ bool flushIsSufficientToSyncContexts;
};
inline GLvoid *QOpenGLExtensions::glMapBuffer(GLenum target, GLenum access)
diff --git a/src/gui/opengl/qopenglfunctions.cpp b/src/gui/opengl/qopenglfunctions.cpp
index 587995515d..c60532b90b 100644
--- a/src/gui/opengl/qopenglfunctions.cpp
+++ b/src/gui/opengl/qopenglfunctions.cpp
@@ -3538,7 +3538,8 @@ QOpenGLFunctionsPrivate::QOpenGLFunctionsPrivate(QOpenGLContext *)
}
QOpenGLExtensionsPrivate::QOpenGLExtensionsPrivate(QOpenGLContext *ctx)
- : QOpenGLFunctionsPrivate(ctx)
+ : QOpenGLFunctionsPrivate(ctx),
+ flushVendorChecked(false)
{
MapBuffer = qopenglfResolveMapBuffer;
MapBufferRange = qopenglfResolveMapBufferRange;
@@ -3554,4 +3555,33 @@ QOpenGLES3Helper *QOpenGLExtensions::gles3Helper()
return qgles3Helper();
}
+void QOpenGLExtensions::flushShared()
+{
+ Q_D(QOpenGLExtensions);
+
+ if (!d->flushVendorChecked) {
+ d->flushVendorChecked = true;
+ // It is not quite clear if glFlush() is sufficient to synchronize access to
+ // resources between sharing contexts in the same thread. On most platforms this
+ // is enough (e.g. iOS explicitly documents it), while certain drivers only work
+ // properly when doing glFinish().
+ d->flushIsSufficientToSyncContexts = false; // default to false, not guaranteed by the spec
+ const char *vendor = (const char *) glGetString(GL_VENDOR);
+ if (vendor) {
+ static const char *flushEnough[] = { "Apple", "ATI", "Intel", "NVIDIA" };
+ for (size_t i = 0; i < sizeof(flushEnough) / sizeof(const char *); ++i) {
+ if (strstr(vendor, flushEnough[i])) {
+ d->flushIsSufficientToSyncContexts = true;
+ break;
+ }
+ }
+ }
+ }
+
+ if (d->flushIsSufficientToSyncContexts)
+ glFlush();
+ else
+ glFinish();
+}
+
QT_END_NAMESPACE
diff --git a/src/widgets/kernel/qopenglwidget.cpp b/src/widgets/kernel/qopenglwidget.cpp
index 3b33894627..8faa9f8681 100644
--- a/src/widgets/kernel/qopenglwidget.cpp
+++ b/src/widgets/kernel/qopenglwidget.cpp
@@ -691,7 +691,7 @@ void QOpenGLWidgetPrivate::beginCompose()
if (flushPending) {
flushPending = false;
q->makeCurrent();
- context->functions()->glFlush();
+ static_cast<QOpenGLExtensions *>(context->functions())->flushShared();
}
hasBeenComposed = true;
emit q->aboutToCompose();
@@ -768,7 +768,7 @@ void QOpenGLWidgetPrivate::resolveSamples()
q->makeCurrent();
QRect rect(QPoint(0, 0), fbo->size());
QOpenGLFramebufferObject::blitFramebuffer(resolvedFbo, rect, fbo, rect);
- QOpenGLContext::currentContext()->functions()->glFlush();
+ flushPending = true;
}
}
@@ -779,7 +779,7 @@ void QOpenGLWidgetPrivate::invokeUserPaint()
f->glViewport(0, 0, q->width() * q->devicePixelRatio(), q->height() * q->devicePixelRatio());
q->paintGL();
- f->glFlush();
+ flushPending = true;
}
void QOpenGLWidgetPrivate::render()