From 0541516907da117c391b6c8d9820209673fcd9cd Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Wed, 2 Jul 2014 16:33:15 +0200 Subject: [PATCH] Use the standard functions in GLES3 builds in VAOs There is no guarantee that the OES extension is present and the standard functions are not required to be dynamically resolvable on ES. By performing the ARB-style lookup for the suffixless function names we can also support ES3 compatible contexts on desktop GL. This also fixes the problem of picking up the APPLE extension functions instead of ARB when both are available. vaoFuncsType was set to ARB correctly but the helper has to take the preference of ARB into account too. Task-number: QTBUG-38168 Change-Id: If7402320e8f96891017674f3c43bc57c4b5d29f3 Reviewed-by: Sean Harmer --- src/gui/opengl/qopenglvertexarrayobject.cpp | 42 ++++++++++++++------- tests/auto/gui/qopengl/qopengl.pro | 2 +- tests/auto/gui/qopengl/tst_qopengl.cpp | 24 ++++++++++++ 3 files changed, 53 insertions(+), 15 deletions(-) diff --git a/src/gui/opengl/qopenglvertexarrayobject.cpp b/src/gui/opengl/qopenglvertexarrayobject.cpp index 5ebfc9a9c8..d9b9385751 100644 --- a/src/gui/opengl/qopenglvertexarrayobject.cpp +++ b/src/gui/opengl/qopenglvertexarrayobject.cpp @@ -60,20 +60,34 @@ public: QVertexArrayObjectHelper(QOpenGLContext *context) { Q_ASSERT(context); + bool tryARB = true; + if (context->isOpenGLES()) { - GenVertexArrays = reinterpret_cast(context->getProcAddress(QByteArrayLiteral("glGenVertexArraysOES"))); - DeleteVertexArrays = reinterpret_cast(context->getProcAddress(QByteArrayLiteral("glDeleteVertexArraysOES"))); - BindVertexArray = reinterpret_cast(context->getProcAddress(QByteArrayLiteral("glBindVertexArrayOES"))); - } else { - if (context->hasExtension(QByteArrayLiteral("GL_APPLE_vertex_array_object"))) { - GenVertexArrays = reinterpret_cast(context->getProcAddress(QByteArrayLiteral("glGenVertexArraysAPPLE"))); - DeleteVertexArrays = reinterpret_cast(context->getProcAddress(QByteArrayLiteral("glDeleteVertexArraysAPPLE"))); - BindVertexArray = reinterpret_cast(context->getProcAddress(QByteArrayLiteral("glBindVertexArrayAPPLE"))); - } else { - GenVertexArrays = reinterpret_cast(context->getProcAddress(QByteArrayLiteral("glGenVertexArrays"))); - DeleteVertexArrays = reinterpret_cast(context->getProcAddress(QByteArrayLiteral("glDeleteVertexArrays"))); - BindVertexArray = reinterpret_cast(context->getProcAddress(QByteArrayLiteral("glBindVertexArray"))); +#ifdef QT_OPENGL_ES_3 + GenVertexArrays = ::glGenVertexArrays; + DeleteVertexArrays = ::glDeleteVertexArrays; + BindVertexArray = ::glBindVertexArray; + tryARB = false; +#else + if (context->hasExtension(QByteArrayLiteral("GL_OES_vertex_array_object"))) { + GenVertexArrays = reinterpret_cast(context->getProcAddress(QByteArrayLiteral("glGenVertexArraysOES"))); + DeleteVertexArrays = reinterpret_cast(context->getProcAddress(QByteArrayLiteral("glDeleteVertexArraysOES"))); + BindVertexArray = reinterpret_cast(context->getProcAddress(QByteArrayLiteral("glBindVertexArrayOES"))); + tryARB = false; } +#endif + } else if (!context->hasExtension(QByteArrayLiteral("GL_ARB_vertex_array_object")) + && context->hasExtension(QByteArrayLiteral("GL_APPLE_vertex_array_object"))) { + GenVertexArrays = reinterpret_cast(context->getProcAddress(QByteArrayLiteral("glGenVertexArraysAPPLE"))); + DeleteVertexArrays = reinterpret_cast(context->getProcAddress(QByteArrayLiteral("glDeleteVertexArraysAPPLE"))); + BindVertexArray = reinterpret_cast(context->getProcAddress(QByteArrayLiteral("glBindVertexArrayAPPLE"))); + tryARB = false; + } + + if (tryARB) { + GenVertexArrays = reinterpret_cast(context->getProcAddress(QByteArrayLiteral("glGenVertexArrays"))); + DeleteVertexArrays = reinterpret_cast(context->getProcAddress(QByteArrayLiteral("glDeleteVertexArrays"))); + BindVertexArray = reinterpret_cast(context->getProcAddress(QByteArrayLiteral("glBindVertexArray"))); } } @@ -93,7 +107,7 @@ public: } private: - // Function signatures are equivalent between desktop core, ARB, APPLE and ES 2 extensions + // Function signatures are equivalent between desktop core, ARB, APPLE, ES3 and ES 2 extensions void (QOPENGLF_APIENTRYP GenVertexArrays)(GLsizei n, GLuint *arrays); void (QOPENGLF_APIENTRYP DeleteVertexArrays)(GLsizei n, const GLuint *arrays); void (QOPENGLF_APIENTRYP BindVertexArray)(GLuint array); @@ -160,7 +174,7 @@ bool QOpenGLVertexArrayObjectPrivate::create() QObject::connect(context, SIGNAL(aboutToBeDestroyed()), q, SLOT(_q_contextAboutToBeDestroyed())); if (ctx->isOpenGLES()) { - if (ctx->hasExtension(QByteArrayLiteral("GL_OES_vertex_array_object"))) { + if (ctx->format().majorVersion() >= 3 || ctx->hasExtension(QByteArrayLiteral("GL_OES_vertex_array_object"))) { vaoFuncs.helper = new QVertexArrayObjectHelper(ctx); vaoFuncsType = OES; vaoFuncs.helper->glGenVertexArrays(1, &vao); diff --git a/tests/auto/gui/qopengl/qopengl.pro b/tests/auto/gui/qopengl/qopengl.pro index fcf457fec4..85297de1e1 100644 --- a/tests/auto/gui/qopengl/qopengl.pro +++ b/tests/auto/gui/qopengl/qopengl.pro @@ -11,4 +11,4 @@ SOURCES += tst_qopengl.cpp win32-msvc2010:contains(QT_CONFIG, angle):CONFIG += insignificant_test # QTBUG-31611 -linux:contains(QT_CONFIG, xcb-glx):contains(QT_CONFIG, xcb-xlib): DEFINES += USE_GLX +linux:contains(QT_CONFIG, xcb-glx):contains(QT_CONFIG, xcb-xlib):!contains(QT_CONFIG, opengles2): DEFINES += USE_GLX diff --git a/tests/auto/gui/qopengl/tst_qopengl.cpp b/tests/auto/gui/qopengl/tst_qopengl.cpp index c32edd3f71..7de1989ada 100644 --- a/tests/auto/gui/qopengl/tst_qopengl.cpp +++ b/tests/auto/gui/qopengl/tst_qopengl.cpp @@ -43,6 +43,7 @@ #include #include #include +#include #include #include #include @@ -96,6 +97,8 @@ private slots: #ifdef USE_GLX void glxContextWrap(); #endif + + void vaoCreate(); }; struct SharedResourceTracker @@ -1020,6 +1023,27 @@ void tst_QOpenGL::glxContextWrap() } #endif // USE_GLX +void tst_QOpenGL::vaoCreate() +{ + QScopedPointer surface(createSurface(QSurface::Window)); + QOpenGLContext *ctx = new QOpenGLContext; + ctx->create(); + ctx->makeCurrent(surface.data()); + + QOpenGLVertexArrayObject vao; + bool success = vao.create(); + if (ctx->isOpenGLES()) { + if (ctx->format().majorVersion() >= 3 || ctx->hasExtension(QByteArrayLiteral("GL_OES_vertex_array_object"))) + QVERIFY(success); + } else { + if (ctx->format().majorVersion() >= 3 || ctx->hasExtension(QByteArrayLiteral("GL_ARB_vertex_array_object"))) + QVERIFY(success); + } + + vao.destroy(); + ctx->doneCurrent(); +} + QTEST_MAIN(tst_QOpenGL) #include "tst_qopengl.moc"