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