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