On Thu, Nov 04, 1999 at 11:47:57AM -0800, John M. Zulauf wrote:
> > In general, undefined. Since we can now query *any* entry point, and
> > since error semantics are different for GL, GLX, and GLU entry points,
> > the only meaningful consistent (e.g. specifiable) behavior you could
> > require is "termination" or "noop". I don't think "noop" is useful to
> > the ISV;
>
> with context independance, since you cannot know what FUTURE contexts will
> be created, you must return a non-NULL dispatcher proc. The only open
> question is whether an unsupported EXT should be dispatched to a noop or
> error-generating function.
We cannot know what future contexts will be created, but we can know
the bounded set of all extensions available to the implementation. This
can be interpreted to mean that all loadable driver modules which may
ever be used during the current invocation of the X server must be known
to the server so that it can request this information from all of them
(mechanism TBD of course).
This is consistent with how XFree86 configuration works today
(statically), and it is not an issue for commercial X implementations
which a priori know all drivers they support. The only scenario in which
it seems intrinsically unworkable is hot plug and play of heterogeneous
hardware with drivers added to the system during the course of the X
session - an ability I've never heard anyone articulate for 2D much less
3D.
> > consider the scenario:
> >
> > #ifdef GL_ARB_multitexture
> > /* Verify that GL_EXTENSIONS contains ARB_multitexture */
> > if (gluCheckExtension("GL_ARB_multitexture",
> > glGetString(GL_EXTENSIONS))
> > {
> > /* Valid ptr to "noop" function returned (note typo)*/
> > activetexptr = glXGetProcAddressARB("glActiveTextureARV");
> > }
> > #endif
> > ...
> > (*activetexptr)(GL_TEXTURE2_ARB); /* Oops, noop */
> > ... further calls affect/use texture 0 instead of texture 2
>
> This IS a bug since the app DIDN'T stor the check extension result and is
> assuming it is extant. If we returned NULL as you suggest then on some
> untested platform missing a prereq. extension the app crashes -- YUCK!
My point here is that the *function* being called is not behaving as
the app expects, and there is no way to validate the pointer other than
when it's created. Perhaps this will make the example more clear:
static GLboolean multitex_is_supported = GL_FALSE;
#ifdef GL_ARB_multitexture
/* Verify that GL_EXTENSIONS contains ARB_multitexture */
if (gluCheckExtension("GL_ARB_multitexture",
glGetString(GL_EXTENSIONS))
{
multitex_is_supported = GL_TRUE;
/* Valid ptr to "noop" function returned (note typo)*/
activetexptr = glXGetProcAddressARB("glActiveTextureARV");
}
#endif
...
#ifdef GL_ARB_multitexture
if (multitex_is_supported) {
(*activetexptr)(GL_TEXTURE2_ARB); /* Oops, noop */
... further calls affect/use texture 0 instead of texture 2
}
#endif
It's possible that the app may do something like query for
"glActiveTexture3fvARB" while treating the pointer as
"glActiveTexture3fARB" - or other sorts of typos - but at least in that
case you are likely to get visibly incorrect results, or stack trashing
and a crash at call time or very shortly thereafter - exactly as you
would by
GLfloat v[3];
((void (*)(GLfloat *))glTexCoord3f)(&v[0]);
> > Now the app silently gets incorrect behavior, yet when the ISV
> > attempts to debug it, the call succeeds and the actual problem is far
> > removed from where it *seems* to be! So having a checkable
> > success/failure flag (NULL return) on the call seems desirable to me.
>
> I thought that the return value from getProc was NOT supposed to be
> interpreted as an exsistance flag for any extension.
Agreed. But it can be used as a NON-existence flag for an extension.
It should always be safe to say that an extension *doesn't* exist even
if it really does.
> To solve the "silent
> failure" problem returning a error noop would give the application a way to
> track this down without building crash.
No useful runtime error behavior is possible given that the pointers
may be to any of GL, GLX, or perhaps GLU functions. GL and GLU calls
would raise a GL_INVALID_OPERATION error, while GLX would generate an X
error. As none of the existing GLX error codes describe this situation,
we'd have to create a new one.
Which is it supposed to be for a function identified by a string
name which is not known to be of either category, and which the
implementation has no idea how the application intends to use? It's
impossible to mandate raising a GL error when there may be no current
context, but no application is likely to query for GLX errors in the
middle of its rendering loop.
> I say we require a NON-null return (that is in fact the only truely context
> independent possibility) which will either noop or error (to address your
> concern).
The noop *is* my concern.
> This removes the requirement for NULL test AND the temptation to
> incorrectly associate getProc with getString as the appropriate means to
> determine exsistance of an extension.
I don't see a NULL test as particularly onerous, since the
difference amounts to
ptr = glXGetProcAddress(name);
vs.
if ((ptr = glXGetProcAddress(name)) == NULL)
turn_off_use_of_extension_or_die_from_assertion_failure();
Jon Leech
SGI