Add internal _cogl_get_proc_address

This adds an internal _cogl_get_proc_address that doesn't need a
CoglContext. This will enable us to check driver features earlier.
This commit is contained in:
Robert Bragg 2011-05-24 01:38:48 +01:00
parent 32e7c93aff
commit be15bf75e4
10 changed files with 64 additions and 114 deletions

View File

@ -33,7 +33,8 @@
#include "cogl-feature-private.h" #include "cogl-feature-private.h"
gboolean gboolean
_cogl_feature_check (const char *driver_prefix, _cogl_feature_check (const CoglWinsysVtable *winsys,
const char *driver_prefix,
const CoglFeatureData *data, const CoglFeatureData *data,
unsigned int gl_major, unsigned int gl_major,
unsigned int gl_minor, unsigned int gl_minor,
@ -44,8 +45,6 @@ _cogl_feature_check (const char *driver_prefix,
const char *suffix = NULL; const char *suffix = NULL;
int func_num; int func_num;
_COGL_GET_CONTEXT (ctx, FALSE);
/* First check whether the functions should be directly provided by /* First check whether the functions should be directly provided by
GL */ GL */
if (COGL_CHECK_GL_VERSION (gl_major, gl_minor, if (COGL_CHECK_GL_VERSION (gl_major, gl_minor,
@ -107,7 +106,7 @@ _cogl_feature_check (const char *driver_prefix,
/* If we couldn't find anything that provides the functions then /* If we couldn't find anything that provides the functions then
give up */ give up */
if (suffix == NULL) if (suffix == NULL)
return FALSE; goto error;
/* Try to get all of the entry points */ /* Try to get all of the entry points */
for (func_num = 0; data->functions[func_num].name; func_num++) for (func_num = 0; data->functions[func_num].name; func_num++)
@ -117,28 +116,26 @@ _cogl_feature_check (const char *driver_prefix,
full_function_name = g_strconcat (data->functions[func_num].name, full_function_name = g_strconcat (data->functions[func_num].name,
suffix, NULL); suffix, NULL);
func = cogl_get_proc_address (full_function_name); func = _cogl_get_proc_address (winsys, full_function_name);
g_free (full_function_name); g_free (full_function_name);
if (func == NULL) if (func == NULL)
break; goto error;
/* Set the function pointer in the context */ /* Set the function pointer in the context */
*(void **) ((guint8 *) function_table + *(void **) ((guint8 *) function_table +
data->functions[func_num].pointer_offset) = func; data->functions[func_num].pointer_offset) = func;
} }
/* If one of the functions wasn't found then we should set all of return TRUE;
the function pointers back to NULL so that the rest of Cogl can
safely do feature testing by just looking at the function /* If the extension isn't found or one of the functions wasn't found
pointers */ * then set all of the functions pointers to NULL so Cogl can safely
if (data->functions[func_num].name) * do feature testing by just looking at the function pointers */
{ error:
while (func_num-- > 0) for (func_num = 0; data->functions[func_num].name; func_num++)
*(void **) ((guint8 *) ctx + *(void **) ((guint8 *) function_table +
data->functions[func_num].pointer_offset) = NULL; data->functions[func_num].pointer_offset) = NULL;
return FALSE; return FALSE;
} }
else
return TRUE;
}

View File

@ -71,7 +71,8 @@ struct _CoglFeatureData
}; };
gboolean gboolean
_cogl_feature_check (const char *driver_prefix, _cogl_feature_check (const CoglWinsysVtable *winsys,
const char *driver_prefix,
const CoglFeatureData *data, const CoglFeatureData *data,
unsigned int gl_major, unsigned int gl_major,
unsigned int gl_minor, unsigned int gl_minor,

View File

@ -30,7 +30,6 @@
#include <string.h> #include <string.h>
#include <math.h> #include <math.h>
#include <stdlib.h> #include <stdlib.h>
#include <gmodule.h>
#include "cogl-debug.h" #include "cogl-debug.h"
#include "cogl-internal.h" #include "cogl-internal.h"
@ -93,32 +92,13 @@ cogl_gl_error_to_string (GLenum error_code)
CoglFuncPtr CoglFuncPtr
cogl_get_proc_address (const char* name) cogl_get_proc_address (const char* name)
{ {
void *address;
static GModule *module = NULL;
const CoglWinsysVtable *winsys; const CoglWinsysVtable *winsys;
_COGL_GET_CONTEXT (ctx, NULL); _COGL_GET_CONTEXT (ctx, NULL);
winsys = _cogl_context_get_winsys (ctx); winsys = _cogl_context_get_winsys (ctx);
address = winsys->get_proc_address (name); return _cogl_get_proc_address (winsys, name);
if (address)
return address;
/* this should find the right function if the program is linked against a
* library providing it */
if (G_UNLIKELY (module == NULL))
module = g_module_open (NULL, 0);
if (module)
{
gpointer symbol;
if (g_module_symbol (module, name, &symbol))
return symbol;
}
return NULL;
} }
gboolean gboolean

View File

@ -148,20 +148,6 @@ static const CoglFeatureData cogl_feature_data[] =
#include "cogl-feature-functions-gl.h" #include "cogl-feature-functions-gl.h"
}; };
#undef COGL_FEATURE_BEGIN
#define COGL_FEATURE_BEGIN(a, b, c, d, e, f, g)
#undef COGL_FEATURE_FUNCTION
#define COGL_FEATURE_FUNCTION(ret, name, args) \
context->drv.pf_ ## name = NULL;
#undef COGL_FEATURE_END
#define COGL_FEATURE_END()
static void
initialize_function_table (CoglContext *context)
{
#include "cogl-feature-functions-gl.h"
}
/* Query the GL extensions and lookup the corresponding function /* Query the GL extensions and lookup the corresponding function
* pointers. Theoretically the list of extensions can change for * pointers. Theoretically the list of extensions can change for
* different GL contexts so it is the winsys backend's responsiblity * different GL contexts so it is the winsys backend's responsiblity
@ -220,10 +206,9 @@ _cogl_gl_update_features (CoglContext *context)
if (max_clip_planes >= 4) if (max_clip_planes >= 4)
flags |= COGL_FEATURE_FOUR_CLIP_PLANES; flags |= COGL_FEATURE_FOUR_CLIP_PLANES;
initialize_function_table (context);
for (i = 0; i < G_N_ELEMENTS (cogl_feature_data); i++) for (i = 0; i < G_N_ELEMENTS (cogl_feature_data); i++)
if (_cogl_feature_check ("GL", cogl_feature_data + i, if (_cogl_feature_check (_cogl_context_get_winsys (context),
"GL", cogl_feature_data + i,
gl_major, gl_minor, gl_major, gl_minor,
gl_extensions, gl_extensions,
context)) context))

View File

@ -70,20 +70,6 @@ static const CoglFeatureData cogl_feature_data[] =
#include "cogl-feature-functions-gles.h" #include "cogl-feature-functions-gles.h"
}; };
#undef COGL_FEATURE_BEGIN
#define COGL_FEATURE_BEGIN(a, b, c, d, e, f, g)
#undef COGL_FEATURE_FUNCTION
#define COGL_FEATURE_FUNCTION(ret, name, args) \
context->drv.pf_ ## name = NULL;
#undef COGL_FEATURE_END
#define COGL_FEATURE_END()
static void
initialize_function_table (CoglContext *context)
{
#include "cogl-feature-functions-gles.h"
}
/* Query the GL extensions and lookup the corresponding function /* Query the GL extensions and lookup the corresponding function
* pointers. Theoretically the list of extensions can change for * pointers. Theoretically the list of extensions can change for
* different GL contexts so it is the winsys backend's responsiblity * different GL contexts so it is the winsys backend's responsiblity
@ -137,10 +123,9 @@ _cogl_gl_update_features (CoglContext *context)
/* Both GLES 1.1 and GLES 2.0 support point sprites in core */ /* Both GLES 1.1 and GLES 2.0 support point sprites in core */
flags |= COGL_FEATURE_POINT_SPRITE; flags |= COGL_FEATURE_POINT_SPRITE;
initialize_function_table (context);
for (i = 0; i < G_N_ELEMENTS (cogl_feature_data); i++) for (i = 0; i < G_N_ELEMENTS (cogl_feature_data); i++)
if (_cogl_feature_check ("GL", cogl_feature_data + i, if (_cogl_feature_check (_cogl_context_get_winsys (context),
"GL", cogl_feature_data + i,
0, 0, 0, 0,
gl_extensions, gl_extensions,
context)) context))

View File

@ -195,22 +195,6 @@ _cogl_winsys_get_proc_address (const char *name)
return (CoglFuncPtr) eglGetProcAddress (name); return (CoglFuncPtr) eglGetProcAddress (name);
} }
#undef COGL_WINSYS_FEATURE_BEGIN
#define COGL_WINSYS_FEATURE_BEGIN(a, b, c, d, e, f)
#undef COGL_WINSYS_FEATURE_FUNCTION
#define COGL_WINSYS_FEATURE_FUNCTION(ret, name, args) \
egl_renderer->pf_ ## name = NULL;
#undef COGL_WINSYS_FEATURE_END
#define COGL_WINSYS_FEATURE_END()
static void
initialize_function_table (CoglRenderer *renderer)
{
CoglRendererEGL *egl_renderer = renderer->winsys;
#include "cogl-winsys-egl-feature-functions.h"
}
#ifdef COGL_HAS_EGL_PLATFORM_ANDROID_SUPPORT #ifdef COGL_HAS_EGL_PLATFORM_ANDROID_SUPPORT
static ANativeWindow *android_native_window; static ANativeWindow *android_native_window;
@ -494,10 +478,9 @@ update_winsys_features (CoglContext *context)
TRUE); TRUE);
#endif #endif
initialize_function_table (context->display->renderer);
for (i = 0; i < G_N_ELEMENTS (winsys_feature_data); i++) for (i = 0; i < G_N_ELEMENTS (winsys_feature_data); i++)
if (_cogl_feature_check ("EGL", winsys_feature_data + i, 0, 0, if (_cogl_feature_check (_cogl_context_get_winsys (context),
"EGL", winsys_feature_data + i, 0, 0,
egl_extensions, egl_extensions,
egl_renderer)) egl_renderer))
{ {

View File

@ -178,22 +178,6 @@ _cogl_winsys_get_proc_address (const char *name)
return NULL; return NULL;
} }
#undef COGL_WINSYS_FEATURE_BEGIN
#define COGL_WINSYS_FEATURE_BEGIN(a, b, c, d, e, f)
#undef COGL_WINSYS_FEATURE_FUNCTION
#define COGL_WINSYS_FEATURE_FUNCTION(ret, name, args) \
glx_renderer->pf_ ## name = NULL;
#undef COGL_WINSYS_FEATURE_END
#define COGL_WINSYS_FEATURE_END()
static void
initialize_function_table (CoglRenderer *renderer)
{
CoglRendererGLX *glx_renderer = renderer->winsys;
#include "cogl-winsys-glx-feature-functions.h"
}
static CoglOnscreen * static CoglOnscreen *
find_onscreen_for_xid (CoglContext *context, guint32 xid) find_onscreen_for_xid (CoglContext *context, guint32 xid)
{ {
@ -361,10 +345,9 @@ update_winsys_features (CoglContext *context)
COGL_WINSYS_FEATURE_MULTIPLE_ONSCREEN, COGL_WINSYS_FEATURE_MULTIPLE_ONSCREEN,
TRUE); TRUE);
initialize_function_table (context->display->renderer);
for (i = 0; i < G_N_ELEMENTS (winsys_feature_data); i++) for (i = 0; i < G_N_ELEMENTS (winsys_feature_data); i++)
if (_cogl_feature_check ("GLX", winsys_feature_data + i, 0, 0, if (_cogl_feature_check (_cogl_context_get_winsys (context),
"GLX", winsys_feature_data + i, 0, 0,
glx_extensions, glx_extensions,
glx_renderer)) glx_renderer))
{ {

View File

@ -154,4 +154,8 @@ typedef struct _CoglWinsysVtable
gboolean gboolean
_cogl_winsys_has_feature (CoglWinsysFeature feature); _cogl_winsys_has_feature (CoglWinsysFeature feature);
CoglFuncPtr
_cogl_get_proc_address (const CoglWinsysVtable *winsys,
const char *name);
#endif /* __COGL_WINSYS_PRIVATE_H */ #endif /* __COGL_WINSYS_PRIVATE_H */

View File

@ -566,7 +566,8 @@ update_winsys_features (CoglContext *context)
COGL_NOTE (WINSYS, " WGL Extensions: %s", wgl_extensions); COGL_NOTE (WINSYS, " WGL Extensions: %s", wgl_extensions);
for (i = 0; i < G_N_ELEMENTS (winsys_feature_data); i++) for (i = 0; i < G_N_ELEMENTS (winsys_feature_data); i++)
if (_cogl_feature_check ("WGL", winsys_feature_data + i, 0, 0, if (_cogl_feature_check (_cogl_context_get_winsys (context),
"WGL", winsys_feature_data + i, 0, 0,
wgl_extensions, wgl_extensions,
wgl_renderer)) wgl_renderer))
{ {

View File

@ -29,6 +29,8 @@
#include "cogl.h" #include "cogl.h"
#include "cogl-context-private.h" #include "cogl-context-private.h"
#include <gmodule.h>
GQuark GQuark
_cogl_winsys_error_quark (void) _cogl_winsys_error_quark (void)
{ {
@ -43,3 +45,32 @@ _cogl_winsys_has_feature (CoglWinsysFeature feature)
return COGL_FLAGS_GET (ctx->winsys_features, feature); return COGL_FLAGS_GET (ctx->winsys_features, feature);
} }
/* XXX: we would call this _cogl_winsys_get_proc_address but that
* currently collides with the per winsys implementation names we use.
* */
CoglFuncPtr
_cogl_get_proc_address (const CoglWinsysVtable *winsys,
const char *name)
{
void *address = winsys->get_proc_address (name);
static GModule *module = NULL;
if (address)
return address;
/* this should find the right function if the program is linked against a
* library providing it */
if (G_UNLIKELY (module == NULL))
module = g_module_open (NULL, 0);
if (module)
{
gpointer symbol;
if (g_module_symbol (module, name, &symbol))
return symbol;
}
return NULL;
}