[Cogl] [PATCH v2 5/5] Adds gles2-context renderer constraint

Robert Bragg robert at sixbynine.org
Mon May 14 15:02:21 PDT 2012


From: Robert Bragg <robert at linux.intel.com>

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.
---
 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     |   10 ++++++-
 examples/cogl-gles2-gears.c       |   10 ++++++-
 tests/conform/test-conform-main.c |    2 +-
 tests/conform/test-utils.c        |    6 ++++
 tests/conform/test-utils.h        |   11 ++++----
 9 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/cogl/cogl-renderer.c b/cogl/cogl-renderer.c
index 74fc35d..fa84625 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 d67704f..98fb05c 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 fd4f9bd..f5cb976 100644
--- a/cogl/cogl-types.h
+++ b/cogl/cogl-types.h
@@ -685,7 +685,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 b2413ad..289bc80 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 c25b73d..408852a 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;
-
-    data.ctx = cogl_context_new (NULL, NULL);
+    CoglRenderer *renderer;
+    CoglDisplay *display;
+
+    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 f77e550..2952ca6 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;
-
-    data.ctx = cogl_context_new (NULL, NULL);
+    CoglRenderer *renderer;
+    CoglDisplay *display;
+
+    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 7702791..4b9f009 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 00ae9a3..5a6e52f 100644
--- a/tests/conform/test-utils.c
+++ b/tests/conform/test-utils.c
@@ -75,6 +75,12 @@ test_utils_init (TestFlags flags)
       missing_requirement = TRUE;
     }
 
+  if (flags & TEST_REQUIREMENT_GLES2_CONTEXT &&
+      !cogl_has_feature (test_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 21141e7..7753995 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 *test_ctx;
-- 
1.7.7.6



More information about the Cogl mailing list