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"
gboolean
_cogl_feature_check (const char *driver_prefix,
_cogl_feature_check (const CoglWinsysVtable *winsys,
const char *driver_prefix,
const CoglFeatureData *data,
unsigned int gl_major,
unsigned int gl_minor,
@ -44,8 +45,6 @@ _cogl_feature_check (const char *driver_prefix,
const char *suffix = NULL;
int func_num;
_COGL_GET_CONTEXT (ctx, FALSE);
/* First check whether the functions should be directly provided by
GL */
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
give up */
if (suffix == NULL)
return FALSE;
goto error;
/* Try to get all of the entry points */
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,
suffix, NULL);
func = cogl_get_proc_address (full_function_name);
func = _cogl_get_proc_address (winsys, full_function_name);
g_free (full_function_name);
if (func == NULL)
break;
goto error;
/* Set the function pointer in the context */
*(void **) ((guint8 *) function_table +
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
_cogl_feature_check (const char *driver_prefix,
_cogl_feature_check (const CoglWinsysVtable *winsys,
const char *driver_prefix,
const CoglFeatureData *data,
unsigned int gl_major,
unsigned int gl_minor,

View File

@ -30,7 +30,6 @@
#include <string.h>
#include <math.h>
#include <stdlib.h>
#include <gmodule.h>
#include "cogl-debug.h"
#include "cogl-internal.h"
@ -93,32 +92,13 @@ cogl_gl_error_to_string (GLenum error_code)
CoglFuncPtr
cogl_get_proc_address (const char* name)
{
void *address;
static GModule *module = NULL;
const CoglWinsysVtable *winsys;
_COGL_GET_CONTEXT (ctx, NULL);
winsys = _cogl_context_get_winsys (ctx);
address = winsys->get_proc_address (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;
return _cogl_get_proc_address (winsys, name);
}
gboolean

View File

@ -148,20 +148,6 @@ static const CoglFeatureData cogl_feature_data[] =
#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
* pointers. Theoretically the list of extensions can change for
* 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)
flags |= COGL_FEATURE_FOUR_CLIP_PLANES;
initialize_function_table (context);
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_extensions,
context))

View File

@ -70,20 +70,6 @@ static const CoglFeatureData cogl_feature_data[] =
#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
* pointers. Theoretically the list of extensions can change for
* 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 */
flags |= COGL_FEATURE_POINT_SPRITE;
initialize_function_table (context);
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,
gl_extensions,
context))

View File

@ -195,22 +195,6 @@ _cogl_winsys_get_proc_address (const char *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
static ANativeWindow *android_native_window;
@ -494,10 +478,9 @@ update_winsys_features (CoglContext *context)
TRUE);
#endif
initialize_function_table (context->display->renderer);
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_renderer))
{

View File

@ -178,22 +178,6 @@ _cogl_winsys_get_proc_address (const char *name)
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 *
find_onscreen_for_xid (CoglContext *context, guint32 xid)
{
@ -361,10 +345,9 @@ update_winsys_features (CoglContext *context)
COGL_WINSYS_FEATURE_MULTIPLE_ONSCREEN,
TRUE);
initialize_function_table (context->display->renderer);
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_renderer))
{

View File

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

View File

@ -566,7 +566,8 @@ update_winsys_features (CoglContext *context)
COGL_NOTE (WINSYS, " WGL Extensions: %s", wgl_extensions);
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_renderer))
{

View File

@ -29,6 +29,8 @@
#include "cogl.h"
#include "cogl-context-private.h"
#include <gmodule.h>
GQuark
_cogl_winsys_error_quark (void)
{
@ -43,3 +45,32 @@ _cogl_winsys_has_feature (CoglWinsysFeature 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;
}