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