1// Copyright (C) 2013 Klaralvdalens Datakonsult AB (KDAB)
2// Copyright (C) 2016 The Qt Company Ltd.
3// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
4/***************************************************************************
5** This file was generated by glgen version 0.1
6** Command line was: glgen
7**
8** glgen is Copyright (C) 2013 Klaralvdalens Datakonsult AB (KDAB)
9**
10** This is an auto-generated file.
11** Do not edit! All changes made to it will be lost.
12**
13****************************************************************************/
14
15#include "qopenglversionfunctions.h"
16#include "qopenglversionfunctions_p.h"
17#include "qopenglcontext.h"
18#include "qdebug.h"
19
20QT_BEGIN_NAMESPACE
21
22QOpenGLContextVersionData::~QOpenGLContextVersionData()
23{
24 for (auto *f : std::as_const(t&: externalFunctions)) {
25 auto *fp = QAbstractOpenGLFunctionsPrivate::get(q: f);
26 fp->owningContext = nullptr;
27 fp->initialized = false;
28 }
29 externalFunctions.clear();
30 qDeleteAll(c: functions);
31 functions.clear();
32}
33
34QOpenGLContextVersionData *QOpenGLContextVersionData::forContext(QOpenGLContext *context)
35{
36 QOpenGLContextPrivate *context_d = QOpenGLContextPrivate::get(context);
37 if (context_d->versionFunctions == nullptr)
38 context_d->versionFunctions = new QOpenGLContextVersionData;
39
40 return static_cast<QOpenGLContextVersionData *>(context_d->versionFunctions);
41}
42
43#define QT_OPENGL_COUNT_FUNCTIONS(ret, name, args) +1
44#define QT_OPENGL_FUNCTION_NAMES(ret, name, args) \
45 "gl"#name"\0"
46#define QT_OPENGL_IMPLEMENT(CLASS, FUNCTIONS) \
47void CLASS::init() \
48{ \
49 const char *names = FUNCTIONS(QT_OPENGL_FUNCTION_NAMES); \
50 const char *name = names; \
51 for (int i = 0; i < FUNCTIONS(QT_OPENGL_COUNT_FUNCTIONS); ++i) { \
52 functions[i] = context->getProcAddress(name); \
53 name += strlen(name) + 1; \
54 } \
55}
56
57QOpenGLVersionFunctionsStorage::QOpenGLVersionFunctionsStorage()
58 : backends(nullptr)
59{
60}
61
62QOpenGLVersionFunctionsStorage::~QOpenGLVersionFunctionsStorage()
63{
64#if !QT_CONFIG(opengles2)
65 if (backends) {
66
67 int i = 0;
68
69#define DELETE_BACKEND(X) \
70 if (backends[i] && !--backends[i]->refs) \
71 delete static_cast<QOpenGLFunctions_##X##Backend*>(backends[i]); \
72 ++i;
73
74 QT_OPENGL_VERSIONS(DELETE_BACKEND)
75#undef DELETE_BACKEND
76 delete[] backends;
77 }
78#endif
79}
80
81QOpenGLVersionFunctionsBackend *QOpenGLVersionFunctionsStorage::backend(QOpenGLContext *context, QOpenGLVersionFunctionsBackend::Version v)
82{
83#if QT_CONFIG(opengles2)
84 Q_UNUSED(context);
85 Q_UNUSED(v);
86 return 0;
87#else
88 if (!backends) {
89 backends = new QOpenGLVersionFunctionsBackend *[QOpenGLVersionFunctionsBackend::OpenGLVersionBackendCount];
90 memset(s: backends, c: 0, n: sizeof(QOpenGLVersionFunctionsBackend *)*QOpenGLVersionFunctionsBackend::OpenGLVersionBackendCount);
91 }
92 if (backends[v])
93 return backends[v];
94
95 switch(v) {
96#define VERSION_ENUM(X) QOpenGLVersionFunctionsBackend::OpenGL_##X
97#define CREATE_BACKEND(X) \
98 case VERSION_ENUM(X): \
99 backends[VERSION_ENUM(X)] = new QOpenGLFunctions_##X##Backend(context); \
100 break;
101 QT_OPENGL_VERSIONS(CREATE_BACKEND)
102 case QOpenGLVersionFunctionsBackend::OpenGLVersionBackendCount:
103 Q_UNREACHABLE();
104 }
105 // the storage keeps one ref
106 ++backends[v]->refs;
107 return backends[v];
108#endif
109}
110
111QOpenGLVersionFunctionsBackend *QAbstractOpenGLFunctionsPrivate::functionsBackend(QOpenGLContext *context, QOpenGLVersionFunctionsBackend::Version v)
112{
113 Q_ASSERT(context);
114 return QOpenGLContextVersionData::forContext(context)->functionsStorage.backend(context, v);
115}
116
117void QAbstractOpenGLFunctionsPrivate::insertExternalFunctions(QOpenGLContext *context, QAbstractOpenGLFunctions *f)
118{
119 Q_ASSERT(context);
120 QOpenGLContextVersionData::forContext(context)->externalFunctions.insert(value: f);
121}
122
123void QAbstractOpenGLFunctionsPrivate::removeExternalFunctions(QOpenGLContext *context, QAbstractOpenGLFunctions *f)
124{
125 Q_ASSERT(context);
126 QOpenGLContextVersionData::forContext(context)->externalFunctions.remove(value: f);
127}
128
129/*!
130 \class QAbstractOpenGLFunctions
131 \inmodule QtOpenGL
132 \since 5.1
133 \brief The QAbstractOpenGLFunctions class is the base class of a family of
134 classes that expose all functions for each OpenGL version and
135 profile.
136
137 OpenGL implementations on different platforms are able to link to a variable
138 number of OpenGL functions depending upon the OpenGL ABI on that platform.
139 For example, on Microsoft Windows only functions up to those in OpenGL 1.1
140 can be linked to at build time. All other functions must be resolved at
141 runtime. The traditional solution to this has been to use either
142 QOpenGLContext::getProcAddress() or QOpenGLFunctions. The former is tedious
143 and error prone and means dealing directly with function pointers. The
144 latter only exposes those functions common to OpenGL ES 2 and desktop
145 OpenGL. There is however much new OpenGL functionality that is useful when
146 writing real world OpenGL applications.
147
148 Qt now provides a family of classes which all inherit from
149 QAbstractOpenGLFunctions which expose every core OpenGL function by way of a
150 corresponding member function. There is a class for every valid combination
151 of OpenGL version and profile. Each class follows the naming convention:
152 \badcode
153 QOpenGLFunctions_<MAJOR VERSION>_<MINOR VERSION>[_PROFILE]
154 \endcode
155
156 For OpenGL versions 1.0 through to 3.0 there are no profiles, leading to the
157 classes:
158
159 \list
160 \li QOpenGLFunctions_1_0
161 \li QOpenGLFunctions_1_1
162 \li QOpenGLFunctions_1_2
163 \li QOpenGLFunctions_1_3
164 \li QOpenGLFunctions_1_4
165 \li QOpenGLFunctions_1_5
166 \li QOpenGLFunctions_2_0
167 \li QOpenGLFunctions_2_1
168 \li QOpenGLFunctions_3_0
169 \endlist
170
171 where each class inherits from QAbstractOpenGLFunctions.
172
173 OpenGL version 3.1 removed many deprecated functions leading to a much
174 simpler and generic API.
175
176 With OpenGL 3.2 the concept of profiles was introduced. Two profiles are
177 currently defined for OpenGL: Core and Compatibility.
178
179 The Core profile does not include any of the functions that were removed
180 in OpenGL 3.1. The Compatibility profile contains all functions in the
181 Core profile of the same version plus all of the functions that were
182 removed in OpenGL 3.1. In this way the Compatibility profile classes allow
183 use of newer OpenGL functionality but also allows you to keep using your
184 legacy OpenGL code. For new OpenGL code the Core profile should be
185 preferred.
186
187 Please note that some vendors, notably Apple, do not implement the
188 Compatibility profile. Therefore if you wish to target new OpenGL features
189 on \macos then you should ensure that you request a Core profile context via
190 QSurfaceFormat::setProfile().
191
192 Qt provides classes for all version and Core and Compatibility profile
193 combinations. The classes for OpenGL versions 3.1 through to 4.3 are:
194
195 \list
196 \li QOpenGLFunctions_3_1
197 \li QOpenGLFunctions_3_2_Core
198 \li QOpenGLFunctions_3_2_Compatibility
199 \li QOpenGLFunctions_3_3_Core
200 \li QOpenGLFunctions_3_3_Compatibility
201 \li QOpenGLFunctions_4_0_Core
202 \li QOpenGLFunctions_4_0_Compatibility
203 \li QOpenGLFunctions_4_1_Core
204 \li QOpenGLFunctions_4_1_Compatibility
205 \li QOpenGLFunctions_4_2_Core
206 \li QOpenGLFunctions_4_2_Compatibility
207 \li QOpenGLFunctions_4_3_Core
208 \li QOpenGLFunctions_4_3_Compatibility
209 \endlist
210
211 where each class inherits from QAbstractOpenGLFunctions.
212
213 A pointer to an object of the class corresponding to the version and
214 profile of OpenGL in use can be obtained from
215 QOpenGLVersionFunctionsFactory::get(). If obtained in this way, note that
216 the QOpenGLContext retains ownership of the object. This is so that the
217 instance can be cached and shared.
218
219 Before calling any of the exposed OpenGL functions you must ensure that the
220 object has resolved the function pointers to the OpenGL functions. This
221 only needs to be done once per instance with initializeOpenGLFunctions().
222 Once initialized, the object can be used to call any OpenGL function for
223 the corresponding version and profile. Note that initializeOpenGLFunctions()
224 can fail in some circumstances so check the return value. Situations in
225 which initialization can fail are if you have a functions object for a version
226 or profile that contains functions that are not part of the context being
227 used to resolve the function pointers.
228
229 If you exclusively use function objects then you will get compile time
230 errors if you attempt to use a function not included in that version and
231 profile. This is obviously a lot easier to debug than undefined behavior
232 at run time.
233
234 \sa QOpenGLVersionFunctionsFactory::get()
235*/
236/*!
237 Constructs a QAbstractOpenGLFunctions object.
238*/
239QAbstractOpenGLFunctions::QAbstractOpenGLFunctions()
240 : d_ptr(new QAbstractOpenGLFunctionsPrivate)
241{
242}
243
244/*!
245 Destroys a QAbstractOpenGLFunctions object.
246*/
247QAbstractOpenGLFunctions::~QAbstractOpenGLFunctions()
248{
249 Q_D(QAbstractOpenGLFunctions);
250 if (d->owningContext)
251 d->removeExternalFunctions(context: d->owningContext, f: this);
252 delete d_ptr;
253}
254
255/*! \internal
256 */
257bool QAbstractOpenGLFunctions::initializeOpenGLFunctions()
258{
259 Q_D(QAbstractOpenGLFunctions);
260 d->initialized = true;
261
262 // For a subclass whose instance is not created via
263 // QOpenGLContext::versionFunctions() owningContext is not set. Set it now
264 // and register such instances to the context as external ones. These are
265 // not owned by the context but still need certain cleanup when the context
266 // is destroyed.
267 if (!d->owningContext) {
268 d->owningContext = QOpenGLContext::currentContext();
269 if (d->owningContext)
270 d->insertExternalFunctions(context: d->owningContext, f: this);
271 }
272
273 return true;
274}
275
276/*! \internal
277 */
278bool QAbstractOpenGLFunctions::isInitialized() const
279{
280 Q_D(const QAbstractOpenGLFunctions);
281 return d->initialized;
282}
283
284/*! \internal
285 */
286void QAbstractOpenGLFunctions::setOwningContext(const QOpenGLContext *context)
287{
288 Q_D(QAbstractOpenGLFunctions);
289 d->owningContext = const_cast<QOpenGLContext*>(context);
290}
291
292/*! \internal
293 */
294QOpenGLContext *QAbstractOpenGLFunctions::owningContext() const
295{
296 Q_D(const QAbstractOpenGLFunctions);
297 return d->owningContext;
298}
299
300#if !QT_CONFIG(opengles2)
301
302QT_OPENGL_IMPLEMENT(QOpenGLFunctions_1_0_CoreBackend, QT_OPENGL_1_0_FUNCTIONS)
303QT_OPENGL_IMPLEMENT(QOpenGLFunctions_1_1_CoreBackend, QT_OPENGL_1_1_FUNCTIONS)
304
305QT_OPENGL_IMPLEMENT(QOpenGLFunctions_1_2_CoreBackend, QT_OPENGL_1_2_FUNCTIONS)
306QT_OPENGL_IMPLEMENT(QOpenGLFunctions_1_3_CoreBackend, QT_OPENGL_1_3_FUNCTIONS)
307QT_OPENGL_IMPLEMENT(QOpenGLFunctions_1_4_CoreBackend, QT_OPENGL_1_4_FUNCTIONS)
308QT_OPENGL_IMPLEMENT(QOpenGLFunctions_1_5_CoreBackend, QT_OPENGL_1_5_FUNCTIONS)
309QT_OPENGL_IMPLEMENT(QOpenGLFunctions_2_0_CoreBackend, QT_OPENGL_2_0_FUNCTIONS)
310QT_OPENGL_IMPLEMENT(QOpenGLFunctions_2_1_CoreBackend, QT_OPENGL_2_1_FUNCTIONS)
311QT_OPENGL_IMPLEMENT(QOpenGLFunctions_3_0_CoreBackend, QT_OPENGL_3_0_FUNCTIONS)
312QT_OPENGL_IMPLEMENT(QOpenGLFunctions_3_1_CoreBackend, QT_OPENGL_3_1_FUNCTIONS)
313QT_OPENGL_IMPLEMENT(QOpenGLFunctions_3_2_CoreBackend, QT_OPENGL_3_2_FUNCTIONS)
314QT_OPENGL_IMPLEMENT(QOpenGLFunctions_3_3_CoreBackend, QT_OPENGL_3_3_FUNCTIONS)
315QT_OPENGL_IMPLEMENT(QOpenGLFunctions_4_0_CoreBackend, QT_OPENGL_4_0_FUNCTIONS)
316QT_OPENGL_IMPLEMENT(QOpenGLFunctions_4_1_CoreBackend, QT_OPENGL_4_1_FUNCTIONS)
317QT_OPENGL_IMPLEMENT(QOpenGLFunctions_4_2_CoreBackend, QT_OPENGL_4_2_FUNCTIONS)
318QT_OPENGL_IMPLEMENT(QOpenGLFunctions_4_3_CoreBackend, QT_OPENGL_4_3_FUNCTIONS)
319QT_OPENGL_IMPLEMENT(QOpenGLFunctions_4_4_CoreBackend, QT_OPENGL_4_4_FUNCTIONS)
320QT_OPENGL_IMPLEMENT(QOpenGLFunctions_4_5_CoreBackend, QT_OPENGL_4_5_FUNCTIONS)
321
322QT_OPENGL_IMPLEMENT(QOpenGLFunctions_1_0_DeprecatedBackend, QT_OPENGL_1_0_DEPRECATED_FUNCTIONS)
323QT_OPENGL_IMPLEMENT(QOpenGLFunctions_1_1_DeprecatedBackend, QT_OPENGL_1_1_DEPRECATED_FUNCTIONS)
324
325QT_OPENGL_IMPLEMENT(QOpenGLFunctions_1_2_DeprecatedBackend, QT_OPENGL_1_2_DEPRECATED_FUNCTIONS)
326QT_OPENGL_IMPLEMENT(QOpenGLFunctions_1_3_DeprecatedBackend, QT_OPENGL_1_3_DEPRECATED_FUNCTIONS)
327QT_OPENGL_IMPLEMENT(QOpenGLFunctions_1_4_DeprecatedBackend, QT_OPENGL_1_4_DEPRECATED_FUNCTIONS)
328QT_OPENGL_IMPLEMENT(QOpenGLFunctions_2_0_DeprecatedBackend, QT_OPENGL_2_0_DEPRECATED_FUNCTIONS)
329QT_OPENGL_IMPLEMENT(QOpenGLFunctions_3_0_DeprecatedBackend, QT_OPENGL_3_0_DEPRECATED_FUNCTIONS)
330QT_OPENGL_IMPLEMENT(QOpenGLFunctions_3_3_DeprecatedBackend, QT_OPENGL_3_3_DEPRECATED_FUNCTIONS)
331QT_OPENGL_IMPLEMENT(QOpenGLFunctions_4_5_DeprecatedBackend, QT_OPENGL_4_5_DEPRECATED_FUNCTIONS)
332
333#else
334
335// No backends for OpenGL ES 2
336
337#endif // !QT_CONFIG(opengles2)
338
339QT_END_NAMESPACE
340

source code of qtbase/src/opengl/qopenglversionfunctions.cpp