On Tue, May 02, 2000 at 07:09:08PM -0700, [EMAIL PROTECTED] wrote:
> Option A is essentially to leave gl.h as it is, without any provisions
> to include glext.h. However, multiple versions of gl.h have already
> been deployed, and they include enumerant and function declarations
> for different sets of extensions. This has three consequences:
>
> 1. The common idiom for declaring extension functions actually
> can't be used reliably, because gl.h *might* contain
> conflicting declarations for the same names. For example:
It's a dangerous idiom. The app should not be declaring pointers
whose names are in the 'gl' namespace, period. This problem exists
completely independently of Linux or the ABI, and we should not cater to
apps that are doing this.
> #include <GL/gl.h>
> ...
> PFNGLEXTENSIONEXTPROC glExtensionEXT;
> ...
> glExtensionEXT = (PFNGLEXTENSIONEXTPROC)
> glXGetProcAddressARB("glExtensionEXT");
> ...
> glExtensionExt();
>
> This fails to compile on some systems because glExtensionEXT
> is already declared in gl.h
>
> GLAPI void GLAPIENTRY glExtensionExt();
>
> and fails to compile on some other systems because
> PFNGLEXTENSIONEXTPROC is *not* declared in gl.h.
>
> This can't be handled readily with conditional compilation,
> because there's no way to test for the existence of the
> typedef or the function declaration.
The GL_<extension_name> symbols are being overloaded. In the past
they've been used to mean (a) prototypes and enums are defined (b)
corresponding interfaces are runtime linkable, though perhaps not
callable.
With the advent of the ABI it instead is used to mean (a) interface
is defined - in some cases via prototypes, in others via typedefs and
(b) interface is in some fashion accessible at runtime, but not
necessarily by static linking. Having *two* preprocessor
symbols/extension is going to produce even more confusion, though.
In that case, the best we can do is make guarantees in the ABI as to
which functions are prototyped and which are typedefed. I believe the
answer should be that all 1.1 or below functions are prototyped only;
1.2/ARB_multitexture functions are both prototyped and typedefed, for
crossplatform portability; all extensions are typedefed only. An
implementation may provide prototypes for extensions it exports from
libGL, but calling them is intrinsically unportable. The hypothetical
ABI compliance checker will eventually catch this.
> The existence of the
> extension's compile-time-test macro does *not* guarantee the
> existence of both the typedef and function declarations.
> (There are existence proofs for several cases.)
You need a rule outside the context of the preprocessor symbols, per
above.
> At the moment, I see no way for an app developer to solve this
> but to choose distinct names for extension typedefs and
> functions, and re-declare them in the app. (glean uses a C++
> namespace for this purpose.) This essentially bypasses the
> shared header file, and the consequences of such a move are
> usually bad.
Perhaps we should create a utility library, maintained in a central
location along with glext.h, which lets you do something like:
glextCurrentContext(glext, ctx); // loads function pointers for extensions
glext->TexImage3DEXT(params); // use function pointer
Or maybe it would be in the GLU namespace. Just something to remove
the burden of extension function pointer handling from ISVs. If it gets
done soon along with the ABI, it might get wide use.
> Option B resolves the difficulties with Option A by introducing new
> conventions for the structure of extension declarations in gl.h and
> glext.h. The rules are:
>
> 1. Declarations of extensions in gl.h are guarded by a new
> conditional compilation flag (let's call it GL_PORTABLE_SDK
> for the moment). When GL_PORTABLE_SDK is *not* defined,
> extension declarations are preserved in the same form they
> have today, whatever that may be for any given vendor's gl.h.
> Compatibility is maintained to the greatest extent possible;
> applications compiled with existing Makefiles and a fresh gl.h
> from the same vendor will compile and behave just as they did
> before.
>
> 2. When GL_PORTABLE_SDK is defined, all the extension
> declarations are compiled out of gl.h. This yields a pristine
> header file that covers just declarations for the OpenGL core.
> This guarantees that gl.h contains no extension declarations
> that might conflict with those in the app or in glext.h.
>
> 3. In addition, when GL_PORTABLE_SDK is defined, gl.h includes
> glext.h. From the app developer's point of view, including
> gl.h brings in all the declarations needed to use both the
> core and the extensions, but from the system administrator's
> point of view, it's possible to maintain gl.h and glext.h
> independently.
>
> 4. glext.h declares enumerants and typedefs for extensions in the
> usual way. However, it does *not* declare extension function
> entry points. This allows naked references to extension
> functions to be caught at compile time.
...
> Have I persuaded anyone to switch from A to C or B? :-)
I can live with the original option B, since it doesn't hurt
existing applications. But what you're talking about here is not the
original option B, which had only to do with clause (3) above. The other
clauses impose new structure on gl.h and glext.h beyond what we've
discussed in the past. I'm not necessarily opposed to the new structure,
but we should hash it out a bit.
There's also an issue regarding crossplatform use of glext.h (which
is, recall, a design parameter). As I mentioned in response to Thomas
Roell yesterday, it's necessary to put the 1.2 entry points into glext.h
for use on e.g. Windows. Whatever solution we come up with needs to
accomodate this (1.2 prototypes are defined for use on Linux -
presumably in the core gl.h - and 1.2 typedefs are defined for use
elsewhere).
Finally, nobody ever responded regarding glxext.h. I assume silence
== consent, so unless there are complaints, glxext.h will go into the
final ABI specification along with glext.h, and similar structural rules
will apply to it as well.
Jon Leech
SGI