summaryrefslogtreecommitdiffstats
path: root/src/gui/opengl
diff options
context:
space:
mode:
authorLaszlo Agocs <laszlo.agocs@theqtcompany.com>2015-03-19 14:49:54 +0100
committerLaszlo Agocs <laszlo.agocs@theqtcompany.com>2015-03-23 09:26:42 +0000
commitcafd54d34b0e4e0fb9d99650c7c6ffd1969811a1 (patch)
tree116c309bfcd0ab6c2b54730fc5fd90e24a992adf /src/gui/opengl
parent09f631d78710420d25fa0765772bef3ef37e78cb (diff)
Use glFinish() in QOpenGLWidget unless glFlush() is known to be enough
The driver used on the Odroid-XU3 does not like doing just glFlush() before accessing the texture in another context. There is no guarantee that glFlush() is enough to sync access to resources between contexts, so start using glFinish() as the default, except on common desktop hw + iOS where flush is enough and presumably more efficient. To unify the code pathes, remove the separate flushes and do it only once, before the backingstore compositor indicates that it is about to access the textures. This should improve performance a bit, esp. when doing multisampling since we flush only once then. A helper function is added to the internal QOpenGLExtensions because it is highly likely that QQuickWidget will need the same. Task-number: QTBUG-45106 Change-Id: Ifb405c5723f29f2f6c04df8e15fb70280681755e Reviewed-by: Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
Diffstat (limited to 'src/gui/opengl')
-rw-r--r--src/gui/opengl/qopenglextensions_p.h5
-rw-r--r--src/gui/opengl/qopenglfunctions.cpp32
2 files changed, 36 insertions, 1 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