From 918f62184950adb2b3a2aee30bb4dcdafcafa613 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Thu, 3 Jul 2008 15:25:12 -0400 Subject: [PATCH] Added MOJOSHADER_glAvailableProfiles(). --HG-- branch : trunk --- mojoshader.h | 31 +++++++++++++++++++++++++-- mojoshader_opengl.c | 51 ++++++++++++++++++++++++++++++--------------- 2 files changed, 63 insertions(+), 19 deletions(-) diff --git a/mojoshader.h b/mojoshader.h index 3aa29d17..4da4e429 100644 --- a/mojoshader.h +++ b/mojoshader.h @@ -434,9 +434,36 @@ typedef struct MOJOSHADER_glProgram MOJOSHADER_glProgram; /* - * Determine the best profile to use for the current system. + * Get a list of available profiles. This will fill in the array (profs) + * with up to (size) pointers of profiles that the current system can handle; + * that is, the profiles are built into MojoShader and the OpenGL extensions + * required for them exist at runtime. This function returns the number of + * available profiles, which may be more, less, or equal to (size). * - * You do not need to call this if all you want is MOJOSHADER_parse(). + * If there are more than (size) profiles, the (profs) buffer will not + * overflow. You can check the return value for the total number of + * available profiles, allocate more space, and try again if necessary. + * Calling this function with (size) == 0 is legal. + * + * 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. + * + * You should not free any strings returned from this function; they are + * pointers to internal, probably static, memory. + * + * This call is NOT thread safe! As most OpenGL implementations are not thread + * safe, you should probably only call this from the same thread that created + * the GL context. + */ +int MOJOSHADER_glAvailableProfiles(void *(*lookup)(const char *fnname), + const char **profs, const int size); + + +/* + * Determine the best profile to use for the current system. * * 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 diff --git a/mojoshader_opengl.c b/mojoshader_opengl.c index 72a1c41e..111fa689 100644 --- a/mojoshader_opengl.c +++ b/mojoshader_opengl.c @@ -804,9 +804,22 @@ static int valid_profile(const char *profile) } // valid_profile -const char *MOJOSHADER_glBestProfile(void *(*lookup)(const char *fnname)) +static const char *profile_priorities[] = { +#if SUPPORT_PROFILE_GLSL + MOJOSHADER_PROFILE_GLSL120, + MOJOSHADER_PROFILE_GLSL, +#endif +#if SUPPORT_PROFILE_ARB1 + MOJOSHADER_PROFILE_NV3, + MOJOSHADER_PROFILE_NV2, + MOJOSHADER_PROFILE_ARB1, +#endif +}; + +int MOJOSHADER_glAvailableProfiles(void *(*lookup)(const char *fnname), + const char **profs, const int size) { - const char *retval = NULL; + int retval = 0; MOJOSHADER_glContext _ctx; MOJOSHADER_glContext *current_ctx = ctx; @@ -816,32 +829,36 @@ const char *MOJOSHADER_glBestProfile(void *(*lookup)(const char *fnname)) if (ctx->have_base_opengl) { - static const char *priority[] = { - MOJOSHADER_PROFILE_GLSL120, - MOJOSHADER_PROFILE_GLSL, - MOJOSHADER_PROFILE_NV3, - MOJOSHADER_PROFILE_NV2, - MOJOSHADER_PROFILE_ARB1, - }; - int i; - for (i = 0; i < STATICARRAYLEN(priority); i++) + for (i = 0; i < STATICARRAYLEN(profile_priorities); i++) { // !!! FIXME: if Mac OS X <= 10.4, don't ever pick GLSL, even if // !!! FIXME: the system claims it is available. - if (valid_profile(priority[i])) + const char *profile = profile_priorities[i]; + if (valid_profile(profile)) { - retval = priority[i]; - break; + if (retval < size) + profs[retval] = profile; + retval++; } // if } // for - - if (retval == NULL) - set_error("no profiles available"); } // if ctx = current_ctx; return retval; +} // MOJOSHADER_glAvailableProfiles + + +const char *MOJOSHADER_glBestProfile(void *(*lookup)(const char *fnname)) +{ + const char *prof[STATICARRAYLEN(profile_priorities)]; + if (MOJOSHADER_glAvailableProfiles(lookup, prof, STATICARRAYLEN(prof)) <= 0) + { + set_error("no profiles available"); + return NULL; + } // if + + return prof[0]; // profiles are sorted "best" to "worst." } // MOJOSHADER_glBestProfile