コード例 #1
0
static CoglBool
_cogl_driver_update_features (CoglContext *context,
                              CoglError **error)
{
  CoglPrivateFeatureFlags private_flags = 0;
  CoglFeatureFlags flags = 0;
  const char *gl_extensions;
  int num_stencil_bits = 0;

  /* We have to special case getting the pointer to the glGetString
     function because we need to use it to determine what functions we
     can expect */
  context->glGetString =
    (void *) _cogl_renderer_get_proc_address (context->display->renderer,
                                              "glGetString",
                                              TRUE);

  COGL_NOTE (WINSYS,
             "Checking features\n"
             "  GL_VENDOR: %s\n"
             "  GL_RENDERER: %s\n"
             "  GL_VERSION: %s\n"
             "  GL_EXTENSIONS: %s",
             context->glGetString (GL_VENDOR),
             context->glGetString (GL_RENDERER),
             _cogl_context_get_gl_version (context),
             _cogl_context_get_gl_extensions (context));

  _cogl_gpu_info_init (context, &context->gpu);

  gl_extensions = _cogl_context_get_gl_extensions (context);

  _cogl_feature_check_ext_functions (context,
                                     -1 /* GL major version */,
                                     -1 /* GL minor version */,
                                     gl_extensions);

  GE( context, glGetIntegerv (GL_STENCIL_BITS, &num_stencil_bits) );
  /* We need at least three stencil bits to combine clips */
  if (num_stencil_bits > 2)
    private_flags |= COGL_PRIVATE_FEATURE_STENCIL_BUFFER;

#ifdef HAVE_COGL_GLES
  if (context->driver == COGL_DRIVER_GLES1)
    {
      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;
    }
#endif

  if (context->driver == COGL_DRIVER_GLES2)
    {
      flags |= COGL_FEATURE_SHADERS_GLSL | COGL_FEATURE_OFFSCREEN;
      /* Note GLES 2 core doesn't support mipmaps for npot textures or
       * repeat modes other than CLAMP_TO_EDGE. */
      flags |= COGL_FEATURE_TEXTURE_NPOT_BASIC;
      flags |= COGL_FEATURE_DEPTH_RANGE;
      COGL_FLAGS_SET (context->features, COGL_FEATURE_ID_GLSL, TRUE);
      COGL_FLAGS_SET (context->features, COGL_FEATURE_ID_OFFSCREEN, TRUE);
      COGL_FLAGS_SET (context->features,
                      COGL_FEATURE_ID_TEXTURE_NPOT_BASIC, TRUE);
      COGL_FLAGS_SET (context->features, COGL_FEATURE_ID_DEPTH_RANGE, TRUE);
      COGL_FLAGS_SET (context->features,
                      COGL_FEATURE_ID_MIRRORED_REPEAT, TRUE);
    }

  private_flags |= COGL_PRIVATE_FEATURE_VBOS;

  /* Both GLES 1.1 and GLES 2.0 support point sprites in core */
  flags |= COGL_FEATURE_POINT_SPRITE;
  COGL_FLAGS_SET (context->features, COGL_FEATURE_ID_POINT_SPRITE, TRUE);

  if (context->glGenRenderbuffers)
    {
      flags |= COGL_FEATURE_OFFSCREEN;
      COGL_FLAGS_SET (context->features, COGL_FEATURE_ID_OFFSCREEN, TRUE);
    }

  if (context->glBlitFramebuffer)
    private_flags |= COGL_PRIVATE_FEATURE_OFFSCREEN_BLIT;

  if (_cogl_check_extension ("GL_OES_element_index_uint", gl_extensions))
    {
      flags |= COGL_FEATURE_UNSIGNED_INT_INDICES;
      COGL_FLAGS_SET (context->features,
                      COGL_FEATURE_ID_UNSIGNED_INT_INDICES, TRUE);
    }

  if (_cogl_check_extension ("GL_OES_depth_texture", gl_extensions))
    {
      flags |= COGL_FEATURE_DEPTH_TEXTURE;
      COGL_FLAGS_SET (context->features, COGL_FEATURE_ID_DEPTH_TEXTURE, TRUE);
    }

  if (_cogl_check_extension ("GL_OES_texture_npot", gl_extensions))
    {
      flags |= (COGL_FEATURE_TEXTURE_NPOT |
                COGL_FEATURE_TEXTURE_NPOT_BASIC |
                COGL_FEATURE_TEXTURE_NPOT_MIPMAP |
                COGL_FEATURE_TEXTURE_NPOT_REPEAT);
      COGL_FLAGS_SET (context->features,
                      COGL_FEATURE_ID_TEXTURE_NPOT, TRUE);
      COGL_FLAGS_SET (context->features,
                      COGL_FEATURE_ID_TEXTURE_NPOT_BASIC, TRUE);
      COGL_FLAGS_SET (context->features,
                      COGL_FEATURE_ID_TEXTURE_NPOT_MIPMAP, TRUE);
      COGL_FLAGS_SET (context->features,
                      COGL_FEATURE_ID_TEXTURE_NPOT_REPEAT, TRUE);
    }
  else if (_cogl_check_extension ("GL_IMG_texture_npot", gl_extensions))
    {
      flags |= (COGL_FEATURE_TEXTURE_NPOT_BASIC |
                COGL_FEATURE_TEXTURE_NPOT_MIPMAP);
      COGL_FLAGS_SET (context->features,
                      COGL_FEATURE_ID_TEXTURE_NPOT_BASIC, TRUE);
      COGL_FLAGS_SET (context->features,
                      COGL_FEATURE_ID_TEXTURE_NPOT_MIPMAP, TRUE);
    }

  if (context->glTexImage3D)
    {
      flags |= COGL_FEATURE_TEXTURE_3D;
      COGL_FLAGS_SET (context->features, COGL_FEATURE_ID_TEXTURE_3D, TRUE);
    }

  if (context->glMapBuffer)
    {
      /* The GL_OES_mapbuffer extension doesn't support mapping for
         read */
      flags |= COGL_FEATURE_MAP_BUFFER_FOR_WRITE;
      COGL_FLAGS_SET (context->features,
                      COGL_FEATURE_ID_MAP_BUFFER_FOR_WRITE, TRUE);
    }

  if (context->glEGLImageTargetTexture2D)
    private_flags |= COGL_PRIVATE_FEATURE_TEXTURE_2D_FROM_EGL_IMAGE;

  if (_cogl_check_extension ("GL_OES_packed_depth_stencil", gl_extensions))
    private_flags |= COGL_PRIVATE_FEATURE_OES_PACKED_DEPTH_STENCIL;

  if (_cogl_check_extension ("GL_EXT_texture_format_BGRA8888", gl_extensions))
    private_flags |= COGL_PRIVATE_FEATURE_TEXTURE_FORMAT_BGRA8888;

  if (_cogl_check_extension ("GL_EXT_unpack_subimage", gl_extensions))
    private_flags |= COGL_PRIVATE_FEATURE_UNPACK_SUBIMAGE;

  /* Cache features */
  context->private_feature_flags |= private_flags;
  context->feature_flags |= flags;

  return TRUE;
}
コード例 #2
0
ファイル: cogl-driver-gl.c プロジェクト: gcampax/cogl
static CoglBool
_cogl_driver_update_features (CoglContext *ctx,
                              CoglError **error)
{
  CoglPrivateFeatureFlags private_flags = 0;
  char **gl_extensions;
  int gl_major = 0, gl_minor = 0;

  /* We have to special case getting the pointer to the glGetString*
     functions because we need to use them to determine what functions
     we can expect */
  ctx->glGetString =
    (void *) _cogl_renderer_get_proc_address (ctx->display->renderer,
                                              "glGetString",
                                              TRUE);
  ctx->glGetStringi =
    (void *) _cogl_renderer_get_proc_address (ctx->display->renderer,
                                              "glGetStringi",
                                              TRUE);
  ctx->glGetIntegerv =
    (void *) _cogl_renderer_get_proc_address (ctx->display->renderer,
                                              "glGetIntegerv",
                                              TRUE);

  gl_extensions = _cogl_context_get_gl_extensions (ctx);

  if (!check_gl_version (ctx, gl_extensions, error))
    return FALSE;

  if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_WINSYS)))
    {
      char *all_extensions = g_strjoinv (" ", gl_extensions);

      COGL_NOTE (WINSYS,
                 "Checking features\n"
                 "  GL_VENDOR: %s\n"
                 "  GL_RENDERER: %s\n"
                 "  GL_VERSION: %s\n"
                 "  GL_EXTENSIONS: %s",
                 ctx->glGetString (GL_VENDOR),
                 ctx->glGetString (GL_RENDERER),
                 _cogl_context_get_gl_version (ctx),
                 all_extensions);

      g_free (all_extensions);
    }

  _cogl_get_gl_version (ctx, &gl_major, &gl_minor);

  _cogl_gpu_info_init (ctx, &ctx->gpu);

  ctx->glsl_major = 1;
  ctx->glsl_minor = 1;

  if (COGL_CHECK_GL_VERSION (gl_major, gl_minor, 2, 0))
    {
      const char *glsl_version =
        (char *)ctx->glGetString (GL_SHADING_LANGUAGE_VERSION);
      parse_gl_version (glsl_version, &ctx->glsl_major, &ctx->glsl_minor);
    }

  COGL_FLAGS_SET (ctx->features,
                  COGL_FEATURE_ID_UNSIGNED_INT_INDICES, TRUE);
  COGL_FLAGS_SET (ctx->features, COGL_FEATURE_ID_DEPTH_RANGE, TRUE);

  if (COGL_CHECK_GL_VERSION (gl_major, gl_minor, 1, 4))
    COGL_FLAGS_SET (ctx->features, COGL_FEATURE_ID_MIRRORED_REPEAT, TRUE);

  _cogl_feature_check_ext_functions (ctx,
                                     gl_major,
                                     gl_minor,
                                     gl_extensions);

  if (COGL_CHECK_GL_VERSION (gl_major, gl_minor, 2, 0) ||
      _cogl_check_extension ("GL_ARB_texture_non_power_of_two", gl_extensions))
    {
      COGL_FLAGS_SET (ctx->features, COGL_FEATURE_ID_TEXTURE_NPOT, TRUE);
      COGL_FLAGS_SET (ctx->features,
                      COGL_FEATURE_ID_TEXTURE_NPOT_BASIC, TRUE);
      COGL_FLAGS_SET (ctx->features,
                      COGL_FEATURE_ID_TEXTURE_NPOT_MIPMAP, TRUE);
      COGL_FLAGS_SET (ctx->features,
                      COGL_FEATURE_ID_TEXTURE_NPOT_REPEAT, TRUE);
    }

  if (_cogl_check_extension ("GL_MESA_pack_invert", gl_extensions))
    private_flags |= COGL_PRIVATE_FEATURE_MESA_PACK_INVERT;

  if (ctx->glGenRenderbuffers)
    {
      COGL_FLAGS_SET (ctx->features, COGL_FEATURE_ID_OFFSCREEN, TRUE);
      private_flags |= COGL_PRIVATE_FEATURE_QUERY_FRAMEBUFFER_BITS;
    }

  if (ctx->glBlitFramebuffer)
    private_flags |= COGL_PRIVATE_FEATURE_OFFSCREEN_BLIT;

  if (ctx->glRenderbufferStorageMultisampleIMG)
    COGL_FLAGS_SET (ctx->features,
                    COGL_FEATURE_ID_OFFSCREEN_MULTISAMPLE, TRUE);

  if (COGL_CHECK_GL_VERSION (gl_major, gl_minor, 3, 0) ||
      _cogl_check_extension ("GL_ARB_depth_texture", gl_extensions))
    COGL_FLAGS_SET (ctx->features, COGL_FEATURE_ID_DEPTH_TEXTURE, TRUE);

  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;

  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;

  if (ctx->glGenPrograms)
    private_flags |= COGL_PRIVATE_FEATURE_ARBFP;

  if (ctx->glCreateProgram)
    COGL_FLAGS_SET (ctx->features, COGL_FEATURE_ID_GLSL, TRUE);
  else
    {
      /* If all of the old GLSL extensions are available then we can fake
       * the GL 2.0 GLSL support by diverting to the old function names */
      if (ctx->glCreateProgramObject && /* GL_ARB_shader_objects */
          ctx->glVertexAttribPointer && /* GL_ARB_vertex_shader */
          _cogl_check_extension ("GL_ARB_fragment_shader", gl_extensions))
        {
          ctx->glCreateShader = ctx->glCreateShaderObject;
          ctx->glCreateProgram = ctx->glCreateProgramObject;
          ctx->glDeleteShader = ctx->glDeleteObject;
          ctx->glDeleteProgram = ctx->glDeleteObject;
          ctx->glAttachShader = ctx->glAttachObject;
          ctx->glUseProgram = ctx->glUseProgramObject;
          ctx->glGetProgramInfoLog = ctx->glGetInfoLog;
          ctx->glGetShaderInfoLog = ctx->glGetInfoLog;
          ctx->glGetShaderiv = ctx->glGetObjectParameteriv;
          ctx->glGetProgramiv = ctx->glGetObjectParameteriv;
          ctx->glDetachShader = ctx->glDetachObject;
          ctx->glGetAttachedShaders = ctx->glGetAttachedObjects;
          /* FIXME: there doesn't seem to be an equivalent for glIsShader
           * and glIsProgram. This doesn't matter for now because Cogl
           * doesn't use these but if we add support for simulating a
           * GLES2 context on top of regular GL then we'll need to do
           * something here */

          COGL_FLAGS_SET (ctx->features, COGL_FEATURE_ID_GLSL, TRUE);
        }
    }

  if ((COGL_CHECK_GL_VERSION (gl_major, gl_minor, 2, 0) ||
       _cogl_check_extension ("GL_ARB_point_sprite", gl_extensions)) &&

      /* If GLSL is supported then we only enable point sprite support
       * too if we have glsl >= 1.2 otherwise we don't have the
       * gl_PointCoord builtin which we depend on in the glsl backend.
       */
      (!COGL_FLAGS_GET (ctx->features, COGL_FEATURE_ID_GLSL) ||
       COGL_CHECK_GL_VERSION (ctx->glsl_major, ctx->glsl_minor, 1, 2)))
    {
      COGL_FLAGS_SET (ctx->features, COGL_FEATURE_ID_POINT_SPRITE, TRUE);
    }

  if (ctx->glGenBuffers)
    {
      private_flags |= COGL_PRIVATE_FEATURE_VBOS;
      COGL_FLAGS_SET (ctx->features,
                         COGL_FEATURE_ID_MAP_BUFFER_FOR_READ, TRUE);
      COGL_FLAGS_SET (ctx->features,
                      COGL_FEATURE_ID_MAP_BUFFER_FOR_WRITE, TRUE);
    }

  if (_cogl_check_extension ("GL_ARB_texture_rectangle", gl_extensions))
    COGL_FLAGS_SET (ctx->features,
                    COGL_FEATURE_ID_TEXTURE_RECTANGLE, TRUE);

  if (ctx->glTexImage3D)
    COGL_FLAGS_SET (ctx->features, COGL_FEATURE_ID_TEXTURE_3D, TRUE);

  if (ctx->glEGLImageTargetTexture2D)
    private_flags |= COGL_PRIVATE_FEATURE_TEXTURE_2D_FROM_EGL_IMAGE;

  if (_cogl_check_extension ("GL_EXT_packed_depth_stencil", gl_extensions))
    private_flags |= COGL_PRIVATE_FEATURE_EXT_PACKED_DEPTH_STENCIL;

  if (ctx->glGenSamplers)
    private_flags |= COGL_PRIVATE_FEATURE_SAMPLER_OBJECTS;


  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;

  /* 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
   * GLSL extensions) */
  if (COGL_CHECK_GL_VERSION (gl_major, gl_minor, 2, 0))
    {
      COGL_FLAGS_SET (ctx->features,
                      COGL_FEATURE_ID_PER_VERTEX_POINT_SIZE,
                      TRUE);
      private_flags |= COGL_PRIVATE_FEATURE_ENABLE_PROGRAM_POINT_SIZE;
    }

  if (ctx->driver == COGL_DRIVER_GL)
    {
      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);

      GE( ctx, glGetIntegerv (GL_MAX_CLIP_PLANES, &max_clip_planes) );
      if (max_clip_planes >= 4)
        private_flags |= COGL_PRIVATE_FEATURE_FOUR_CLIP_PLANES;
    }

  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);

  if (ctx->glFenceSync)
    COGL_FLAGS_SET (ctx->features, COGL_FEATURE_ID_FENCE, TRUE);

  /* Cache features */
  ctx->private_feature_flags |= private_flags;

  g_strfreev (gl_extensions);

  if ((private_flags & (COGL_PRIVATE_FEATURE_ALPHA_TEXTURES |
                        COGL_PRIVATE_FEATURE_TEXTURE_SWIZZLE)) == 0)
    {
      _cogl_set_error (error,
                       COGL_DRIVER_ERROR,
                       COGL_DRIVER_ERROR_NO_SUITABLE_DRIVER_FOUND,
                       "The GL_ARB_texture_swizzle extension is required "
                       "to use the GL3 driver");
      return FALSE;
    }

  return TRUE;
}
コード例 #3
0
static CoglBool
_cogl_driver_update_features (CoglContext *context,
                              CoglError **error)
{
    CoglPrivateFeatureFlags private_flags = 0;
    char **gl_extensions;

    /* We have to special case getting the pointer to the glGetString
       function because we need to use it to determine what functions we
       can expect */
    context->glGetString =
        (void *) _cogl_renderer_get_proc_address (context->display->renderer,
                "glGetString",
                TRUE);

    gl_extensions = _cogl_context_get_gl_extensions (context);

    if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_WINSYS)))
    {
        char *all_extensions = g_strjoinv (" ", gl_extensions);

        COGL_NOTE (WINSYS,
                   "Checking features\n"
                   "  GL_VENDOR: %s\n"
                   "  GL_RENDERER: %s\n"
                   "  GL_VERSION: %s\n"
                   "  GL_EXTENSIONS: %s",
                   context->glGetString (GL_VENDOR),
                   context->glGetString (GL_RENDERER),
                   _cogl_context_get_gl_version (context),
                   all_extensions);

        g_free (all_extensions);
    }

    context->glsl_major = 1;
    context->glsl_minor = 0;

    _cogl_gpu_info_init (context, &context->gpu);

    _cogl_feature_check_ext_functions (context,
                                       -1 /* GL major version */,
                                       -1 /* GL minor version */,
                                       gl_extensions);

#ifdef HAVE_COGL_GLES
    if (context->driver == COGL_DRIVER_GLES1)
    {
        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;
    }
#endif

    if (context->driver == COGL_DRIVER_GLES2)
    {
        /* Note GLES 2 core doesn't support mipmaps for npot textures or
         * repeat modes other than CLAMP_TO_EDGE. */
        COGL_FLAGS_SET (context->features, COGL_FEATURE_ID_GLSL, TRUE);
        COGL_FLAGS_SET (context->features, COGL_FEATURE_ID_OFFSCREEN, TRUE);
        COGL_FLAGS_SET (context->features,
                        COGL_FEATURE_ID_TEXTURE_NPOT_BASIC, TRUE);
        COGL_FLAGS_SET (context->features, COGL_FEATURE_ID_DEPTH_RANGE, TRUE);
        COGL_FLAGS_SET (context->features,
                        COGL_FEATURE_ID_MIRRORED_REPEAT, TRUE);

        private_flags |= COGL_PRIVATE_FEATURE_BLEND_CONSTANT;
    }
    else if (context->driver == COGL_DRIVER_GLES1)
        private_flags |= (COGL_PRIVATE_FEATURE_FIXED_FUNCTION |
                          COGL_PRIVATE_FEATURE_ALPHA_TEST |
                          COGL_PRIVATE_FEATURE_BUILTIN_POINT_SIZE_UNIFORM);

    private_flags |= (COGL_PRIVATE_FEATURE_VBOS |
                      COGL_PRIVATE_FEATURE_ANY_GL |
                      COGL_PRIVATE_FEATURE_ALPHA_TEXTURES);

    /* Both GLES 1.1 and GLES 2.0 support point sprites in core */
    COGL_FLAGS_SET (context->features, COGL_FEATURE_ID_POINT_SPRITE, TRUE);

    if (context->glGenRenderbuffers)
        COGL_FLAGS_SET (context->features, COGL_FEATURE_ID_OFFSCREEN, TRUE);

    if (context->glBlitFramebuffer)
        private_flags |= COGL_PRIVATE_FEATURE_OFFSCREEN_BLIT;

    if (_cogl_check_extension ("GL_OES_element_index_uint", gl_extensions))
        COGL_FLAGS_SET (context->features,
                        COGL_FEATURE_ID_UNSIGNED_INT_INDICES, TRUE);

    if (_cogl_check_extension ("GL_OES_depth_texture", gl_extensions))
        COGL_FLAGS_SET (context->features, COGL_FEATURE_ID_DEPTH_TEXTURE, TRUE);

    if (_cogl_check_extension ("GL_OES_texture_npot", gl_extensions))
    {
        COGL_FLAGS_SET (context->features,
                        COGL_FEATURE_ID_TEXTURE_NPOT, TRUE);
        COGL_FLAGS_SET (context->features,
                        COGL_FEATURE_ID_TEXTURE_NPOT_BASIC, TRUE);
        COGL_FLAGS_SET (context->features,
                        COGL_FEATURE_ID_TEXTURE_NPOT_MIPMAP, TRUE);
        COGL_FLAGS_SET (context->features,
                        COGL_FEATURE_ID_TEXTURE_NPOT_REPEAT, TRUE);
    }
    else if (_cogl_check_extension ("GL_IMG_texture_npot", gl_extensions))
    {
        COGL_FLAGS_SET (context->features,
                        COGL_FEATURE_ID_TEXTURE_NPOT_BASIC, TRUE);
        COGL_FLAGS_SET (context->features,
                        COGL_FEATURE_ID_TEXTURE_NPOT_MIPMAP, TRUE);
    }

    if (context->glTexImage3D)
        COGL_FLAGS_SET (context->features, COGL_FEATURE_ID_TEXTURE_3D, TRUE);

    if (context->glMapBuffer)
        /* The GL_OES_mapbuffer extension doesn't support mapping for
           read */
        COGL_FLAGS_SET (context->features,
                        COGL_FEATURE_ID_MAP_BUFFER_FOR_WRITE, TRUE);

    if (context->glEGLImageTargetTexture2D)
        private_flags |= COGL_PRIVATE_FEATURE_TEXTURE_2D_FROM_EGL_IMAGE;

    if (_cogl_check_extension ("GL_OES_packed_depth_stencil", gl_extensions))
        private_flags |= COGL_PRIVATE_FEATURE_OES_PACKED_DEPTH_STENCIL;

    if (_cogl_check_extension ("GL_EXT_texture_format_BGRA8888", gl_extensions))
        private_flags |= COGL_PRIVATE_FEATURE_TEXTURE_FORMAT_BGRA8888;

    if (_cogl_check_extension ("GL_EXT_unpack_subimage", gl_extensions))
        private_flags |= COGL_PRIVATE_FEATURE_UNPACK_SUBIMAGE;

    /* Cache features */
    context->private_feature_flags |= private_flags;

    g_strfreev (gl_extensions);

    return TRUE;
}