From 498937083e014b4ecf412f4b35882dc7b6ff2316 Mon Sep 17 00:00:00 2001 From: Robert Bragg Date: Thu, 26 Apr 2012 12:18:56 +0100 Subject: [PATCH] Adds gles2-context renderer constraint This adds a new renderer constraint enum: COGL_RENDERER_CONSTRAINT_SUPPORTS_GLES2_CONTEXT that can be used by applications to ensure the renderer they connect to has support for creating a GLES2 context via cogl_gles2_context_new(). The cogl-gles2-context and cogl-gles2-gears examples and the conformance tests have been updated to use this constraint. Reviewed-by: Neil Roberts (cherry picked from commit ed61463d7194354b26624e8014859f0fbfc06a12) --- cogl/cogl-renderer.c | 47 +++++++++++++++++++++++++++---- cogl/cogl-renderer.h | 7 ++++- cogl/cogl-types.h | 3 +- cogl/winsys/cogl-winsys-egl.c | 3 +- examples/cogl-gles2-context.c | 8 +++++- examples/cogl-gles2-gears.c | 8 +++++- tests/conform/test-conform-main.c | 2 +- tests/conform/test-utils.c | 6 ++++ tests/conform/test-utils.h | 11 ++++---- 9 files changed, 79 insertions(+), 16 deletions(-) diff --git a/cogl/cogl-renderer.c b/cogl/cogl-renderer.c index 74fc35df7..fa84625ff 100644 --- a/cogl/cogl-renderer.c +++ b/cogl/cogl-renderer.c @@ -241,10 +241,25 @@ _cogl_renderer_choose_driver (CoglRenderer *renderer, { const char *driver_name = g_getenv ("COGL_DRIVER"); const char *libgl_name; + CoglBool support_gles2_constraint = FALSE; + GList *l; if (!driver_name) driver_name = _cogl_config_driver; + for (l = renderer->constraints; l; l = l->next) + { + CoglRendererConstraint constraint = GPOINTER_TO_UINT (l->data); + if (constraint == COGL_RENDERER_CONSTRAINT_SUPPORTS_COGL_GLES2) + { + support_gles2_constraint = TRUE; + + if (!driver_name && renderer->driver_override == COGL_DRIVER_ANY) + renderer->driver_override = COGL_DRIVER_GLES2; + break; + } + } + #ifdef HAVE_COGL_GL if (renderer->driver_override == COGL_DRIVER_GL || (renderer->driver_override == COGL_DRIVER_ANY && @@ -284,7 +299,17 @@ _cogl_renderer_choose_driver (CoglRenderer *renderer, "No suitable driver found"); return FALSE; - found: +found: + + if (support_gles2_constraint && + renderer->driver != COGL_DRIVER_GLES2) + { + g_set_error (error, + COGL_RENDERER_ERROR, + COGL_RENDERER_ERROR_BAD_CONSTRAINT, + "No suitable driver found"); + return FALSE; + } #ifndef HAVE_DIRECTLY_LINKED_GL_LIBRARY @@ -312,6 +337,7 @@ cogl_renderer_connect (CoglRenderer *renderer, GError **error) { int i; GString *error_message; + CoglBool constraints_failed = FALSE; if (renderer->connected) return TRUE; @@ -328,7 +354,7 @@ cogl_renderer_connect (CoglRenderer *renderer, GError **error) const CoglWinsysVtable *winsys = _cogl_winsys_vtable_getters[i](); GError *tmp_error = NULL; GList *l; - CoglBool constraints_failed = FALSE; + CoglBool skip_due_to_constraints = FALSE; if (renderer->winsys_id_override != COGL_WINSYS_ID_ANY) { @@ -350,12 +376,15 @@ cogl_renderer_connect (CoglRenderer *renderer, GError **error) CoglRendererConstraint constraint = GPOINTER_TO_UINT (l->data); if (!(winsys->constraints & constraint)) { - constraints_failed = TRUE; + skip_due_to_constraints = TRUE; break; } } - if (constraints_failed) - continue; + if (skip_due_to_constraints) + { + constraints_failed |= TRUE; + continue; + } /* At least temporarily we will associate this winsys with * the renderer in-case ->renderer_connect calls API that @@ -378,6 +407,14 @@ cogl_renderer_connect (CoglRenderer *renderer, GError **error) if (!renderer->connected) { + if (constraints_failed) + { + g_set_error (error, COGL_RENDERER_ERROR, + COGL_RENDERER_ERROR_BAD_CONSTRAINT, + "Failed to connected to any renderer due to constraints"); + return FALSE; + } + renderer->winsys_vtable = NULL; g_set_error (error, COGL_WINSYS_ERROR, COGL_WINSYS_ERROR_INIT, diff --git a/cogl/cogl-renderer.h b/cogl/cogl-renderer.h index d67704fce..98fb05c98 100644 --- a/cogl/cogl-renderer.h +++ b/cogl/cogl-renderer.h @@ -261,6 +261,10 @@ cogl_renderer_connect (CoglRenderer *renderer, GError **error); * @COGL_RENDERER_CONSTRAINT_USES_XLIB: Require the renderer to be X11 * based and use Xlib * @COGL_RENDERER_CONSTRAINT_USES_EGL: Require the renderer to be EGL based + * @COGL_RENDERER_CONSTRAINT_SUPPORTS_COGL_GLES2: Require that the + * renderer supports creating a #CoglGLES2Context via + * cogl_gles2_context_new(). This can be used to integrate GLES 2.0 + * code into Cogl based applications. * * These constraint flags are hard-coded features of the different renderer * backends. Sometimes a platform may support multiple rendering options which @@ -281,7 +285,8 @@ typedef enum { COGL_RENDERER_CONSTRAINT_USES_X11 = (1 << 0), COGL_RENDERER_CONSTRAINT_USES_XLIB = (1 << 1), - COGL_RENDERER_CONSTRAINT_USES_EGL = (1 << 2) + COGL_RENDERER_CONSTRAINT_USES_EGL = (1 << 2), + COGL_RENDERER_CONSTRAINT_SUPPORTS_COGL_GLES2 = (1 << 3) } CoglRendererConstraint; diff --git a/cogl/cogl-types.h b/cogl/cogl-types.h index d3a072490..120fff90b 100644 --- a/cogl/cogl-types.h +++ b/cogl/cogl-types.h @@ -737,7 +737,8 @@ typedef enum typedef enum { /*< prefix=COGL_RENDERER_ERROR >*/ COGL_RENDERER_ERROR_NOT_FOUND, - COGL_RENDERER_ERROR_XLIB_DISPLAY_OPEN + COGL_RENDERER_ERROR_XLIB_DISPLAY_OPEN, + COGL_RENDERER_ERROR_BAD_CONSTRAINT } CoglRendererError; /* diff --git a/cogl/winsys/cogl-winsys-egl.c b/cogl/winsys/cogl-winsys-egl.c index b2413adc5..289bc808c 100644 --- a/cogl/winsys/cogl-winsys-egl.c +++ b/cogl/winsys/cogl-winsys-egl.c @@ -809,7 +809,8 @@ _cogl_winsys_restore_context (CoglContext *ctx) static CoglWinsysVtable _cogl_winsys_vtable = { - .constraints = COGL_RENDERER_CONSTRAINT_USES_EGL, + .constraints = COGL_RENDERER_CONSTRAINT_USES_EGL | + COGL_RENDERER_CONSTRAINT_SUPPORTS_COGL_GLES2, /* This winsys is only used as a base for the EGL-platform winsys's so it does not have an ID or a name */ diff --git a/examples/cogl-gles2-context.c b/examples/cogl-gles2-context.c index c25b73d5e..408852ab7 100644 --- a/examples/cogl-gles2-context.c +++ b/examples/cogl-gles2-context.c @@ -79,8 +79,14 @@ main (int argc, char **argv) }; GSource *cogl_source; GMainLoop *loop; + CoglRenderer *renderer; + CoglDisplay *display; - data.ctx = cogl_context_new (NULL, NULL); + renderer = cogl_renderer_new (); + cogl_renderer_add_constraint (renderer, + COGL_RENDERER_CONSTRAINT_SUPPORTS_COGL_GLES2); + display = cogl_display_new (renderer, NULL); + data.ctx = cogl_context_new (display, NULL); onscreen = cogl_onscreen_new (data.ctx, 640, 480); cogl_onscreen_show (onscreen); diff --git a/examples/cogl-gles2-gears.c b/examples/cogl-gles2-gears.c index f77e550fd..2952ca6dc 100644 --- a/examples/cogl-gles2-gears.c +++ b/examples/cogl-gles2-gears.c @@ -758,8 +758,14 @@ main (int argc, char **argv) GError *error = NULL; GSource *cogl_source; GMainLoop *loop; + CoglRenderer *renderer; + CoglDisplay *display; - data.ctx = cogl_context_new (NULL, NULL); + renderer = cogl_renderer_new (); + cogl_renderer_add_constraint (renderer, + COGL_RENDERER_CONSTRAINT_SUPPORTS_COGL_GLES2); + display = cogl_display_new (renderer, NULL); + data.ctx = cogl_context_new (display, NULL); onscreen = cogl_onscreen_new (data.ctx, 300, 300); cogl_onscreen_show (onscreen); diff --git a/tests/conform/test-conform-main.c b/tests/conform/test-conform-main.c index 72e22c774..5b38aa164 100644 --- a/tests/conform/test-conform-main.c +++ b/tests/conform/test-conform-main.c @@ -99,7 +99,7 @@ main (int argc, char **argv) UNPORTED_TEST (test_viewport); - ADD_TEST (test_gles2_context, 0); + ADD_TEST (test_gles2_context, TEST_REQUIREMENT_GLES2_CONTEXT); g_printerr ("Unknown test name \"%s\"\n", argv[1]); diff --git a/tests/conform/test-utils.c b/tests/conform/test-utils.c index 10015ec0e..e712d14a0 100644 --- a/tests/conform/test-utils.c +++ b/tests/conform/test-utils.c @@ -76,6 +76,12 @@ test_utils_init (TestFlags flags) missing_requirement = TRUE; } + if (flags & TEST_REQUIREMENT_GLES2_CONTEXT && + !cogl_has_feature (ctx, COGL_FEATURE_ID_GLES2_CONTEXT)) + { + missing_requirement = TRUE; + } + if (flags & TEST_KNOWN_FAILURE) { missing_requirement = TRUE; diff --git a/tests/conform/test-utils.h b/tests/conform/test-utils.h index 1e15edea3..6fcdca1e7 100644 --- a/tests/conform/test-utils.h +++ b/tests/conform/test-utils.h @@ -9,11 +9,12 @@ typedef enum _TestFlags { - TEST_KNOWN_FAILURE = 1<<0, - TEST_REQUIREMENT_GL = 1<<1, - TEST_REQUIREMENT_NPOT = 1<<2, - TEST_REQUIREMENT_TEXTURE_3D = 1<<3, - TEST_REQUIREMENT_POINT_SPRITE = 1<<4 + TEST_KNOWN_FAILURE = 1<<0, + TEST_REQUIREMENT_GL = 1<<1, + TEST_REQUIREMENT_NPOT = 1<<2, + TEST_REQUIREMENT_TEXTURE_3D = 1<<3, + TEST_REQUIREMENT_POINT_SPRITE = 1<<4, + TEST_REQUIREMENT_GLES2_CONTEXT = 1<<5 } TestFlags; extern CoglContext *ctx;