Added data argument to GL entry point lookup callback.
authorRyan C. Gordon <icculus@icculus.org>
Tue, 30 Mar 2010 20:12:29 -0400
changeset 904 5989f0d4185a
parent 903 c5cb0a6381fe
child 905 3bbe451a2913
Added data argument to GL entry point lookup callback. Sorry to break the public API!
mojoshader.h
mojoshader_opengl.c
utils/availableprofiles.c
utils/bestprofile.c
utils/finderrors.c
--- a/mojoshader.h	Mon Mar 29 14:46:59 2010 -0400
+++ b/mojoshader.h	Tue Mar 30 20:12:29 2010 -0400
@@ -885,6 +885,27 @@
 /* OpenGL interface... */
 
 /*
+ * Signature for function lookup callbacks. MojoShader will call a function
+ *  you provide to get OpenGL entry points (both standard functions and
+ *  extensions). Through this, MojoShader never links directly to OpenGL,
+ *  but relies on you to provide the implementation. This means you can
+ *  swap in different drivers, or hook functions (log every GL call MojoShader
+ *  makes, etc).
+ *
+ * (fnname) is the function name we want the address for ("glBegin" or
+ *  whatever. (data) is a void pointer you provide, if this callback needs
+ *  extra information. If you don't need it, you may specify NULL.
+ *
+ * Return the entry point on success, NULL if it couldn't be found.
+ *  Note that this could ask for standard entry points like glEnable(), or
+ *  extensions like glProgramLocalParameterI4ivNV(), so you might need
+ *  to check two places to find the desired entry point, depending on your
+ *  platform (Windows might need to look in OpenGL32.dll and use WGL, etc).
+ */
+typedef void *(*MOJOSHADER_glGetProcAddress)(const char *fnname, void *data);
+
+
+/*
  * "Contexts" map to OpenGL contexts...you need one per window, or whatever,
  *  and need to inform MojoShader when you make a new one current.
  *
@@ -913,9 +934,9 @@
  *
  * You can only call this AFTER you have successfully built your GL context
  *  and made it current. This function will lookup the GL functions it needs
- *  through the callback you supply. The lookup function is neither stored nor
- *  used by MojoShader after this function returns, nor are the functions it
- *  might look up.
+ *  through the callback you supply, via (lookup) and (d). The lookup function
+ *  is neither stored nor used by MojoShader after this function returns, nor
+ *  are the functions it might look up.
  *
  * You should not free any strings returned from this function; they are
  *  pointers to internal, probably static, memory.
@@ -924,7 +945,7 @@
  *  safe, you should probably only call this from the same thread that created
  *  the GL context.
  */
-int MOJOSHADER_glAvailableProfiles(void *(*lookup)(const char *fnname),
+int MOJOSHADER_glAvailableProfiles(MOJOSHADER_glGetProcAddress lookup, void *d,
                                    const char **profs, const int size);
 
 
@@ -933,9 +954,9 @@
  *
  * You can only call this AFTER you have successfully built your GL context
  *  and made it current. This function will lookup the GL functions it needs
- *  through the callback you supply. The lookup function is neither stored nor
- *  used by MojoShader after this function returns, nor are the functions it
- *  might look up.
+ *  through the callback you supply via (lookup) and (d). The lookup function
+ *  is neither stored nor used by MojoShader after this function returns, nor
+ *  are the functions it might look up.
  *
  * Returns the name of the "best" profile on success, NULL if none of the
  *  available profiles will work on this system. "Best" is a relative term,
@@ -950,7 +971,7 @@
  *  safe, you should probably only call this from the same thread that created
  *  the GL context.
  */
-const char *MOJOSHADER_glBestProfile(void *(*lookup)(const char *fnname));
+const char *MOJOSHADER_glBestProfile(MOJOSHADER_glGetProcAddress lookup, void *d);
 
 
 /*
@@ -960,23 +981,26 @@
  *
  * You must call this once AFTER you have successfully built your GL context
  *  and made it current. This function will lookup the GL functions it needs
- *  through the callback you supply, after which it may call them at any time
- *  up until you call MOJOSHADER_glDestroyContext(). The lookup function is
- *  neither stored nor used by MojoShader after this function returns.
+ *  through the callback you supply via (lookup) and (lookup_d), after which
+ *  it may call them at any time up until you call
+ *  MOJOSHADER_glDestroyContext(). The lookup function is neither stored nor
+ *  used by MojoShader after this function returns.
  *
  * (profile) is an OpenGL-specific MojoShader profile, which decides how
  *  Direct3D bytecode shaders get turned into OpenGL programs, and how they
  *  are fed to the GL.
  *
  * (lookup) is a callback that is used to load GL entry points. This callback
- *  has to look up base GL functions and extension entry points.
+ *  has to look up base GL functions and extension entry points. The pointer
+ *  you supply in (lookup_d) is passed as-is to the callback.
  *
  * As MojoShader requires some memory to be allocated, you may provide a
  *  custom allocator to this function, which will be used to allocate/free
  *  memory. They function just like malloc() and free(). We do not use
  *  realloc(). If you don't care, pass NULL in for the allocator functions.
  *  If your allocator needs instance-specific data, you may supply it with the
- *  (d) parameter. This pointer is passed as-is to your (m) and (f) functions.
+ *  (malloc_d) parameter. This pointer is passed as-is to your (m) and (f)
+ *  functions.
  *
  * Returns a new context on success, NULL on error. If you get a new context,
  *  you need to make it current before using it with
@@ -988,9 +1012,10 @@
  *  thread that created the GL context.
  */
 MOJOSHADER_glContext *MOJOSHADER_glCreateContext(const char *profile,
-                                        void *(*lookup)(const char *fnname),
+                                        MOJOSHADER_glGetProcAddress lookup,
+                                        void *lookup_d,
                                         MOJOSHADER_malloc m, MOJOSHADER_free f,
-                                        void *d);
+                                        void *malloc_d);
 
 /*
  * You must call this before using the context that you got from
--- a/mojoshader_opengl.c	Mon Mar 29 14:46:59 2010 -0400
+++ b/mojoshader_opengl.c	Tue Mar 30 20:12:29 2010 -0400
@@ -748,17 +748,18 @@
 } // MOJOSHADER_glGetError
 
 
-static void *loadsym(void *(*lookup)(const char *fn), const char *fn, int *ext)
+static void *loadsym(MOJOSHADER_glGetProcAddress lookup, void *d,
+                     const char *fn, int *ext)
 {
     void *retval = NULL;
     if (lookup != NULL)
     {
-        retval = lookup(fn);
+        retval = lookup(fn, d);
         if (retval == NULL)
         {
             char arbfn[64];
             snprintf(arbfn, sizeof (arbfn), "%sARB", fn);
-            retval = lookup(arbfn);
+            retval = lookup(arbfn, d);
         } // if
     } // if
 
@@ -768,11 +769,11 @@
     return retval;
 } // loadsym
 
-static void lookup_entry_points(void *(*lookup)(const char *fnname))
+static void lookup_entry_points(MOJOSHADER_glGetProcAddress lookup, void *d)
 {
     #define DO_LOOKUP(ext, typ, fn) { \
         int exist = ctx->have_##ext; \
-        ctx->fn = (typ) loadsym(lookup, #fn, &exist); \
+        ctx->fn = (typ) loadsym(lookup, d, #fn, &exist); \
         ctx->have_##ext = exist; \
     }
 
@@ -875,7 +876,7 @@
 #endif
 
 
-static void load_extensions(void *(*lookup)(const char *fnname))
+static void load_extensions(MOJOSHADER_glGetProcAddress lookup, void *d)
 {
     const char *extlist = NULL;
 
@@ -894,7 +895,7 @@
     ctx->have_GL_ARB_half_float_vertex = 1;
     ctx->have_GL_OES_vertex_half_float = 1;
 
-    lookup_entry_points(lookup);
+    lookup_entry_points(lookup, d);
 
     if (!ctx->have_base_opengl)
         set_error("missing basic OpenGL entry points");
@@ -1034,7 +1035,7 @@
 #endif
 };
 
-int MOJOSHADER_glAvailableProfiles(void *(*lookup)(const char *fnname),
+int MOJOSHADER_glAvailableProfiles(MOJOSHADER_glGetProcAddress lookup, void *d,
                                    const char **profs, const int size)
 {
     int retval = 0;
@@ -1043,7 +1044,7 @@
 
     ctx = &_ctx;
     memset(ctx, '\0', sizeof (MOJOSHADER_glContext));
-    load_extensions(lookup);
+    load_extensions(lookup, d);
 
     if (ctx->have_base_opengl)
     {
@@ -1065,10 +1066,10 @@
 } // MOJOSHADER_glAvailableProfiles
 
 
-const char *MOJOSHADER_glBestProfile(void *(*lookup)(const char *fnname))
+const char *MOJOSHADER_glBestProfile(MOJOSHADER_glGetProcAddress gpa, void *d)
 {
     const char *prof[STATICARRAYLEN(profile_priorities)];
-    if (MOJOSHADER_glAvailableProfiles(lookup, prof, STATICARRAYLEN(prof)) <= 0)
+    if (MOJOSHADER_glAvailableProfiles(gpa, d, prof, STATICARRAYLEN(prof)) <= 0)
     {
         set_error("no profiles available");
         return NULL;
@@ -1079,9 +1080,10 @@
 
 
 MOJOSHADER_glContext *MOJOSHADER_glCreateContext(const char *profile,
-                                        void *(*lookup)(const char *fnname),
+                                        MOJOSHADER_glGetProcAddress lookup,
+                                        void *lookup_d,
                                         MOJOSHADER_malloc m, MOJOSHADER_free f,
-                                        void *d)
+                                        void *malloc_d)
 {
     MOJOSHADER_glContext *retval = NULL;
     MOJOSHADER_glContext *current_ctx = ctx;
@@ -1091,7 +1093,7 @@
     if (m == NULL) m = MOJOSHADER_internal_malloc;
     if (f == NULL) f = MOJOSHADER_internal_free;
 
-    ctx = (MOJOSHADER_glContext *) m(sizeof (MOJOSHADER_glContext), d);
+    ctx = (MOJOSHADER_glContext *) m(sizeof (MOJOSHADER_glContext), malloc_d);
     if (ctx == NULL)
     {
         set_error("out of memory");
@@ -1101,10 +1103,10 @@
     memset(ctx, '\0', sizeof (MOJOSHADER_glContext));
     ctx->malloc_fn = m;
     ctx->free_fn = f;
-    ctx->malloc_data = d;
+    ctx->malloc_data = malloc_d;
     snprintf(ctx->profile, sizeof (ctx->profile), "%s", profile);
 
-    load_extensions(lookup);
+    load_extensions(lookup, lookup_d);
     if (!valid_profile(profile))
         goto init_fail;
 
@@ -1184,7 +1186,7 @@
 
 init_fail:
     if (ctx != NULL)
-        f(ctx, d);
+        f(ctx, malloc_d);
     ctx = current_ctx;
     return NULL;
 } // MOJOSHADER_glCreateContext
@@ -1909,7 +1911,7 @@
     ctx = _ctx;
     MOJOSHADER_glBindProgram(NULL);
     update_enabled_arrays();  // disables all vertex arrays.
-    lookup_entry_points(NULL);
+    lookup_entry_points(NULL, NULL);
     Free(ctx);
     ctx = ((current_ctx == _ctx) ? NULL : current_ctx);
 } // MOJOSHADER_glDestroyContext
--- a/utils/availableprofiles.c	Mon Mar 29 14:46:59 2010 -0400
+++ b/utils/availableprofiles.c	Tue Mar 30 20:12:29 2010 -0400
@@ -11,14 +11,20 @@
 #include "mojoshader.h"
 #include "SDL.h"
 
+static void *lookup(const char *fnname, void *unused)
+{
+    (void) unused;
+    return SDL_GL_GetProcAddress(fnname);
+} // lookup
+
 static int check_available(void)
 {
     const char **avail = NULL;
-    int total = MOJOSHADER_glAvailableProfiles(SDL_GL_GetProcAddress, NULL, 0);
+    int total = MOJOSHADER_glAvailableProfiles(lookup, NULL, NULL, 0);
     if (total > 0)
     {
         avail = (const char **) alloca(sizeof (const char *) * total);
-        total = MOJOSHADER_glAvailableProfiles(SDL_GL_GetProcAddress, avail, total);
+        total = MOJOSHADER_glAvailableProfiles(lookup, NULL, avail, total);
     } // if
 
     if (total <= 0)
--- a/utils/bestprofile.c	Mon Mar 29 14:46:59 2010 -0400
+++ b/utils/bestprofile.c	Tue Mar 30 20:12:29 2010 -0400
@@ -11,6 +11,12 @@
 #include "mojoshader.h"
 #include "SDL.h"
 
+static void *lookup(const char *fnname, void *unused)
+{
+    (void) unused;
+    return SDL_GL_GetProcAddress(fnname);
+} // lookup
+
 int main(int argc, char **argv)
 {
     int retval = 1;
@@ -31,9 +37,9 @@
             fprintf(stderr, "SDL_SetVideoMode() error: %s\n", SDL_GetError());
         else
         {
-            const char *best = MOJOSHADER_glBestProfile(SDL_GL_GetProcAddress);
+            const char *best = MOJOSHADER_glBestProfile(lookup, NULL);
             MOJOSHADER_glContext *ctx;
-            ctx = MOJOSHADER_glCreateContext(best, SDL_GL_GetProcAddress, 0, 0, 0);
+            ctx = MOJOSHADER_glCreateContext(best, lookup, 0, 0, 0, 0);
             if (ctx == NULL)
                 printf("MOJOSHADER_glCreateContext() fail: %s\n", MOJOSHADER_glGetError());
             else
--- a/utils/finderrors.c	Mon Mar 29 14:46:59 2010 -0400
+++ b/utils/finderrors.c	Tue Mar 30 20:12:29 2010 -0400
@@ -18,6 +18,11 @@
 
 #if FINDERRORS_COMPILE_SHADERS
 #include "SDL.h"
+static void *lookup(const char *fnname, void *unused)
+{
+    (void) unused;
+    return SDL_GL_GetProcAddress(fnname);
+} // lookup
 #endif
 
 #ifdef _MSC_VER
@@ -192,9 +197,9 @@
         SDL_Init(SDL_INIT_VIDEO);
         SDL_GL_LoadLibrary(NULL);
         SDL_SetVideoMode(640, 480, 0, SDL_OPENGL);
-        printf("Best profile is '%s'\n", MOJOSHADER_glBestProfile(SDL_GL_GetProcAddress));
+        printf("Best profile is '%s'\n", MOJOSHADER_glBestProfile(lookup, 0));
         MOJOSHADER_glContext *ctx;
-        ctx = MOJOSHADER_glCreateContext(profile, SDL_GL_GetProcAddress, 0, 0, 0);
+        ctx = MOJOSHADER_glCreateContext(profile, lookup, 0, 0, 0, 0);
         if (ctx == NULL)
         {
             printf("MOJOSHADER_glCreateContext() fail: %s\n", MOJOSHADER_glGetError());