From be15bf75e44bcab213e840f26b0347f6eb50f393 Mon Sep 17 00:00:00 2001 From: Robert Bragg Date: Tue, 24 May 2011 01:38:48 +0100 Subject: [PATCH] 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. --- cogl/cogl-feature-private.c | 35 ++++++++++++++----------------- cogl/cogl-feature-private.h | 3 ++- cogl/cogl.c | 22 +------------------ cogl/driver/gl/cogl-gl.c | 19 ++--------------- cogl/driver/gles/cogl-gles.c | 19 ++--------------- cogl/winsys/cogl-winsys-egl.c | 21 ++----------------- cogl/winsys/cogl-winsys-glx.c | 21 ++----------------- cogl/winsys/cogl-winsys-private.h | 4 ++++ cogl/winsys/cogl-winsys-wgl.c | 3 ++- cogl/winsys/cogl-winsys.c | 31 +++++++++++++++++++++++++++ 10 files changed, 64 insertions(+), 114 deletions(-) diff --git a/cogl/cogl-feature-private.c b/cogl/cogl-feature-private.c index d3904b489..1b60afd7c 100644 --- a/cogl/cogl-feature-private.c +++ b/cogl/cogl-feature-private.c @@ -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; } diff --git a/cogl/cogl-feature-private.h b/cogl/cogl-feature-private.h index 5d0101e40..5b26b708d 100644 --- a/cogl/cogl-feature-private.h +++ b/cogl/cogl-feature-private.h @@ -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, diff --git a/cogl/cogl.c b/cogl/cogl.c index 896b2e66e..07cc76da4 100644 --- a/cogl/cogl.c +++ b/cogl/cogl.c @@ -30,7 +30,6 @@ #include #include #include -#include #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 diff --git a/cogl/driver/gl/cogl-gl.c b/cogl/driver/gl/cogl-gl.c index c738806af..ce81a6ac4 100644 --- a/cogl/driver/gl/cogl-gl.c +++ b/cogl/driver/gl/cogl-gl.c @@ -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)) diff --git a/cogl/driver/gles/cogl-gles.c b/cogl/driver/gles/cogl-gles.c index 09d038281..080efeb61 100644 --- a/cogl/driver/gles/cogl-gles.c +++ b/cogl/driver/gles/cogl-gles.c @@ -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)) diff --git a/cogl/winsys/cogl-winsys-egl.c b/cogl/winsys/cogl-winsys-egl.c index 49b1965a2..d9da042ed 100644 --- a/cogl/winsys/cogl-winsys-egl.c +++ b/cogl/winsys/cogl-winsys-egl.c @@ -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)) { diff --git a/cogl/winsys/cogl-winsys-glx.c b/cogl/winsys/cogl-winsys-glx.c index 412f8fe89..74a366834 100644 --- a/cogl/winsys/cogl-winsys-glx.c +++ b/cogl/winsys/cogl-winsys-glx.c @@ -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)) { diff --git a/cogl/winsys/cogl-winsys-private.h b/cogl/winsys/cogl-winsys-private.h index 2208a86bc..a8aaf90c6 100644 --- a/cogl/winsys/cogl-winsys-private.h +++ b/cogl/winsys/cogl-winsys-private.h @@ -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 */ diff --git a/cogl/winsys/cogl-winsys-wgl.c b/cogl/winsys/cogl-winsys-wgl.c index 8c2cb7efe..9eb9e8769 100644 --- a/cogl/winsys/cogl-winsys-wgl.c +++ b/cogl/winsys/cogl-winsys-wgl.c @@ -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)) { diff --git a/cogl/winsys/cogl-winsys.c b/cogl/winsys/cogl-winsys.c index 547ea5a59..e75b906ff 100644 --- a/cogl/winsys/cogl-winsys.c +++ b/cogl/winsys/cogl-winsys.c @@ -29,6 +29,8 @@ #include "cogl.h" #include "cogl-context-private.h" +#include + 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; +}