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