1 /****************************************************************************
2 **
3 ** Copyright (C) 2016 The Qt Company Ltd.
4 ** Contact: https://www.qt.io/licensing/
5 **
6 ** This file is part of the plugins of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and The Qt Company. For licensing terms
14 ** and conditions see https://www.qt.io/terms-conditions. For further
15 ** information use the contact form at https://www.qt.io/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 3 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL3 included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 3 requirements
23 ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24 **
25 ** GNU General Public License Usage
26 ** Alternatively, this file may be used under the terms of the GNU
27 ** General Public License version 2.0 or (at your option) the GNU General
28 ** Public license version 3 or any later version approved by the KDE Free
29 ** Qt Foundation. The licenses are as published by the Free Software
30 ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31 ** included in the packaging of this file. Please review the following
32 ** information to ensure the GNU General Public License requirements will
33 ** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34 ** https://www.gnu.org/licenses/gpl-3.0.html.
35 **
36 ** $QT_END_LICENSE$
37 **
38 ****************************************************************************/
39 
40 #include "qeglplatformcontext_p.h"
41 #include "qeglconvenience_p.h"
42 #include "qeglpbuffer_p.h"
43 #include <qpa/qplatformwindow.h>
44 #include <QOpenGLContext>
45 #include <QtPlatformHeaders/QEGLNativeContext>
46 #include <QDebug>
47 
48 #if defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_EMBEDDED)
49 #include <QtCore/private/qjnihelpers_p.h>
50 #endif
51 #ifndef Q_OS_WIN
52 #include <dlfcn.h>
53 #endif
54 
55 QT_BEGIN_NAMESPACE
56 
57 /*!
58     \class QEGLPlatformContext
59     \brief An EGL context implementation.
60     \since 5.2
61     \internal
62     \ingroup qpa
63 
64     Implement QPlatformOpenGLContext using EGL. To use it in platform
65     plugins a subclass must be created since
66     eglSurfaceForPlatformSurface() has to be reimplemented. This
67     function is used for mapping platform surfaces (windows) to EGL
68     surfaces and is necessary since different platform plugins may
69     have different ways of handling native windows (for example, a
70     plugin may choose not to back every platform window by a real EGL
71     surface). Other than that, no further customization is necessary.
72  */
73 
74 // Constants from EGL_KHR_create_context
75 #ifndef EGL_CONTEXT_MINOR_VERSION_KHR
76 #define EGL_CONTEXT_MINOR_VERSION_KHR 0x30FB
77 #endif
78 #ifndef EGL_CONTEXT_FLAGS_KHR
79 #define EGL_CONTEXT_FLAGS_KHR 0x30FC
80 #endif
81 #ifndef EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR
82 #define EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR 0x30FD
83 #endif
84 #ifndef EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR
85 #define EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR 0x00000001
86 #endif
87 #ifndef EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR
88 #define EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR 0x00000002
89 #endif
90 #ifndef EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR
91 #define EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR 0x00000001
92 #endif
93 #ifndef EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR
94 #define EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR 0x00000002
95 #endif
96 
97 // Constants for OpenGL which are not available in the ES headers.
98 #ifndef GL_CONTEXT_FLAGS
99 #define GL_CONTEXT_FLAGS 0x821E
100 #endif
101 #ifndef GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT
102 #define GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT 0x0001
103 #endif
104 #ifndef GL_CONTEXT_FLAG_DEBUG_BIT
105 #define GL_CONTEXT_FLAG_DEBUG_BIT 0x00000002
106 #endif
107 #ifndef GL_CONTEXT_PROFILE_MASK
108 #define GL_CONTEXT_PROFILE_MASK 0x9126
109 #endif
110 #ifndef GL_CONTEXT_CORE_PROFILE_BIT
111 #define GL_CONTEXT_CORE_PROFILE_BIT 0x00000001
112 #endif
113 #ifndef GL_CONTEXT_COMPATIBILITY_PROFILE_BIT
114 #define GL_CONTEXT_COMPATIBILITY_PROFILE_BIT 0x00000002
115 #endif
116 
QEGLPlatformContext(const QSurfaceFormat & format,QPlatformOpenGLContext * share,EGLDisplay display,EGLConfig * config,const QVariant & nativeHandle,Flags flags)117 QEGLPlatformContext::QEGLPlatformContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share, EGLDisplay display,
118                                          EGLConfig *config, const QVariant &nativeHandle, Flags flags)
119     : m_eglDisplay(display)
120     , m_swapInterval(-1)
121     , m_swapIntervalEnvChecked(false)
122     , m_swapIntervalFromEnv(-1)
123     , m_flags(flags)
124 {
125     if (nativeHandle.isNull()) {
126         m_eglConfig = config ? *config : q_configFromGLFormat(display, format);
127         m_ownsContext = true;
128         init(format, share);
129     } else {
130         m_ownsContext = false;
131         adopt(nativeHandle, share);
132     }
133 }
134 
init(const QSurfaceFormat & format,QPlatformOpenGLContext * share)135 void QEGLPlatformContext::init(const QSurfaceFormat &format, QPlatformOpenGLContext *share)
136 {
137     m_format = q_glFormatFromConfig(m_eglDisplay, m_eglConfig, format);
138     // m_format now has the renderableType() resolved (it cannot be Default anymore)
139     // but does not yet contain version, profile, options.
140     m_shareContext = share ? static_cast<QEGLPlatformContext *>(share)->m_eglContext : nullptr;
141 
142     QVector<EGLint> contextAttrs;
143     contextAttrs.append(EGL_CONTEXT_CLIENT_VERSION);
144     contextAttrs.append(format.majorVersion());
145     const bool hasKHRCreateContext = q_hasEglExtension(m_eglDisplay, "EGL_KHR_create_context");
146     if (hasKHRCreateContext) {
147         contextAttrs.append(EGL_CONTEXT_MINOR_VERSION_KHR);
148         contextAttrs.append(format.minorVersion());
149         int flags = 0;
150         // The debug bit is supported both for OpenGL and OpenGL ES.
151         if (format.testOption(QSurfaceFormat::DebugContext))
152             flags |= EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR;
153         // The fwdcompat bit is only for OpenGL 3.0+.
154         if (m_format.renderableType() == QSurfaceFormat::OpenGL
155             && format.majorVersion() >= 3
156             && !format.testOption(QSurfaceFormat::DeprecatedFunctions))
157             flags |= EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR;
158         if (flags) {
159             contextAttrs.append(EGL_CONTEXT_FLAGS_KHR);
160             contextAttrs.append(flags);
161         }
162         // Profiles are OpenGL only and mandatory in 3.2+. The value is silently ignored for < 3.2.
163         if (m_format.renderableType() == QSurfaceFormat::OpenGL) {
164             contextAttrs.append(EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR);
165             contextAttrs.append(format.profile() == QSurfaceFormat::CoreProfile
166                                 ? EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR
167                                 : EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR);
168         }
169     }
170 
171     // Special Options for OpenVG surfaces
172     if (m_format.renderableType() == QSurfaceFormat::OpenVG) {
173         contextAttrs.append(EGL_ALPHA_MASK_SIZE);
174         contextAttrs.append(8);
175     }
176 
177     contextAttrs.append(EGL_NONE);
178     m_contextAttrs = contextAttrs;
179 
180     switch (m_format.renderableType()) {
181     case QSurfaceFormat::OpenVG:
182         m_api = EGL_OPENVG_API;
183         break;
184 #ifdef EGL_VERSION_1_4
185     case QSurfaceFormat::OpenGL:
186         m_api = EGL_OPENGL_API;
187         break;
188 #endif // EGL_VERSION_1_4
189     default:
190         m_api = EGL_OPENGL_ES_API;
191         break;
192     }
193 
194     eglBindAPI(m_api);
195     m_eglContext = eglCreateContext(m_eglDisplay, m_eglConfig, m_shareContext, contextAttrs.constData());
196     if (m_eglContext == EGL_NO_CONTEXT && m_shareContext != EGL_NO_CONTEXT) {
197         m_shareContext = nullptr;
198         m_eglContext = eglCreateContext(m_eglDisplay, m_eglConfig, nullptr, contextAttrs.constData());
199     }
200 
201     if (m_eglContext == EGL_NO_CONTEXT) {
202         qWarning("QEGLPlatformContext: Failed to create context: %x", eglGetError());
203         return;
204     }
205 
206     static const bool printConfig = qEnvironmentVariableIntValue("QT_QPA_EGLFS_DEBUG");
207     if (printConfig) {
208         qDebug() << "Created context for format" << format << "with config:";
209         q_printEglConfig(m_eglDisplay, m_eglConfig);
210     }
211 
212     // Cannot just call updateFormatFromGL() since it relies on virtuals. Defer it to initialize().
213 }
214 
adopt(const QVariant & nativeHandle,QPlatformOpenGLContext * share)215 void QEGLPlatformContext::adopt(const QVariant &nativeHandle, QPlatformOpenGLContext *share)
216 {
217     if (!nativeHandle.canConvert<QEGLNativeContext>()) {
218         qWarning("QEGLPlatformContext: Requires a QEGLNativeContext");
219         return;
220     }
221     QEGLNativeContext handle = qvariant_cast<QEGLNativeContext>(nativeHandle);
222     EGLContext context = handle.context();
223     if (!context) {
224         qWarning("QEGLPlatformContext: No EGLContext given");
225         return;
226     }
227 
228     // A context belonging to a given EGLDisplay cannot be used with another one.
229     if (handle.display() != m_eglDisplay) {
230         qWarning("QEGLPlatformContext: Cannot adopt context from different display");
231         return;
232     }
233 
234     // Figure out the EGLConfig.
235     EGLint value = 0;
236     eglQueryContext(m_eglDisplay, context, EGL_CONFIG_ID, &value);
237     EGLint n = 0;
238     EGLConfig cfg;
239     const EGLint attribs[] = { EGL_CONFIG_ID, value, EGL_NONE };
240     if (eglChooseConfig(m_eglDisplay, attribs, &cfg, 1, &n) && n == 1) {
241         m_eglConfig = cfg;
242         m_format = q_glFormatFromConfig(m_eglDisplay, m_eglConfig);
243     } else {
244         qWarning("QEGLPlatformContext: Failed to get framebuffer configuration for context");
245     }
246 
247     // Fetch client API type.
248     value = 0;
249     eglQueryContext(m_eglDisplay, context, EGL_CONTEXT_CLIENT_TYPE, &value);
250     if (value == EGL_OPENGL_API || value == EGL_OPENGL_ES_API) {
251         // if EGL config supports both OpenGL and OpenGL ES render type,
252         // q_glFormatFromConfig() with the default "referenceFormat" parameter
253         // will always figure it out as OpenGL render type.
254         // We can override it to match user's real render type.
255         if (value == EGL_OPENGL_ES_API)
256             m_format.setRenderableType(QSurfaceFormat::OpenGLES);
257         m_api = value;
258         eglBindAPI(m_api);
259     } else {
260         qWarning("QEGLPlatformContext: Failed to get client API type");
261         m_api = EGL_OPENGL_ES_API;
262     }
263 
264     m_eglContext = context;
265     m_shareContext = share ? static_cast<QEGLPlatformContext *>(share)->m_eglContext : nullptr;
266     updateFormatFromGL();
267 }
268 
initialize()269 void QEGLPlatformContext::initialize()
270 {
271     if (m_eglContext != EGL_NO_CONTEXT)
272         updateFormatFromGL();
273 }
274 
275 // Base implementation for pbuffers. Subclasses will handle the specialized cases for
276 // platforms without pbuffers.
createTemporaryOffscreenSurface()277 EGLSurface QEGLPlatformContext::createTemporaryOffscreenSurface()
278 {
279     // Make the context current to ensure the GL version query works. This needs a surface too.
280     const EGLint pbufferAttributes[] = {
281         EGL_WIDTH, 1,
282         EGL_HEIGHT, 1,
283         EGL_LARGEST_PBUFFER, EGL_FALSE,
284         EGL_NONE
285     };
286 
287     // Cannot just pass m_eglConfig because it may not be suitable for pbuffers. Instead,
288     // do what QEGLPbuffer would do: request a config with the same attributes but with
289     // PBUFFER_BIT set.
290     EGLConfig config = q_configFromGLFormat(m_eglDisplay, m_format, false, EGL_PBUFFER_BIT);
291 
292     return eglCreatePbufferSurface(m_eglDisplay, config, pbufferAttributes);
293 }
294 
destroyTemporaryOffscreenSurface(EGLSurface surface)295 void QEGLPlatformContext::destroyTemporaryOffscreenSurface(EGLSurface surface)
296 {
297     eglDestroySurface(m_eglDisplay, surface);
298 }
299 
runGLChecks()300 void QEGLPlatformContext::runGLChecks()
301 {
302     // Nothing to do here, subclasses may override in order to perform OpenGL
303     // queries needing a context.
304 }
305 
updateFormatFromGL()306 void QEGLPlatformContext::updateFormatFromGL()
307 {
308 #ifndef QT_NO_OPENGL
309     // Have to save & restore to prevent QOpenGLContext::currentContext() from becoming
310     // inconsistent after QOpenGLContext::create().
311     EGLDisplay prevDisplay = eglGetCurrentDisplay();
312     if (prevDisplay == EGL_NO_DISPLAY) // when no context is current
313         prevDisplay = m_eglDisplay;
314     EGLContext prevContext = eglGetCurrentContext();
315     EGLSurface prevSurfaceDraw = eglGetCurrentSurface(EGL_DRAW);
316     EGLSurface prevSurfaceRead = eglGetCurrentSurface(EGL_READ);
317 
318     // Rely on the surfaceless extension, if available. This is beneficial since we can
319     // avoid creating an extra pbuffer surface which is apparently troublesome with some
320     // drivers (Mesa) when certain attributes are present (multisampling).
321     EGLSurface tempSurface = EGL_NO_SURFACE;
322     EGLContext tempContext = EGL_NO_CONTEXT;
323     if (m_flags.testFlag(NoSurfaceless) || !q_hasEglExtension(m_eglDisplay, "EGL_KHR_surfaceless_context"))
324         tempSurface = createTemporaryOffscreenSurface();
325 
326     EGLBoolean ok = eglMakeCurrent(m_eglDisplay, tempSurface, tempSurface, m_eglContext);
327     if (!ok) {
328         EGLConfig config = q_configFromGLFormat(m_eglDisplay, m_format, false, EGL_PBUFFER_BIT);
329         tempContext = eglCreateContext(m_eglDisplay, config, nullptr, m_contextAttrs.constData());
330         if (tempContext != EGL_NO_CONTEXT)
331             ok = eglMakeCurrent(m_eglDisplay, tempSurface, tempSurface, tempContext);
332     }
333     if (ok) {
334         if (m_format.renderableType() == QSurfaceFormat::OpenGL
335             || m_format.renderableType() == QSurfaceFormat::OpenGLES) {
336             const GLubyte *s = glGetString(GL_VERSION);
337             if (s) {
338                 QByteArray version = QByteArray(reinterpret_cast<const char *>(s));
339                 int major, minor;
340                 if (QPlatformOpenGLContext::parseOpenGLVersion(version, major, minor)) {
341                     m_format.setMajorVersion(major);
342                     m_format.setMinorVersion(minor);
343                 }
344             }
345             m_format.setProfile(QSurfaceFormat::NoProfile);
346             m_format.setOptions(QSurfaceFormat::FormatOptions());
347             if (m_format.renderableType() == QSurfaceFormat::OpenGL) {
348                 // Check profile and options.
349                 if (m_format.majorVersion() < 3) {
350                     m_format.setOption(QSurfaceFormat::DeprecatedFunctions);
351                 } else {
352                     GLint value = 0;
353                     glGetIntegerv(GL_CONTEXT_FLAGS, &value);
354                     if (!(value & GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT))
355                         m_format.setOption(QSurfaceFormat::DeprecatedFunctions);
356                     if (value & GL_CONTEXT_FLAG_DEBUG_BIT)
357                         m_format.setOption(QSurfaceFormat::DebugContext);
358                     if (m_format.version() >= qMakePair(3, 2)) {
359                         value = 0;
360                         glGetIntegerv(GL_CONTEXT_PROFILE_MASK, &value);
361                         if (value & GL_CONTEXT_CORE_PROFILE_BIT)
362                             m_format.setProfile(QSurfaceFormat::CoreProfile);
363                         else if (value & GL_CONTEXT_COMPATIBILITY_PROFILE_BIT)
364                             m_format.setProfile(QSurfaceFormat::CompatibilityProfile);
365                     }
366                 }
367             }
368         }
369         runGLChecks();
370         eglMakeCurrent(prevDisplay, prevSurfaceDraw, prevSurfaceRead, prevContext);
371     } else {
372         qWarning("QEGLPlatformContext: Failed to make temporary surface current, format not updated (%x)", eglGetError());
373     }
374     if (tempSurface != EGL_NO_SURFACE)
375         destroyTemporaryOffscreenSurface(tempSurface);
376     if (tempContext != EGL_NO_CONTEXT)
377         eglDestroyContext(m_eglDisplay, tempContext);
378 #endif // QT_NO_OPENGL
379 }
380 
makeCurrent(QPlatformSurface * surface)381 bool QEGLPlatformContext::makeCurrent(QPlatformSurface *surface)
382 {
383     Q_ASSERT(surface->surface()->supportsOpenGL());
384 
385     eglBindAPI(m_api);
386 
387     EGLSurface eglSurface = eglSurfaceForPlatformSurface(surface);
388 
389     // shortcut: on some GPUs, eglMakeCurrent is not a cheap operation
390     if (eglGetCurrentContext() == m_eglContext &&
391         eglGetCurrentDisplay() == m_eglDisplay &&
392         eglGetCurrentSurface(EGL_READ) == eglSurface &&
393         eglGetCurrentSurface(EGL_DRAW) == eglSurface) {
394         return true;
395     }
396 
397     const bool ok = eglMakeCurrent(m_eglDisplay, eglSurface, eglSurface, m_eglContext);
398     if (ok) {
399         if (!m_swapIntervalEnvChecked) {
400             m_swapIntervalEnvChecked = true;
401             if (qEnvironmentVariableIsSet("QT_QPA_EGLFS_SWAPINTERVAL")) {
402                 QByteArray swapIntervalString = qgetenv("QT_QPA_EGLFS_SWAPINTERVAL");
403                 bool intervalOk;
404                 const int swapInterval = swapIntervalString.toInt(&intervalOk);
405                 if (intervalOk)
406                     m_swapIntervalFromEnv = swapInterval;
407             }
408         }
409         const int requestedSwapInterval = m_swapIntervalFromEnv >= 0
410             ? m_swapIntervalFromEnv
411             : surface->format().swapInterval();
412         if (requestedSwapInterval >= 0 && m_swapInterval != requestedSwapInterval) {
413             m_swapInterval = requestedSwapInterval;
414             if (eglSurface != EGL_NO_SURFACE) // skip if using surfaceless context
415                 eglSwapInterval(eglDisplay(), m_swapInterval);
416         }
417     } else {
418         qWarning("QEGLPlatformContext: eglMakeCurrent failed: %x", eglGetError());
419     }
420 
421     return ok;
422 }
423 
~QEGLPlatformContext()424 QEGLPlatformContext::~QEGLPlatformContext()
425 {
426     if (m_ownsContext && m_eglContext != EGL_NO_CONTEXT)
427         eglDestroyContext(m_eglDisplay, m_eglContext);
428 
429     m_eglContext = EGL_NO_CONTEXT;
430 }
431 
doneCurrent()432 void QEGLPlatformContext::doneCurrent()
433 {
434     eglBindAPI(m_api);
435     bool ok = eglMakeCurrent(m_eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
436     if (!ok)
437         qWarning("QEGLPlatformContext: eglMakeCurrent failed: %x", eglGetError());
438 }
439 
swapBuffers(QPlatformSurface * surface)440 void QEGLPlatformContext::swapBuffers(QPlatformSurface *surface)
441 {
442     eglBindAPI(m_api);
443     EGLSurface eglSurface = eglSurfaceForPlatformSurface(surface);
444     if (eglSurface != EGL_NO_SURFACE) { // skip if using surfaceless context
445         bool ok = eglSwapBuffers(m_eglDisplay, eglSurface);
446         if (!ok)
447             qWarning("QEGLPlatformContext: eglSwapBuffers failed: %x", eglGetError());
448     }
449 }
450 
getProcAddress(const char * procName)451 QFunctionPointer QEGLPlatformContext::getProcAddress(const char *procName)
452 {
453     eglBindAPI(m_api);
454     QFunctionPointer proc = (QFunctionPointer) eglGetProcAddress(procName);
455 #if !defined(Q_OS_WIN) && !defined(Q_OS_INTEGRITY)
456     if (!proc)
457         proc = (QFunctionPointer) dlsym(RTLD_DEFAULT, procName);
458 #elif !defined(QT_OPENGL_DYNAMIC)
459     // On systems without KHR_get_all_proc_addresses and without
460     // dynamic linking there still has to be a way to access the
461     // standard GLES functions. QOpenGL(Extra)Functions never makes
462     // direct GL API calls since Qt 5.7, so all such workarounds are
463     // expected to be handled in the platform plugin.
464     if (!proc) {
465         static struct StdFunc {
466             const char *name;
467             QFunctionPointer func;
468         } standardFuncs[] = {
469 #ifdef QT_OPENGL_ES_2
470             { "glBindTexture", (QFunctionPointer) ::glBindTexture },
471             { "glBlendFunc", (QFunctionPointer) ::glBlendFunc },
472             { "glClear", (QFunctionPointer) ::glClear },
473             { "glClearColor", (QFunctionPointer) ::glClearColor },
474             { "glClearStencil", (QFunctionPointer) ::glClearStencil },
475             { "glColorMask", (QFunctionPointer) ::glColorMask },
476             { "glCopyTexImage2D", (QFunctionPointer) ::glCopyTexImage2D },
477             { "glCopyTexSubImage2D", (QFunctionPointer) ::glCopyTexSubImage2D },
478             { "glCullFace", (QFunctionPointer) ::glCullFace },
479             { "glDeleteTextures", (QFunctionPointer) ::glDeleteTextures },
480             { "glDepthFunc", (QFunctionPointer) ::glDepthFunc },
481             { "glDepthMask", (QFunctionPointer) ::glDepthMask },
482             { "glDisable", (QFunctionPointer) ::glDisable },
483             { "glDrawArrays", (QFunctionPointer) ::glDrawArrays },
484             { "glDrawElements", (QFunctionPointer) ::glDrawElements },
485             { "glEnable", (QFunctionPointer) ::glEnable },
486             { "glFinish", (QFunctionPointer) ::glFinish },
487             { "glFlush", (QFunctionPointer) ::glFlush },
488             { "glFrontFace", (QFunctionPointer) ::glFrontFace },
489             { "glGenTextures", (QFunctionPointer) ::glGenTextures },
490             { "glGetBooleanv", (QFunctionPointer) ::glGetBooleanv },
491             { "glGetError", (QFunctionPointer) ::glGetError },
492             { "glGetFloatv", (QFunctionPointer) ::glGetFloatv },
493             { "glGetIntegerv", (QFunctionPointer) ::glGetIntegerv },
494             { "glGetString", (QFunctionPointer) ::glGetString },
495             { "glGetTexParameterfv", (QFunctionPointer) ::glGetTexParameterfv },
496             { "glGetTexParameteriv", (QFunctionPointer) ::glGetTexParameteriv },
497             { "glHint", (QFunctionPointer) ::glHint },
498             { "glIsEnabled", (QFunctionPointer) ::glIsEnabled },
499             { "glIsTexture", (QFunctionPointer) ::glIsTexture },
500             { "glLineWidth", (QFunctionPointer) ::glLineWidth },
501             { "glPixelStorei", (QFunctionPointer) ::glPixelStorei },
502             { "glPolygonOffset", (QFunctionPointer) ::glPolygonOffset },
503             { "glReadPixels", (QFunctionPointer) ::glReadPixels },
504             { "glScissor", (QFunctionPointer) ::glScissor },
505             { "glStencilFunc", (QFunctionPointer) ::glStencilFunc },
506             { "glStencilMask", (QFunctionPointer) ::glStencilMask },
507             { "glStencilOp", (QFunctionPointer) ::glStencilOp },
508             { "glTexImage2D", (QFunctionPointer) ::glTexImage2D },
509             { "glTexParameterf", (QFunctionPointer) ::glTexParameterf },
510             { "glTexParameterfv", (QFunctionPointer) ::glTexParameterfv },
511             { "glTexParameteri", (QFunctionPointer) ::glTexParameteri },
512             { "glTexParameteriv", (QFunctionPointer) ::glTexParameteriv },
513             { "glTexSubImage2D", (QFunctionPointer) ::glTexSubImage2D },
514             { "glViewport", (QFunctionPointer) ::glViewport },
515 
516             { "glActiveTexture", (QFunctionPointer) ::glActiveTexture },
517             { "glAttachShader", (QFunctionPointer) ::glAttachShader },
518             { "glBindAttribLocation", (QFunctionPointer) ::glBindAttribLocation },
519             { "glBindBuffer", (QFunctionPointer) ::glBindBuffer },
520             { "glBindFramebuffer", (QFunctionPointer) ::glBindFramebuffer },
521             { "glBindRenderbuffer", (QFunctionPointer) ::glBindRenderbuffer },
522             { "glBlendColor", (QFunctionPointer) ::glBlendColor },
523             { "glBlendEquation", (QFunctionPointer) ::glBlendEquation },
524             { "glBlendEquationSeparate", (QFunctionPointer) ::glBlendEquationSeparate },
525             { "glBlendFuncSeparate", (QFunctionPointer) ::glBlendFuncSeparate },
526             { "glBufferData", (QFunctionPointer) ::glBufferData },
527             { "glBufferSubData", (QFunctionPointer) ::glBufferSubData },
528             { "glCheckFramebufferStatus", (QFunctionPointer) ::glCheckFramebufferStatus },
529             { "glCompileShader", (QFunctionPointer) ::glCompileShader },
530             { "glCompressedTexImage2D", (QFunctionPointer) ::glCompressedTexImage2D },
531             { "glCompressedTexSubImage2D", (QFunctionPointer) ::glCompressedTexSubImage2D },
532             { "glCreateProgram", (QFunctionPointer) ::glCreateProgram },
533             { "glCreateShader", (QFunctionPointer) ::glCreateShader },
534             { "glDeleteBuffers", (QFunctionPointer) ::glDeleteBuffers },
535             { "glDeleteFramebuffers", (QFunctionPointer) ::glDeleteFramebuffers },
536             { "glDeleteProgram", (QFunctionPointer) ::glDeleteProgram },
537             { "glDeleteRenderbuffers", (QFunctionPointer) ::glDeleteRenderbuffers },
538             { "glDeleteShader", (QFunctionPointer) ::glDeleteShader },
539             { "glDetachShader", (QFunctionPointer) ::glDetachShader },
540             { "glDisableVertexAttribArray", (QFunctionPointer) ::glDisableVertexAttribArray },
541             { "glEnableVertexAttribArray", (QFunctionPointer) ::glEnableVertexAttribArray },
542             { "glFramebufferRenderbuffer", (QFunctionPointer) ::glFramebufferRenderbuffer },
543             { "glFramebufferTexture2D", (QFunctionPointer) ::glFramebufferTexture2D },
544             { "glGenBuffers", (QFunctionPointer) ::glGenBuffers },
545             { "glGenerateMipmap", (QFunctionPointer) ::glGenerateMipmap },
546             { "glGenFramebuffers", (QFunctionPointer) ::glGenFramebuffers },
547             { "glGenRenderbuffers", (QFunctionPointer) ::glGenRenderbuffers },
548             { "glGetActiveAttrib", (QFunctionPointer) ::glGetActiveAttrib },
549             { "glGetActiveUniform", (QFunctionPointer) ::glGetActiveUniform },
550             { "glGetAttachedShaders", (QFunctionPointer) ::glGetAttachedShaders },
551             { "glGetAttribLocation", (QFunctionPointer) ::glGetAttribLocation },
552             { "glGetBufferParameteriv", (QFunctionPointer) ::glGetBufferParameteriv },
553             { "glGetFramebufferAttachmentParameteriv", (QFunctionPointer) ::glGetFramebufferAttachmentParameteriv },
554             { "glGetProgramiv", (QFunctionPointer) ::glGetProgramiv },
555             { "glGetProgramInfoLog", (QFunctionPointer) ::glGetProgramInfoLog },
556             { "glGetRenderbufferParameteriv", (QFunctionPointer) ::glGetRenderbufferParameteriv },
557             { "glGetShaderiv", (QFunctionPointer) ::glGetShaderiv },
558             { "glGetShaderInfoLog", (QFunctionPointer) ::glGetShaderInfoLog },
559             { "glGetShaderPrecisionFormat", (QFunctionPointer) ::glGetShaderPrecisionFormat },
560             { "glGetShaderSource", (QFunctionPointer) ::glGetShaderSource },
561             { "glGetUniformfv", (QFunctionPointer) ::glGetUniformfv },
562             { "glGetUniformiv", (QFunctionPointer) ::glGetUniformiv },
563             { "glGetUniformLocation", (QFunctionPointer) ::glGetUniformLocation },
564             { "glGetVertexAttribfv", (QFunctionPointer) ::glGetVertexAttribfv },
565             { "glGetVertexAttribiv", (QFunctionPointer) ::glGetVertexAttribiv },
566             { "glGetVertexAttribPointerv", (QFunctionPointer) ::glGetVertexAttribPointerv },
567             { "glIsBuffer", (QFunctionPointer) ::glIsBuffer },
568             { "glIsFramebuffer", (QFunctionPointer) ::glIsFramebuffer },
569             { "glIsProgram", (QFunctionPointer) ::glIsProgram },
570             { "glIsRenderbuffer", (QFunctionPointer) ::glIsRenderbuffer },
571             { "glIsShader", (QFunctionPointer) ::glIsShader },
572             { "glLinkProgram", (QFunctionPointer) ::glLinkProgram },
573             { "glReleaseShaderCompiler", (QFunctionPointer) ::glReleaseShaderCompiler },
574             { "glRenderbufferStorage", (QFunctionPointer) ::glRenderbufferStorage },
575             { "glSampleCoverage", (QFunctionPointer) ::glSampleCoverage },
576             { "glShaderBinary", (QFunctionPointer) ::glShaderBinary },
577             { "glShaderSource", (QFunctionPointer) ::glShaderSource },
578             { "glStencilFuncSeparate", (QFunctionPointer) ::glStencilFuncSeparate },
579             { "glStencilMaskSeparate", (QFunctionPointer) ::glStencilMaskSeparate },
580             { "glStencilOpSeparate", (QFunctionPointer) ::glStencilOpSeparate },
581             { "glUniform1f", (QFunctionPointer) ::glUniform1f },
582             { "glUniform1fv", (QFunctionPointer) ::glUniform1fv },
583             { "glUniform1i", (QFunctionPointer) ::glUniform1i },
584             { "glUniform1iv", (QFunctionPointer) ::glUniform1iv },
585             { "glUniform2f", (QFunctionPointer) ::glUniform2f },
586             { "glUniform2fv", (QFunctionPointer) ::glUniform2fv },
587             { "glUniform2i", (QFunctionPointer) ::glUniform2i },
588             { "glUniform2iv", (QFunctionPointer) ::glUniform2iv },
589             { "glUniform3f", (QFunctionPointer) ::glUniform3f },
590             { "glUniform3fv", (QFunctionPointer) ::glUniform3fv },
591             { "glUniform3i", (QFunctionPointer) ::glUniform3i },
592             { "glUniform3iv", (QFunctionPointer) ::glUniform3iv },
593             { "glUniform4f", (QFunctionPointer) ::glUniform4f },
594             { "glUniform4fv", (QFunctionPointer) ::glUniform4fv },
595             { "glUniform4i", (QFunctionPointer) ::glUniform4i },
596             { "glUniform4iv", (QFunctionPointer) ::glUniform4iv },
597             { "glUniformMatrix2fv", (QFunctionPointer) ::glUniformMatrix2fv },
598             { "glUniformMatrix3fv", (QFunctionPointer) ::glUniformMatrix3fv },
599             { "glUniformMatrix4fv", (QFunctionPointer) ::glUniformMatrix4fv },
600             { "glUseProgram", (QFunctionPointer) ::glUseProgram },
601             { "glValidateProgram", (QFunctionPointer) ::glValidateProgram },
602             { "glVertexAttrib1f", (QFunctionPointer) ::glVertexAttrib1f },
603             { "glVertexAttrib1fv", (QFunctionPointer) ::glVertexAttrib1fv },
604             { "glVertexAttrib2f", (QFunctionPointer) ::glVertexAttrib2f },
605             { "glVertexAttrib2fv", (QFunctionPointer) ::glVertexAttrib2fv },
606             { "glVertexAttrib3f", (QFunctionPointer) ::glVertexAttrib3f },
607             { "glVertexAttrib3fv", (QFunctionPointer) ::glVertexAttrib3fv },
608             { "glVertexAttrib4f", (QFunctionPointer) ::glVertexAttrib4f },
609             { "glVertexAttrib4fv", (QFunctionPointer) ::glVertexAttrib4fv },
610             { "glVertexAttribPointer", (QFunctionPointer) ::glVertexAttribPointer },
611 
612             { "glClearDepthf", (QFunctionPointer) ::glClearDepthf },
613             { "glDepthRangef", (QFunctionPointer) ::glDepthRangef },
614 #endif // QT_OPENGL_ES_2
615 
616 #ifdef QT_OPENGL_ES_3
617             { "glBeginQuery", (QFunctionPointer) ::glBeginQuery },
618             { "glBeginTransformFeedback", (QFunctionPointer) ::glBeginTransformFeedback },
619             { "glBindBufferBase", (QFunctionPointer) ::glBindBufferBase },
620             { "glBindBufferRange", (QFunctionPointer) ::glBindBufferRange },
621             { "glBindSampler", (QFunctionPointer) ::glBindSampler },
622             { "glBindTransformFeedback", (QFunctionPointer) ::glBindTransformFeedback },
623             { "glBindVertexArray", (QFunctionPointer) ::glBindVertexArray },
624             { "glBlitFramebuffer", (QFunctionPointer) ::glBlitFramebuffer },
625             { "glClearBufferfi", (QFunctionPointer) ::glClearBufferfi },
626             { "glClearBufferfv", (QFunctionPointer) ::glClearBufferfv },
627             { "glClearBufferiv", (QFunctionPointer) ::glClearBufferiv },
628             { "glClearBufferuiv", (QFunctionPointer) ::glClearBufferuiv },
629             { "glClientWaitSync", (QFunctionPointer) ::glClientWaitSync },
630             { "glCompressedTexImage3D", (QFunctionPointer) ::glCompressedTexImage3D },
631             { "glCompressedTexSubImage3D", (QFunctionPointer) ::glCompressedTexSubImage3D },
632             { "glCopyBufferSubData", (QFunctionPointer) ::glCopyBufferSubData },
633             { "glCopyTexSubImage3D", (QFunctionPointer) ::glCopyTexSubImage3D },
634             { "glDeleteQueries", (QFunctionPointer) ::glDeleteQueries },
635             { "glDeleteSamplers", (QFunctionPointer) ::glDeleteSamplers },
636             { "glDeleteSync", (QFunctionPointer) ::glDeleteSync },
637             { "glDeleteTransformFeedbacks", (QFunctionPointer) ::glDeleteTransformFeedbacks },
638             { "glDeleteVertexArrays", (QFunctionPointer) ::glDeleteVertexArrays },
639             { "glDrawArraysInstanced", (QFunctionPointer) ::glDrawArraysInstanced },
640             { "glDrawBuffers", (QFunctionPointer) ::glDrawBuffers },
641             { "glDrawElementsInstanced", (QFunctionPointer) ::glDrawElementsInstanced },
642             { "glDrawRangeElements", (QFunctionPointer) ::glDrawRangeElements },
643             { "glEndQuery", (QFunctionPointer) ::glEndQuery },
644             { "glEndTransformFeedback", (QFunctionPointer) ::glEndTransformFeedback },
645             { "glFenceSync", (QFunctionPointer) ::glFenceSync },
646             { "glFlushMappedBufferRange", (QFunctionPointer) ::glFlushMappedBufferRange },
647             { "glFramebufferTextureLayer", (QFunctionPointer) ::glFramebufferTextureLayer },
648             { "glGenQueries", (QFunctionPointer) ::glGenQueries },
649             { "glGenSamplers", (QFunctionPointer) ::glGenSamplers },
650             { "glGenTransformFeedbacks", (QFunctionPointer) ::glGenTransformFeedbacks },
651             { "glGenVertexArrays", (QFunctionPointer) ::glGenVertexArrays },
652             { "glGetActiveUniformBlockName", (QFunctionPointer) ::glGetActiveUniformBlockName },
653             { "glGetActiveUniformBlockiv", (QFunctionPointer) ::glGetActiveUniformBlockiv },
654             { "glGetActiveUniformsiv", (QFunctionPointer) ::glGetActiveUniformsiv },
655             { "glGetBufferParameteri64v", (QFunctionPointer) ::glGetBufferParameteri64v },
656             { "glGetBufferPointerv", (QFunctionPointer) ::glGetBufferPointerv },
657             { "glGetFragDataLocation", (QFunctionPointer) ::glGetFragDataLocation },
658             { "glGetInteger64i_v", (QFunctionPointer) ::glGetInteger64i_v },
659             { "glGetInteger64v", (QFunctionPointer) ::glGetInteger64v },
660             { "glGetIntegeri_v", (QFunctionPointer) ::glGetIntegeri_v },
661             { "glGetInternalformativ", (QFunctionPointer) ::glGetInternalformativ },
662             { "glGetProgramBinary", (QFunctionPointer) ::glGetProgramBinary },
663             { "glGetQueryObjectuiv", (QFunctionPointer) ::glGetQueryObjectuiv },
664             { "glGetQueryiv", (QFunctionPointer) ::glGetQueryiv },
665             { "glGetSamplerParameterfv", (QFunctionPointer) ::glGetSamplerParameterfv },
666             { "glGetSamplerParameteriv", (QFunctionPointer) ::glGetSamplerParameteriv },
667             { "glGetStringi", (QFunctionPointer) ::glGetStringi },
668             { "glGetSynciv", (QFunctionPointer) ::glGetSynciv },
669             { "glGetTransformFeedbackVarying", (QFunctionPointer) ::glGetTransformFeedbackVarying },
670             { "glGetUniformBlockIndex", (QFunctionPointer) ::glGetUniformBlockIndex },
671             { "glGetUniformIndices", (QFunctionPointer) ::glGetUniformIndices },
672             { "glGetUniformuiv", (QFunctionPointer) ::glGetUniformuiv },
673             { "glGetVertexAttribIiv", (QFunctionPointer) ::glGetVertexAttribIiv },
674             { "glGetVertexAttribIuiv", (QFunctionPointer) ::glGetVertexAttribIuiv },
675             { "glInvalidateFramebuffer", (QFunctionPointer) ::glInvalidateFramebuffer },
676             { "glInvalidateSubFramebuffer", (QFunctionPointer) ::glInvalidateSubFramebuffer },
677             { "glIsQuery", (QFunctionPointer) ::glIsQuery },
678             { "glIsSampler", (QFunctionPointer) ::glIsSampler },
679             { "glIsSync", (QFunctionPointer) ::glIsSync },
680             { "glIsTransformFeedback", (QFunctionPointer) ::glIsTransformFeedback },
681             { "glIsVertexArray", (QFunctionPointer) ::glIsVertexArray },
682             { "glMapBufferRange", (QFunctionPointer) ::glMapBufferRange },
683             { "glPauseTransformFeedback", (QFunctionPointer) ::glPauseTransformFeedback },
684             { "glProgramBinary", (QFunctionPointer) ::glProgramBinary },
685             { "glProgramParameteri", (QFunctionPointer) ::glProgramParameteri },
686             { "glReadBuffer", (QFunctionPointer) ::glReadBuffer },
687             { "glRenderbufferStorageMultisample", (QFunctionPointer) ::glRenderbufferStorageMultisample },
688             { "glResumeTransformFeedback", (QFunctionPointer) ::glResumeTransformFeedback },
689             { "glSamplerParameterf", (QFunctionPointer) ::glSamplerParameterf },
690             { "glSamplerParameterfv", (QFunctionPointer) ::glSamplerParameterfv },
691             { "glSamplerParameteri", (QFunctionPointer) ::glSamplerParameteri },
692             { "glSamplerParameteriv", (QFunctionPointer) ::glSamplerParameteriv },
693             { "glTexImage3D", (QFunctionPointer) ::glTexImage3D },
694             { "glTexStorage2D", (QFunctionPointer) ::glTexStorage2D },
695             { "glTexStorage3D", (QFunctionPointer) ::glTexStorage3D },
696             { "glTexSubImage3D", (QFunctionPointer) ::glTexSubImage3D },
697             { "glTransformFeedbackVaryings", (QFunctionPointer) ::glTransformFeedbackVaryings },
698             { "glUniform1ui", (QFunctionPointer) ::glUniform1ui },
699             { "glUniform1uiv", (QFunctionPointer) ::glUniform1uiv },
700             { "glUniform2ui", (QFunctionPointer) ::glUniform2ui },
701             { "glUniform2uiv", (QFunctionPointer) ::glUniform2uiv },
702             { "glUniform3ui", (QFunctionPointer) ::glUniform3ui },
703             { "glUniform3uiv", (QFunctionPointer) ::glUniform3uiv },
704             { "glUniform4ui", (QFunctionPointer) ::glUniform4ui },
705             { "glUniform4uiv", (QFunctionPointer) ::glUniform4uiv },
706             { "glUniformBlockBinding", (QFunctionPointer) ::glUniformBlockBinding },
707             { "glUniformMatrix2x3fv", (QFunctionPointer) ::glUniformMatrix2x3fv },
708             { "glUniformMatrix2x4fv", (QFunctionPointer) ::glUniformMatrix2x4fv },
709             { "glUniformMatrix3x2fv", (QFunctionPointer) ::glUniformMatrix3x2fv },
710             { "glUniformMatrix3x4fv", (QFunctionPointer) ::glUniformMatrix3x4fv },
711             { "glUniformMatrix4x2fv", (QFunctionPointer) ::glUniformMatrix4x2fv },
712             { "glUniformMatrix4x3fv", (QFunctionPointer) ::glUniformMatrix4x3fv },
713             { "glUnmapBuffer", (QFunctionPointer) ::glUnmapBuffer },
714             { "glVertexAttribDivisor", (QFunctionPointer) ::glVertexAttribDivisor },
715             { "glVertexAttribI4i", (QFunctionPointer) ::glVertexAttribI4i },
716             { "glVertexAttribI4iv", (QFunctionPointer) ::glVertexAttribI4iv },
717             { "glVertexAttribI4ui", (QFunctionPointer) ::glVertexAttribI4ui },
718             { "glVertexAttribI4uiv", (QFunctionPointer) ::glVertexAttribI4uiv },
719             { "glVertexAttribIPointer", (QFunctionPointer) ::glVertexAttribIPointer },
720             { "glWaitSync", (QFunctionPointer) ::glWaitSync },
721 #endif // QT_OPENGL_ES_3
722 
723 #ifdef QT_OPENGL_ES_3_1
724             { "glActiveShaderProgram", (QFunctionPointer) ::glActiveShaderProgram },
725             { "glBindImageTexture", (QFunctionPointer) ::glBindImageTexture },
726             { "glBindProgramPipeline", (QFunctionPointer) ::glBindProgramPipeline },
727             { "glBindVertexBuffer", (QFunctionPointer) ::glBindVertexBuffer },
728             { "glCreateShaderProgramv", (QFunctionPointer) ::glCreateShaderProgramv },
729             { "glDeleteProgramPipelines", (QFunctionPointer) ::glDeleteProgramPipelines },
730             { "glDispatchCompute", (QFunctionPointer) ::glDispatchCompute },
731             { "glDispatchComputeIndirect", (QFunctionPointer) ::glDispatchComputeIndirect },
732             { "glDrawArraysIndirect", (QFunctionPointer) ::glDrawArraysIndirect },
733             { "glDrawElementsIndirect", (QFunctionPointer) ::glDrawElementsIndirect },
734             { "glFramebufferParameteri", (QFunctionPointer) ::glFramebufferParameteri },
735             { "glGenProgramPipelines", (QFunctionPointer) ::glGenProgramPipelines },
736             { "glGetBooleani_v", (QFunctionPointer) ::glGetBooleani_v },
737             { "glGetFramebufferParameteriv", (QFunctionPointer) ::glGetFramebufferParameteriv },
738             { "glGetMultisamplefv", (QFunctionPointer) ::glGetMultisamplefv },
739             { "glGetProgramInterfaceiv", (QFunctionPointer) ::glGetProgramInterfaceiv },
740             { "glGetProgramPipelineInfoLog", (QFunctionPointer) ::glGetProgramPipelineInfoLog },
741             { "glGetProgramPipelineiv", (QFunctionPointer) ::glGetProgramPipelineiv },
742             { "glGetProgramResourceIndex", (QFunctionPointer) ::glGetProgramResourceIndex },
743             { "glGetProgramResourceLocation", (QFunctionPointer) ::glGetProgramResourceLocation },
744             { "glGetProgramResourceName", (QFunctionPointer) ::glGetProgramResourceName },
745             { "glGetProgramResourceiv", (QFunctionPointer) ::glGetProgramResourceiv },
746             { "glGetTexLevelParameterfv", (QFunctionPointer) ::glGetTexLevelParameterfv },
747             { "glGetTexLevelParameteriv", (QFunctionPointer) ::glGetTexLevelParameteriv },
748             { "glIsProgramPipeline", (QFunctionPointer) ::glIsProgramPipeline },
749             { "glMemoryBarrier", (QFunctionPointer) ::glMemoryBarrier },
750             { "glMemoryBarrierByRegion", (QFunctionPointer) ::glMemoryBarrierByRegion },
751             { "glProgramUniform1f", (QFunctionPointer) ::glProgramUniform1f },
752             { "glProgramUniform1fv", (QFunctionPointer) ::glProgramUniform1fv },
753             { "glProgramUniform1i", (QFunctionPointer) ::glProgramUniform1i },
754             { "glProgramUniform1iv", (QFunctionPointer) ::glProgramUniform1iv },
755             { "glProgramUniform1ui", (QFunctionPointer) ::glProgramUniform1ui },
756             { "glProgramUniform1uiv", (QFunctionPointer) ::glProgramUniform1uiv },
757             { "glProgramUniform2f", (QFunctionPointer) ::glProgramUniform2f },
758             { "glProgramUniform2fv", (QFunctionPointer) ::glProgramUniform2fv },
759             { "glProgramUniform2i", (QFunctionPointer) ::glProgramUniform2i },
760             { "glProgramUniform2iv", (QFunctionPointer) ::glProgramUniform2iv },
761             { "glProgramUniform2ui", (QFunctionPointer) ::glProgramUniform2ui },
762             { "glProgramUniform2uiv", (QFunctionPointer) ::glProgramUniform2uiv },
763             { "glProgramUniform3f", (QFunctionPointer) ::glProgramUniform3f },
764             { "glProgramUniform3fv", (QFunctionPointer) ::glProgramUniform3fv },
765             { "glProgramUniform3i", (QFunctionPointer) ::glProgramUniform3i },
766             { "glProgramUniform3iv", (QFunctionPointer) ::glProgramUniform3iv },
767             { "glProgramUniform3ui", (QFunctionPointer) ::glProgramUniform3ui },
768             { "glProgramUniform3uiv", (QFunctionPointer) ::glProgramUniform3uiv },
769             { "glProgramUniform4f", (QFunctionPointer) ::glProgramUniform4f },
770             { "glProgramUniform4fv", (QFunctionPointer) ::glProgramUniform4fv },
771             { "glProgramUniform4i", (QFunctionPointer) ::glProgramUniform4i },
772             { "glProgramUniform4iv", (QFunctionPointer) ::glProgramUniform4iv },
773             { "glProgramUniform4ui", (QFunctionPointer) ::glProgramUniform4ui },
774             { "glProgramUniform4uiv", (QFunctionPointer) ::glProgramUniform4uiv },
775             { "glProgramUniformMatrix2fv", (QFunctionPointer) ::glProgramUniformMatrix2fv },
776             { "glProgramUniformMatrix2x3fv", (QFunctionPointer) ::glProgramUniformMatrix2x3fv },
777             { "glProgramUniformMatrix2x4fv", (QFunctionPointer) ::glProgramUniformMatrix2x4fv },
778             { "glProgramUniformMatrix3fv", (QFunctionPointer) ::glProgramUniformMatrix3fv },
779             { "glProgramUniformMatrix3x2fv", (QFunctionPointer) ::glProgramUniformMatrix3x2fv },
780             { "glProgramUniformMatrix3x4fv", (QFunctionPointer) ::glProgramUniformMatrix3x4fv },
781             { "glProgramUniformMatrix4fv", (QFunctionPointer) ::glProgramUniformMatrix4fv },
782             { "glProgramUniformMatrix4x2fv", (QFunctionPointer) ::glProgramUniformMatrix4x2fv },
783             { "glProgramUniformMatrix4x3fv", (QFunctionPointer) ::glProgramUniformMatrix4x3fv },
784             { "glSampleMaski", (QFunctionPointer) ::glSampleMaski },
785             { "glTexStorage2DMultisample", (QFunctionPointer) ::glTexStorage2DMultisample },
786             { "glUseProgramStages", (QFunctionPointer) ::glUseProgramStages },
787             { "glValidateProgramPipeline", (QFunctionPointer) ::glValidateProgramPipeline },
788             { "glVertexAttribBinding", (QFunctionPointer) ::glVertexAttribBinding },
789             { "glVertexAttribFormat", (QFunctionPointer) ::glVertexAttribFormat },
790             { "glVertexAttribIFormat", (QFunctionPointer) ::glVertexAttribIFormat },
791             { "glVertexBindingDivisor", (QFunctionPointer) ::glVertexBindingDivisor },
792 #endif // QT_OPENGL_ES_3_1
793 
794 #ifdef QT_OPENGL_ES_3_2
795             { "glBlendBarrier", (QFunctionPointer) ::glBlendBarrier },
796             { "glCopyImageSubData", (QFunctionPointer) ::glCopyImageSubData },
797             { "glDebugMessageControl", (QFunctionPointer) ::glDebugMessageControl },
798             { "glDebugMessageInsert", (QFunctionPointer) ::glDebugMessageInsert },
799             { "glDebugMessageCallback", (QFunctionPointer) ::glDebugMessageCallback },
800             { "glGetDebugMessageLog", (QFunctionPointer) ::glGetDebugMessageLog },
801             { "glPushDebugGroup", (QFunctionPointer) ::glPushDebugGroup },
802             { "glPopDebugGroup", (QFunctionPointer) ::glPopDebugGroup },
803             { "glObjectLabel", (QFunctionPointer) ::glObjectLabel },
804             { "glGetObjectLabel", (QFunctionPointer) ::glGetObjectLabel },
805             { "glObjectPtrLabel", (QFunctionPointer) ::glObjectPtrLabel },
806             { "glGetObjectPtrLabel", (QFunctionPointer) ::glGetObjectPtrLabel },
807             { "glGetPointerv", (QFunctionPointer) ::glGetPointerv },
808             { "glEnablei", (QFunctionPointer) ::glEnablei },
809             { "glDisablei", (QFunctionPointer) ::glDisablei },
810             { "glBlendEquationi", (QFunctionPointer) ::glBlendEquationi },
811             { "glBlendEquationSeparatei", (QFunctionPointer) ::glBlendEquationSeparatei },
812             { "glBlendFunci", (QFunctionPointer) ::glBlendFunci },
813             { "glBlendFuncSeparatei", (QFunctionPointer) ::glBlendFuncSeparatei },
814             { "glColorMaski", (QFunctionPointer) ::glColorMaski },
815             { "glIsEnabledi", (QFunctionPointer) ::glIsEnabledi },
816             { "glDrawElementsBaseVertex", (QFunctionPointer) ::glDrawElementsBaseVertex },
817             { "glDrawRangeElementsBaseVertex", (QFunctionPointer) ::glDrawRangeElementsBaseVertex },
818             { "glDrawElementsInstancedBaseVertex", (QFunctionPointer) ::glDrawElementsInstancedBaseVertex },
819             { "glFramebufferTexture", (QFunctionPointer) ::glFramebufferTexture },
820             { "glPrimitiveBoundingBox", (QFunctionPointer) ::glPrimitiveBoundingBox },
821             { "glGetGraphicsResetStatus", (QFunctionPointer) ::glGetGraphicsResetStatus },
822             { "glReadnPixels", (QFunctionPointer) ::glReadnPixels },
823             { "glGetnUniformfv", (QFunctionPointer) ::glGetnUniformfv },
824             { "glGetnUniformiv", (QFunctionPointer) ::glGetnUniformiv },
825             { "glGetnUniformuiv", (QFunctionPointer) ::glGetnUniformuiv },
826             { "glMinSampleShading", (QFunctionPointer) ::glMinSampleShading },
827             { "glPatchParameteri", (QFunctionPointer) ::glPatchParameteri },
828             { "glTexParameterIiv", (QFunctionPointer) ::glTexParameterIiv },
829             { "glTexParameterIuiv", (QFunctionPointer) ::glTexParameterIuiv },
830             { "glGetTexParameterIiv", (QFunctionPointer) ::glGetTexParameterIiv },
831             { "glGetTexParameterIuiv", (QFunctionPointer) ::glGetTexParameterIuiv },
832             { "glSamplerParameterIiv", (QFunctionPointer) ::glSamplerParameterIiv },
833             { "glSamplerParameterIuiv", (QFunctionPointer) ::glSamplerParameterIuiv },
834             { "glGetSamplerParameterIiv", (QFunctionPointer) ::glGetSamplerParameterIiv },
835             { "glGetSamplerParameterIuiv", (QFunctionPointer) ::glGetSamplerParameterIuiv },
836             { "glTexBuffer", (QFunctionPointer) ::glTexBuffer },
837             { "glTexBufferRange", (QFunctionPointer) ::glTexBufferRange },
838             { "glTexStorage3DMultisample", (QFunctionPointer) ::glTexStorage3DMultisample },
839 #endif // QT_OPENGL_ES_3_2
840         };
841 
842         for (size_t i = 0; i < sizeof(standardFuncs) / sizeof(StdFunc); ++i) {
843             if (!qstrcmp(procName, standardFuncs[i].name)) {
844                 proc = standardFuncs[i].func;
845                 break;
846             }
847         }
848     }
849 #endif
850 
851     return proc;
852 }
853 
format() const854 QSurfaceFormat QEGLPlatformContext::format() const
855 {
856     return m_format;
857 }
858 
eglContext() const859 EGLContext QEGLPlatformContext::eglContext() const
860 {
861     return m_eglContext;
862 }
863 
eglDisplay() const864 EGLDisplay QEGLPlatformContext::eglDisplay() const
865 {
866     return m_eglDisplay;
867 }
868 
eglConfig() const869 EGLConfig QEGLPlatformContext::eglConfig() const
870 {
871     return m_eglConfig;
872 }
873 
874 QT_END_NAMESPACE
875