qt5base-lts/util/glgen
Lucie Gérard 05fc3aef53 Use SPDX license identifiers
Replace the current license disclaimer in files by
a SPDX-License-Identifier.
Files that have to be modified by hand are modified.
License files are organized under LICENSES directory.

Task-number: QTBUG-67283
Change-Id: Id880c92784c40f3bbde861c0d93f58151c18b9f1
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
Reviewed-by: Jörg Bornemann <joerg.bornemann@qt.io>
2022-05-16 16:37:38 +02:00
..
codegenerator.cpp
codegenerator.h
glgen.pro
legacyspecparser.cpp
legacyspecparser.h
main.cpp
qopenglextensions.cpp.footer
qopenglextensions.cpp.header
qopenglextensions.h.footer
qopenglextensions.h.header
qopenglversionfunctions__VERSION__.cpp.footer
qopenglversionfunctions__VERSION__.cpp.header
qopenglversionfunctions__VERSION__.h.footer
qopenglversionfunctions__VERSION__.h.header
qopenglversionfunctions.cpp.footer
qopenglversionfunctions.cpp.header
qopenglversionfunctions.h.footer
qopenglversionfunctions.h.header
qopenglversionfunctionsfactory_p.h.header
qopenglversionfunctionsfactory.cpp.footer
qopenglversionfunctionsfactory.cpp.header
README.txt
specparser.h
xmlspecparser.cpp
xmlspecparser.h

Overview
========

This is the glgen application used to generate OpenGL related classes from the
official Khronos OpenGL specification and typemap files.

To run this application download the gl.spec and gl.tm files from:

http://www.opengl.org/registry/api/gl.spec
http://www.opengl.org/registry/api/gl.tm

and place them into the application directory. These files are not stored in
the Qt Project's git repo or downloaded automatically to

a) avoid copyright issues
b) make sure the version of OpenGL used is controlled by a human

The glgen application parses these files and generates:

1) A set of public classes, one for each combination of OpenGL version and profile.
2) A set of backend helper classes that contain the actual function pointers
3) A factory class for the classes in 1)
4) A set of classes, one for each OpenGL extension which introduces new entry points

We will now describe each of these categories.


OpenGL Version and Profile Classes
==================================

The base class of this set is QAbstractOpenGLFunctions. From this we inherit one class
for each OpenGL version and if supported, profile.

The Core profile contains only the non-deprecated functionality. The Compatibility profile
also includes all functionality that was removed in OpenGL 3.1. Therefore, for OpenGL
3.2 onwards we have two classes for each version.

All of these classes are named with the following convention:

QOpenGLFunctions_<MAJOR>_<MINOR>[_PROFILE]

For example QOpenGLFunctions_2_1, QOpenGLFunctions_4_3_Core

The source and header files for these classes take the form

qopenglfunction_<MAJOR>_<MINOR>[_PROFILE].cpp
qopenglfunction_<MAJOR>_<MINOR>[_PROFILE].h

and should be moved to

$QTBASE/src/gui/opengl/

and forms part of the public QtGui library API.


Backend Helper Classes
======================

Every OpenGL function is categorised by which version it was introduced with and
whether it is part of the Core Profile and is deemed part of the core specification
or whther it is only part of the Compatibility profile and has been marked as
deprecated.

Glgen creates a backend helper class containing function pointers to match each
possible case. E.g. QOpenGLFunctions_1_5_CoreBackend contains functions introduced
in OpenGL 1.5 which are still core (not deprecated).

The public frontend classes described above contain pointers to the set of backend
objects necessary to implement the functions for their version and profile.

Creating new instances of these backend objects for each public version functions
object would be wasteful in terms of memory (repeated function pointers) and CPU
time (no need to keep re-solving the same functions).

We cannot share the backend objects globally as OpenGL entry point addresses are
specific to the OpenGL context. They cannot even be reliably shared between a
context group. This is not surprising if you consider the case of contexts in a share
group where the contexts have different versions or even profiles. We therefore share
the backend instances at the QOpenGLContext level using a simple reference counting
scheme.

When the frontend version functions objects are intialized they check to see if
the associated context already has suitable backend objects available. If so they use
them, otherwise they will create backend objects and associate them with the context.

The backend classes are in

qopenglversionfunctions.h
qopenglversionfunctions.cpp

and should also be moved to

$QTBASE/src/gui/opengl/


OpenGL Version and Profile Factory
==================================

Instances of the OpenGL version and profile classes described above can be obtained
from QOpenGLContext by means of the versionFunctions() member. The OpenGLContext
retains ownership of the QOpenGLFunctions_* object. If a suitable object does not
already exist it is created by the factory class generated by glgen.

It is possible to request version functions objects for any version/profile
combination from a context. However not all requests can be serviced. For example
consider the case of an OpenGL 3.3 Core profile context. In this case:

* Requesting a 3.3 core profile functions object would succeed.
* Requesting a 3.3 compatibility profile functions object would fail. We would fail
  to resolve the deprecated functions.
* Requesting a 4.3 core profile functions object would fail. We would fail to resolve
  the new core functions introduced in versions 4.0-4.3.
* Requesting a 3.1 functions object would succeed. There is nothing in 3.1 that is not
  also in 3.3 core.

If a request is not able to be serviced the factory, and hence QOpenGLContext::versionFunctions()
will return a null pointer that can be checked for.

The source and header file for this class should be moved to

$QTBASE/src/gui/opengl/

and forms part of the QtGui library.

If a user instantiates a version functions object directly (i.e. not via QOpenGLContext)
then it bypasses the above checks. However, the same checks are applied in the
initializeOpenGLFunctions() method and the result can once again be checked.

This approach allows maximum flexibility but ensure's safety in that once the user
posesses a functions object that has been successfully initialized they can rely upon its
member functions being successfully resolved.


OpenGL Extension Classes
========================

In addition, glgen also creates one class for each OpenGL extension that introduces
new entry points. These classes are named with the convention

QOpenGLExtension_<name-of-extension>

The usage pattern for OpenGL extensions is to just use a small
number of extensions out of the large number of those available.

Prior to Qt 6, these classes were provided as the openglextensions
module. Because of the new graphics architecture in Qt 6, that module
has been removed.