features: Support more than 32 features!

Currently features are represented as bits in a 32bit mask so we
obviously can't have more than 32 features with that approach. The new
approach is to use the COGL_FLAGS_ macros which lets us handle bitmasks
without a size limit and we change the public api to accept individual
feature enums instead of a mask. This way there is no limit on the
number of features we can add to Cogl.

Instead of using cogl_features_available() there is a new
cogl_has_feature() function and for checking multiple features there is
cogl_has_features() which takes a zero terminated vararg list of
features.

In addition to being able to check for individual features this also
adds a way to query all the features currently available via
cogl_foreach_feature() which will call a callback for each feature.

Since the new functions take an explicit context pointer there is also
no longer any ambiguity over when users can first start to query
features.

Reviewed-by: Neil Roberts <neil@linux.intel.com>
This commit is contained in:
Robert Bragg 2011-10-12 22:31:12 +01:00
parent c86f698eb9
commit 426c8b8f41
27 changed files with 353 additions and 64 deletions

View File

@ -657,7 +657,7 @@ _cogl_atlas_texture_new_with_size (unsigned int width,
/* If we can't use FBOs then it will be too slow to migrate textures /* If we can't use FBOs then it will be too slow to migrate textures
and we shouldn't use the atlas */ and we shouldn't use the atlas */
if (!cogl_features_available (COGL_FEATURE_OFFSCREEN)) if (!cogl_has_feature (ctx, COGL_FEATURE_ID_OFFSCREEN))
return COGL_INVALID_HANDLE; return COGL_INVALID_HANDLE;
COGL_NOTE (ATLAS, "Adding texture of size %ix%i", width, height); COGL_NOTE (ATLAS, "Adding texture of size %ix%i", width, height);

View File

@ -134,10 +134,10 @@ bo_map (CoglBuffer *buffer,
_COGL_GET_CONTEXT (ctx, NULL); _COGL_GET_CONTEXT (ctx, NULL);
if ((access & COGL_BUFFER_ACCESS_READ) && if ((access & COGL_BUFFER_ACCESS_READ) &&
!cogl_features_available (COGL_FEATURE_MAP_BUFFER_FOR_READ)) !cogl_has_feature (ctx, COGL_FEATURE_ID_MAP_BUFFER_FOR_READ))
return NULL; return NULL;
if ((access & COGL_BUFFER_ACCESS_WRITE) && if ((access & COGL_BUFFER_ACCESS_WRITE) &&
!cogl_features_available (COGL_FEATURE_MAP_BUFFER_FOR_WRITE)) !cogl_has_feature (ctx, COGL_FEATURE_ID_MAP_BUFFER_FOR_WRITE))
return NULL; return NULL;
target = buffer->last_target; target = buffer->last_target;

View File

@ -63,7 +63,8 @@ struct _CoglContext
const CoglTextureDriver *texture_driver; const CoglTextureDriver *texture_driver;
/* Features cache */ /* Features cache */
CoglFeatureFlags feature_flags; unsigned int features[COGL_FLAGS_N_INTS_FOR_SIZE (_COGL_N_FEATURE_IDS)];
CoglFeatureFlags feature_flags; /* legacy/deprecated feature flags */
CoglPrivateFeatureFlags private_feature_flags; CoglPrivateFeatureFlags private_feature_flags;
CoglHandle default_pipeline; CoglHandle default_pipeline;

View File

@ -80,16 +80,31 @@ _cogl_init_feature_overrides (CoglContext *ctx)
ctx->private_feature_flags &= ~COGL_PRIVATE_FEATURE_PBOS; ctx->private_feature_flags &= ~COGL_PRIVATE_FEATURE_PBOS;
if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_DISABLE_ARBFP))) if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_DISABLE_ARBFP)))
ctx->feature_flags &= ~COGL_FEATURE_SHADERS_ARBFP; {
ctx->feature_flags &= ~COGL_FEATURE_SHADERS_ARBFP;
COGL_FLAGS_SET (ctx->features, COGL_FEATURE_ID_ARBFP, FALSE);
}
if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_DISABLE_GLSL))) if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_DISABLE_GLSL)))
ctx->feature_flags &= ~COGL_FEATURE_SHADERS_GLSL; {
ctx->feature_flags &= ~COGL_FEATURE_SHADERS_GLSL;
COGL_FLAGS_SET (ctx->features, COGL_FEATURE_ID_GLSL, FALSE);
}
if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_DISABLE_NPOT_TEXTURES))) if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_DISABLE_NPOT_TEXTURES)))
ctx->feature_flags &= ~(COGL_FEATURE_TEXTURE_NPOT | {
COGL_FEATURE_TEXTURE_NPOT_BASIC | ctx->feature_flags &= ~(COGL_FEATURE_TEXTURE_NPOT |
COGL_FEATURE_TEXTURE_NPOT_MIPMAP | COGL_FEATURE_TEXTURE_NPOT_BASIC |
COGL_FEATURE_TEXTURE_NPOT_REPEAT); COGL_FEATURE_TEXTURE_NPOT_MIPMAP |
COGL_FEATURE_TEXTURE_NPOT_REPEAT);
COGL_FLAGS_SET (ctx->features, COGL_FEATURE_ID_TEXTURE_NPOT, FALSE);
COGL_FLAGS_SET (ctx->features,
COGL_FEATURE_ID_TEXTURE_NPOT_BASIC, FALSE);
COGL_FLAGS_SET (ctx->features,
COGL_FEATURE_ID_TEXTURE_NPOT_MIPMAP, FALSE);
COGL_FLAGS_SET (ctx->features,
COGL_FEATURE_ID_TEXTURE_NPOT_REPEAT, FALSE);
}
} }
const CoglWinsysVtable * const CoglWinsysVtable *
@ -148,6 +163,7 @@ cogl_context_new (CoglDisplay *display,
_context = context; _context = context;
/* Init default values */ /* Init default values */
memset (context->features, 0, sizeof (context->features));
context->feature_flags = 0; context->feature_flags = 0;
context->private_feature_flags = 0; context->private_feature_flags = 0;
@ -378,7 +394,7 @@ cogl_context_new (CoglDisplay *display,
coords enabled. We don't need to do this for GLES2 because point coords enabled. We don't need to do this for GLES2 because point
sprites are handled using a builtin varying in the shader. */ sprites are handled using a builtin varying in the shader. */
if (_context->driver != COGL_DRIVER_GLES2 && if (_context->driver != COGL_DRIVER_GLES2 &&
cogl_features_available (COGL_FEATURE_POINT_SPRITE)) cogl_has_feature (context, COGL_FEATURE_ID_POINT_SPRITE))
GE (context, glEnable (GL_POINT_SPRITE)); GE (context, glEnable (GL_POINT_SPRITE));
return _cogl_context_object_new (context); return _cogl_context_object_new (context);

View File

@ -219,8 +219,8 @@ cogl_depth_state_get_test_function (CoglDepthState *state);
* using GLES 1 drivers) then if you don't use the default range * using GLES 1 drivers) then if you don't use the default range
* values you will get an error reported when calling * values you will get an error reported when calling
* cogl_pipeline_set_depth_state (). You can check ahead of time for * cogl_pipeline_set_depth_state (). You can check ahead of time for
* the %COGL_FEATURE_DEPTH_RANGE feature with * the %COGL_FEATURE_ID_DEPTH_RANGE feature with
* cogl_features_available() to know if this function will succeed. * cogl_has_feature() to know if this function will succeed.
* *
* By default normalized device coordinate depth values are mapped to * By default normalized device coordinate depth values are mapped to
* the full range of depth buffer values, [0, 1]. * the full range of depth buffer values, [0, 1].

View File

@ -629,7 +629,7 @@ _cogl_framebuffer_init_bits (CoglFramebuffer *framebuffer)
#ifdef HAVE_COGL_GL #ifdef HAVE_COGL_GL
if (ctx->driver == COGL_DRIVER_GL && if (ctx->driver == COGL_DRIVER_GL &&
cogl_features_available (COGL_FEATURE_OFFSCREEN) && cogl_has_feature (ctx, COGL_FEATURE_ID_OFFSCREEN) &&
framebuffer->type == COGL_FRAMEBUFFER_TYPE_OFFSCREEN) framebuffer->type == COGL_FRAMEBUFFER_TYPE_OFFSCREEN)
{ {
GLenum attachment, pname; GLenum attachment, pname;
@ -701,7 +701,7 @@ _cogl_offscreen_new_to_texture_full (CoglTexture *texture,
_COGL_GET_CONTEXT (ctx, COGL_INVALID_HANDLE); _COGL_GET_CONTEXT (ctx, COGL_INVALID_HANDLE);
if (!cogl_features_available (COGL_FEATURE_OFFSCREEN)) if (!cogl_has_feature (ctx, COGL_FEATURE_ID_OFFSCREEN))
return COGL_INVALID_HANDLE; return COGL_INVALID_HANDLE;
/* Make texture is a valid texture object */ /* Make texture is a valid texture object */
@ -1469,7 +1469,7 @@ bind_gl_framebuffer (CoglContext *ctx,
_cogl_framebuffer_get_winsys (framebuffer); _cogl_framebuffer_get_winsys (framebuffer);
winsys->onscreen_bind (COGL_ONSCREEN (framebuffer)); winsys->onscreen_bind (COGL_ONSCREEN (framebuffer));
/* glBindFramebuffer is an an extension with OpenGL ES 1.1 */ /* glBindFramebuffer is an an extension with OpenGL ES 1.1 */
if (cogl_features_available (COGL_FEATURE_OFFSCREEN)) if (cogl_has_feature (ctx, COGL_FEATURE_ID_OFFSCREEN))
GE (ctx, glBindFramebuffer (target, 0)); GE (ctx, glBindFramebuffer (target, 0));
} }
} }

View File

@ -171,7 +171,7 @@ _cogl_pipeline_fragend_arbfp_start (CoglPipeline *pipeline,
/* First validate that we can handle the current state using ARBfp /* First validate that we can handle the current state using ARBfp
*/ */
if (!cogl_features_available (COGL_FEATURE_SHADERS_ARBFP)) if (!cogl_has_feature (ctx, COGL_FEATURE_ID_ARBFP))
return FALSE; return FALSE;
/* TODO: support fog */ /* TODO: support fog */

View File

@ -190,7 +190,7 @@ _cogl_pipeline_fragend_glsl_start (CoglPipeline *pipeline,
_COGL_GET_CONTEXT (ctx, FALSE); _COGL_GET_CONTEXT (ctx, FALSE);
if (!cogl_features_available (COGL_FEATURE_SHADERS_GLSL)) if (!cogl_has_feature (ctx, COGL_FEATURE_ID_GLSL))
return FALSE; return FALSE;
user_program = cogl_pipeline_get_user_program (pipeline); user_program = cogl_pipeline_get_user_program (pipeline);

View File

@ -664,11 +664,13 @@ cogl_pipeline_set_layer_point_sprite_coords_enabled (CoglPipeline *pipeline,
CoglPipelineLayer *new; CoglPipelineLayer *new;
CoglPipelineLayer *authority; CoglPipelineLayer *authority;
_COGL_GET_CONTEXT (ctx, FALSE);
g_return_val_if_fail (cogl_is_pipeline (pipeline), FALSE); g_return_val_if_fail (cogl_is_pipeline (pipeline), FALSE);
/* Don't allow point sprite coordinates to be enabled if the driver /* Don't allow point sprite coordinates to be enabled if the driver
doesn't support it */ doesn't support it */
if (enable && !cogl_features_available (COGL_FEATURE_POINT_SPRITE)) if (enable && !cogl_has_feature (ctx, COGL_FEATURE_ID_POINT_SPRITE))
{ {
if (error) if (error)
{ {

View File

@ -687,8 +687,8 @@ get_max_activateable_texture_units (void)
defines the number of texture coordinates that can be defines the number of texture coordinates that can be
uploaded (but doesn't necessarily relate to how many texture uploaded (but doesn't necessarily relate to how many texture
images can be sampled) */ images can be sampled) */
if (cogl_features_available (COGL_FEATURE_SHADERS_GLSL) || if (cogl_has_feature (ctx, COGL_FEATURE_ID_GLSL) ||
cogl_features_available (COGL_FEATURE_SHADERS_ARBFP)) cogl_has_feature (ctx, COGL_FEATURE_ID_ARBFP))
/* Previously this code subtracted the value by one but there /* Previously this code subtracted the value by one but there
was no explanation for why it did this and it doesn't seem was no explanation for why it did this and it doesn't seem
to make sense so it has been removed */ to make sense so it has been removed */
@ -697,7 +697,7 @@ get_max_activateable_texture_units (void)
/* GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS is defined for GLSL but /* GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS is defined for GLSL but
not ARBfp */ not ARBfp */
if (cogl_features_available (COGL_FEATURE_SHADERS_GLSL)) if (cogl_has_feature (ctx, COGL_FEATURE_ID_GLSL))
GE (ctx, glGetIntegerv (GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, GE (ctx, glGetIntegerv (GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS,
values + n_values++)); values + n_values++));
} }

View File

@ -134,7 +134,7 @@ _cogl_pipeline_vertend_glsl_start (CoglPipeline *pipeline,
_COGL_GET_CONTEXT (ctx, FALSE); _COGL_GET_CONTEXT (ctx, FALSE);
if (!cogl_features_available (COGL_FEATURE_SHADERS_GLSL)) if (!cogl_has_feature (ctx, COGL_FEATURE_ID_GLSL))
return FALSE; return FALSE;
user_program = cogl_pipeline_get_user_program (pipeline); user_program = cogl_pipeline_get_user_program (pipeline);

View File

@ -203,7 +203,7 @@ _cogl_shader_set_source_with_boilerplate (GLuint shader_gl_handle,
} }
if (ctx->driver == COGL_DRIVER_GLES2 && if (ctx->driver == COGL_DRIVER_GLES2 &&
cogl_features_available (COGL_FEATURE_TEXTURE_3D)) cogl_has_feature (ctx, COGL_FEATURE_ID_TEXTURE_3D))
{ {
static const char texture_3d_extension[] = static const char texture_3d_extension[] =
"#extension GL_OES_texture_3D : enable\n"; "#extension GL_OES_texture_3D : enable\n";

View File

@ -702,7 +702,7 @@ _cogl_texture_2d_sliced_slices_create (CoglContext *ctx,
int (*slices_for_size) (int, int, int, GArray*); int (*slices_for_size) (int, int, int, GArray*);
/* Initialize size of largest slice according to supported features */ /* Initialize size of largest slice according to supported features */
if (cogl_features_available (COGL_FEATURE_TEXTURE_NPOT)) if (cogl_has_feature (ctx, COGL_FEATURE_ID_TEXTURE_NPOT))
{ {
max_width = width; max_width = width;
max_height = height; max_height = height;

View File

@ -181,7 +181,7 @@ _cogl_texture_2d_can_create (unsigned int width,
/* If NPOT textures aren't supported then the size must be a power /* If NPOT textures aren't supported then the size must be a power
of two */ of two */
if (!cogl_features_available (COGL_FEATURE_TEXTURE_NPOT) && if (!cogl_has_feature (ctx, COGL_FEATURE_ID_TEXTURE_NPOT) &&
(!_cogl_util_is_pot (width) || (!_cogl_util_is_pot (width) ||
!_cogl_util_is_pot (height))) !_cogl_util_is_pot (height)))
return FALSE; return FALSE;
@ -329,7 +329,7 @@ _cogl_texture_2d_new_from_bitmap (CoglBitmap *bmp,
/* Keep a copy of the first pixel so that if glGenerateMipmap isn't /* Keep a copy of the first pixel so that if glGenerateMipmap isn't
supported we can fallback to using GL_GENERATE_MIPMAP */ supported we can fallback to using GL_GENERATE_MIPMAP */
if (!cogl_features_available (COGL_FEATURE_OFFSCREEN) && if (!cogl_has_feature (ctx, COGL_FEATURE_ID_OFFSCREEN) &&
(data = _cogl_bitmap_map (dst_bmp, (data = _cogl_bitmap_map (dst_bmp,
COGL_BUFFER_ACCESS_READ, 0))) COGL_BUFFER_ACCESS_READ, 0)))
{ {
@ -771,7 +771,7 @@ _cogl_texture_2d_pre_paint (CoglTexture *tex, CoglTexturePrePaintFlags flags)
/* glGenerateMipmap is defined in the FBO extension. If it's not /* glGenerateMipmap is defined in the FBO extension. If it's not
available we'll fallback to temporarily enabling available we'll fallback to temporarily enabling
GL_GENERATE_MIPMAP and reuploading the first pixel */ GL_GENERATE_MIPMAP and reuploading the first pixel */
if (cogl_features_available (COGL_FEATURE_OFFSCREEN)) if (cogl_has_feature (ctx, COGL_FEATURE_ID_OFFSCREEN))
ctx->texture_driver->gl_generate_mipmaps (GL_TEXTURE_2D); ctx->texture_driver->gl_generate_mipmaps (GL_TEXTURE_2D);
#if defined(HAVE_COGL_GLES) || defined(HAVE_COGL_GL) #if defined(HAVE_COGL_GLES) || defined(HAVE_COGL_GL)
else else
@ -825,7 +825,7 @@ _cogl_texture_2d_set_region (CoglTexture *tex,
/* If this touches the first pixel then we'll update our copy */ /* If this touches the first pixel then we'll update our copy */
if (dst_x == 0 && dst_y == 0 && if (dst_x == 0 && dst_y == 0 &&
!cogl_features_available (COGL_FEATURE_OFFSCREEN) && !cogl_has_feature (ctx, COGL_FEATURE_ID_OFFSCREEN) &&
(data = _cogl_bitmap_map (bmp, COGL_BUFFER_ACCESS_READ, 0))) (data = _cogl_bitmap_map (bmp, COGL_BUFFER_ACCESS_READ, 0)))
{ {
CoglPixelFormat bpp = CoglPixelFormat bpp =

View File

@ -49,8 +49,8 @@ G_BEGIN_DECLS
* *
* You should be aware that many GPUs only support power of two sizes * You should be aware that many GPUs only support power of two sizes
* for #CoglTexture2D textures. You can check support for non power of * for #CoglTexture2D textures. You can check support for non power of
* two textures by checking for the %COGL_FEATURE_TEXTURE_NPOT feature * two textures by checking for the %COGL_FEATURE_ID_TEXTURE_NPOT feature
* via cogl_features_available (). * via cogl_has_feature().
*/ */
typedef struct _CoglTexture2D CoglTexture2D; typedef struct _CoglTexture2D CoglTexture2D;
@ -87,8 +87,8 @@ cogl_is_texture_2d (void *object);
* *
* <note>Many GPUs only support power of two sizes for #CoglTexture2D * <note>Many GPUs only support power of two sizes for #CoglTexture2D
* textures. You can check support for non power of two textures by * textures. You can check support for non power of two textures by
* checking for the %COGL_FEATURE_TEXTURE_NPOT feature via * checking for the %COGL_FEATURE_ID_TEXTURE_NPOT feature via
* cogl_features_available ().</note> * cogl_has_feature().</note>
* *
* Returns: A newly allocated #CoglTexture2D, or if the size is not * Returns: A newly allocated #CoglTexture2D, or if the size is not
* supported (because it is too large or a non-power-of-two * supported (because it is too large or a non-power-of-two
@ -132,8 +132,8 @@ cogl_texture_2d_new_with_size (CoglContext *ctx,
* *
* <note>Many GPUs only support power of two sizes for #CoglTexture2D * <note>Many GPUs only support power of two sizes for #CoglTexture2D
* textures. You can check support for non power of two textures by * textures. You can check support for non power of two textures by
* checking for the %COGL_FEATURE_TEXTURE_NPOT feature via * checking for the %COGL_FEATURE_ID_TEXTURE_NPOT feature via
* cogl_features_available ().</note> * cogl_has_feature().</note>
* *
* Returns: A newly allocated #CoglTexture2D, or if the size is not * Returns: A newly allocated #CoglTexture2D, or if the size is not
* supported (because it is too large or a non-power-of-two * supported (because it is too large or a non-power-of-two

View File

@ -219,7 +219,7 @@ _cogl_texture_3d_can_create (unsigned int width,
_COGL_GET_CONTEXT (ctx, FALSE); _COGL_GET_CONTEXT (ctx, FALSE);
/* This should only happen on GLES */ /* This should only happen on GLES */
if (!cogl_features_available (COGL_FEATURE_TEXTURE_3D)) if (!cogl_has_feature (ctx, COGL_FEATURE_ID_TEXTURE_3D))
{ {
g_set_error (error, g_set_error (error,
COGL_ERROR, COGL_ERROR,
@ -230,7 +230,7 @@ _cogl_texture_3d_can_create (unsigned int width,
/* If NPOT textures aren't supported then the size must be a power /* If NPOT textures aren't supported then the size must be a power
of two */ of two */
if (!cogl_features_available (COGL_FEATURE_TEXTURE_NPOT) && if (!cogl_has_feature (ctx, COGL_FEATURE_ID_TEXTURE_NPOT) &&
(!_cogl_util_is_pot (width) || (!_cogl_util_is_pot (width) ||
!_cogl_util_is_pot (height) || !_cogl_util_is_pot (height) ||
!_cogl_util_is_pot (depth))) !_cogl_util_is_pot (depth)))
@ -357,7 +357,7 @@ _cogl_texture_3d_new_from_bitmap (CoglBitmap *bmp,
/* Keep a copy of the first pixel so that if glGenerateMipmap isn't /* Keep a copy of the first pixel so that if glGenerateMipmap isn't
supported we can fallback to using GL_GENERATE_MIPMAP */ supported we can fallback to using GL_GENERATE_MIPMAP */
if (!cogl_features_available (COGL_FEATURE_OFFSCREEN) && if (!cogl_has_feature (ctx, COGL_FEATURE_ID_OFFSCREEN) &&
(data = _cogl_bitmap_map (dst_bmp, (data = _cogl_bitmap_map (dst_bmp,
COGL_BUFFER_ACCESS_READ, 0))) COGL_BUFFER_ACCESS_READ, 0)))
{ {
@ -578,7 +578,7 @@ _cogl_texture_3d_pre_paint (CoglTexture *tex, CoglTexturePrePaintFlags flags)
/* glGenerateMipmap is defined in the FBO extension. If it's not /* glGenerateMipmap is defined in the FBO extension. If it's not
available we'll fallback to temporarily enabling available we'll fallback to temporarily enabling
GL_GENERATE_MIPMAP and reuploading the first pixel */ GL_GENERATE_MIPMAP and reuploading the first pixel */
if (cogl_features_available (COGL_FEATURE_OFFSCREEN)) if (cogl_has_feature (ctx, COGL_FEATURE_ID_OFFSCREEN))
ctx->texture_driver->gl_generate_mipmaps (GL_TEXTURE_3D); ctx->texture_driver->gl_generate_mipmaps (GL_TEXTURE_3D);
#if defined (HAVE_COGL_GL) || defined (HAVE_COGL_GLES) #if defined (HAVE_COGL_GL) || defined (HAVE_COGL_GLES)
else if (ctx->driver != COGL_DRIVER_GLES2) else if (ctx->driver != COGL_DRIVER_GLES2)

View File

@ -198,7 +198,7 @@ _cogl_texture_rectangle_can_create (unsigned int width,
_COGL_GET_CONTEXT (ctx, FALSE); _COGL_GET_CONTEXT (ctx, FALSE);
if (!cogl_features_available (COGL_FEATURE_TEXTURE_RECTANGLE)) if (!cogl_has_feature (ctx, COGL_FEATURE_ID_TEXTURE_RECTANGLE))
return FALSE; return FALSE;
ctx->texture_driver->pixel_format_to_gl (internal_format, ctx->texture_driver->pixel_format_to_gl (internal_format,

View File

@ -1121,7 +1121,7 @@ get_texture_bits_via_offscreen (CoglTexture *texture,
_COGL_GET_CONTEXT (ctx, FALSE); _COGL_GET_CONTEXT (ctx, FALSE);
if (!cogl_features_available (COGL_FEATURE_OFFSCREEN)) if (!cogl_has_feature (ctx, COGL_FEATURE_ID_OFFSCREEN))
return FALSE; return FALSE;
framebuffer = _cogl_offscreen_new_to_texture_full framebuffer = _cogl_offscreen_new_to_texture_full

View File

@ -319,6 +319,38 @@ cogl_features_available (CoglFeatureFlags features)
return (ctx->feature_flags & features) == features; return (ctx->feature_flags & features) == features;
} }
gboolean
cogl_has_feature (CoglContext *ctx, CoglFeatureID feature)
{
return COGL_FLAGS_GET (ctx->features, feature);
}
gboolean
cogl_has_features (CoglContext *ctx, ...)
{
va_list args;
CoglFeatureID feature;
va_start (args, ctx);
while ((feature = va_arg (args, CoglFeatureID)))
if (!cogl_has_feature (ctx, feature))
return FALSE;
va_end (args);
return TRUE;
}
void
cogl_foreach_feature (CoglContext *ctx,
CoglFeatureCallback callback,
void *user_data)
{
int i;
for (i = 0; i < _COGL_N_FEATURE_IDS; i++)
if (COGL_FLAGS_GET (ctx->features, i))
callback (i, user_data);
}
/* XXX: This function should either be replaced with one returning /* XXX: This function should either be replaced with one returning
* integers, or removed/deprecated and make the * integers, or removed/deprecated and make the
* _cogl_framebuffer_get_viewport* functions public. * _cogl_framebuffer_get_viewport* functions public.

View File

@ -157,6 +157,156 @@ cogl_get_features (void);
gboolean gboolean
cogl_features_available (CoglFeatureFlags features); cogl_features_available (CoglFeatureFlags features);
/* XXX: not guarded by the EXPERIMENTAL_2_0_API defines to avoid
* upsetting glib-mkenums, but this can still be considered implicitly
* experimental since it's only useable with experimental API... */
/**
* CoglFeatureID:
* @COGL_FEATURE_ID_TEXTURE_NPOT_BASIC: The hardware supports non power
* of two textures, but you also need to check the
* %COGL_FEATURE_ID_TEXTURE_NPOT_MIPMAP and %COGL_FEATURE_ID_TEXTURE_NPOT_REPEAT
* features to know if the hardware supports npot texture mipmaps
* or repeat modes other than
* %COGL_RENDERER_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE respectively.
* @COGL_FEATURE_ID_TEXTURE_NPOT_MIPMAP: Mipmapping is supported in
* conjuntion with non power of two textures.
* @COGL_FEATURE_ID_TEXTURE_NPOT_REPEAT: Repeat modes other than
* %COGL_RENDERER_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE are supported by the
* hardware.
* @COGL_FEATURE_ID_TEXTURE_NPOT: Non power of two textures are supported
* by the hardware. This is a equivalent to the
* %COGL_FEATURE_ID_TEXTURE_NPOT_BASIC, %COGL_FEATURE_ID_TEXTURE_NPOT_MIPMAP
* and %COGL_FEATURE_ID_TEXTURE_NPOT_REPEAT features combined.
* @COGL_FEATURE_ID_TEXTURE_RECTANGLE: Support for rectangular
* textures with non-normalized texture coordinates.
* @COGL_FEATURE_ID_TEXTURE_3D: 3D texture support
* @COGL_FEATURE_ID_OFFSCREEN: Offscreen rendering support
* @COGL_FEATURE_ID_OFFSCREEN_MULTISAMPLE: Multisample support for
* offscreen framebuffers
* @COGL_FEATURE_ID_ONSCREEN_MULTIPLE: Multiple onscreen framebuffers
* supported.
* @COGL_FEATURE_ID_GLSL: GLSL support
* @COGL_FEATURE_ID_ARBFP: ARBFP support
* @COGL_FEATURE_ID_UNSIGNED_INT_INDICES: Set if
* %COGL_RENDERER_INDICES_TYPE_UNSIGNED_INT is supported in
* cogl_indices_new().
* @COGL_FEATURE_ID_DEPTH_RANGE: cogl_pipeline_set_depth_range() support
* @COGL_FEATURE_ID_POINT_SPRITE: Whether
* cogl_pipeline_set_layer_point_sprite_coords_enabled() is supported.
* @COGL_FEATURE_ID_MAP_BUFFER_FOR_READ: Whether cogl_buffer_map() is
* supported with CoglBufferAccess including read support.
* @COGL_FEATURE_ID_MAP_BUFFER_FOR_WRITE: Whether cogl_buffer_map() is
* supported with CoglBufferAccess including write support.
*
*
* All the capabilities that can vary between different GPUs supported
* by Cogl. Applications that depend on any of these features should explicitly
* check for them using cogl_has_feature() or cogl_has_features().
*
* Since: 1.10
*/
typedef enum _CoglFeatureID
{
COGL_FEATURE_ID_TEXTURE_NPOT_BASIC = 1,
COGL_FEATURE_ID_TEXTURE_NPOT_MIPMAP,
COGL_FEATURE_ID_TEXTURE_NPOT_REPEAT,
COGL_FEATURE_ID_TEXTURE_NPOT,
COGL_FEATURE_ID_TEXTURE_RECTANGLE,
COGL_FEATURE_ID_TEXTURE_3D,
COGL_FEATURE_ID_GLSL,
COGL_FEATURE_ID_ARBFP,
COGL_FEATURE_ID_OFFSCREEN,
COGL_FEATURE_ID_OFFSCREEN_MULTISAMPLE,
COGL_FEATURE_ID_ONSCREEN_MULTIPLE,
COGL_FEATURE_ID_UNSIGNED_INT_INDICES,
COGL_FEATURE_ID_DEPTH_RANGE,
COGL_FEATURE_ID_POINT_SPRITE,
COGL_FEATURE_ID_MAP_BUFFER_FOR_READ,
COGL_FEATURE_ID_MAP_BUFFER_FOR_WRITE,
/*< private > */
_COGL_N_FEATURE_IDS
} CoglFeatureID;
#ifdef COGL_ENABLE_EXPERIMENTAL_2_0_API
#define cogl_has_feature cogl_has_feature_EXP
/**
* cogl_has_feature:
* @context: A #CoglContext pointer
* @feature: A #CoglFeatureID
*
* Checks if a given @feature is currently available
*
* Cogl does not aim to be a lowest common denominator API, it aims to
* expose all the interesting features of GPUs to application which
* means applications have some responsibility to explicitly check
* that certain features are available before depending on them.
*
* Returns: %TRUE if the @feature is currently supported or %FALSE if
* not.
*
* Since: 1.10
* Stability: unstable
*/
gboolean
cogl_has_feature (CoglContext *context, CoglFeatureID feature);
#define cogl_has_features cogl_has_features_EXP
/**
* cogl_has_features:
* @context: A #CoglContext pointer
* @...: A 0 terminated list of CoglFeatureID<!-- -->s
*
* Checks if a list of features are all currently available.
*
* This checks all of the listed features using cogl_has_feature() and
* returns %TRUE if all the features are available or %FALSE
* otherwise.
*
* Return value: %TRUE if all the features are available, %FALSE
* otherwise.
*
* Since: 1.10
* Stability: unstable
*/
gboolean
cogl_has_features (CoglContext *context, ...);
/**
* CoglFeatureCallback:
* @feature: A single feature currently supported by Cogl
* @user_data: A private pointer passed to cogl_foreach_feature().
*
* A callback used with cogl_foreach_feature() for enumerating all
* context level features supported by Cogl.
*
* Since: 1.10
* Stability: unstable
*/
typedef void (*CoglFeatureCallback) (CoglFeatureID feature, void *user_data);
#define cogl_foreach_feature cogl_foreach_feature_EXP
/**
* cogl_foreach_feature:
* @context: A #CoglContext pointer
* @callback: A #CoglFeatureCallback called for each supported feature
* @user_data: Private data to pass to the callback
*
* Iterates through all the context level features currently supported
* for a given @context and for each feature @callback is called.
*
* Since: 1.10
* Stability: unstable
*/
void
cogl_foreach_feature (CoglContext *context,
CoglFeatureCallback callback,
void *user_data);
#endif /* COGL_ENABLE_EXPERIMENTAL_2_0_API */
/** /**
* cogl_get_proc_address: * cogl_get_proc_address:
* @name: the name of the function. * @name: the name of the function.

View File

@ -160,6 +160,9 @@ _cogl_gl_update_features (CoglContext *context,
flags = (COGL_FEATURE_TEXTURE_READ_PIXELS flags = (COGL_FEATURE_TEXTURE_READ_PIXELS
| COGL_FEATURE_UNSIGNED_INT_INDICES | COGL_FEATURE_UNSIGNED_INT_INDICES
| COGL_FEATURE_DEPTH_RANGE); | COGL_FEATURE_DEPTH_RANGE);
COGL_FLAGS_SET (ctx->features,
COGL_FEATURE_ID_UNSIGNED_INT_INDICES, TRUE);
COGL_FLAGS_SET (ctx->features, COGL_FEATURE_ID_DEPTH_RANGE, TRUE);
gl_extensions = (const char *)ctx->glGetString (GL_EXTENSIONS); gl_extensions = (const char *)ctx->glGetString (GL_EXTENSIONS);
@ -175,6 +178,13 @@ _cogl_gl_update_features (CoglContext *context,
| COGL_FEATURE_TEXTURE_NPOT_BASIC | COGL_FEATURE_TEXTURE_NPOT_BASIC
| COGL_FEATURE_TEXTURE_NPOT_MIPMAP | COGL_FEATURE_TEXTURE_NPOT_MIPMAP
| COGL_FEATURE_TEXTURE_NPOT_REPEAT; | COGL_FEATURE_TEXTURE_NPOT_REPEAT;
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)) if (_cogl_check_extension ("GL_MESA_pack_invert", gl_extensions))
@ -190,13 +200,20 @@ _cogl_gl_update_features (CoglContext *context,
private_flags |= COGL_PRIVATE_FEATURE_FOUR_CLIP_PLANES; private_flags |= COGL_PRIVATE_FEATURE_FOUR_CLIP_PLANES;
if (context->glGenRenderbuffers) if (context->glGenRenderbuffers)
flags |= COGL_FEATURE_OFFSCREEN; {
flags |= COGL_FEATURE_OFFSCREEN;
COGL_FLAGS_SET (ctx->features, COGL_FEATURE_ID_OFFSCREEN, TRUE);
}
if (context->glBlitFramebuffer) if (context->glBlitFramebuffer)
private_flags |= COGL_PRIVATE_FEATURE_OFFSCREEN_BLIT; private_flags |= COGL_PRIVATE_FEATURE_OFFSCREEN_BLIT;
if (context->glRenderbufferStorageMultisampleIMG) if (context->glRenderbufferStorageMultisampleIMG)
{
flags |= COGL_FEATURE_OFFSCREEN_MULTISAMPLE; flags |= COGL_FEATURE_OFFSCREEN_MULTISAMPLE;
COGL_FLAGS_SET (ctx->features,
COGL_FEATURE_ID_OFFSCREEN_MULTISAMPLE, TRUE);
}
if (COGL_CHECK_GL_VERSION (gl_major, gl_minor, 2, 1) || if (COGL_CHECK_GL_VERSION (gl_major, gl_minor, 2, 1) ||
_cogl_check_extension ("GL_EXT_pixel_buffer_object", gl_extensions)) _cogl_check_extension ("GL_EXT_pixel_buffer_object", gl_extensions))
@ -204,26 +221,46 @@ _cogl_gl_update_features (CoglContext *context,
if (COGL_CHECK_GL_VERSION (gl_major, gl_minor, 2, 0) || if (COGL_CHECK_GL_VERSION (gl_major, gl_minor, 2, 0) ||
_cogl_check_extension ("GL_ARB_point_sprite", gl_extensions)) _cogl_check_extension ("GL_ARB_point_sprite", gl_extensions))
flags |= COGL_FEATURE_POINT_SPRITE; {
flags |= COGL_FEATURE_POINT_SPRITE;
COGL_FLAGS_SET (ctx->features, COGL_FEATURE_ID_POINT_SPRITE, TRUE);
}
if (context->glGenPrograms) if (context->glGenPrograms)
flags |= COGL_FEATURE_SHADERS_ARBFP; {
flags |= COGL_FEATURE_SHADERS_ARBFP;
COGL_FLAGS_SET (ctx->features, COGL_FEATURE_ID_ARBFP, TRUE);
}
if (context->glCreateProgram) if (context->glCreateProgram)
flags |= COGL_FEATURE_SHADERS_GLSL; {
flags |= COGL_FEATURE_SHADERS_GLSL;
COGL_FLAGS_SET (ctx->features, COGL_FEATURE_ID_GLSL, TRUE);
}
if (context->glGenBuffers) if (context->glGenBuffers)
{ {
private_flags |= COGL_PRIVATE_FEATURE_VBOS; private_flags |= COGL_PRIVATE_FEATURE_VBOS;
flags |= (COGL_FEATURE_MAP_BUFFER_FOR_READ | flags |= (COGL_FEATURE_MAP_BUFFER_FOR_READ |
COGL_FEATURE_MAP_BUFFER_FOR_WRITE); COGL_FEATURE_MAP_BUFFER_FOR_WRITE);
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)) if (_cogl_check_extension ("GL_ARB_texture_rectangle", gl_extensions))
flags |= COGL_FEATURE_TEXTURE_RECTANGLE; {
flags |= COGL_FEATURE_TEXTURE_RECTANGLE;
COGL_FLAGS_SET (ctx->features,
COGL_FEATURE_ID_TEXTURE_RECTANGLE, TRUE);
}
if (context->glTexImage3D) if (context->glTexImage3D)
flags |= COGL_FEATURE_TEXTURE_3D; {
flags |= COGL_FEATURE_TEXTURE_3D;
COGL_FLAGS_SET (ctx->features, COGL_FEATURE_ID_TEXTURE_3D, TRUE);
}
if (context->glEGLImageTargetTexture2D) if (context->glEGLImageTargetTexture2D)
private_flags |= COGL_PRIVATE_FEATURE_TEXTURE_2D_FROM_EGL_IMAGE; private_flags |= COGL_PRIVATE_FEATURE_TEXTURE_2D_FROM_EGL_IMAGE;

View File

@ -101,7 +101,7 @@ prep_gl_for_pixels_upload_full (int pixels_rowstride,
GE( ctx, glPixelStorei (GL_UNPACK_SKIP_PIXELS, pixels_src_x) ); GE( ctx, glPixelStorei (GL_UNPACK_SKIP_PIXELS, pixels_src_x) );
GE( ctx, glPixelStorei (GL_UNPACK_SKIP_ROWS, pixels_src_y) ); GE( ctx, glPixelStorei (GL_UNPACK_SKIP_ROWS, pixels_src_y) );
if (cogl_features_available (COGL_FEATURE_TEXTURE_3D)) if (cogl_has_feature (ctx, COGL_FEATURE_ID_TEXTURE_3D))
GE( ctx, glPixelStorei (GL_UNPACK_IMAGE_HEIGHT, image_height) ); GE( ctx, glPixelStorei (GL_UNPACK_IMAGE_HEIGHT, image_height) );
_cogl_texture_prep_gl_alignment_for_pixels_upload (pixels_rowstride); _cogl_texture_prep_gl_alignment_for_pixels_upload (pixels_rowstride);
@ -130,7 +130,7 @@ prep_gl_for_pixels_download_full (int pixels_rowstride,
GE( ctx, glPixelStorei (GL_PACK_SKIP_PIXELS, pixels_src_x) ); GE( ctx, glPixelStorei (GL_PACK_SKIP_PIXELS, pixels_src_x) );
GE( ctx, glPixelStorei (GL_PACK_SKIP_ROWS, pixels_src_y) ); GE( ctx, glPixelStorei (GL_PACK_SKIP_ROWS, pixels_src_y) );
if (cogl_features_available (COGL_FEATURE_TEXTURE_3D)) if (cogl_has_feature (ctx, COGL_FEATURE_ID_TEXTURE_3D))
GE( ctx, glPixelStorei (GL_PACK_IMAGE_HEIGHT, image_height) ); GE( ctx, glPixelStorei (GL_PACK_IMAGE_HEIGHT, image_height) );
_cogl_texture_prep_gl_alignment_for_pixels_download (pixels_rowstride); _cogl_texture_prep_gl_alignment_for_pixels_download (pixels_rowstride);

View File

@ -89,36 +89,74 @@ _cogl_gles_update_features (CoglContext *context,
* repeat modes other than CLAMP_TO_EDGE. */ * repeat modes other than CLAMP_TO_EDGE. */
flags |= COGL_FEATURE_TEXTURE_NPOT_BASIC; flags |= COGL_FEATURE_TEXTURE_NPOT_BASIC;
flags |= COGL_FEATURE_DEPTH_RANGE; 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);
} }
private_flags |= COGL_PRIVATE_FEATURE_VBOS; private_flags |= COGL_PRIVATE_FEATURE_VBOS;
/* Both GLES 1.1 and GLES 2.0 support point sprites in core */ /* Both GLES 1.1 and GLES 2.0 support point sprites in core */
flags |= COGL_FEATURE_POINT_SPRITE; flags |= COGL_FEATURE_POINT_SPRITE;
COGL_FLAGS_SET (context->features, COGL_FEATURE_ID_POINT_SPRITE, TRUE);
if (context->glGenRenderbuffers) if (context->glGenRenderbuffers)
flags |= COGL_FEATURE_OFFSCREEN; {
flags |= COGL_FEATURE_OFFSCREEN;
COGL_FLAGS_SET (context->features, COGL_FEATURE_ID_OFFSCREEN, TRUE);
}
if (context->glBlitFramebuffer) if (context->glBlitFramebuffer)
private_flags |= COGL_PRIVATE_FEATURE_OFFSCREEN_BLIT; private_flags |= COGL_PRIVATE_FEATURE_OFFSCREEN_BLIT;
if (_cogl_check_extension ("GL_OES_element_index_uint", gl_extensions)) if (_cogl_check_extension ("GL_OES_element_index_uint", gl_extensions))
flags |= COGL_FEATURE_UNSIGNED_INT_INDICES; {
flags |= COGL_FEATURE_UNSIGNED_INT_INDICES;
COGL_FLAGS_SET (context->features,
COGL_FEATURE_ID_UNSIGNED_INT_INDICES, TRUE);
}
if (_cogl_check_extension ("GL_OES_texture_npot", gl_extensions) || if (_cogl_check_extension ("GL_OES_texture_npot", gl_extensions))
_cogl_check_extension ("GL_IMG_texture_npot", gl_extensions)) {
flags |= (COGL_FEATURE_TEXTURE_NPOT | flags |= (COGL_FEATURE_TEXTURE_NPOT |
COGL_FEATURE_TEXTURE_NPOT_BASIC | COGL_FEATURE_TEXTURE_NPOT_BASIC |
COGL_FEATURE_TEXTURE_NPOT_MIPMAP | COGL_FEATURE_TEXTURE_NPOT_MIPMAP |
COGL_FEATURE_TEXTURE_NPOT_REPEAT); 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) if (context->glTexImage3D)
flags |= COGL_FEATURE_TEXTURE_3D; {
flags |= COGL_FEATURE_TEXTURE_3D;
COGL_FLAGS_SET (context->features, COGL_FEATURE_ID_TEXTURE_3D, TRUE);
}
if (context->glMapBuffer) if (context->glMapBuffer)
/* The GL_OES_mapbuffer extension doesn't support mapping for {
read */ /* The GL_OES_mapbuffer extension doesn't support mapping for
flags |= COGL_FEATURE_MAP_BUFFER_FOR_WRITE; read */
flags |= COGL_FEATURE_MAP_BUFFER_FOR_WRITE;
COGL_FLAGS_SET (context->features,
COGL_FEATURE_ID_MAP_BUFFER_FOR_WRITE, TRUE);
}
if (context->glEGLImageTargetTexture2D) if (context->glEGLImageTargetTexture2D)
private_flags |= COGL_PRIVATE_FEATURE_TEXTURE_2D_FROM_EGL_IMAGE; private_flags |= COGL_PRIVATE_FEATURE_TEXTURE_2D_FROM_EGL_IMAGE;

View File

@ -533,6 +533,8 @@ update_winsys_features (CoglContext *context, GError **error)
#if defined (COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT) || \ #if defined (COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT) || \
defined (COGL_HAS_EGL_PLATFORM_WAYLAND_SUPPORT) defined (COGL_HAS_EGL_PLATFORM_WAYLAND_SUPPORT)
context->feature_flags |= COGL_FEATURE_ONSCREEN_MULTIPLE; context->feature_flags |= COGL_FEATURE_ONSCREEN_MULTIPLE;
COGL_FLAGS_SET (context->features,
COGL_FEATURE_ID_ONSCREEN_MULTIPLE, TRUE);
COGL_FLAGS_SET (context->winsys_features, COGL_FLAGS_SET (context->winsys_features,
COGL_WINSYS_FEATURE_MULTIPLE_ONSCREEN, COGL_WINSYS_FEATURE_MULTIPLE_ONSCREEN,
TRUE); TRUE);

View File

@ -395,6 +395,8 @@ update_winsys_features (CoglContext *context, GError **error)
COGL_NOTE (WINSYS, " GLX Extensions: %s", glx_extensions); COGL_NOTE (WINSYS, " GLX Extensions: %s", glx_extensions);
context->feature_flags |= COGL_FEATURE_ONSCREEN_MULTIPLE; context->feature_flags |= COGL_FEATURE_ONSCREEN_MULTIPLE;
COGL_FLAGS_SET (context->features,
COGL_FEATURE_ID_ONSCREEN_MULTIPLE, TRUE);
COGL_FLAGS_SET (context->winsys_features, COGL_FLAGS_SET (context->winsys_features,
COGL_WINSYS_FEATURE_MULTIPLE_ONSCREEN, COGL_WINSYS_FEATURE_MULTIPLE_ONSCREEN,
TRUE); TRUE);
@ -1604,7 +1606,7 @@ get_fbconfig_for_depth (CoglContext *context,
stencil = value; stencil = value;
/* glGenerateMipmap is defined in the offscreen extension */ /* glGenerateMipmap is defined in the offscreen extension */
if (cogl_features_available (COGL_FEATURE_OFFSCREEN)) if (cogl_has_feature (context, COGL_FEATURE_ID_OFFSCREEN))
{ {
glx_renderer->glXGetFBConfigAttrib (dpy, glx_renderer->glXGetFBConfigAttrib (dpy,
fbconfigs[i], fbconfigs[i],
@ -1639,7 +1641,7 @@ should_use_rectangle (CoglContext *context)
if (context->rectangle_state == COGL_WINSYS_RECTANGLE_STATE_UNKNOWN) if (context->rectangle_state == COGL_WINSYS_RECTANGLE_STATE_UNKNOWN)
{ {
if (cogl_features_available (COGL_FEATURE_TEXTURE_RECTANGLE)) if (cogl_has_feature (context, COGL_FEATURE_ID_TEXTURE_RECTANGLE))
{ {
const char *rect_env; const char *rect_env;
@ -1654,7 +1656,7 @@ should_use_rectangle (CoglContext *context)
are not available */ are not available */
context->rectangle_state = context->rectangle_state =
cogl_features_available (COGL_FEATURE_TEXTURE_NPOT) ? cogl_has_feature (context, COGL_FEATURE_ID_TEXTURE_NPOT) ?
COGL_WINSYS_RECTANGLE_STATE_DISABLE : COGL_WINSYS_RECTANGLE_STATE_DISABLE :
COGL_WINSYS_RECTANGLE_STATE_ENABLE; COGL_WINSYS_RECTANGLE_STATE_ENABLE;

View File

@ -592,6 +592,8 @@ update_winsys_features (CoglContext *context, GError **error)
memset (context->winsys_features, 0, sizeof (context->winsys_features)); memset (context->winsys_features, 0, sizeof (context->winsys_features));
context->feature_flags |= COGL_FEATURE_ONSCREEN_MULTIPLE; context->feature_flags |= COGL_FEATURE_ONSCREEN_MULTIPLE;
COGL_FLAGS_SET (context->features,
COGL_FEATURE_ID_ONSCREEN_MULTIPLE, TRUE);
COGL_FLAGS_SET (context->winsys_features, COGL_FLAGS_SET (context->winsys_features,
COGL_WINSYS_FEATURE_MULTIPLE_ONSCREEN, COGL_WINSYS_FEATURE_MULTIPLE_ONSCREEN,
TRUE); TRUE);

View File

@ -76,6 +76,13 @@ cogl_wayland_display_set_compositor_display
cogl_context_new cogl_context_new
cogl_context_get_display cogl_context_get_display
<SUBSECTION>
CoglFeatureID
cogl_has_feature
cogl_has_features
CoglFeatureCallback
cogl_foreach_feature
<SUBSECTION> <SUBSECTION>
cogl_push_matrix cogl_push_matrix
cogl_pop_matrix cogl_pop_matrix