Skip to content

Commit

Permalink
Added data argument to GL entry point lookup callback.
Browse files Browse the repository at this point in the history
Sorry to break the public API!
  • Loading branch information
icculus committed Mar 31, 2010
1 parent b22aca1 commit e4c87ae
Show file tree
Hide file tree
Showing 5 changed files with 83 additions and 39 deletions.
55 changes: 40 additions & 15 deletions mojoshader.h
Expand Up @@ -884,6 +884,27 @@ const MOJOSHADER_parseData *MOJOSHADER_assemble(const char *filename,

/* 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.
Expand Down Expand Up @@ -913,9 +934,9 @@ typedef struct MOJOSHADER_glProgram MOJOSHADER_glProgram;
*
* 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.
Expand All @@ -924,7 +945,7 @@ typedef struct MOJOSHADER_glProgram MOJOSHADER_glProgram;
* 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);


Expand All @@ -933,9 +954,9 @@ int MOJOSHADER_glAvailableProfiles(void *(*lookup)(const char *fnname),
*
* 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,
Expand All @@ -950,7 +971,7 @@ int MOJOSHADER_glAvailableProfiles(void *(*lookup)(const char *fnname),
* 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);


/*
Expand All @@ -960,23 +981,26 @@ const char *MOJOSHADER_glBestProfile(void *(*lookup)(const char *fnname));
*
* 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
Expand All @@ -988,9 +1012,10 @@ const char *MOJOSHADER_glBestProfile(void *(*lookup)(const char *fnname));
* 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
Expand Down
38 changes: 20 additions & 18 deletions mojoshader_opengl.c
Expand Up @@ -748,17 +748,18 @@ const char *MOJOSHADER_glGetError(void)
} // 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

Expand All @@ -768,11 +769,11 @@ static void *loadsym(void *(*lookup)(const char *fn), const char *fn, int *ext)
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; \
}

Expand Down Expand Up @@ -875,7 +876,7 @@ static int glsl_version_atleast(int maj, int min)
#endif


static void load_extensions(void *(*lookup)(const char *fnname))
static void load_extensions(MOJOSHADER_glGetProcAddress lookup, void *d)
{
const char *extlist = NULL;

Expand All @@ -894,7 +895,7 @@ static void load_extensions(void *(*lookup)(const char *fnname))
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");
Expand Down Expand Up @@ -1034,7 +1035,7 @@ static const char *profile_priorities[] = {
#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;
Expand All @@ -1043,7 +1044,7 @@ int MOJOSHADER_glAvailableProfiles(void *(*lookup)(const char *fnname),

ctx = &_ctx;
memset(ctx, '\0', sizeof (MOJOSHADER_glContext));
load_extensions(lookup);
load_extensions(lookup, d);

if (ctx->have_base_opengl)
{
Expand All @@ -1065,10 +1066,10 @@ int MOJOSHADER_glAvailableProfiles(void *(*lookup)(const char *fnname),
} // 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;
Expand All @@ -1079,9 +1080,10 @@ const char *MOJOSHADER_glBestProfile(void *(*lookup)(const char *fnname))


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;
Expand All @@ -1091,7 +1093,7 @@ MOJOSHADER_glContext *MOJOSHADER_glCreateContext(const char *profile,
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");
Expand All @@ -1101,10 +1103,10 @@ MOJOSHADER_glContext *MOJOSHADER_glCreateContext(const char *profile,
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;

Expand Down Expand Up @@ -1184,7 +1186,7 @@ MOJOSHADER_glContext *MOJOSHADER_glCreateContext(const char *profile,

init_fail:
if (ctx != NULL)
f(ctx, d);
f(ctx, malloc_d);
ctx = current_ctx;
return NULL;
} // MOJOSHADER_glCreateContext
Expand Down Expand Up @@ -1909,7 +1911,7 @@ void MOJOSHADER_glDestroyContext(MOJOSHADER_glContext *_ctx)
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
Expand Down
10 changes: 8 additions & 2 deletions utils/availableprofiles.c
Expand Up @@ -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)
Expand Down
10 changes: 8 additions & 2 deletions utils/bestprofile.c
Expand Up @@ -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;
Expand All @@ -31,9 +37,9 @@ int main(int argc, char **argv)
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
Expand Down
9 changes: 7 additions & 2 deletions utils/finderrors.c
Expand Up @@ -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
Expand Down Expand Up @@ -192,9 +197,9 @@ int main(int argc, char **argv)
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());
Expand Down

0 comments on commit e4c87ae

Please sign in to comment.