[cogl] Use COGL_FLAGS_* for the context's private feature flags



commit d94cb984e3c93630f3c2e6e3be9d189672aa20f3
Author: Neil Roberts <neil linux intel com>
Date:   Mon Nov 25 16:11:36 2013 +0000

    Use COGL_FLAGS_* for the context's private feature flags
    
    Previously the private feature flags were stored in an enum and we
    already had 31 flags. Adding the 32nd flag would presumably make it
    add -2³¹ as one of the values which might cause problems. To avoid
    this we'll just use an fixed-size array of longs and use indices for
    the enum values like we do for the public features.
    
    A slight complication with this is in the CoglDriverDescription where
    we were previously using a static intialised value to describe the set
    of features that the driver supports. We can't easily do this with the
    flags array so instead the features are stored in a fixed-size array
    of indices.
    
    Reviewed-by: Robert Bragg <robert linux intel com>

 cogl-pango/cogl-pango-display-list.c               |    2 +-
 cogl/cogl-bitmap-conversion.c                      |    4 +-
 cogl/cogl-blend-string.c                           |    4 +-
 cogl/cogl-blit.c                                   |    2 +-
 cogl/cogl-buffer.c                                 |    4 +-
 cogl/cogl-context-private.h                        |    4 +-
 cogl/cogl-context.c                                |   17 ++--
 cogl/cogl-framebuffer.c                            |    6 +-
 cogl/cogl-glsl-shader.c                            |    2 +-
 cogl/cogl-journal.c                                |    6 +-
 cogl/cogl-matrix-stack.c                           |    4 +-
 cogl/cogl-onscreen.c                               |    4 +-
 cogl/cogl-pipeline-state.c                         |    2 +-
 cogl/cogl-pipeline.c                               |    6 +-
 cogl/cogl-private.h                                |   71 +++++++++--------
 cogl/cogl-renderer-private.h                       |    3 +-
 cogl/cogl-renderer.c                               |   48 +++++++-----
 cogl/cogl-sampler-cache.c                          |    8 +-
 cogl/cogl-texture-2d.c                             |    7 +-
 cogl/cogl-texture-3d.c                             |    2 +-
 cogl/cogl-texture-rectangle.c                      |    4 +-
 cogl/cogl-texture.c                                |    2 +-
 cogl/driver/gl/cogl-attribute-gl.c                 |   12 ++--
 cogl/driver/gl/cogl-clip-stack-gl.c                |    2 +-
 cogl/driver/gl/cogl-framebuffer-gl.c               |   49 ++++++------
 cogl/driver/gl/cogl-pipeline-fragend-glsl.c        |    2 +-
 cogl/driver/gl/cogl-pipeline-opengl.c              |   26 +++---
 cogl/driver/gl/cogl-pipeline-progend-fixed.c       |    2 +-
 cogl/driver/gl/cogl-pipeline-progend-glsl.c        |   14 ++--
 cogl/driver/gl/cogl-pipeline-vertend-glsl.c        |   12 ++--
 cogl/driver/gl/cogl-texture-2d-gl.c                |    4 +-
 cogl/driver/gl/cogl-texture-gl.c                   |    2 +-
 cogl/driver/gl/gl/cogl-driver-gl.c                 |   81 ++++++++++++--------
 .../gl/gl/cogl-pipeline-progend-fixed-arbfp.c      |    4 +-
 cogl/driver/gl/gl/cogl-texture-driver-gl.c         |    8 +-
 cogl/driver/gl/gles/cogl-driver-gles.c             |   49 ++++++++-----
 cogl/driver/gl/gles/cogl-texture-driver-gles.c     |    6 +-
 cogl/driver/nop/cogl-driver-nop.c                  |    2 +-
 cogl/winsys/cogl-winsys-egl-wayland.c              |    4 +-
 cogl/winsys/cogl-winsys-egl-x11.c                  |    8 +-
 cogl/winsys/cogl-winsys-egl.c                      |    2 +-
 cogl/winsys/cogl-winsys-glx.c                      |    4 +-
 cogl/winsys/cogl-winsys-sdl.c                      |    4 +-
 cogl/winsys/cogl-winsys-sdl2.c                     |    4 +-
 cogl/winsys/cogl-winsys-wgl.c                      |    4 +-
 45 files changed, 291 insertions(+), 226 deletions(-)
---
diff --git a/cogl-pango/cogl-pango-display-list.c b/cogl-pango/cogl-pango-display-list.c
index f44d223..73cb3cf 100644
--- a/cogl-pango/cogl-pango-display-list.c
+++ b/cogl-pango/cogl-pango-display-list.c
@@ -356,7 +356,7 @@ emit_vertex_buffer_geometry (CoglFramebuffer *fb,
                                                  2 /* n_attributes */);
 
 #ifdef CLUTTER_COGL_HAS_GL
-      if ((ctx->private_feature_flags & COGL_PRIVATE_FEATURE_QUADS))
+      if (_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_QUADS))
         cogl_primitive_set_mode (prim, GL_QUADS);
       else
 #endif
diff --git a/cogl/cogl-bitmap-conversion.c b/cogl/cogl-bitmap-conversion.c
index 08606b6..d2527b4 100644
--- a/cogl/cogl-bitmap-conversion.c
+++ b/cogl/cogl-bitmap-conversion.c
@@ -529,8 +529,8 @@ _cogl_bitmap_convert_for_upload (CoglBitmap *src_bmp,
    * won't work correctly to convert to/from component-alpha
    * textures */
 
-  if ((ctx->private_feature_flags & COGL_PRIVATE_FEATURE_FORMAT_CONVERSION) &&
-      ((ctx->private_feature_flags & COGL_PRIVATE_FEATURE_ALPHA_TEXTURES) ||
+  if (_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_FORMAT_CONVERSION) &&
+      (_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_ALPHA_TEXTURES) ||
        (src_format != COGL_PIXEL_FORMAT_A_8 &&
         internal_format != COGL_PIXEL_FORMAT_A_8) ||
        src_format == internal_format))
diff --git a/cogl/cogl-blend-string.c b/cogl/cogl-blend-string.c
index f62e8c0..0d0d73b 100644
--- a/cogl/cogl-blend-string.c
+++ b/cogl/cogl-blend-string.c
@@ -245,8 +245,8 @@ validate_blend_statements (CoglBlendStringStatement *statements,
             goto error;
           }
 
-        if (!(ctx->private_feature_flags &
-              COGL_PRIVATE_FEATURE_BLEND_CONSTANT) &&
+        if (!_cogl_has_private_feature (ctx,
+                                        COGL_PRIVATE_FEATURE_BLEND_CONSTANT) &&
             arg->factor.is_color &&
             (arg->factor.source.info->type ==
              COGL_BLEND_STRING_COLOR_SOURCE_CONSTANT))
diff --git a/cogl/cogl-blit.c b/cogl/cogl-blit.c
index 09338de..f37e453 100644
--- a/cogl/cogl-blit.c
+++ b/cogl/cogl-blit.c
@@ -152,7 +152,7 @@ _cogl_blit_framebuffer_begin (CoglBlitData *data)
      format and the blit framebuffer extension is supported */
   if ((cogl_texture_get_format (data->src_tex) & ~COGL_A_BIT) !=
       (cogl_texture_get_format (data->dst_tex) & ~COGL_A_BIT) ||
-      !(ctx->private_feature_flags & COGL_PRIVATE_FEATURE_OFFSCREEN_BLIT))
+      !_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_OFFSCREEN_BLIT))
     return FALSE;
 
   dst_offscreen = _cogl_offscreen_new_with_texture_full
diff --git a/cogl/cogl-buffer.c b/cogl/cogl-buffer.c
index 4edfa54..a503637 100644
--- a/cogl/cogl-buffer.c
+++ b/cogl/cogl-buffer.c
@@ -129,13 +129,13 @@ _cogl_buffer_initialize (CoglBuffer *buffer,
   if (default_target == COGL_BUFFER_BIND_TARGET_PIXEL_PACK ||
       default_target == COGL_BUFFER_BIND_TARGET_PIXEL_UNPACK)
     {
-      if (!(ctx->private_feature_flags & COGL_PRIVATE_FEATURE_PBOS))
+      if (!_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_PBOS))
         use_malloc = TRUE;
     }
   else if (default_target == COGL_BUFFER_BIND_TARGET_ATTRIBUTE_BUFFER ||
            default_target == COGL_BUFFER_BIND_TARGET_INDEX_BUFFER)
     {
-      if (!(ctx->private_feature_flags & COGL_PRIVATE_FEATURE_VBOS))
+      if (!_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_VBOS))
         use_malloc = TRUE;
     }
 
diff --git a/cogl/cogl-context-private.h b/cogl/cogl-context-private.h
index 502740d..23245c2 100644
--- a/cogl/cogl-context-private.h
+++ b/cogl/cogl-context-private.h
@@ -52,6 +52,7 @@
 #include "cogl-onscreen-private.h"
 #include "cogl-fence-private.h"
 #include "cogl-poll-private.h"
+#include "cogl-private.h"
 
 typedef struct
 {
@@ -89,7 +90,8 @@ struct _CoglContext
 
   /* Features cache */
   unsigned long features[COGL_FLAGS_N_LONGS_FOR_SIZE (_COGL_N_FEATURE_IDS)];
-  CoglPrivateFeatureFlags private_feature_flags;
+  unsigned long private_features
+    [COGL_FLAGS_N_LONGS_FOR_SIZE (COGL_N_PRIVATE_FEATURES)];
 
   CoglBool needs_viewport_scissor_workaround;
   CoglFramebuffer *viewport_scissor_workaround_framebuffer;
diff --git a/cogl/cogl-context.c b/cogl/cogl-context.c
index 2a27b0c..e4453f9 100644
--- a/cogl/cogl-context.c
+++ b/cogl/cogl-context.c
@@ -78,13 +78,13 @@ static void
 _cogl_init_feature_overrides (CoglContext *ctx)
 {
   if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_DISABLE_VBOS)))
-    ctx->private_feature_flags &= ~COGL_PRIVATE_FEATURE_VBOS;
+    COGL_FLAGS_SET (ctx->private_features, COGL_PRIVATE_FEATURE_VBOS, FALSE);
 
   if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_DISABLE_PBOS)))
-    ctx->private_feature_flags &= ~COGL_PRIVATE_FEATURE_PBOS;
+    COGL_FLAGS_SET (ctx->private_features, COGL_PRIVATE_FEATURE_PBOS, FALSE);
 
   if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_DISABLE_ARBFP)))
-    ctx->private_feature_flags &= ~COGL_PRIVATE_FEATURE_ARBFP;
+    COGL_FLAGS_SET (ctx->private_features, COGL_PRIVATE_FEATURE_ARBFP, FALSE);
 
   if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_DISABLE_GLSL)))
     {
@@ -169,7 +169,7 @@ cogl_context_new (CoglDisplay *display,
 
   /* Init default values */
   memset (context->features, 0, sizeof (context->features));
-  context->private_feature_flags = 0;
+  memset (context->private_features, 0, sizeof (context->private_features));
 
   context->rectangle_state = COGL_WINSYS_RECTANGLE_STATE_UNKNOWN;
 
@@ -209,7 +209,8 @@ cogl_context_new (CoglDisplay *display,
   context->driver_vtable = display->renderer->driver_vtable;
   context->texture_driver = display->renderer->texture_driver;
 
-  context->private_feature_flags |= display->renderer->private_feature_flags;
+  for (i = 0; i < G_N_ELEMENTS (context->private_features); i++)
+    context->private_features[i] |= display->renderer->private_features[i];
 
   winsys = _cogl_context_get_winsys (context);
   if (!winsys->context_init (context, error))
@@ -272,7 +273,7 @@ cogl_context_new (CoglDisplay *display,
   context->texture_units =
     g_array_new (FALSE, FALSE, sizeof (CoglTextureUnit));
 
-  if ((context->private_feature_flags & COGL_PRIVATE_FEATURE_ANY_GL))
+  if (_cogl_has_private_feature (context, COGL_PRIVATE_FEATURE_ANY_GL))
     {
       /* See cogl-pipeline.c for more details about why we leave texture unit 1
        * active by default... */
@@ -348,7 +349,7 @@ cogl_context_new (CoglDisplay *display,
   context->blit_texture_pipeline = NULL;
 
 #if defined (HAVE_COGL_GL) || defined (HAVE_COGL_GLES)
-  if ((context->private_feature_flags & COGL_PRIVATE_FEATURE_ALPHA_TEST))
+  if (_cogl_has_private_feature (context, COGL_PRIVATE_FEATURE_ALPHA_TEST))
     /* The default for GL_ALPHA_TEST is to always pass which is equivalent to
      * the test being disabled therefore we assume that for all drivers there
      * will be no performance impact if we always leave the test enabled which
@@ -429,7 +430,7 @@ cogl_context_new (CoglDisplay *display,
      pipeline to track whether any layers have point sprite coords
      enabled. We don't need to do this for GL3 or GLES2 because point
      sprites are handled using a builtin varying in the shader. */
-  if ((context->private_feature_flags & COGL_PRIVATE_FEATURE_GL_FIXED) &&
+  if (_cogl_has_private_feature (context, COGL_PRIVATE_FEATURE_GL_FIXED) &&
       cogl_has_feature (context, COGL_FEATURE_ID_POINT_SPRITE))
     GE (context, glEnable (GL_POINT_SPRITE));
 
diff --git a/cogl/cogl-framebuffer.c b/cogl/cogl-framebuffer.c
index 5c54509..2be598a 100644
--- a/cogl/cogl-framebuffer.c
+++ b/cogl/cogl-framebuffer.c
@@ -668,7 +668,7 @@ cogl_framebuffer_allocate (CoglFramebuffer *framebuffer,
        * one on allocation so that if the application only paints in
        * response to dirty events then it will at least paint once to
        * start */
-      if (!(ctx->private_feature_flags & COGL_PRIVATE_FEATURE_DIRTY_EVENTS))
+      if (!_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_DIRTY_EVENTS))
         _cogl_onscreen_queue_full_dirty (onscreen);
     }
   else
@@ -1296,8 +1296,8 @@ _cogl_blit_framebuffer (CoglFramebuffer *src,
 {
   CoglContext *ctx = src->context;
 
-  _COGL_RETURN_IF_FAIL (ctx->private_feature_flags &
-                        COGL_PRIVATE_FEATURE_OFFSCREEN_BLIT);
+  _COGL_RETURN_IF_FAIL (_cogl_has_private_feature
+                        (ctx, COGL_PRIVATE_FEATURE_OFFSCREEN_BLIT));
 
   /* We can only support blitting between offscreen buffers because
      otherwise we would need to mirror the image and GLES2.0 doesn't
diff --git a/cogl/cogl-glsl-shader.c b/cogl/cogl-glsl-shader.c
index 6bdd266..2c98292 100644
--- a/cogl/cogl-glsl-shader.c
+++ b/cogl/cogl-glsl-shader.c
@@ -63,7 +63,7 @@ _cogl_glsl_shader_set_source_with_boilerplate (CoglContext *ctx,
   strings[count] = version_string;
   lengths[count++] = -1;
 
-  if (ctx->private_feature_flags & COGL_PRIVATE_FEATURE_GL_EMBEDDED &&
+  if (_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_GL_EMBEDDED) &&
       cogl_has_feature (ctx, COGL_FEATURE_ID_TEXTURE_3D))
     {
       static const char texture_3d_extension[] =
diff --git a/cogl/cogl-journal.c b/cogl/cogl-journal.c
index 703f162..5efa9aa 100644
--- a/cogl/cogl-journal.c
+++ b/cogl/cogl-journal.c
@@ -299,7 +299,7 @@ _cogl_journal_flush_modelview_and_entries (CoglJournalEntry *batch_start,
     draw_flags |= COGL_DRAW_COLOR_ATTRIBUTE_IS_OPAQUE;
 
 #ifdef HAVE_COGL_GL
-  if ((ctx->private_feature_flags & COGL_PRIVATE_FEATURE_QUADS))
+  if (_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_QUADS))
     {
       /* XXX: it's rather evil that we sneak in the GL_QUADS enum here... */
       _cogl_framebuffer_draw_attributes (framebuffer,
@@ -630,7 +630,7 @@ _cogl_journal_flush_vbo_offsets_and_entries (CoglJournalEntry *batch_start,
                         4,
                         COGL_ATTRIBUTE_TYPE_UNSIGNED_BYTE);
 
-  if (!(ctx->private_feature_flags & COGL_PRIVATE_FEATURE_QUADS))
+  if (!_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_QUADS))
     state->indices = cogl_get_rectangle_indices (ctx, batch_len);
 
   /* We only create new Attributes when the stride within the
@@ -1040,7 +1040,7 @@ create_attribute_buffer (CoglJournal *journal,
   /* If CoglBuffers are being emulated with malloc then there's not
      really any point in using the pool so we'll just allocate the
      buffer directly */
-  if (!(ctx->private_feature_flags & COGL_PRIVATE_FEATURE_VBOS))
+  if (!_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_VBOS))
     return cogl_attribute_buffer_new_with_size (ctx, n_bytes);
 
   vbo = journal->vbo_pool[journal->next_vbo_in_pool];
diff --git a/cogl/cogl-matrix-stack.c b/cogl/cogl-matrix-stack.c
index 388980d..79b8781 100644
--- a/cogl/cogl-matrix-stack.c
+++ b/cogl/cogl-matrix-stack.c
@@ -815,7 +815,7 @@ _cogl_matrix_flush_to_gl_builtin (CoglContext *ctx,
                                   CoglMatrix *matrix,
                                   CoglMatrixMode mode)
 {
-  g_assert ((ctx->private_feature_flags & COGL_PRIVATE_FEATURE_GL_FIXED));
+  g_assert (_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_GL_FIXED));
 
 #if defined (HAVE_COGL_GL) || defined (HAVE_COGL_GLES)
   if (ctx->flushed_matrix_mode != mode)
@@ -855,7 +855,7 @@ _cogl_matrix_entry_flush_to_gl_builtins (CoglContext *ctx,
                                          CoglFramebuffer *framebuffer,
                                          CoglBool disable_flip)
 {
-  g_assert ((ctx->private_feature_flags & COGL_PRIVATE_FEATURE_GL_FIXED));
+  g_assert (_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_GL_FIXED));
 
 #if defined (HAVE_COGL_GL) || defined (HAVE_COGL_GLES)
   {
diff --git a/cogl/cogl-onscreen.c b/cogl/cogl-onscreen.c
index 3782a21..f97af94 100644
--- a/cogl/cogl-onscreen.c
+++ b/cogl/cogl-onscreen.c
@@ -526,8 +526,8 @@ _cogl_framebuffer_winsys_update_size (CoglFramebuffer *framebuffer,
 
   cogl_framebuffer_set_viewport (framebuffer, 0, 0, width, height);
 
-  if (!(framebuffer->context->private_feature_flags &
-        COGL_PRIVATE_FEATURE_DIRTY_EVENTS))
+  if (!_cogl_has_private_feature (framebuffer->context,
+                                  COGL_PRIVATE_FEATURE_DIRTY_EVENTS))
     _cogl_onscreen_queue_full_dirty (COGL_ONSCREEN (framebuffer));
 }
 
diff --git a/cogl/cogl-pipeline-state.c b/cogl/cogl-pipeline-state.c
index 131a09a..77e9aea 100644
--- a/cogl/cogl-pipeline-state.c
+++ b/cogl/cogl-pipeline-state.c
@@ -710,7 +710,7 @@ cogl_pipeline_set_blend_constant (CoglPipeline *pipeline,
 
   _COGL_RETURN_IF_FAIL (cogl_is_pipeline (pipeline));
 
-  if (!(ctx->private_feature_flags & COGL_PRIVATE_FEATURE_BLEND_CONSTANT))
+  if (!_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_BLEND_CONSTANT))
     return;
 
 #if defined(HAVE_COGL_GLES2) || defined(HAVE_COGL_GL)
diff --git a/cogl/cogl-pipeline.c b/cogl/cogl-pipeline.c
index 2d12606..1589089 100644
--- a/cogl/cogl-pipeline.c
+++ b/cogl/cogl-pipeline.c
@@ -2845,8 +2845,8 @@ _cogl_pipeline_get_state_for_vertex_codegen (CoglContext *context)
    * one in the GLSL but we'll only do this if the point size is
    * non-zero. Whether or not the point size is zero is represented by
    * COGL_PIPELINE_STATE_NON_ZERO_POINT_SIZE */
-  if (!(context->private_feature_flags &
-        COGL_PRIVATE_FEATURE_BUILTIN_POINT_SIZE_UNIFORM))
+  if (!_cogl_has_private_feature
+      (context, COGL_PRIVATE_FEATURE_BUILTIN_POINT_SIZE_UNIFORM))
     state |= COGL_PIPELINE_STATE_NON_ZERO_POINT_SIZE;
 
   return state;
@@ -2876,7 +2876,7 @@ _cogl_pipeline_get_state_for_fragment_codegen (CoglContext *context)
   CoglPipelineState state = (COGL_PIPELINE_STATE_LAYERS |
                              COGL_PIPELINE_STATE_FRAGMENT_SNIPPETS);
 
-  if (!(context->private_feature_flags & COGL_PRIVATE_FEATURE_ALPHA_TEST))
+  if (!_cogl_has_private_feature (context, COGL_PRIVATE_FEATURE_ALPHA_TEST))
     state |= COGL_PIPELINE_STATE_ALPHA_FUNC;
 
   return state;
diff --git a/cogl/cogl-private.h b/cogl/cogl-private.h
index 42d6c0f..9294cfb 100644
--- a/cogl/cogl-private.h
+++ b/cogl/cogl-private.h
@@ -27,50 +27,52 @@
 #include <cogl/cogl-pipeline.h>
 
 #include "cogl-context.h"
-
+#include "cogl-flags.h"
 
 COGL_BEGIN_DECLS
 
 typedef enum
 {
-  COGL_PRIVATE_FEATURE_TEXTURE_2D_FROM_EGL_IMAGE = 1L<<0,
-  COGL_PRIVATE_FEATURE_MESA_PACK_INVERT = 1L<<1,
-  COGL_PRIVATE_FEATURE_OFFSCREEN_BLIT = 1L<<2,
-  COGL_PRIVATE_FEATURE_FOUR_CLIP_PLANES = 1L<<3,
-  COGL_PRIVATE_FEATURE_PBOS = 1L<<4,
-  COGL_PRIVATE_FEATURE_VBOS = 1L<<5,
-  COGL_PRIVATE_FEATURE_EXT_PACKED_DEPTH_STENCIL = 1L<<6,
-  COGL_PRIVATE_FEATURE_OES_PACKED_DEPTH_STENCIL = 1L<<7,
-  COGL_PRIVATE_FEATURE_TEXTURE_FORMAT_BGRA8888 = 1L<<8,
-  COGL_PRIVATE_FEATURE_UNPACK_SUBIMAGE = 1L<<9,
-  COGL_PRIVATE_FEATURE_SAMPLER_OBJECTS = 1L<<10,
-  COGL_PRIVATE_FEATURE_READ_PIXELS_ANY_FORMAT = 1L<<11,
-  COGL_PRIVATE_FEATURE_ALPHA_TEST = 1L<<12,
-  COGL_PRIVATE_FEATURE_FORMAT_CONVERSION = 1L<<13,
-  COGL_PRIVATE_FEATURE_QUADS = 1L<<14,
-  COGL_PRIVATE_FEATURE_BLEND_CONSTANT = 1L<<15,
-  COGL_PRIVATE_FEATURE_QUERY_FRAMEBUFFER_BITS = 1L<<16,
-  COGL_PRIVATE_FEATURE_BUILTIN_POINT_SIZE_UNIFORM = 1L<<17,
-  COGL_PRIVATE_FEATURE_QUERY_TEXTURE_PARAMETERS = 1L<<18,
-  COGL_PRIVATE_FEATURE_ALPHA_TEXTURES = 1L<<19,
-  COGL_PRIVATE_FEATURE_TEXTURE_SWIZZLE = 1L<<20,
-  COGL_PRIVATE_FEATURE_TEXTURE_MAX_LEVEL = 1L<<21,
-  COGL_PRIVATE_FEATURE_ARBFP = 1L<<22,
-  COGL_PRIVATE_FEATURE_OES_EGL_SYNC = 1L<<23,
+  COGL_PRIVATE_FEATURE_TEXTURE_2D_FROM_EGL_IMAGE,
+  COGL_PRIVATE_FEATURE_MESA_PACK_INVERT,
+  COGL_PRIVATE_FEATURE_OFFSCREEN_BLIT,
+  COGL_PRIVATE_FEATURE_FOUR_CLIP_PLANES,
+  COGL_PRIVATE_FEATURE_PBOS,
+  COGL_PRIVATE_FEATURE_VBOS,
+  COGL_PRIVATE_FEATURE_EXT_PACKED_DEPTH_STENCIL,
+  COGL_PRIVATE_FEATURE_OES_PACKED_DEPTH_STENCIL,
+  COGL_PRIVATE_FEATURE_TEXTURE_FORMAT_BGRA8888,
+  COGL_PRIVATE_FEATURE_UNPACK_SUBIMAGE,
+  COGL_PRIVATE_FEATURE_SAMPLER_OBJECTS,
+  COGL_PRIVATE_FEATURE_READ_PIXELS_ANY_FORMAT,
+  COGL_PRIVATE_FEATURE_ALPHA_TEST,
+  COGL_PRIVATE_FEATURE_FORMAT_CONVERSION,
+  COGL_PRIVATE_FEATURE_QUADS,
+  COGL_PRIVATE_FEATURE_BLEND_CONSTANT,
+  COGL_PRIVATE_FEATURE_QUERY_FRAMEBUFFER_BITS,
+  COGL_PRIVATE_FEATURE_BUILTIN_POINT_SIZE_UNIFORM,
+  COGL_PRIVATE_FEATURE_QUERY_TEXTURE_PARAMETERS,
+  COGL_PRIVATE_FEATURE_ALPHA_TEXTURES,
+  COGL_PRIVATE_FEATURE_TEXTURE_SWIZZLE,
+  COGL_PRIVATE_FEATURE_TEXTURE_MAX_LEVEL,
+  COGL_PRIVATE_FEATURE_ARBFP,
+  COGL_PRIVATE_FEATURE_OES_EGL_SYNC,
   /* If this is set then the winsys is responsible for queueing dirty
    * events. Otherwise a dirty event will be queued when the onscreen
    * is first allocated or when it is shown or resized */
-  COGL_PRIVATE_FEATURE_DIRTY_EVENTS = 1L<<24,
-  COGL_PRIVATE_FEATURE_ENABLE_PROGRAM_POINT_SIZE = 1L<<25,
+  COGL_PRIVATE_FEATURE_DIRTY_EVENTS,
+  COGL_PRIVATE_FEATURE_ENABLE_PROGRAM_POINT_SIZE,
   /* These features let us avoid conditioning code based on the exact
    * driver being used and instead check for broad opengl feature
    * sets that can be shared by several GL apis */
-  COGL_PRIVATE_FEATURE_ANY_GL = 1L<<26,
-  COGL_PRIVATE_FEATURE_GL_FIXED = 1L<<27,
-  COGL_PRIVATE_FEATURE_GL_PROGRAMMABLE = 1L<<28,
-  COGL_PRIVATE_FEATURE_GL_EMBEDDED = 1L<<29,
-  COGL_PRIVATE_FEATURE_GL_WEB = 1L<<30
-} CoglPrivateFeatureFlags;
+  COGL_PRIVATE_FEATURE_ANY_GL,
+  COGL_PRIVATE_FEATURE_GL_FIXED,
+  COGL_PRIVATE_FEATURE_GL_PROGRAMMABLE,
+  COGL_PRIVATE_FEATURE_GL_EMBEDDED,
+  COGL_PRIVATE_FEATURE_GL_WEB,
+
+  COGL_N_PRIVATE_FEATURES
+} CoglPrivateFeature;
 
 /* Sometimes when evaluating pipelines, either during comparisons or
  * if calculating a hash value we need to tweak the evaluation
@@ -99,6 +101,9 @@ _cogl_clear (const CoglColor *color, unsigned long buffers);
 void
 _cogl_init (void);
 
+#define _cogl_has_private_feature(ctx, feature) \
+  COGL_FLAGS_GET ((ctx)->private_features, (feature))
+
 /*
  * _cogl_pixel_format_get_bytes_per_pixel:
  * @format: a #CoglPixelFormat
diff --git a/cogl/cogl-renderer-private.h b/cogl/cogl-renderer-private.h
index 8b8d2bf..23b5303 100644
--- a/cogl/cogl-renderer-private.h
+++ b/cogl/cogl-renderer-private.h
@@ -70,7 +70,8 @@ struct _CoglRenderer
 #endif
 
   CoglDriver driver;
-  CoglPrivateFeatureFlags private_feature_flags;
+  unsigned long private_features
+    [COGL_FLAGS_N_LONGS_FOR_SIZE (COGL_N_PRIVATE_FEATURES)];
 #ifndef HAVE_DIRECTLY_LINKED_GL_LIBRARY
   GModule *libgl_module;
 #endif
diff --git a/cogl/cogl-renderer.c b/cogl/cogl-renderer.c
index 2564c9d..8626595 100644
--- a/cogl/cogl-renderer.c
+++ b/cogl/cogl-renderer.c
@@ -95,16 +95,17 @@ typedef struct _CoglDriverDescription
   CoglDriver id;
   const char *name;
   CoglRendererConstraint constraints;
-  CoglPrivateFeatureFlags private_feature_flags;
+  /* It would be nice to make this a pointer and then use a compound
+   * literal from C99 to initialise it but we probably can't get away
+   * with using C99 here. Instead we'll just use a fixed-size array.
+   * GCC should complain if someone adds an 8th feature to a
+   * driver. */
+  const CoglPrivateFeature private_features[8];
   const CoglDriverVtable *vtable;
   const CoglTextureDriver *texture_driver;
   const char *libgl_name;
 } CoglDriverDescription;
 
-_COGL_STATIC_ASSERT(sizeof (CoglPrivateFeatureFlags) <=
-                    sizeof (uint32_t),
-                    "Private feature flags don't fit in 32 bits");
-
 static CoglDriverDescription _cogl_drivers[] =
 {
 #ifdef HAVE_COGL_GL
@@ -112,8 +113,9 @@ static CoglDriverDescription _cogl_drivers[] =
     COGL_DRIVER_GL3,
     "gl3",
     0,
-    COGL_PRIVATE_FEATURE_ANY_GL |
+    { COGL_PRIVATE_FEATURE_ANY_GL,
       COGL_PRIVATE_FEATURE_GL_PROGRAMMABLE,
+      -1 },
     &_cogl_driver_gl,
     &_cogl_texture_driver_gl,
     COGL_GL_LIBNAME,
@@ -122,9 +124,10 @@ static CoglDriverDescription _cogl_drivers[] =
     COGL_DRIVER_GL,
     "gl",
     0,
-    COGL_PRIVATE_FEATURE_ANY_GL |
-      COGL_PRIVATE_FEATURE_GL_FIXED |
+    { COGL_PRIVATE_FEATURE_ANY_GL,
+      COGL_PRIVATE_FEATURE_GL_FIXED,
       COGL_PRIVATE_FEATURE_GL_PROGRAMMABLE,
+      -1 },
     &_cogl_driver_gl,
     &_cogl_texture_driver_gl,
     COGL_GL_LIBNAME,
@@ -135,9 +138,10 @@ static CoglDriverDescription _cogl_drivers[] =
     COGL_DRIVER_GLES2,
     "gles2",
     COGL_RENDERER_CONSTRAINT_SUPPORTS_COGL_GLES2,
-    COGL_PRIVATE_FEATURE_ANY_GL |
-      COGL_PRIVATE_FEATURE_GL_EMBEDDED |
+    { COGL_PRIVATE_FEATURE_ANY_GL,
+      COGL_PRIVATE_FEATURE_GL_EMBEDDED,
       COGL_PRIVATE_FEATURE_GL_PROGRAMMABLE,
+      -1 },
     &_cogl_driver_gles,
     &_cogl_texture_driver_gles,
     COGL_GLES2_LIBNAME,
@@ -148,9 +152,10 @@ static CoglDriverDescription _cogl_drivers[] =
     COGL_DRIVER_GLES1,
     "gles1",
     0,
-    COGL_PRIVATE_FEATURE_ANY_GL |
-      COGL_PRIVATE_FEATURE_GL_EMBEDDED |
+    { COGL_PRIVATE_FEATURE_ANY_GL,
+      COGL_PRIVATE_FEATURE_GL_EMBEDDED,
       COGL_PRIVATE_FEATURE_GL_FIXED,
+      -1 },
     &_cogl_driver_gles,
     &_cogl_texture_driver_gles,
     COGL_GLES1_LIBNAME,
@@ -161,10 +166,11 @@ static CoglDriverDescription _cogl_drivers[] =
     COGL_DRIVER_WEBGL,
     "webgl",
     0,
-    COGL_PRIVATE_FEATURE_ANY_GL |
-      COGL_PRIVATE_FEATURE_GL_EMBEDDED |
-      COGL_PRIVATE_FEATURE_GL_PROGRAMMABLE |
+    { COGL_PRIVATE_FEATURE_ANY_GL,
+      COGL_PRIVATE_FEATURE_GL_EMBEDDED,
+      COGL_PRIVATE_FEATURE_GL_PROGRAMMABLE,
       COGL_PRIVATE_FEATURE_GL_WEB,
+      -1 },
     &_cogl_driver_gles,
     &_cogl_texture_driver_gles,
     NULL,
@@ -174,7 +180,7 @@ static CoglDriverDescription _cogl_drivers[] =
     COGL_DRIVER_NOP,
     "nop",
     0, /* constraints satisfied */
-    0, /* flags */
+    { -1 },
     &_cogl_driver_nop,
     NULL, /* texture driver */
     NULL /* libgl_name */
@@ -495,6 +501,7 @@ _cogl_renderer_choose_driver (CoglRenderer *renderer,
   const char *libgl_name;
   SatisfyConstraintsState state;
   const CoglDriverDescription *desc;
+  int i;
 
   if (!driver_name)
     driver_name = _cogl_config_driver;
@@ -569,12 +576,17 @@ _cogl_renderer_choose_driver (CoglRenderer *renderer,
   renderer->driver = desc->id;
   renderer->driver_vtable = desc->vtable;
   renderer->texture_driver = desc->texture_driver;
-  renderer->private_feature_flags = desc->private_feature_flags;
   libgl_name = desc->libgl_name;
 
+  memset(renderer->private_features, 0, sizeof (renderer->private_features));
+  for (i = 0; desc->private_features[i] != -1; i++)
+    COGL_FLAGS_SET (renderer->private_features,
+                    desc->private_features[i], TRUE);
+
 #ifndef HAVE_DIRECTLY_LINKED_GL_LIBRARY
 
-  if (renderer->private_feature_flags & COGL_PRIVATE_FEATURE_ANY_GL)
+  if (COGL_FLAGS_GET (renderer->private_features,
+                      COGL_PRIVATE_FEATURE_ANY_GL))
     {
       renderer->libgl_module = g_module_open (libgl_name,
                                               G_MODULE_BIND_LAZY);
diff --git a/cogl/cogl-sampler-cache.c b/cogl/cogl-sampler-cache.c
index 84bb81d..a914ed7 100644
--- a/cogl/cogl-sampler-cache.c
+++ b/cogl/cogl-sampler-cache.c
@@ -208,8 +208,8 @@ _cogl_sampler_cache_get_entry_gl (CoglSamplerCache *cache,
 
       entry = g_slice_dup (CoglSamplerCacheEntry, key);
 
-      if ((context->private_feature_flags &
-           COGL_PRIVATE_FEATURE_SAMPLER_OBJECTS))
+      if (_cogl_has_private_feature (context,
+                                     COGL_PRIVATE_FEATURE_SAMPLER_OBJECTS))
         {
           GE( context, glGenSamplers (1, &entry->sampler_object) );
 
@@ -329,8 +329,8 @@ hash_table_free_gl_cb (void *key,
   CoglContext *context = user_data;
   CoglSamplerCacheEntry *entry = value;
 
-  if ((context->private_feature_flags &
-       COGL_PRIVATE_FEATURE_SAMPLER_OBJECTS))
+  if (_cogl_has_private_feature (context,
+                                 COGL_PRIVATE_FEATURE_SAMPLER_OBJECTS))
     GE( context, glDeleteSamplers (1, &entry->sampler_object) );
 
   g_slice_free (CoglSamplerCacheEntry, entry);
diff --git a/cogl/cogl-texture-2d.c b/cogl/cogl-texture-2d.c
index 07a9a3c..835254e 100644
--- a/cogl/cogl-texture-2d.c
+++ b/cogl/cogl-texture-2d.c
@@ -268,9 +268,10 @@ _cogl_egl_texture_2d_new_from_image (CoglContext *ctx,
                             COGL_RENDERER_CONSTRAINT_USES_EGL,
                             NULL);
 
-  _COGL_RETURN_VAL_IF_FAIL (ctx->private_feature_flags &
-                        COGL_PRIVATE_FEATURE_TEXTURE_2D_FROM_EGL_IMAGE,
-                        NULL);
+  _COGL_RETURN_VAL_IF_FAIL (_cogl_has_private_feature
+                            (ctx,
+                             COGL_PRIVATE_FEATURE_TEXTURE_2D_FROM_EGL_IMAGE),
+                            NULL);
 
   if (ctx->driver_vtable->egl_texture_2d_new_from_image)
     return ctx->driver_vtable->egl_texture_2d_new_from_image (ctx,
diff --git a/cogl/cogl-texture-3d.c b/cogl/cogl-texture-3d.c
index 83f85c1..98d1a21 100644
--- a/cogl/cogl-texture-3d.c
+++ b/cogl/cogl-texture-3d.c
@@ -573,7 +573,7 @@ _cogl_texture_3d_pre_paint (CoglTexture *tex, CoglTexturePrePaintFlags flags)
       if (cogl_has_feature (ctx, COGL_FEATURE_ID_OFFSCREEN))
         _cogl_texture_gl_generate_mipmaps (tex);
 #if defined (HAVE_COGL_GL) || defined (HAVE_COGL_GLES)
-      else if (ctx->private_feature_flags & COGL_PRIVATE_FEATURE_GL_FIXED)
+      else if (_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_GL_FIXED))
         {
           _cogl_bind_gl_texture_transient (GL_TEXTURE_3D,
                                            tex_3d->gl_texture,
diff --git a/cogl/cogl-texture-rectangle.c b/cogl/cogl-texture-rectangle.c
index 22e5176..a2eb4a1 100644
--- a/cogl/cogl-texture-rectangle.c
+++ b/cogl/cogl-texture-rectangle.c
@@ -383,8 +383,8 @@ cogl_texture_rectangle_new_from_foreign (CoglContext *ctx,
   /* Obtain texture parameters */
 
 #ifdef HAVE_COGL_GL
-  if ((ctx->private_feature_flags &
-       COGL_PRIVATE_FEATURE_QUERY_TEXTURE_PARAMETERS))
+  if (_cogl_has_private_feature
+      (ctx, COGL_PRIVATE_FEATURE_QUERY_TEXTURE_PARAMETERS))
     {
       GLint val;
 
diff --git a/cogl/cogl-texture.c b/cogl/cogl-texture.c
index 0b77a17..ad063f6 100644
--- a/cogl/cogl-texture.c
+++ b/cogl/cogl-texture.c
@@ -932,7 +932,7 @@ cogl_texture_get_data (CoglTexture *texture,
    * this case the driver will be faking the alpha textures with a
    * red-component texture and it won't swizzle to the correct format
    * while reading */
-  if ((ctx->private_feature_flags & COGL_PRIVATE_FEATURE_ALPHA_TEXTURES) == 0)
+  if (!_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_ALPHA_TEXTURES))
     {
       if (texture_format == COGL_PIXEL_FORMAT_A_8)
         {
diff --git a/cogl/driver/gl/cogl-attribute-gl.c b/cogl/driver/gl/cogl-attribute-gl.c
index 16ce991..b22be5b 100644
--- a/cogl/driver/gl/cogl-attribute-gl.c
+++ b/cogl/driver/gl/cogl-attribute-gl.c
@@ -55,8 +55,8 @@ toggle_builtin_attribute_enabled_cb (int bit_num, void *user_data)
   ForeachChangedBitState *state = user_data;
   CoglContext *context = state->context;
 
-  _COGL_RETURN_VAL_IF_FAIL ((context->private_feature_flags &
-                             COGL_PRIVATE_FEATURE_GL_FIXED),
+  _COGL_RETURN_VAL_IF_FAIL (_cogl_has_private_feature
+                            (context, COGL_PRIVATE_FEATURE_GL_FIXED),
                             FALSE);
 
 #if defined (HAVE_COGL_GL) || defined (HAVE_COGL_GLES)
@@ -92,8 +92,8 @@ toggle_texcood_attribute_enabled_cb (int bit_num, void *user_data)
   ForeachChangedBitState *state = user_data;
   CoglContext *context = state->context;
 
-  _COGL_RETURN_VAL_IF_FAIL ((context->private_feature_flags &
-                             COGL_PRIVATE_FEATURE_GL_FIXED),
+  _COGL_RETURN_VAL_IF_FAIL (_cogl_has_private_feature
+                            (context, COGL_PRIVATE_FEATURE_GL_FIXED),
                             FALSE);
 
 #if defined (HAVE_COGL_GL) || defined (HAVE_COGL_GLES)
@@ -282,7 +282,7 @@ setup_legacy_buffered_attribute (CoglContext *ctx,
       break;
     case COGL_ATTRIBUTE_NAME_ID_CUSTOM_ARRAY:
 #ifdef COGL_PIPELINE_PROGEND_GLSL
-      if (ctx->private_feature_flags & COGL_PRIVATE_FEATURE_GL_PROGRAMMABLE)
+      if (_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_GL_PROGRAMMABLE))
         setup_generic_buffered_attribute (ctx, pipeline, attribute, base);
 #endif
       break;
@@ -299,7 +299,7 @@ setup_legacy_const_attribute (CoglContext *ctx,
 #ifdef COGL_PIPELINE_PROGEND_GLSL
   if (attribute->name_state->name_id == COGL_ATTRIBUTE_NAME_ID_CUSTOM_ARRAY)
     {
-      if (ctx->private_feature_flags & COGL_PRIVATE_FEATURE_GL_PROGRAMMABLE)
+      if (_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_GL_PROGRAMMABLE))
         setup_generic_const_attribute (ctx, pipeline, attribute);
     }
   else
diff --git a/cogl/driver/gl/cogl-clip-stack-gl.c b/cogl/driver/gl/cogl-clip-stack-gl.c
index f83ad6d..77320ec 100644
--- a/cogl/driver/gl/cogl-clip-stack-gl.c
+++ b/cogl/driver/gl/cogl-clip-stack-gl.c
@@ -448,7 +448,7 @@ _cogl_clip_stack_gl_flush (CoglClipStack *stack,
   ctx->current_clip_stack = _cogl_clip_stack_ref (stack);
 
   has_clip_planes =
-    ctx->private_feature_flags & COGL_PRIVATE_FEATURE_FOUR_CLIP_PLANES;
+    _cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_FOUR_CLIP_PLANES);
 
   if (has_clip_planes)
     disable_clip_planes (ctx);
diff --git a/cogl/driver/gl/cogl-framebuffer-gl.c b/cogl/driver/gl/cogl-framebuffer-gl.c
index e34b58a..b88ed34 100644
--- a/cogl/driver/gl/cogl-framebuffer-gl.c
+++ b/cogl/driver/gl/cogl-framebuffer-gl.c
@@ -327,8 +327,8 @@ _cogl_framebuffer_gl_flush_state (CoglFramebuffer *draw_buffer,
           /* NB: Currently we only take advantage of binding separate
            * read/write buffers for offscreen framebuffer blit
            * purposes.  */
-          _COGL_RETURN_IF_FAIL (ctx->private_feature_flags &
-                                COGL_PRIVATE_FEATURE_OFFSCREEN_BLIT);
+          _COGL_RETURN_IF_FAIL (_cogl_has_private_feature
+                                (ctx, COGL_PRIVATE_FEATURE_OFFSCREEN_BLIT));
           _COGL_RETURN_IF_FAIL (draw_buffer->type == COGL_FRAMEBUFFER_TYPE_OFFSCREEN);
           _COGL_RETURN_IF_FAIL (read_buffer->type == COGL_FRAMEBUFFER_TYPE_OFFSCREEN);
 
@@ -390,12 +390,11 @@ create_depth_texture (CoglContext *ctx,
   CoglPixelFormat format;
   CoglTexture2D *depth_texture;
 
-  if (ctx->private_feature_flags &
-      (COGL_PRIVATE_FEATURE_EXT_PACKED_DEPTH_STENCIL |
-       COGL_PRIVATE_FEATURE_OES_PACKED_DEPTH_STENCIL))
-    {
-      format = COGL_PIXEL_FORMAT_DEPTH_24_STENCIL_8;
-    }
+  if (_cogl_has_private_feature
+      (ctx, COGL_PRIVATE_FEATURE_EXT_PACKED_DEPTH_STENCIL) ||
+      _cogl_has_private_feature
+      (ctx, COGL_PRIVATE_FEATURE_OES_PACKED_DEPTH_STENCIL))
+    format = COGL_PIXEL_FORMAT_DEPTH_24_STENCIL_8;
   else
     format = COGL_PIXEL_FORMAT_DEPTH_16;
 
@@ -476,15 +475,15 @@ try_creating_renderbuffers (CoglContext *ctx,
        * GL_OES_packed_depth_stencil doesn't allow GL_DEPTH_STENCIL to
        * be passed as an internal format to glRenderbufferStorage.
        */
-      if (ctx->private_feature_flags &
-          COGL_PRIVATE_FEATURE_EXT_PACKED_DEPTH_STENCIL)
+      if (_cogl_has_private_feature
+          (ctx, COGL_PRIVATE_FEATURE_EXT_PACKED_DEPTH_STENCIL))
         format = GL_DEPTH_STENCIL;
       else
         {
           _COGL_RETURN_VAL_IF_FAIL (
-                                  ctx->private_feature_flags &
-                                  COGL_PRIVATE_FEATURE_OES_PACKED_DEPTH_STENCIL,
-                                  NULL);
+            _cogl_has_private_feature (ctx,
+              COGL_PRIVATE_FEATURE_OES_PACKED_DEPTH_STENCIL),
+            NULL);
           format = GL_DEPTH24_STENCIL8;
         }
 #endif
@@ -794,9 +793,10 @@ _cogl_offscreen_gl_allocate (CoglOffscreen *offscreen,
        /* NB: WebGL introduces a DEPTH_STENCIL_ATTACHMENT and doesn't
         * need an extension to handle _FLAG_DEPTH_STENCIL */
 #ifndef HAVE_COGL_WEBGL
-       (ctx->private_feature_flags
-        & (COGL_PRIVATE_FEATURE_EXT_PACKED_DEPTH_STENCIL |
-           COGL_PRIVATE_FEATURE_OES_PACKED_DEPTH_STENCIL)) &&
+       (_cogl_has_private_feature
+        (ctx, COGL_PRIVATE_FEATURE_EXT_PACKED_DEPTH_STENCIL) ||
+        _cogl_has_private_feature
+        (ctx, COGL_PRIVATE_FEATURE_OES_PACKED_DEPTH_STENCIL)) &&
 #endif
        try_creating_fbo (ctx,
                          offscreen->texture,
@@ -955,8 +955,8 @@ _cogl_framebuffer_init_bits (CoglFramebuffer *framebuffer)
                                  COGL_FRAMEBUFFER_STATE_BIND);
 
 #ifdef HAVE_COGL_GL
-  if ((ctx->private_feature_flags &
-       COGL_PRIVATE_FEATURE_QUERY_FRAMEBUFFER_BITS) &&
+  if (_cogl_has_private_feature
+      (ctx, COGL_PRIVATE_FEATURE_QUERY_FRAMEBUFFER_BITS) &&
       framebuffer->type == COGL_FRAMEBUFFER_TYPE_OFFSCREEN)
     {
       static const struct
@@ -1003,8 +1003,7 @@ _cogl_framebuffer_init_bits (CoglFramebuffer *framebuffer)
 
   /* If we don't have alpha textures then the alpha bits are actually
    * stored in the red component */
-  if ((ctx->private_feature_flags &
-       COGL_PRIVATE_FEATURE_ALPHA_TEXTURES) == 0 &&
+  if (!_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_ALPHA_TEXTURES) &&
       framebuffer->type == COGL_FRAMEBUFFER_TYPE_OFFSCREEN &&
       framebuffer->format == COGL_PIXEL_FORMAT_A_8)
     {
@@ -1333,7 +1332,7 @@ _cogl_framebuffer_gl_read_pixels_into_bitmap (CoglFramebuffer *framebuffer,
 
   /* NB: All offscreen rendering is done upside down so there is no need
    * to flip in this case... */
-  if ((ctx->private_feature_flags & COGL_PRIVATE_FEATURE_MESA_PACK_INVERT) &&
+  if (_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_MESA_PACK_INVERT) &&
       (source & COGL_READ_PIXELS_NO_FLIP) == 0 &&
       !cogl_is_offscreen (framebuffer))
     {
@@ -1353,8 +1352,8 @@ _cogl_framebuffer_gl_read_pixels_into_bitmap (CoglFramebuffer *framebuffer,
      GL_RGBA/GL_UNSIGNED_BYTE and convert if necessary. We also need
      to use this intermediate buffer if the rowstride has padding
      because GLES does not support setting GL_ROW_LENGTH */
-  if ((!(ctx->private_feature_flags &
-         COGL_PRIVATE_FEATURE_READ_PIXELS_ANY_FORMAT) &&
+  if ((!_cogl_has_private_feature
+       (ctx, COGL_PRIVATE_FEATURE_READ_PIXELS_ANY_FORMAT) &&
        (gl_format != GL_RGBA || gl_type != GL_UNSIGNED_BYTE ||
         cogl_bitmap_get_rowstride (bitmap) != 4 * width)) ||
       (required_format & ~COGL_PREMULT_BIT) != (format & ~COGL_PREMULT_BIT))
@@ -1365,8 +1364,8 @@ _cogl_framebuffer_gl_read_pixels_into_bitmap (CoglFramebuffer *framebuffer,
       uint8_t *tmp_data;
       CoglBool succeeded;
 
-      if ((ctx->private_feature_flags &
-           COGL_PRIVATE_FEATURE_READ_PIXELS_ANY_FORMAT))
+      if (_cogl_has_private_feature
+          (ctx, COGL_PRIVATE_FEATURE_READ_PIXELS_ANY_FORMAT))
         read_format = required_format;
       else
         {
diff --git a/cogl/driver/gl/cogl-pipeline-fragend-glsl.c b/cogl/driver/gl/cogl-pipeline-fragend-glsl.c
index aff4225..687a826 100644
--- a/cogl/driver/gl/cogl-pipeline-fragend-glsl.c
+++ b/cogl/driver/gl/cogl-pipeline-fragend-glsl.c
@@ -1009,7 +1009,7 @@ _cogl_pipeline_fragend_glsl_end (CoglPipeline *pipeline,
                          "  cogl_color_out = cogl_color_in;\n");
 
 #if defined(HAVE_COGL_GLES2) || defined (HAVE_COGL_GL)
-      if (!(ctx->private_feature_flags & COGL_PRIVATE_FEATURE_ALPHA_TEST))
+      if (!_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_ALPHA_TEST))
         add_alpha_test_snippet (pipeline, shader_state);
 #endif
 
diff --git a/cogl/driver/gl/cogl-pipeline-opengl.c b/cogl/driver/gl/cogl-pipeline-opengl.c
index 51db17a..5344626 100644
--- a/cogl/driver/gl/cogl-pipeline-opengl.c
+++ b/cogl/driver/gl/cogl-pipeline-opengl.c
@@ -439,7 +439,7 @@ flush_depth_state (CoglContext *ctx,
       (ctx->depth_range_near_cache != depth_state->range_near ||
        ctx->depth_range_far_cache != depth_state->range_far))
     {
-      if (ctx->private_feature_flags & COGL_PRIVATE_FEATURE_GL_EMBEDDED)
+      if (_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_GL_EMBEDDED))
         GE (ctx, glDepthRangef (depth_state->range_near,
                                 depth_state->range_far));
       else
@@ -492,7 +492,7 @@ _cogl_pipeline_flush_color_blend_alpha_depth_state (
   _COGL_GET_CONTEXT (ctx, NO_RETVAL);
 
   /* On GLES2 we'll flush the color later */
-  if ((ctx->private_feature_flags & COGL_PRIVATE_FEATURE_GL_FIXED) &&
+  if (_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_GL_FIXED) &&
       !with_color_attrib)
     {
       if ((pipelines_difference & COGL_PIPELINE_STATE_COLOR) ||
@@ -571,7 +571,7 @@ _cogl_pipeline_flush_color_blend_alpha_depth_state (
 
 #if defined (HAVE_COGL_GL) || defined (HAVE_COGL_GLES)
 
-  if ((ctx->private_feature_flags & COGL_PRIVATE_FEATURE_ALPHA_TEST))
+  if (_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_ALPHA_TEST))
     {
       /* Under GLES2 the alpha function is implemented as part of the
          fragment shader */
@@ -670,8 +670,8 @@ _cogl_pipeline_flush_color_blend_alpha_depth_state (
     }
 
 #ifdef HAVE_COGL_GL
-  if ((ctx->private_feature_flags &
-       COGL_PRIVATE_FEATURE_ENABLE_PROGRAM_POINT_SIZE) &&
+  if (_cogl_has_private_feature
+      (ctx, COGL_PRIVATE_FEATURE_ENABLE_PROGRAM_POINT_SIZE) &&
       (pipelines_difference & COGL_PIPELINE_STATE_PER_VERTEX_POINT_SIZE))
     {
       unsigned long state = COGL_PIPELINE_STATE_PER_VERTEX_POINT_SIZE;
@@ -708,14 +708,14 @@ get_max_activateable_texture_units (void)
       int i;
 
 #ifdef HAVE_COGL_GL
-      if (!(ctx->private_feature_flags & COGL_PRIVATE_FEATURE_GL_EMBEDDED))
+      if (!_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_GL_EMBEDDED))
         {
           /* GL_MAX_TEXTURE_COORDS is provided for both GLSL and ARBfp. It
              defines the number of texture coordinates that can be
              uploaded (but doesn't necessarily relate to how many texture
              images can be sampled) */
           if (cogl_has_feature (ctx, COGL_FEATURE_ID_GLSL) ||
-              (ctx->private_feature_flags & COGL_PRIVATE_FEATURE_ARBFP))
+              _cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_ARBFP))
             /* Previously this code subtracted the value by one but there
                was no explanation for why it did this and it doesn't seem
                to make sense so it has been removed */
@@ -731,8 +731,8 @@ get_max_activateable_texture_units (void)
 #endif /* HAVE_COGL_GL */
 
 #ifdef HAVE_COGL_GLES2
-      if (ctx->private_feature_flags & COGL_PRIVATE_FEATURE_GL_EMBEDDED &&
-          ctx->private_feature_flags & COGL_PRIVATE_FEATURE_GL_PROGRAMMABLE)
+      if (_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_GL_EMBEDDED) &&
+          _cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_GL_PROGRAMMABLE))
         {
           GE (ctx, glGetIntegerv (GL_MAX_VERTEX_ATTRIBS, values + n_values));
           /* Two of the vertex attribs need to be used for the position
@@ -745,7 +745,7 @@ get_max_activateable_texture_units (void)
 #endif
 
 #if defined (HAVE_COGL_GL) || defined (HAVE_COGL_GLES)
-      if (ctx->private_feature_flags & COGL_PRIVATE_FEATURE_GL_FIXED)
+      if (_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_GL_FIXED))
         {
           /* GL_MAX_TEXTURE_UNITS defines the number of units that are
              usable from the fixed function pipeline, therefore it isn't
@@ -875,7 +875,7 @@ flush_layers_common_gl_state_cb (CoglPipelineLayer *layer, void *user_data)
     }
 
   if ((layers_difference & COGL_PIPELINE_LAYER_STATE_SAMPLER) &&
-      (ctx->private_feature_flags & COGL_PRIVATE_FEATURE_SAMPLER_OBJECTS))
+      _cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_SAMPLER_OBJECTS))
     {
       const CoglSamplerCacheEntry *sampler_state;
 
@@ -890,7 +890,7 @@ flush_layers_common_gl_state_cb (CoglPipelineLayer *layer, void *user_data)
    * glsl progend.
    */
 #if defined (HAVE_COGL_GLES) || defined (HAVE_COGL_GL)
-  if ((ctx->private_feature_flags & COGL_PRIVATE_FEATURE_GL_FIXED) &&
+  if (_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_GL_FIXED) &&
       (layers_difference & COGL_PIPELINE_LAYER_STATE_POINT_SPRITE_COORDS))
     {
       CoglPipelineState change = COGL_PIPELINE_LAYER_STATE_POINT_SPRITE_COORDS;
@@ -1432,7 +1432,7 @@ done:
 
   /* Handle the fact that OpenGL associates texture filter and wrap
    * modes with the texture objects not the texture units... */
-  if (!(ctx->private_feature_flags & COGL_PRIVATE_FEATURE_SAMPLER_OBJECTS))
+  if (!_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_SAMPLER_OBJECTS))
     foreach_texture_unit_update_filter_and_wrap_modes ();
 
   /* If this pipeline has more than one layer then we always need
diff --git a/cogl/driver/gl/cogl-pipeline-progend-fixed.c b/cogl/driver/gl/cogl-pipeline-progend-fixed.c
index 163b6a5..d950378 100644
--- a/cogl/driver/gl/cogl-pipeline-progend-fixed.c
+++ b/cogl/driver/gl/cogl-pipeline-progend-fixed.c
@@ -48,7 +48,7 @@ _cogl_pipeline_progend_fixed_start (CoglPipeline *pipeline)
   if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_DISABLE_FIXED)))
     return FALSE;
 
-  if (!(ctx->private_feature_flags & COGL_PRIVATE_FEATURE_GL_FIXED))
+  if (!_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_GL_FIXED))
     return FALSE;
 
   /* Vertex snippets are only supported in the GLSL fragend */
diff --git a/cogl/driver/gl/cogl-pipeline-progend-glsl.c b/cogl/driver/gl/cogl-pipeline-progend-glsl.c
index 077cfd7..c4ca385 100644
--- a/cogl/driver/gl/cogl-pipeline-progend-glsl.c
+++ b/cogl/driver/gl/cogl-pipeline-progend-glsl.c
@@ -71,7 +71,7 @@ typedef struct
 
   /* This builtin is only necessary if the following private feature
    * is not implemented in the driver */
-  CoglPrivateFeatureFlags feature_replacement;
+  CoglPrivateFeature feature_replacement;
 } BuiltinUniformData;
 
 static BuiltinUniformData builtin_uniforms[] =
@@ -410,8 +410,8 @@ update_builtin_uniforms (CoglContext *context,
     return;
 
   for (i = 0; i < G_N_ELEMENTS (builtin_uniforms); i++)
-    if ((context->private_feature_flags &
-         builtin_uniforms[i].feature_replacement) == 0 &&
+    if (!_cogl_has_private_feature (context,
+                                    builtin_uniforms[i].feature_replacement) &&
         (program_state->dirty_builtin_uniforms & (1 << i)) &&
         program_state->builtin_uniform_locations[i] != -1)
       builtin_uniforms[i].update_func (pipeline,
@@ -721,8 +721,8 @@ _cogl_pipeline_progend_glsl_end (CoglPipeline *pipeline,
       clear_flushed_matrix_stacks (program_state);
 
       for (i = 0; i < G_N_ELEMENTS (builtin_uniforms); i++)
-        if ((ctx->private_feature_flags &
-             builtin_uniforms[i].feature_replacement) == 0)
+        if (!_cogl_has_private_feature
+            (ctx, builtin_uniforms[i].feature_replacement))
           GE_RET( program_state->builtin_uniform_locations[i], ctx,
                   glGetUniformLocation (gl_program,
                                         builtin_uniforms[i].uniform_name) );
@@ -773,8 +773,8 @@ _cogl_pipeline_progend_glsl_pre_change_notify (CoglPipeline *pipeline,
       int i;
 
       for (i = 0; i < G_N_ELEMENTS (builtin_uniforms); i++)
-        if ((ctx->private_feature_flags &
-             builtin_uniforms[i].feature_replacement) == 0 &&
+        if (!_cogl_has_private_feature
+            (ctx, builtin_uniforms[i].feature_replacement) &&
             (change & builtin_uniforms[i].change))
           {
             CoglPipelineProgramState *program_state
diff --git a/cogl/driver/gl/cogl-pipeline-vertend-glsl.c b/cogl/driver/gl/cogl-pipeline-vertend-glsl.c
index 33d67de..4f5587d 100644
--- a/cogl/driver/gl/cogl-pipeline-vertend-glsl.c
+++ b/cogl/driver/gl/cogl-pipeline-vertend-glsl.c
@@ -284,8 +284,8 @@ _cogl_pipeline_vertend_glsl_start (CoglPipeline *pipeline,
   if (cogl_pipeline_get_per_vertex_point_size (pipeline))
     g_string_append (shader_state->header,
                      "attribute float cogl_point_size_in;\n");
-  else if (!(ctx->private_feature_flags &
-            COGL_PRIVATE_FEATURE_BUILTIN_POINT_SIZE_UNIFORM))
+  else if (!_cogl_has_private_feature
+           (ctx, COGL_PRIVATE_FEATURE_BUILTIN_POINT_SIZE_UNIFORM))
     {
       /* There is no builtin uniform for the point size on GLES2 so we
          need to copy it from the custom uniform in the vertex shader
@@ -509,8 +509,8 @@ _cogl_pipeline_vertend_glsl_end (CoglPipeline *pipeline,
     }
 
 #ifdef HAVE_COGL_GL
-  if ((ctx->private_feature_flags &
-       COGL_PRIVATE_FEATURE_BUILTIN_POINT_SIZE_UNIFORM) &&
+  if (_cogl_has_private_feature
+      (ctx, COGL_PRIVATE_FEATURE_BUILTIN_POINT_SIZE_UNIFORM) &&
       (pipelines_difference & COGL_PIPELINE_STATE_POINT_SIZE))
     {
       CoglPipeline *authority =
@@ -618,8 +618,8 @@ UNIT_TEST (check_point_size_shader,
    * size */
   if (shader_states[0])
     {
-      if ((test_ctx->private_feature_flags &
-           COGL_PRIVATE_FEATURE_BUILTIN_POINT_SIZE_UNIFORM))
+      if (_cogl_has_private_feature
+          (test_ctx, COGL_PRIVATE_FEATURE_BUILTIN_POINT_SIZE_UNIFORM))
         g_assert (shader_states[0] == shader_states[1]);
       else
         g_assert (shader_states[0] != shader_states[1]);
diff --git a/cogl/driver/gl/cogl-texture-2d-gl.c b/cogl/driver/gl/cogl-texture-2d-gl.c
index a793b9f..99c88a7 100644
--- a/cogl/driver/gl/cogl-texture-2d-gl.c
+++ b/cogl/driver/gl/cogl-texture-2d-gl.c
@@ -384,8 +384,8 @@ cogl_texture_2d_gl_new_from_foreign (CoglContext *ctx,
      (only level 0 we are interested in) */
 
 #ifdef HAVE_COGL_GL
-  if ((ctx->private_feature_flags &
-       COGL_PRIVATE_FEATURE_QUERY_TEXTURE_PARAMETERS))
+  if (_cogl_has_private_feature
+      (ctx, COGL_PRIVATE_FEATURE_QUERY_TEXTURE_PARAMETERS))
     {
       GE( ctx, glGetTexLevelParameteriv (GL_TEXTURE_2D, 0,
                                          GL_TEXTURE_COMPRESSED,
diff --git a/cogl/driver/gl/cogl-texture-gl.c b/cogl/driver/gl/cogl-texture-gl.c
index ccf526c..502224e 100644
--- a/cogl/driver/gl/cogl-texture-gl.c
+++ b/cogl/driver/gl/cogl-texture-gl.c
@@ -105,7 +105,7 @@ _cogl_texture_gl_maybe_update_max_level (CoglTexture *texture,
 #ifdef HAVE_COGL_GL
   CoglContext *ctx = texture->context;
 
-  if ((ctx->private_feature_flags & COGL_PRIVATE_FEATURE_TEXTURE_MAX_LEVEL) &&
+  if (_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_TEXTURE_MAX_LEVEL) &&
       texture->max_level < max_level)
     {
       CoglContext *ctx = texture->context;
diff --git a/cogl/driver/gl/gl/cogl-driver-gl.c b/cogl/driver/gl/gl/cogl-driver-gl.c
index 40d76cb..f787b0c 100644
--- a/cogl/driver/gl/gl/cogl-driver-gl.c
+++ b/cogl/driver/gl/gl/cogl-driver-gl.c
@@ -99,8 +99,8 @@ _cogl_driver_pixel_format_to_gl (CoglContext *context,
       /* If the driver doesn't natively support alpha textures then we
        * will use a red component texture with a swizzle to implement
        * the texture */
-      if ((context->private_feature_flags &
-           COGL_PRIVATE_FEATURE_ALPHA_TEXTURES) == 0)
+      if (_cogl_has_private_feature
+          (context, COGL_PRIVATE_FEATURE_ALPHA_TEXTURES) == 0)
         {
           glintformat = GL_RED;
           glformat = GL_RED;
@@ -344,9 +344,11 @@ static CoglBool
 _cogl_driver_update_features (CoglContext *ctx,
                               CoglError **error)
 {
-  CoglPrivateFeatureFlags private_flags = 0;
+  unsigned long private_features
+    [COGL_FLAGS_N_LONGS_FOR_SIZE (COGL_N_PRIVATE_FEATURES)] = { 0 };
   char **gl_extensions;
   int gl_major = 0, gl_minor = 0;
+  int i;
 
   /* We have to special case getting the pointer to the glGetString*
      functions because we need to use them to determine what functions
@@ -433,16 +435,20 @@ _cogl_driver_update_features (CoglContext *ctx,
     }
 
   if (_cogl_check_extension ("GL_MESA_pack_invert", gl_extensions))
-    private_flags |= COGL_PRIVATE_FEATURE_MESA_PACK_INVERT;
+    COGL_FLAGS_SET (private_features,
+                    COGL_PRIVATE_FEATURE_MESA_PACK_INVERT, TRUE);
 
   if (ctx->glGenRenderbuffers)
     {
       COGL_FLAGS_SET (ctx->features, COGL_FEATURE_ID_OFFSCREEN, TRUE);
-      private_flags |= COGL_PRIVATE_FEATURE_QUERY_FRAMEBUFFER_BITS;
+      COGL_FLAGS_SET (private_features,
+                      COGL_PRIVATE_FEATURE_QUERY_FRAMEBUFFER_BITS,
+                      TRUE);
     }
 
   if (ctx->glBlitFramebuffer)
-    private_flags |= COGL_PRIVATE_FEATURE_OFFSCREEN_BLIT;
+    COGL_FLAGS_SET (private_features,
+                    COGL_PRIVATE_FEATURE_OFFSCREEN_BLIT, TRUE);
 
   if (ctx->glRenderbufferStorageMultisampleIMG)
     COGL_FLAGS_SET (ctx->features,
@@ -454,14 +460,15 @@ _cogl_driver_update_features (CoglContext *ctx,
 
   if (COGL_CHECK_GL_VERSION (gl_major, gl_minor, 2, 1) ||
       _cogl_check_extension ("GL_EXT_pixel_buffer_object", gl_extensions))
-    private_flags |= COGL_PRIVATE_FEATURE_PBOS;
+    COGL_FLAGS_SET (private_features, COGL_PRIVATE_FEATURE_PBOS, TRUE);
 
   if (COGL_CHECK_GL_VERSION (gl_major, gl_minor, 1, 4) ||
       _cogl_check_extension ("GL_EXT_blend_color", gl_extensions))
-    private_flags |= COGL_PRIVATE_FEATURE_BLEND_CONSTANT;
+    COGL_FLAGS_SET (private_features,
+                    COGL_PRIVATE_FEATURE_BLEND_CONSTANT, TRUE);
 
   if (ctx->glGenPrograms)
-    private_flags |= COGL_PRIVATE_FEATURE_ARBFP;
+    COGL_FLAGS_SET (private_features, COGL_PRIVATE_FEATURE_ARBFP, TRUE);
 
   if (ctx->glCreateProgram)
     COGL_FLAGS_SET (ctx->features, COGL_FEATURE_ID_GLSL, TRUE);
@@ -510,7 +517,7 @@ _cogl_driver_update_features (CoglContext *ctx,
 
   if (ctx->glGenBuffers)
     {
-      private_flags |= COGL_PRIVATE_FEATURE_VBOS;
+      COGL_FLAGS_SET (private_features, COGL_PRIVATE_FEATURE_VBOS, TRUE);
       COGL_FLAGS_SET (ctx->features,
                          COGL_FEATURE_ID_MAP_BUFFER_FOR_READ, TRUE);
       COGL_FLAGS_SET (ctx->features,
@@ -525,19 +532,22 @@ _cogl_driver_update_features (CoglContext *ctx,
     COGL_FLAGS_SET (ctx->features, COGL_FEATURE_ID_TEXTURE_3D, TRUE);
 
   if (ctx->glEGLImageTargetTexture2D)
-    private_flags |= COGL_PRIVATE_FEATURE_TEXTURE_2D_FROM_EGL_IMAGE;
+    COGL_FLAGS_SET (private_features,
+                    COGL_PRIVATE_FEATURE_TEXTURE_2D_FROM_EGL_IMAGE, TRUE);
 
   if (_cogl_check_extension ("GL_EXT_packed_depth_stencil", gl_extensions))
-    private_flags |= COGL_PRIVATE_FEATURE_EXT_PACKED_DEPTH_STENCIL;
+    COGL_FLAGS_SET (private_features,
+                    COGL_PRIVATE_FEATURE_EXT_PACKED_DEPTH_STENCIL, TRUE);
 
   if (ctx->glGenSamplers)
-    private_flags |= COGL_PRIVATE_FEATURE_SAMPLER_OBJECTS;
-
+    COGL_FLAGS_SET (private_features,
+                    COGL_PRIVATE_FEATURE_SAMPLER_OBJECTS, TRUE);
 
   if (COGL_CHECK_GL_VERSION (gl_major, gl_minor, 3, 3) ||
       _cogl_check_extension ("GL_ARB_texture_swizzle", gl_extensions) ||
       _cogl_check_extension ("GL_EXT_texture_swizzle", gl_extensions))
-    private_flags |= COGL_PRIVATE_FEATURE_TEXTURE_SWIZZLE;
+    COGL_FLAGS_SET (private_features,
+                    COGL_PRIVATE_FEATURE_TEXTURE_SWIZZLE, TRUE);
 
   /* The per-vertex point size is only available via GLSL with the
    * gl_PointSize builtin. This is only available in GL 2.0 (not the
@@ -547,7 +557,8 @@ _cogl_driver_update_features (CoglContext *ctx,
       COGL_FLAGS_SET (ctx->features,
                       COGL_FEATURE_ID_PER_VERTEX_POINT_SIZE,
                       TRUE);
-      private_flags |= COGL_PRIVATE_FEATURE_ENABLE_PROGRAM_POINT_SIZE;
+      COGL_FLAGS_SET (private_features,
+                      COGL_PRIVATE_FEATURE_ENABLE_PROGRAM_POINT_SIZE, TRUE);
     }
 
   if (ctx->driver == COGL_DRIVER_GL)
@@ -555,34 +566,42 @@ _cogl_driver_update_features (CoglContext *ctx,
       int max_clip_planes = 0;
 
       /* Features which are not available in GL 3 */
-      private_flags |= (COGL_PRIVATE_FEATURE_GL_FIXED |
-                        COGL_PRIVATE_FEATURE_ALPHA_TEST |
-                        COGL_PRIVATE_FEATURE_QUADS |
-                        COGL_PRIVATE_FEATURE_ALPHA_TEXTURES);
+      COGL_FLAGS_SET (private_features, COGL_PRIVATE_FEATURE_GL_FIXED, TRUE);
+      COGL_FLAGS_SET (private_features, COGL_PRIVATE_FEATURE_ALPHA_TEST, TRUE);
+      COGL_FLAGS_SET (private_features, COGL_PRIVATE_FEATURE_QUADS, TRUE);
+      COGL_FLAGS_SET (private_features,
+                      COGL_PRIVATE_FEATURE_ALPHA_TEXTURES, TRUE);
 
       GE( ctx, glGetIntegerv (GL_MAX_CLIP_PLANES, &max_clip_planes) );
       if (max_clip_planes >= 4)
-        private_flags |= COGL_PRIVATE_FEATURE_FOUR_CLIP_PLANES;
+        COGL_FLAGS_SET (private_features,
+                        COGL_PRIVATE_FEATURE_FOUR_CLIP_PLANES, TRUE);
     }
 
-  private_flags |= (COGL_PRIVATE_FEATURE_READ_PIXELS_ANY_FORMAT |
-                    COGL_PRIVATE_FEATURE_ANY_GL |
-                    COGL_PRIVATE_FEATURE_FORMAT_CONVERSION |
-                    COGL_PRIVATE_FEATURE_BLEND_CONSTANT |
-                    COGL_PRIVATE_FEATURE_BUILTIN_POINT_SIZE_UNIFORM |
-                    COGL_PRIVATE_FEATURE_QUERY_TEXTURE_PARAMETERS |
-                    COGL_PRIVATE_FEATURE_TEXTURE_MAX_LEVEL);
+  COGL_FLAGS_SET (private_features,
+                  COGL_PRIVATE_FEATURE_READ_PIXELS_ANY_FORMAT, TRUE);
+  COGL_FLAGS_SET (private_features, COGL_PRIVATE_FEATURE_ANY_GL, TRUE);
+  COGL_FLAGS_SET (private_features,
+                  COGL_PRIVATE_FEATURE_FORMAT_CONVERSION, TRUE);
+  COGL_FLAGS_SET (private_features, COGL_PRIVATE_FEATURE_BLEND_CONSTANT, TRUE);
+  COGL_FLAGS_SET (private_features,
+                  COGL_PRIVATE_FEATURE_BUILTIN_POINT_SIZE_UNIFORM, TRUE);
+  COGL_FLAGS_SET (private_features,
+                  COGL_PRIVATE_FEATURE_QUERY_TEXTURE_PARAMETERS, TRUE);
+  COGL_FLAGS_SET (private_features,
+                  COGL_PRIVATE_FEATURE_TEXTURE_MAX_LEVEL, TRUE);
 
   if (ctx->glFenceSync)
     COGL_FLAGS_SET (ctx->features, COGL_FEATURE_ID_FENCE, TRUE);
 
   /* Cache features */
-  ctx->private_feature_flags |= private_flags;
+  for (i = 0; i < G_N_ELEMENTS (private_features); i++)
+    ctx->private_features[i] |= private_features[i];
 
   g_strfreev (gl_extensions);
 
-  if ((private_flags & (COGL_PRIVATE_FEATURE_ALPHA_TEXTURES |
-                        COGL_PRIVATE_FEATURE_TEXTURE_SWIZZLE)) == 0)
+  if (!COGL_FLAGS_GET (private_features, COGL_PRIVATE_FEATURE_ALPHA_TEXTURES) &&
+      !COGL_FLAGS_GET (private_features, COGL_PRIVATE_FEATURE_TEXTURE_SWIZZLE))
     {
       _cogl_set_error (error,
                        COGL_DRIVER_ERROR,
diff --git a/cogl/driver/gl/gl/cogl-pipeline-progend-fixed-arbfp.c 
b/cogl/driver/gl/gl/cogl-pipeline-progend-fixed-arbfp.c
index f10f835..4f0708b 100644
--- a/cogl/driver/gl/gl/cogl-pipeline-progend-fixed-arbfp.c
+++ b/cogl/driver/gl/gl/cogl-pipeline-progend-fixed-arbfp.c
@@ -48,7 +48,7 @@ _cogl_pipeline_progend_fixed_arbfp_start (CoglPipeline *pipeline)
   if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_DISABLE_FIXED)))
     return FALSE;
 
-  if (!(ctx->private_feature_flags & COGL_PRIVATE_FEATURE_GL_FIXED))
+  if (!_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_GL_FIXED))
     return FALSE;
 
   /* Vertex snippets are only supported in the GLSL fragend */
@@ -58,7 +58,7 @@ _cogl_pipeline_progend_fixed_arbfp_start (CoglPipeline *pipeline)
   /* Validate that we can handle the fragment state using ARBfp
    */
 
-  if (!(ctx->private_feature_flags & COGL_PRIVATE_FEATURE_ARBFP))
+  if (!_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_ARBFP))
     return FALSE;
 
   /* Fragment snippets are only supported in the GLSL fragend */
diff --git a/cogl/driver/gl/gl/cogl-texture-driver-gl.c b/cogl/driver/gl/gl/cogl-texture-driver-gl.c
index 731ef7e..1e5aaa9 100644
--- a/cogl/driver/gl/gl/cogl-texture-driver-gl.c
+++ b/cogl/driver/gl/gl/cogl-texture-driver-gl.c
@@ -73,7 +73,8 @@ _cogl_texture_driver_gen (CoglContext *ctx,
        * "complete".
        */
 #ifdef HAVE_COGL_GL
-      if ((ctx->private_feature_flags & COGL_PRIVATE_FEATURE_TEXTURE_MAX_LEVEL))
+      if (_cogl_has_private_feature
+          (ctx, COGL_PRIVATE_FEATURE_TEXTURE_MAX_LEVEL))
         GE( ctx, glTexParameteri (gl_target, GL_TEXTURE_MAX_LEVEL, 0));
 #endif
 
@@ -95,9 +96,8 @@ _cogl_texture_driver_gen (CoglContext *ctx,
   /* If the driver doesn't support alpha textures directly then we'll
    * fake them by setting the swizzle parameters */
   if (internal_format == COGL_PIXEL_FORMAT_A_8 &&
-      (ctx->private_feature_flags & (COGL_PRIVATE_FEATURE_ALPHA_TEXTURES |
-                                     COGL_PRIVATE_FEATURE_TEXTURE_SWIZZLE)) ==
-      COGL_PRIVATE_FEATURE_TEXTURE_SWIZZLE)
+      !_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_ALPHA_TEXTURES) &&
+      _cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_TEXTURE_SWIZZLE))
     {
       static const GLint red_swizzle[] = { GL_ZERO, GL_ZERO, GL_ZERO, GL_RED };
 
diff --git a/cogl/driver/gl/gles/cogl-driver-gles.c b/cogl/driver/gl/gles/cogl-driver-gles.c
index d33a80e..a013f83 100644
--- a/cogl/driver/gl/gles/cogl-driver-gles.c
+++ b/cogl/driver/gl/gles/cogl-driver-gles.c
@@ -79,8 +79,8 @@ _cogl_driver_pixel_format_to_gl (CoglContext *context,
     case COGL_PIXEL_FORMAT_BGRA_8888:
     case COGL_PIXEL_FORMAT_BGRA_8888_PRE:
       /* There is an extension to support this format */
-      if ((context->private_feature_flags &
-           COGL_PRIVATE_FEATURE_TEXTURE_FORMAT_BGRA8888))
+      if (_cogl_has_private_feature
+          (context,  COGL_PRIVATE_FEATURE_TEXTURE_FORMAT_BGRA8888))
         {
           /* For some reason the extension says you have to specify
              BGRA for the internal format too */
@@ -184,8 +184,10 @@ static CoglBool
 _cogl_driver_update_features (CoglContext *context,
                               CoglError **error)
 {
-  CoglPrivateFeatureFlags private_flags = 0;
+  unsigned long private_features
+    [COGL_FLAGS_N_LONGS_FOR_SIZE (COGL_N_PRIVATE_FEATURES)] = { 0 };
   char **gl_extensions;
+  int i;
 
   /* We have to special case getting the pointer to the glGetString
      function because we need to use it to determine what functions we
@@ -232,7 +234,8 @@ _cogl_driver_update_features (CoglContext *context,
       int max_clip_planes;
       GE( context, glGetIntegerv (GL_MAX_CLIP_PLANES, &max_clip_planes) );
       if (max_clip_planes >= 4)
-        private_flags |= COGL_PRIVATE_FEATURE_FOUR_CLIP_PLANES;
+        COGL_FLAGS_SET (private_features,
+                        COGL_PRIVATE_FEATURE_FOUR_CLIP_PLANES, TRUE);
     }
 #endif
 
@@ -250,16 +253,20 @@ _cogl_driver_update_features (CoglContext *context,
       COGL_FLAGS_SET (context->features,
                       COGL_FEATURE_ID_PER_VERTEX_POINT_SIZE, TRUE);
 
-      private_flags |= COGL_PRIVATE_FEATURE_BLEND_CONSTANT;
+      COGL_FLAGS_SET (private_features,
+                      COGL_PRIVATE_FEATURE_BLEND_CONSTANT, TRUE);
     }
   else if (context->driver == COGL_DRIVER_GLES1)
-    private_flags |= (COGL_PRIVATE_FEATURE_GL_FIXED |
-                      COGL_PRIVATE_FEATURE_ALPHA_TEST |
-                      COGL_PRIVATE_FEATURE_BUILTIN_POINT_SIZE_UNIFORM);
+    {
+      COGL_FLAGS_SET (private_features, COGL_PRIVATE_FEATURE_GL_FIXED, TRUE);
+      COGL_FLAGS_SET (private_features, COGL_PRIVATE_FEATURE_ALPHA_TEST, TRUE);
+      COGL_FLAGS_SET (private_features,
+                      COGL_PRIVATE_FEATURE_BUILTIN_POINT_SIZE_UNIFORM, TRUE);
+    }
 
-  private_flags |= (COGL_PRIVATE_FEATURE_VBOS |
-                    COGL_PRIVATE_FEATURE_ANY_GL |
-                    COGL_PRIVATE_FEATURE_ALPHA_TEXTURES);
+  COGL_FLAGS_SET (private_features, COGL_PRIVATE_FEATURE_VBOS, TRUE);
+  COGL_FLAGS_SET (private_features, COGL_PRIVATE_FEATURE_ANY_GL, TRUE);
+  COGL_FLAGS_SET (private_features, COGL_PRIVATE_FEATURE_ALPHA_TEXTURES, TRUE);
 
   /* Both GLES 1.1 and GLES 2.0 support point sprites in core */
   COGL_FLAGS_SET (context->features, COGL_FEATURE_ID_POINT_SPRITE, TRUE);
@@ -268,7 +275,8 @@ _cogl_driver_update_features (CoglContext *context,
     COGL_FLAGS_SET (context->features, COGL_FEATURE_ID_OFFSCREEN, TRUE);
 
   if (context->glBlitFramebuffer)
-    private_flags |= COGL_PRIVATE_FEATURE_OFFSCREEN_BLIT;
+    COGL_FLAGS_SET (private_features,
+                    COGL_PRIVATE_FEATURE_OFFSCREEN_BLIT, TRUE);
 
   if (_cogl_check_extension ("GL_OES_element_index_uint", gl_extensions))
     COGL_FLAGS_SET (context->features,
@@ -306,25 +314,30 @@ _cogl_driver_update_features (CoglContext *context,
                     COGL_FEATURE_ID_MAP_BUFFER_FOR_WRITE, TRUE);
 
   if (context->glEGLImageTargetTexture2D)
-    private_flags |= COGL_PRIVATE_FEATURE_TEXTURE_2D_FROM_EGL_IMAGE;
+    COGL_FLAGS_SET (private_features,
+                    COGL_PRIVATE_FEATURE_TEXTURE_2D_FROM_EGL_IMAGE, TRUE);
 
   if (_cogl_check_extension ("GL_OES_packed_depth_stencil", gl_extensions))
-    private_flags |= COGL_PRIVATE_FEATURE_OES_PACKED_DEPTH_STENCIL;
+    COGL_FLAGS_SET (private_features,
+                    COGL_PRIVATE_FEATURE_OES_PACKED_DEPTH_STENCIL, TRUE);
 
   if (_cogl_check_extension ("GL_EXT_texture_format_BGRA8888", gl_extensions))
-    private_flags |= COGL_PRIVATE_FEATURE_TEXTURE_FORMAT_BGRA8888;
+    COGL_FLAGS_SET (private_features,
+                    COGL_PRIVATE_FEATURE_TEXTURE_FORMAT_BGRA8888, TRUE);
 
   if (_cogl_check_extension ("GL_EXT_unpack_subimage", gl_extensions))
-    private_flags |= COGL_PRIVATE_FEATURE_UNPACK_SUBIMAGE;
+    COGL_FLAGS_SET (private_features,
+                    COGL_PRIVATE_FEATURE_UNPACK_SUBIMAGE, TRUE);
 
   /* A nameless vendor implemented the extension, but got the case wrong
    * per the spec. */
   if (_cogl_check_extension ("GL_OES_EGL_sync", gl_extensions) ||
       _cogl_check_extension ("GL_OES_egl_sync", gl_extensions))
-    private_flags |= COGL_PRIVATE_FEATURE_OES_EGL_SYNC;
+    COGL_FLAGS_SET (private_features, COGL_PRIVATE_FEATURE_OES_EGL_SYNC, TRUE);
 
   /* Cache features */
-  context->private_feature_flags |= private_flags;
+  for (i = 0; i < G_N_ELEMENTS (private_features); i++)
+    context->private_features[i] |= private_features[i];
 
   g_strfreev (gl_extensions);
 
diff --git a/cogl/driver/gl/gles/cogl-texture-driver-gles.c b/cogl/driver/gl/gles/cogl-texture-driver-gles.c
index 1afab86..385b608 100644
--- a/cogl/driver/gl/gles/cogl-texture-driver-gles.c
+++ b/cogl/driver/gl/gles/cogl-texture-driver-gles.c
@@ -101,7 +101,7 @@ prep_gl_for_pixels_upload_full (CoglContext *ctx,
                                 int pixels_src_y,
                                 int pixels_bpp)
 {
-  if ((ctx->private_feature_flags & COGL_PRIVATE_FEATURE_UNPACK_SUBIMAGE))
+  if (_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_UNPACK_SUBIMAGE))
     {
       GE( ctx, glPixelStorei (GL_UNPACK_ROW_LENGTH,
                               pixels_rowstride / pixels_bpp) );
@@ -152,7 +152,7 @@ prepare_bitmap_alignment_for_upload (CoglContext *ctx,
   int width = cogl_bitmap_get_width (src_bmp);
   int alignment = 1;
 
-  if ((ctx->private_feature_flags & COGL_PRIVATE_FEATURE_UNPACK_SUBIMAGE) ||
+  if (_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_UNPACK_SUBIMAGE) ||
       src_rowstride == 0)
     return cogl_object_ref (src_bmp);
 
@@ -204,7 +204,7 @@ _cogl_texture_driver_upload_subregion_to_gl (CoglContext *ctx,
   /* If we have the GL_EXT_unpack_subimage extension then we can
      upload from subregions directly. Otherwise we may need to copy
      the bitmap */
-  if (!(ctx->private_feature_flags & COGL_PRIVATE_FEATURE_UNPACK_SUBIMAGE) &&
+  if (!_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_UNPACK_SUBIMAGE) &&
       (src_x != 0 || src_y != 0 ||
        width != cogl_bitmap_get_width (source_bmp) ||
        height != cogl_bitmap_get_height (source_bmp)))
diff --git a/cogl/driver/nop/cogl-driver-nop.c b/cogl/driver/nop/cogl-driver-nop.c
index 26ae026..92cd43c 100644
--- a/cogl/driver/nop/cogl-driver-nop.c
+++ b/cogl/driver/nop/cogl-driver-nop.c
@@ -43,7 +43,7 @@ _cogl_driver_update_features (CoglContext *ctx,
 {
   /* _cogl_gpu_info_init (ctx, &ctx->gpu); */
 
-  ctx->private_feature_flags = 0;
+  memset (ctx->private_features, 0, sizeof (ctx->private_features));
 
   return TRUE;
 }
diff --git a/cogl/winsys/cogl-winsys-egl-wayland.c b/cogl/winsys/cogl-winsys-egl-wayland.c
index 57ac173..7bb0729 100644
--- a/cogl/winsys/cogl-winsys-egl-wayland.c
+++ b/cogl/winsys/cogl-winsys-egl-wayland.c
@@ -426,7 +426,9 @@ _cogl_winsys_egl_context_init (CoglContext *context,
    * delays setting the surface type until the next buffer is attached
    * so attaching a buffer before setting the type would not cause
    * anything to be displayed */
-  context->private_feature_flags |= COGL_PRIVATE_FEATURE_DIRTY_EVENTS;
+  COGL_FLAGS_SET (context->private_features,
+                  COGL_PRIVATE_FEATURE_DIRTY_EVENTS,
+                  TRUE);
 
   return TRUE;
 }
diff --git a/cogl/winsys/cogl-winsys-egl-x11.c b/cogl/winsys/cogl-winsys-egl-x11.c
index b047db4..1cba231 100644
--- a/cogl/winsys/cogl-winsys-egl-x11.c
+++ b/cogl/winsys/cogl-winsys-egl-x11.c
@@ -321,7 +321,9 @@ _cogl_winsys_egl_context_init (CoglContext *context,
 
   /* We'll manually handle queueing dirty events in response to
    * Expose events from X */
-  context->private_feature_flags |= COGL_PRIVATE_FEATURE_DIRTY_EVENTS;
+  COGL_FLAGS_SET (context->private_features,
+                  COGL_PRIVATE_FEATURE_DIRTY_EVENTS,
+                  TRUE);
 
   return TRUE;
 }
@@ -704,8 +706,8 @@ _cogl_winsys_texture_pixmap_x11_create (CoglTexturePixmapX11 *tex_pixmap)
 
   if (!(egl_renderer->private_features &
         COGL_EGL_WINSYS_FEATURE_EGL_IMAGE_FROM_X11_PIXMAP) ||
-      !(ctx->private_feature_flags &
-        COGL_PRIVATE_FEATURE_TEXTURE_2D_FROM_EGL_IMAGE))
+      !_cogl_has_private_feature
+      (ctx, COGL_PRIVATE_FEATURE_TEXTURE_2D_FROM_EGL_IMAGE))
     {
       tex_pixmap->winsys = NULL;
       return FALSE;
diff --git a/cogl/winsys/cogl-winsys-egl.c b/cogl/winsys/cogl-winsys-egl.c
index 7df2245..8e933d0 100644
--- a/cogl/winsys/cogl-winsys-egl.c
+++ b/cogl/winsys/cogl-winsys-egl.c
@@ -504,7 +504,7 @@ _cogl_winsys_context_init (CoglContext *context, CoglError **error)
     }
 
   if ((egl_renderer->private_features & COGL_EGL_WINSYS_FEATURE_FENCE_SYNC) &&
-      (context->private_feature_flags & COGL_PRIVATE_FEATURE_OES_EGL_SYNC))
+      _cogl_has_private_feature (context, COGL_PRIVATE_FEATURE_OES_EGL_SYNC))
     COGL_FLAGS_SET (context->features, COGL_FEATURE_ID_FENCE, TRUE);
 
   /* NB: We currently only support creating standalone GLES2 contexts
diff --git a/cogl/winsys/cogl-winsys-glx.c b/cogl/winsys/cogl-winsys-glx.c
index 9f90a8f..6c91f73 100644
--- a/cogl/winsys/cogl-winsys-glx.c
+++ b/cogl/winsys/cogl-winsys-glx.c
@@ -843,7 +843,9 @@ update_winsys_features (CoglContext *context, CoglError **error)
 
   /* We'll manually handle queueing dirty events in response to
    * Expose events from X */
-  context->private_feature_flags |= COGL_PRIVATE_FEATURE_DIRTY_EVENTS;
+  COGL_FLAGS_SET (context->private_features,
+                  COGL_PRIVATE_FEATURE_DIRTY_EVENTS,
+                  TRUE);
 
   return TRUE;
 }
diff --git a/cogl/winsys/cogl-winsys-sdl.c b/cogl/winsys/cogl-winsys-sdl.c
index 9d6d8ae..4def553 100644
--- a/cogl/winsys/cogl-winsys-sdl.c
+++ b/cogl/winsys/cogl-winsys-sdl.c
@@ -312,7 +312,9 @@ _cogl_winsys_context_init (CoglContext *context, CoglError **error)
 
   /* We'll manually handle queueing dirty events in response to
    * SDL_VIDEOEXPOSE events */
-  context->private_feature_flags |= COGL_PRIVATE_FEATURE_DIRTY_EVENTS;
+  COGL_FLAGS_SET (context->private_features,
+                  COGL_PRIVATE_FEATURE_DIRTY_EVENTS,
+                  TRUE);
 
   return _cogl_context_update_features (context, error);
 }
diff --git a/cogl/winsys/cogl-winsys-sdl2.c b/cogl/winsys/cogl-winsys-sdl2.c
index 00445b8..91307f0 100644
--- a/cogl/winsys/cogl-winsys-sdl2.c
+++ b/cogl/winsys/cogl-winsys-sdl2.c
@@ -395,7 +395,9 @@ _cogl_winsys_context_init (CoglContext *context, CoglError **error)
 
   /* We'll manually handle queueing dirty events in response to
    * SDL_WINDOWEVENT_EXPOSED events */
-  context->private_feature_flags |= COGL_PRIVATE_FEATURE_DIRTY_EVENTS;
+  COGL_FLAGS_SET (context->private_features,
+                  COGL_PRIVATE_FEATURE_DIRTY_EVENTS,
+                  TRUE);
 
   _cogl_renderer_add_native_filter (renderer,
                                     (CoglNativeFilterFunc) sdl_event_filter_cb,
diff --git a/cogl/winsys/cogl-winsys-wgl.c b/cogl/winsys/cogl-winsys-wgl.c
index d83ff91..b10ff44 100644
--- a/cogl/winsys/cogl-winsys-wgl.c
+++ b/cogl/winsys/cogl-winsys-wgl.c
@@ -705,7 +705,9 @@ update_winsys_features (CoglContext *context, CoglError **error)
 
   /* We'll manually handle queueing dirty events in response to
    * WM_PAINT messages */
-  context->private_feature_flags |= COGL_PRIVATE_FEATURE_DIRTY_EVENTS;
+  COGL_FLAGS_SET (context->private_features,
+                  COGL_PRIVATE_FEATURE_DIRTY_EVENTS,
+                  TRUE);
 
   return TRUE;
 }


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]