egl: Check EGL extension as early as possible

Instead of waiting until initializing a CoglContext we now check EGL
extensions after calling eglInitialize.
This commit is contained in:
Robert Bragg 2011-05-24 17:21:28 +01:00
parent be15bf75e4
commit 52aada8442
3 changed files with 49 additions and 37 deletions

View File

@ -61,8 +61,9 @@ struct _CoglFeatureData
const char *extension_names; const char *extension_names;
/* A set of feature flags to enable if the extension is available */ /* A set of feature flags to enable if the extension is available */
CoglFeatureFlags feature_flags; CoglFeatureFlags feature_flags;
/* FIXME: This is now unused */ /* A set of private feature flags to enable if the extension is
int padding_feature_flags_private; * available */
int feature_flags_private;
/* An optional corresponding winsys feature. */ /* An optional corresponding winsys feature. */
CoglWinsysFeature winsys_feature; CoglWinsysFeature winsys_feature;
/* A list of functions required for this feature. Terminated with a /* A list of functions required for this feature. Terminated with a

View File

@ -28,9 +28,7 @@
/* Macro prototypes: /* Macro prototypes:
* COGL_WINSYS_FEATURE_BEGIN (name, namespaces, extension_names, * COGL_WINSYS_FEATURE_BEGIN (name, namespaces, extension_names,
* implied_public_feature_flags, * implied_private_egl_feature_flags)
* implied_private_feature_flags,
* implied_winsys_feature)
* COGL_WINSYS_FEATURE_FUNCTION (return_type, function_name, * COGL_WINSYS_FEATURE_FUNCTION (return_type, function_name,
* (arguments)) * (arguments))
* ... * ...
@ -46,9 +44,7 @@
COGL_WINSYS_FEATURE_BEGIN (swap_region, COGL_WINSYS_FEATURE_BEGIN (swap_region,
"NOK\0", "NOK\0",
"swap_region\0", "swap_region\0",
0, COGL_EGL_WINSYS_FEATURE_SWAP_REGION)
0,
COGL_WINSYS_FEATURE_SWAP_REGION)
COGL_WINSYS_FEATURE_FUNCTION (EGLBoolean, eglSwapBuffersRegion, COGL_WINSYS_FEATURE_FUNCTION (EGLBoolean, eglSwapBuffersRegion,
(EGLDisplay dpy, (EGLDisplay dpy,
EGLSurface surface, EGLSurface surface,

View File

@ -65,12 +65,21 @@
#define COGL_ONSCREEN_X11_EVENT_MASK StructureNotifyMask #define COGL_ONSCREEN_X11_EVENT_MASK StructureNotifyMask
#endif #endif
typedef enum _CoglEGLWinsysFeature
{
COGL_EGL_WINSYS_FEATURE_SWAP_REGION =1L<<0,
COGL_EGL_WINSYS_FEATURE_EGL_IMAGE_FROM_X11_PIXMAP =1L<<1,
COGL_EGL_WINSYS_FEATURE_EGL_IMAGE_FROM_WAYLAND_BUFFER =1L<<2
} CoglEGLWinsysFeature;
typedef struct _CoglRendererEGL typedef struct _CoglRendererEGL
{ {
#ifdef COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT #ifdef COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT
CoglRendererXlib _parent; CoglRendererXlib _parent;
#endif #endif
CoglEGLWinsysFeature private_features;
#ifdef COGL_HAS_EGL_PLATFORM_WAYLAND_SUPPORT #ifdef COGL_HAS_EGL_PLATFORM_WAYLAND_SUPPORT
struct wl_display *wayland_display; struct wl_display *wayland_display;
struct wl_compositor *wayland_compositor; struct wl_compositor *wayland_compositor;
@ -87,7 +96,7 @@ typedef struct _CoglRendererEGL
#endif #endif
/* Function pointers for GLX specific extensions */ /* Function pointers for GLX specific extensions */
#define COGL_WINSYS_FEATURE_BEGIN(a, b, c, d, e, f) #define COGL_WINSYS_FEATURE_BEGIN(a, b, c, d)
#define COGL_WINSYS_FEATURE_FUNCTION(ret, name, args) \ #define COGL_WINSYS_FEATURE_FUNCTION(ret, name, args) \
ret (APIENTRY * pf_ ## name) args; ret (APIENTRY * pf_ ## name) args;
@ -159,8 +168,7 @@ typedef struct _CoglOnscreenEGL
/* Define a set of arrays containing the functions required from GL /* Define a set of arrays containing the functions required from GL
for each winsys feature */ for each winsys feature */
#define COGL_WINSYS_FEATURE_BEGIN(name, namespaces, extension_names, \ #define COGL_WINSYS_FEATURE_BEGIN(name, namespaces, extension_names, \
feature_flags, feature_flags_private, \ egl_private_flags) \
winsys_feature) \
static const CoglFeatureFunction \ static const CoglFeatureFunction \
cogl_egl_feature_ ## name ## _funcs[] = { cogl_egl_feature_ ## name ## _funcs[] = {
#define COGL_WINSYS_FEATURE_FUNCTION(ret, name, args) \ #define COGL_WINSYS_FEATURE_FUNCTION(ret, name, args) \
@ -173,11 +181,10 @@ typedef struct _CoglOnscreenEGL
/* Define an array of features */ /* Define an array of features */
#undef COGL_WINSYS_FEATURE_BEGIN #undef COGL_WINSYS_FEATURE_BEGIN
#define COGL_WINSYS_FEATURE_BEGIN(name, namespaces, extension_names, \ #define COGL_WINSYS_FEATURE_BEGIN(name, namespaces, extension_names, \
feature_flags, feature_flags_private, \ egl_private_flags) \
winsys_feature) \
{ 255, 255, namespaces, extension_names, \ { 255, 255, namespaces, extension_names, \
feature_flags, feature_flags_private, \ 0, egl_private_flags, \
winsys_feature, \ 0, \
cogl_egl_feature_ ## name ## _funcs }, cogl_egl_feature_ ## name ## _funcs },
#undef COGL_WINSYS_FEATURE_FUNCTION #undef COGL_WINSYS_FEATURE_FUNCTION
#define COGL_WINSYS_FEATURE_FUNCTION(ret, name, args) #define COGL_WINSYS_FEATURE_FUNCTION(ret, name, args)
@ -314,6 +321,31 @@ force_roundtrip(struct wl_display *display)
} }
#endif #endif
/* Updates all the function pointers */
static void
check_egl_extensions (CoglRenderer *renderer)
{
CoglRendererEGL *egl_renderer = renderer->winsys;
const CoglWinsysVtable *winsys = renderer->winsys_vtable;
const char *egl_extensions;
int i;
egl_extensions = eglQueryString (egl_renderer->edpy, EGL_EXTENSIONS);
COGL_NOTE (WINSYS, " EGL Extensions: %s", egl_extensions);
egl_renderer->private_features = 0;
for (i = 0; i < G_N_ELEMENTS (winsys_feature_data); i++)
if (_cogl_feature_check (winsys,
"EGL", winsys_feature_data + i, 0, 0,
egl_extensions,
egl_renderer))
{
egl_renderer->private_features |=
winsys_feature_data[0].feature_flags_private;
}
}
static gboolean static gboolean
_cogl_winsys_renderer_connect (CoglRenderer *renderer, _cogl_winsys_renderer_connect (CoglRenderer *renderer,
GError **error) GError **error)
@ -445,6 +477,8 @@ _cogl_winsys_renderer_connect (CoglRenderer *renderer,
gdl_close (); gdl_close ();
#endif #endif
check_egl_extensions (renderer);
return TRUE; return TRUE;
error: error:
@ -457,18 +491,14 @@ update_winsys_features (CoglContext *context)
{ {
CoglDisplayEGL *egl_display = context->display->winsys; CoglDisplayEGL *egl_display = context->display->winsys;
CoglRendererEGL *egl_renderer = context->display->renderer->winsys; CoglRendererEGL *egl_renderer = context->display->renderer->winsys;
const char *egl_extensions;
int i;
g_return_if_fail (egl_display->egl_context); g_return_if_fail (egl_display->egl_context);
_cogl_gl_update_features (context);
memset (context->winsys_features, 0, sizeof (context->winsys_features)); memset (context->winsys_features, 0, sizeof (context->winsys_features));
egl_extensions = eglQueryString (egl_renderer->edpy, EGL_EXTENSIONS); check_egl_extensions (context->display->renderer);
COGL_NOTE (WINSYS, " EGL Extensions: %s", egl_extensions); _cogl_gl_update_features (context);
#if defined (COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT) || \ #if defined (COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT) || \
defined (COGL_HAS_EGL_PLATFORM_WAYLAND_SUPPORT) defined (COGL_HAS_EGL_PLATFORM_WAYLAND_SUPPORT)
@ -478,22 +508,7 @@ update_winsys_features (CoglContext *context)
TRUE); TRUE);
#endif #endif
for (i = 0; i < G_N_ELEMENTS (winsys_feature_data); i++) if (egl_renderer->private_features & COGL_EGL_WINSYS_FEATURE_SWAP_REGION)
if (_cogl_feature_check (_cogl_context_get_winsys (context),
"EGL", winsys_feature_data + i, 0, 0,
egl_extensions,
egl_renderer))
{
context->feature_flags |= winsys_feature_data[i].feature_flags;
if (winsys_feature_data[i].winsys_feature)
COGL_FLAGS_SET (context->winsys_features,
winsys_feature_data[i].winsys_feature,
TRUE);
}
/* FIXME: the winsys_feature_data can currently only have one
* winsys feature per extension... */
if (egl_renderer->pf_eglSwapBuffersRegion)
{ {
COGL_FLAGS_SET (context->winsys_features, COGL_FLAGS_SET (context->winsys_features,
COGL_WINSYS_FEATURE_SWAP_REGION, TRUE); COGL_WINSYS_FEATURE_SWAP_REGION, TRUE);