Brett Johnson wrote:
> 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:
Bingo. You have convinced me.
>
>
> 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.
Agreed. I repent ;-).
>
>
> > * 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!
--
Richard Pimentel
Manager of Graphics and Integration
Industrial Design Products
Parametric Technology Corp.
540 Arapeen Drive, Suite 100
Salt Lake City, UT 84108
(801) 588-4668