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
the function pointers back to NULL so that the rest of Cogl can
safely do feature testing by just looking at the function
pointers */
if (data->functions[func_num].name)
{
while (func_num-- > 0)
*(void **) ((guint8 *) ctx +
data->functions[func_num].pointer_offset) = NULL;
return FALSE;
}
else
return TRUE; return TRUE;
/* If the extension isn't found or one of the functions wasn't found
* then set all of the functions pointers to NULL so Cogl can safely
* do feature testing by just looking at the function pointers */
error:
for (func_num = 0; data->functions[func_num].name; func_num++)
*(void **) ((guint8 *) function_table +
data->functions[func_num].pointer_offset) = NULL;
return FALSE;
} }

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;
}