Richard Pimentel wrote:
>
> Brett Johnson wrote:
>
> > Richard Pimentel wrote:
> > >
> > > Stephen J Baker wrote:
> > > > Look at it this way: All of the other gl* functions are assumed to
> > > > be "in the present context" - why should glGetFuncAddress be any
> > > > different?
> > >
> > > We can live with this. Just spell this constraint out clearly in the function
> > > spec. To tighten things up even more, will a function pointer be allowed to
> > > ever become invalid within the context that was current when it was queried? I
> > > would say no. What is the behavior of a call to a function pointer after its
> > > context is deleted? Crash the app. I hope since this would be a very bad bug.
> > > It is sort of analoguos to dereferencing stale pointers.
> >
> > As I see it, the problem is exactly the opposite. I.e. it would be a very
> > subtle bug for an application to get a function pointer in context A, then
> > call it in context B.
>
> I think they both would be subtle bugs whose impact could be felt several frames
> later. This tough problem and I agree that having the implementation track which
> context is current and dispatch to the correct underlying function frees up the app.
> But I have two concerns:
>
> * The inefficiency of the extra function call to the context neutral function and
> the deference that function has to do to get to the "real" function.
> o If the app. has the burden, there is just the indirection from its
> internal per context record where it stores its function pointers. This
> isn't fun for the app. and maybe the extra call overhead isn't that
> important, but there is a price to pay no matter how you slice it.
But this indirection has to happen somewhere anyway. For example: Say you obtain a
function pointer to glVertex6fvEXT, then you enter display list compile mode. You
would expect that your function pointer would still be valid, no? But what that
function call does has now completely changed. So the implementation could check
to see if it's in display list mode (and which mode) in each function:
void glVertex6fvEXT(...) {
if (DISPLAY_LIST_COMPILE_MODE(context)) {
... store the call away in a display list ...
} else if (DISPLAY_LIST_COMPILE_AND_EXECUTE_MODE(context)) {
... store the call away in a display list ...
... execute the call ...
} else {
... execute the call ...
}
}
or it could keep a dispatch table around, and plug the appropriate function into
the dispatch table, depending on the current pipeline state (whether display
list compilation is enabled or not, for example):
void glVertex6fvEXT(...) {
CurrentContext->Vertex6fvEXT(...);
}
Either way, an indirection has to be taken. I'm suggesting that we move that
indirection up into the libGL dispatcher, and make it good (and fast) enough
that the driver writers will use it rather than writing their own dispatcher.
> * The complexity of trying to manage this in a heterogeneous environment with
> multiple heads not supplied by the same vendor.
> o This one would go away if we put the stick in the ground and said function
> pointers are only valid on the same display. But even this has all the
> same issues the per context constraint.
I think the fact that a function pointer for a particular context might work with
other contexts serviced by the same driver is an implementation detail that should
not be exposed. In fact, I don't even think it's currently true, at least with
our Windows driver. I don't see much advantage in forcing it to be true either.
> > Must we now require that every OpenGL function whose pointer is returned by
> > "GetProcAddress()" check to ensure that it's being called while the same
> > context from which it was obtained is current? Wuf, I hope not. That would
> > be an awful performance penalty.
>
> So I must be missing something. How would you implement the extension function foo
> to be context independent? Seems like context independence is more of a performance
> hit than this test for the correct context. But maybe I am just stuck on one
> implementation.
Remember, the indirection has to happen in one form or another, somewhere along
the OpenGL pipeline. So I don't agree that doing the indirection in the libGL is
going to be a performance hit. In fact, I think it can result in dramatic
performance improvements if it's taken advantage of by the driver writers.
Having said that, here is one idea. To be efficient (and simple), I believe that
the implementation will have to be platform dependent. So here's some pseudo-sorta
code for one way to do this on X86:
dispatch_x86.c file:
typedef struct {
jumpOpcodeType opcode;
jumpOffsetType offset;
} JumpInstructionStruct;
JumpInstructionStruct GLEXTJumpTable[SOME_MAX_TABLE_SIZE];
static void DoNothingProc(void) {
return;
}
/* This needs to be called at libGL initialization time. */
void InitJumpTable(void) {
int i;
for (i=0; i<SOME_MAX_TABLE_SIZE; i++) {
GLEXTJumpTable[i].opcode = JUMP_INSTRUCTION_OPCODE_VALUE;
GLEXTJumpTable[i].offset = OffsetFromFPtr((FuncPtrType) DoNothingProc);
}
}
/* This would be called by the driver to "plug in" a function to the dispatcher. */
void glDSPSetFunctionPointer(char *funcName, FuncPtrType *ptr) {
int index = LookupTableIndex(funcName); /* This would perform some sort
of hash lookup or something to
assign an offset to a given name */
GLEXTJumpTable[index].offset = OffsetFromFPtr(ptr);
X86_flush_code_cache();
}
FuncPtrType glXGetProcAddress(const char *name) {
int index = LookupTableIndex(name);
return ((FuncPtrType) (GLEXTJumpTable + index));
}
For x86, this approach would insert an extra "jump" instruction into the call
sequence (of course, it's not really "extra", since the indirection has to
happen anyway). On other platforms, this can be done without any additional
instructions being executed (and without using data space for executable code).
> > If we don't require this behavior, we have to say that the behavior in this
> > situation is undefined. The function can't set a glError if it hasn't
> > checked to see if it's in its own context, so it would just do its normal
> > thing, assuming that it owns the current context. It might crash the
> > driver if the developer is lucky, or worse, it might just silently change
> > some unintended context state that won't be noticed until 5 frames later (or
> > until the app user turns on some currently unused feature that relies on said
> > state). Yuck... This is a potential nightmare for app developers.
>
> Yep. But it wouldn't be the first one or even the worst one ;-). That is why
> company's like Rational make a lot of money. We need an OSF "ZAPdb" that would catch
> this kind of stuff.
Yea, but wouldn't it be much better if we just avoid the pitfall in the first
place?
Cheers!
begin:vcard
n:Johnson;Brett
x-mozilla-html:FALSE
org:Hewlett-Packard;Worstation Systems Lab
adr:;;;;;;
version:2.1
email;internet:[EMAIL PROTECTED]
title:WSL Turtle Master
fn:Brett Johnson
end:vcard