Query the framebuffer stencil bits instead of assuming it's global

Previously when the context was initialised Cogl would query the
number of stencil bits and set a private feature flag to mark that it
can use the buffer for clipping if there was at least 3. The problem
with this is that the number of stencil bits returned by
GL_STENCIL_BITS depends on the currently bound framebuffer. This patch
adds an internal function to query the number of stencil bits in a
framebuffer and makes it use that instead when determining whether it
can push the clip using the stencil buffer.

Reviewed-by: Robert Bragg <robert@linux.intel.com>

(cherry picked from commit e928d21516a6c07798655341f4f0f8e3c1d1686c)
This commit is contained in:
Neil Roberts 2012-12-13 15:49:38 +00:00 committed by Robert Bragg
parent 109e576b1f
commit 520ccba49d
7 changed files with 55 additions and 38 deletions

View File

@ -112,6 +112,7 @@ typedef struct
int green;
int alpha;
int depth;
int stencil;
} CoglFramebufferBits;
struct _CoglFramebuffer
@ -471,4 +472,18 @@ _cogl_framebuffer_read_pixels_into_bitmap (CoglFramebuffer *framebuffer,
CoglBitmap *bitmap,
CoglError **error);
/*
* _cogl_framebuffer_get_stencil_bits:
* @framebuffer: a pointer to a #CoglFramebuffer
*
* Retrieves the number of stencil bits of @framebuffer
*
* Return value: the number of bits
*
* Since: 2.0
* Stability: unstable
*/
int
_cogl_framebuffer_get_stencil_bits (CoglFramebuffer *framebuffer);
#endif /* __COGL_FRAMEBUFFER_PRIVATE_H */

View File

@ -1144,6 +1144,17 @@ cogl_framebuffer_get_depth_bits (CoglFramebuffer *framebuffer)
return bits.depth;
}
int
_cogl_framebuffer_get_stencil_bits (CoglFramebuffer *framebuffer)
{
CoglContext *ctx = framebuffer->context;
CoglFramebufferBits bits;
ctx->driver_vtable->framebuffer_query_bits (framebuffer, &bits);
return bits.stencil;
}
CoglColorMask
cogl_framebuffer_get_color_mask (CoglFramebuffer *framebuffer)
{

View File

@ -35,28 +35,27 @@ typedef enum
{
COGL_PRIVATE_FEATURE_TEXTURE_2D_FROM_EGL_IMAGE = 1L<<0,
COGL_PRIVATE_FEATURE_MESA_PACK_INVERT = 1L<<1,
COGL_PRIVATE_FEATURE_STENCIL_BUFFER = 1L<<2,
COGL_PRIVATE_FEATURE_OFFSCREEN_BLIT = 1L<<3,
COGL_PRIVATE_FEATURE_FOUR_CLIP_PLANES = 1L<<4,
COGL_PRIVATE_FEATURE_PBOS = 1L<<5,
COGL_PRIVATE_FEATURE_VBOS = 1L<<6,
COGL_PRIVATE_FEATURE_EXT_PACKED_DEPTH_STENCIL = 1L<<7,
COGL_PRIVATE_FEATURE_OES_PACKED_DEPTH_STENCIL = 1L<<8,
COGL_PRIVATE_FEATURE_TEXTURE_FORMAT_BGRA8888 = 1L<<9,
COGL_PRIVATE_FEATURE_UNPACK_SUBIMAGE = 1L<<10,
COGL_PRIVATE_FEATURE_SAMPLER_OBJECTS = 1L<<11,
COGL_PRIVATE_FEATURE_FIXED_FUNCTION = 1L<<12,
COGL_PRIVATE_FEATURE_READ_PIXELS_ANY_FORMAT = 1L<<13,
COGL_PRIVATE_FEATURE_ANY_GL = 1L<<14,
COGL_PRIVATE_FEATURE_ALPHA_TEST = 1L<<15,
COGL_PRIVATE_FEATURE_FORMAT_CONVERSION = 1L<<16,
COGL_PRIVATE_FEATURE_QUADS = 1L<<17,
COGL_PRIVATE_FEATURE_BLEND_CONSTANT = 1L<<18,
COGL_PRIVATE_FEATURE_QUERY_FRAMEBUFFER_BITS = 1L<<19,
COGL_PRIVATE_FEATURE_BUILTIN_POINT_SIZE_UNIFORM = 1L<<20,
COGL_PRIVATE_FEATURE_QUERY_TEXTURE_PARAMETERS = 1L<<21,
COGL_PRIVATE_FEATURE_ALPHA_TEXTURES = 1L<<22,
COGL_PRIVATE_FEATURE_TEXTURE_SWIZZLE = 1L<<23
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_FIXED_FUNCTION = 1L<<11,
COGL_PRIVATE_FEATURE_READ_PIXELS_ANY_FORMAT = 1L<<12,
COGL_PRIVATE_FEATURE_ANY_GL = 1L<<13,
COGL_PRIVATE_FEATURE_ALPHA_TEST = 1L<<14,
COGL_PRIVATE_FEATURE_FORMAT_CONVERSION = 1L<<15,
COGL_PRIVATE_FEATURE_QUADS = 1L<<16,
COGL_PRIVATE_FEATURE_BLEND_CONSTANT = 1L<<17,
COGL_PRIVATE_FEATURE_QUERY_FRAMEBUFFER_BITS = 1L<<18,
COGL_PRIVATE_FEATURE_BUILTIN_POINT_SIZE_UNIFORM = 1L<<19,
COGL_PRIVATE_FEATURE_QUERY_TEXTURE_PARAMETERS = 1L<<20,
COGL_PRIVATE_FEATURE_ALPHA_TEXTURES = 1L<<21,
COGL_PRIVATE_FEATURE_TEXTURE_SWIZZLE = 1L<<22
} CoglPrivateFeatureFlags;
/* Sometimes when evaluating pipelines, either during comparisons or

View File

@ -271,8 +271,8 @@ _cogl_path_fill_nodes_with_clipped_rectangle (CoglPath *path,
CoglFramebuffer *framebuffer,
CoglPipeline *pipeline)
{
if (!(path->data->context->private_feature_flags &
COGL_PRIVATE_FEATURE_STENCIL_BUFFER))
/* We need at least three stencil bits to combine clips */
if (_cogl_framebuffer_get_stencil_bits (framebuffer) >= 3)
{
static CoglBool seen_warning = FALSE;

View File

@ -922,6 +922,8 @@ _cogl_framebuffer_init_bits (CoglFramebuffer *framebuffer)
offsetof (CoglFramebufferBits, alpha) },
{ GL_DEPTH_ATTACHMENT, GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE,
offsetof (CoglFramebufferBits, depth) },
{ GL_STENCIL_ATTACHMENT, GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE,
offsetof (CoglFramebufferBits, stencil) },
};
int i;
@ -943,11 +945,12 @@ _cogl_framebuffer_init_bits (CoglFramebuffer *framebuffer)
GE( ctx, glGetIntegerv (GL_BLUE_BITS, &framebuffer->bits.blue) );
GE( ctx, glGetIntegerv (GL_ALPHA_BITS, &framebuffer->bits.alpha) );
GE( ctx, glGetIntegerv (GL_DEPTH_BITS, &framebuffer->bits.depth) );
GE( ctx, glGetIntegerv (GL_STENCIL_BITS, &framebuffer->bits.stencil) );
}
COGL_NOTE (OFFSCREEN,
"RGBA/D Bits for framebuffer[%p, %s]: %d, %d, %d, %d, %d",
"RGBA/D/S Bits for framebuffer[%p, %s]: %d, %d, %d, %d, %d, %d",
framebuffer,
framebuffer->type == COGL_FRAMEBUFFER_TYPE_OFFSCREEN
? "offscreen"
@ -956,7 +959,8 @@ _cogl_framebuffer_init_bits (CoglFramebuffer *framebuffer)
framebuffer->bits.blue,
framebuffer->bits.green,
framebuffer->bits.alpha,
framebuffer->bits.depth);
framebuffer->bits.depth,
framebuffer->bits.stencil);
framebuffer->dirty_bitmasks = FALSE;
}

View File

@ -360,7 +360,6 @@ _cogl_driver_update_features (CoglContext *ctx,
CoglFeatureFlags flags = 0;
char **gl_extensions;
int max_clip_planes = 0;
int num_stencil_bits = 0;
int gl_major = 0, gl_minor = 0;
/* We have to special case getting the pointer to the glGetString*
@ -450,11 +449,6 @@ _cogl_driver_update_features (CoglContext *ctx,
if (_cogl_check_extension ("GL_MESA_pack_invert", gl_extensions))
private_flags |= COGL_PRIVATE_FEATURE_MESA_PACK_INVERT;
GE( ctx, 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;
GE( ctx, glGetIntegerv (GL_MAX_CLIP_PLANES, &max_clip_planes) );
if (max_clip_planes >= 4)
private_flags |= COGL_PRIVATE_FEATURE_FOUR_CLIP_PLANES;

View File

@ -193,7 +193,6 @@ _cogl_driver_update_features (CoglContext *context,
CoglPrivateFeatureFlags private_flags = 0;
CoglFeatureFlags flags = 0;
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
@ -233,11 +232,6 @@ _cogl_driver_update_features (CoglContext *context,
-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)
{