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