Enable access to the VAO resolvers through QOpenGLContextPrivate
This is a commit in preparation for an upcoming change in QtQuick. We want to store the resolved functions for managing VAOs somewhere; the "least worst" choice is next to the all other function resolvers, which are in QOpenGLContext(Private). To avoid moving the VAO resolvers themselves, leave a hook in QOGLCPrivate, similar to e.g. the texture function resolvers. The hook gets populated when the VAO resolvers for a given context are requested. This removes memory management burden from the users of those functions (again, just like other function resolvers), and makes the initialization of the functions automatic. Change-Id: I0eba30a85bf8ad82946a5d68e91009d8b4bd91cf Reviewed-by: Laszlo Agocs <laszlo.agocs@qt.io>
This commit is contained in:
parent
f1f0aa4a3a
commit
436b331b71
@ -484,6 +484,13 @@ void QOpenGLContext::destroy()
|
||||
}
|
||||
d->textureFunctions = nullptr;
|
||||
|
||||
if (d->vaoHelperDestroyCallback) {
|
||||
Q_ASSERT(d->vaoHelper);
|
||||
d->vaoHelperDestroyCallback(d->vaoHelper);
|
||||
d->vaoHelperDestroyCallback = nullptr;
|
||||
}
|
||||
d->vaoHelper = nullptr;
|
||||
|
||||
d->nativeHandle = QVariant();
|
||||
}
|
||||
|
||||
|
@ -191,6 +191,7 @@ private:
|
||||
class QPaintEngineEx;
|
||||
class QOpenGLFunctions;
|
||||
class QOpenGLTextureHelper;
|
||||
class QOpenGLVertexArrayObjectHelper;
|
||||
|
||||
class Q_GUI_EXPORT QOpenGLContextVersionFunctionHelper
|
||||
{
|
||||
@ -211,6 +212,8 @@ public:
|
||||
, functions(nullptr)
|
||||
, textureFunctions(nullptr)
|
||||
, versionFunctions(nullptr)
|
||||
, vaoHelper(nullptr)
|
||||
, vaoHelperDestroyCallback(nullptr)
|
||||
, max_texture_size(-1)
|
||||
, workaround_brokenFBOReadBack(false)
|
||||
, workaround_brokenTexSubImage(false)
|
||||
@ -242,6 +245,9 @@ public:
|
||||
QOpenGLTextureHelper* textureFunctions;
|
||||
std::function<void()> textureFunctionsDestroyCallback;
|
||||
QOpenGLContextVersionFunctionHelper *versionFunctions;
|
||||
QOpenGLVertexArrayObjectHelper *vaoHelper;
|
||||
using QOpenGLVertexArrayObjectHelperDestroyCallback_t = void (*)(QOpenGLVertexArrayObjectHelper *);
|
||||
QOpenGLVertexArrayObjectHelperDestroyCallback_t vaoHelperDestroyCallback;
|
||||
|
||||
GLint max_texture_size;
|
||||
|
||||
|
@ -49,6 +49,7 @@
|
||||
#include <QtOpenGL/qopenglfunctions_3_0.h>
|
||||
#include <QtOpenGL/qopenglfunctions_3_2_core.h>
|
||||
|
||||
#include <private/qopenglcontext_p.h>
|
||||
#include <private/qopenglextensions_p.h>
|
||||
#include <private/qopenglvertexarrayobject_p.h>
|
||||
|
||||
@ -57,9 +58,28 @@ QT_BEGIN_NAMESPACE
|
||||
class QOpenGLFunctions_3_0;
|
||||
class QOpenGLFunctions_3_2_Core;
|
||||
|
||||
void qtInitializeVertexArrayObjectHelper(QOpenGLVertexArrayObjectHelper *helper, QOpenGLContext *context)
|
||||
static void vertexArrayObjectHelperDestroyCallback(QOpenGLVertexArrayObjectHelper *vaoHelper)
|
||||
{
|
||||
delete vaoHelper;
|
||||
}
|
||||
|
||||
QOpenGLVertexArrayObjectHelper *QOpenGLVertexArrayObjectHelper::vertexArrayObjectHelperForContext(QOpenGLContext *context)
|
||||
{
|
||||
Q_ASSERT(context);
|
||||
|
||||
auto contextPrivate = QOpenGLContextPrivate::get(context);
|
||||
auto &vaoHelper = contextPrivate->vaoHelper;
|
||||
|
||||
if (!vaoHelper) {
|
||||
vaoHelper = new QOpenGLVertexArrayObjectHelper(context);
|
||||
contextPrivate->vaoHelperDestroyCallback = &vertexArrayObjectHelperDestroyCallback;
|
||||
}
|
||||
|
||||
return vaoHelper;
|
||||
}
|
||||
|
||||
void QOpenGLVertexArrayObjectHelper::initializeFromContext(QOpenGLContext *context)
|
||||
{
|
||||
Q_ASSERT(helper);
|
||||
Q_ASSERT(context);
|
||||
|
||||
bool tryARB = true;
|
||||
@ -67,32 +87,32 @@ void qtInitializeVertexArrayObjectHelper(QOpenGLVertexArrayObjectHelper *helper,
|
||||
if (context->isOpenGLES()) {
|
||||
if (context->format().majorVersion() >= 3) {
|
||||
QOpenGLExtraFunctionsPrivate *extra = static_cast<QOpenGLExtensions *>(context->extraFunctions())->d();
|
||||
helper->GenVertexArrays = extra->f.GenVertexArrays;
|
||||
helper->DeleteVertexArrays = extra->f.DeleteVertexArrays;
|
||||
helper->BindVertexArray = extra->f.BindVertexArray;
|
||||
helper->IsVertexArray = extra->f.IsVertexArray;
|
||||
GenVertexArrays = extra->f.GenVertexArrays;
|
||||
DeleteVertexArrays = extra->f.DeleteVertexArrays;
|
||||
BindVertexArray = extra->f.BindVertexArray;
|
||||
IsVertexArray = extra->f.IsVertexArray;
|
||||
tryARB = false;
|
||||
} else if (context->hasExtension(QByteArrayLiteral("GL_OES_vertex_array_object"))) {
|
||||
helper->GenVertexArrays = reinterpret_cast<QOpenGLVertexArrayObjectHelper::qt_GenVertexArrays_t>(context->getProcAddress("glGenVertexArraysOES"));
|
||||
helper->DeleteVertexArrays = reinterpret_cast<QOpenGLVertexArrayObjectHelper::qt_DeleteVertexArrays_t>(context->getProcAddress("glDeleteVertexArraysOES"));
|
||||
helper->BindVertexArray = reinterpret_cast<QOpenGLVertexArrayObjectHelper::qt_BindVertexArray_t>(context->getProcAddress("glBindVertexArrayOES"));
|
||||
helper->IsVertexArray = reinterpret_cast<QOpenGLVertexArrayObjectHelper::qt_IsVertexArray_t>(context->getProcAddress("glIsVertexArrayOES"));
|
||||
GenVertexArrays = reinterpret_cast<QOpenGLVertexArrayObjectHelper::qt_GenVertexArrays_t>(context->getProcAddress("glGenVertexArraysOES"));
|
||||
DeleteVertexArrays = reinterpret_cast<QOpenGLVertexArrayObjectHelper::qt_DeleteVertexArrays_t>(context->getProcAddress("glDeleteVertexArraysOES"));
|
||||
BindVertexArray = reinterpret_cast<QOpenGLVertexArrayObjectHelper::qt_BindVertexArray_t>(context->getProcAddress("glBindVertexArrayOES"));
|
||||
IsVertexArray = reinterpret_cast<QOpenGLVertexArrayObjectHelper::qt_IsVertexArray_t>(context->getProcAddress("glIsVertexArrayOES"));
|
||||
tryARB = false;
|
||||
}
|
||||
} else if (context->hasExtension(QByteArrayLiteral("GL_APPLE_vertex_array_object")) &&
|
||||
!context->hasExtension(QByteArrayLiteral("GL_ARB_vertex_array_object"))) {
|
||||
helper->GenVertexArrays = reinterpret_cast<QOpenGLVertexArrayObjectHelper::qt_GenVertexArrays_t>(context->getProcAddress("glGenVertexArraysAPPLE"));
|
||||
helper->DeleteVertexArrays = reinterpret_cast<QOpenGLVertexArrayObjectHelper::qt_DeleteVertexArrays_t>(context->getProcAddress("glDeleteVertexArraysAPPLE"));
|
||||
helper->BindVertexArray = reinterpret_cast<QOpenGLVertexArrayObjectHelper::qt_BindVertexArray_t>(context->getProcAddress("glBindVertexArrayAPPLE"));
|
||||
helper->IsVertexArray = reinterpret_cast<QOpenGLVertexArrayObjectHelper::qt_IsVertexArray_t>(context->getProcAddress("glIsVertexArrayAPPLE"));
|
||||
GenVertexArrays = reinterpret_cast<QOpenGLVertexArrayObjectHelper::qt_GenVertexArrays_t>(context->getProcAddress("glGenVertexArraysAPPLE"));
|
||||
DeleteVertexArrays = reinterpret_cast<QOpenGLVertexArrayObjectHelper::qt_DeleteVertexArrays_t>(context->getProcAddress("glDeleteVertexArraysAPPLE"));
|
||||
BindVertexArray = reinterpret_cast<QOpenGLVertexArrayObjectHelper::qt_BindVertexArray_t>(context->getProcAddress("glBindVertexArrayAPPLE"));
|
||||
IsVertexArray = reinterpret_cast<QOpenGLVertexArrayObjectHelper::qt_IsVertexArray_t>(context->getProcAddress("glIsVertexArrayAPPLE"));
|
||||
tryARB = false;
|
||||
}
|
||||
|
||||
if (tryARB && context->hasExtension(QByteArrayLiteral("GL_ARB_vertex_array_object"))) {
|
||||
helper->GenVertexArrays = reinterpret_cast<QOpenGLVertexArrayObjectHelper::qt_GenVertexArrays_t>(context->getProcAddress("glGenVertexArrays"));
|
||||
helper->DeleteVertexArrays = reinterpret_cast<QOpenGLVertexArrayObjectHelper::qt_DeleteVertexArrays_t>(context->getProcAddress("glDeleteVertexArrays"));
|
||||
helper->BindVertexArray = reinterpret_cast<QOpenGLVertexArrayObjectHelper::qt_BindVertexArray_t>(context->getProcAddress("glBindVertexArray"));
|
||||
helper->IsVertexArray = reinterpret_cast<QOpenGLVertexArrayObjectHelper::qt_IsVertexArray_t>(context->getProcAddress("glIsVertexArray"));
|
||||
GenVertexArrays = reinterpret_cast<QOpenGLVertexArrayObjectHelper::qt_GenVertexArrays_t>(context->getProcAddress("glGenVertexArrays"));
|
||||
DeleteVertexArrays = reinterpret_cast<QOpenGLVertexArrayObjectHelper::qt_DeleteVertexArrays_t>(context->getProcAddress("glDeleteVertexArrays"));
|
||||
BindVertexArray = reinterpret_cast<QOpenGLVertexArrayObjectHelper::qt_BindVertexArray_t>(context->getProcAddress("glBindVertexArray"));
|
||||
IsVertexArray = reinterpret_cast<QOpenGLVertexArrayObjectHelper::qt_IsVertexArray_t>(context->getProcAddress("glIsVertexArray"));
|
||||
}
|
||||
}
|
||||
|
||||
@ -107,12 +127,6 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
~QOpenGLVertexArrayObjectPrivate()
|
||||
{
|
||||
if (vaoFuncsType == ARB || vaoFuncsType == APPLE || vaoFuncsType == OES)
|
||||
delete vaoFuncs.helper;
|
||||
}
|
||||
|
||||
bool create();
|
||||
void destroy();
|
||||
void bind();
|
||||
@ -167,7 +181,7 @@ bool QOpenGLVertexArrayObjectPrivate::create()
|
||||
|
||||
if (ctx->isOpenGLES()) {
|
||||
if (ctx->format().majorVersion() >= 3 || ctx->hasExtension(QByteArrayLiteral("GL_OES_vertex_array_object"))) {
|
||||
vaoFuncs.helper = new QOpenGLVertexArrayObjectHelper(ctx);
|
||||
vaoFuncs.helper = QOpenGLVertexArrayObjectHelper::vertexArrayObjectHelperForContext(ctx);
|
||||
vaoFuncsType = OES;
|
||||
vaoFuncs.helper->glGenVertexArrays(1, &vao);
|
||||
}
|
||||
@ -187,11 +201,11 @@ bool QOpenGLVertexArrayObjectPrivate::create()
|
||||
} else
|
||||
#endif
|
||||
if (ctx->hasExtension(QByteArrayLiteral("GL_ARB_vertex_array_object"))) {
|
||||
vaoFuncs.helper = new QOpenGLVertexArrayObjectHelper(ctx);
|
||||
vaoFuncs.helper = QOpenGLVertexArrayObjectHelper::vertexArrayObjectHelperForContext(ctx);
|
||||
vaoFuncsType = ARB;
|
||||
vaoFuncs.helper->glGenVertexArrays(1, &vao);
|
||||
} else if (ctx->hasExtension(QByteArrayLiteral("GL_APPLE_vertex_array_object"))) {
|
||||
vaoFuncs.helper = new QOpenGLVertexArrayObjectHelper(ctx);
|
||||
vaoFuncs.helper = QOpenGLVertexArrayObjectHelper::vertexArrayObjectHelperForContext(ctx);
|
||||
vaoFuncsType = APPLE;
|
||||
vaoFuncs.helper->glGenVertexArrays(1, &vao);
|
||||
}
|
||||
|
@ -57,25 +57,27 @@
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QOpenGLVertexArrayObjectHelper;
|
||||
class QOpenGLContext;
|
||||
|
||||
void Q_OPENGL_EXPORT qtInitializeVertexArrayObjectHelper(QOpenGLVertexArrayObjectHelper *helper, QOpenGLContext *context);
|
||||
|
||||
class QOpenGLVertexArrayObjectHelper
|
||||
{
|
||||
Q_DISABLE_COPY(QOpenGLVertexArrayObjectHelper)
|
||||
|
||||
public:
|
||||
private:
|
||||
explicit inline QOpenGLVertexArrayObjectHelper(QOpenGLContext *context)
|
||||
: GenVertexArrays(nullptr)
|
||||
, DeleteVertexArrays(nullptr)
|
||||
, BindVertexArray(nullptr)
|
||||
, IsVertexArray(nullptr)
|
||||
{
|
||||
qtInitializeVertexArrayObjectHelper(this, context);
|
||||
initializeFromContext(context);
|
||||
}
|
||||
|
||||
void Q_OPENGL_EXPORT initializeFromContext(QOpenGLContext *context);
|
||||
|
||||
public:
|
||||
static Q_OPENGL_EXPORT QOpenGLVertexArrayObjectHelper *vertexArrayObjectHelperForContext(QOpenGLContext *context);
|
||||
|
||||
inline bool isValid() const
|
||||
{
|
||||
return GenVertexArrays && DeleteVertexArrays && BindVertexArray && IsVertexArray;
|
||||
@ -101,9 +103,6 @@ public:
|
||||
return IsVertexArray(array);
|
||||
}
|
||||
|
||||
private:
|
||||
friend void Q_OPENGL_EXPORT qtInitializeVertexArrayObjectHelper(QOpenGLVertexArrayObjectHelper *helper, QOpenGLContext *context);
|
||||
|
||||
// Function signatures are equivalent between desktop core, ARB, APPLE, ES 3 and ES 2 extensions
|
||||
typedef void (QOPENGLF_APIENTRYP qt_GenVertexArrays_t)(GLsizei n, GLuint *arrays);
|
||||
typedef void (QOPENGLF_APIENTRYP qt_DeleteVertexArrays_t)(GLsizei n, const GLuint *arrays);
|
||||
|
@ -375,7 +375,7 @@ struct StateSaver
|
||||
{
|
||||
StateSaver() {
|
||||
f = QOpenGLContext::currentContext()->functions();
|
||||
vaoHelper = new QOpenGLVertexArrayObjectHelper(QOpenGLContext::currentContext());
|
||||
vaoHelper = QOpenGLVertexArrayObjectHelper::vertexArrayObjectHelperForContext(QOpenGLContext::currentContext());
|
||||
|
||||
static bool windowsChecked = false;
|
||||
static bool shouldSave = true;
|
||||
@ -446,7 +446,6 @@ struct StateSaver
|
||||
f->glVertexAttribPointer(i, va[i].size, va[i].type, va[i].normalized, va[i].stride, va[i].pointer);
|
||||
}
|
||||
}
|
||||
delete vaoHelper;
|
||||
}
|
||||
QOpenGLFunctions *f;
|
||||
QOpenGLVertexArrayObjectHelper *vaoHelper;
|
||||
|
Loading…
Reference in New Issue
Block a user