[Cogl] [PATCH 4/6] Query the framebuffer stencil bits instead of assuming it's global

Neil Roberts neil at linux.intel.com
Fri Dec 14 03:43:30 PST 2012


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.
---
 cogl/cogl-framebuffer-private.h        | 15 ++++++++++++
 cogl/cogl-framebuffer.c                | 11 +++++++++
 cogl/cogl-internal.h                   | 43 +++++++++++++++++-----------------
 cogl/cogl-path.c                       |  4 ++--
 cogl/driver/gl/cogl-framebuffer-gl.c   |  8 +++++--
 cogl/driver/gl/gl/cogl-driver-gl.c     |  6 -----
 cogl/driver/gl/gles/cogl-driver-gles.c |  6 -----
 7 files changed, 55 insertions(+), 38 deletions(-)

diff --git a/cogl/cogl-framebuffer-private.h b/cogl/cogl-framebuffer-private.h
index 6acf42c..c6cea50 100644
--- a/cogl/cogl-framebuffer-private.h
+++ b/cogl/cogl-framebuffer-private.h
@@ -112,6 +112,7 @@ typedef struct
   int green;
   int alpha;
   int depth;
+  int stencil;
 } CoglFramebufferBits;
 
 struct _CoglFramebuffer
@@ -490,4 +491,18 @@ _cogl_framebuffer_get_projection_entry (CoglFramebuffer *framebuffer)
 void
 _cogl_framebuffer_flush (CoglFramebuffer *framebuffer);
 
+/*
+ * _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 */
diff --git a/cogl/cogl-framebuffer.c b/cogl/cogl-framebuffer.c
index 771a7bf..a34a510 100644
--- a/cogl/cogl-framebuffer.c
+++ b/cogl/cogl-framebuffer.c
@@ -898,6 +898,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)
 {
diff --git a/cogl/cogl-internal.h b/cogl/cogl-internal.h
index fa921a6..50aef50 100644
--- a/cogl/cogl-internal.h
+++ b/cogl/cogl-internal.h
@@ -95,28 +95,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
diff --git a/cogl/cogl-path.c b/cogl/cogl-path.c
index f02d5b3..72dff20 100644
--- a/cogl/cogl-path.c
+++ b/cogl/cogl-path.c
@@ -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;
 
diff --git a/cogl/driver/gl/cogl-framebuffer-gl.c b/cogl/driver/gl/cogl-framebuffer-gl.c
index 4ecc011..7e4aaca 100644
--- a/cogl/driver/gl/cogl-framebuffer-gl.c
+++ b/cogl/driver/gl/cogl-framebuffer-gl.c
@@ -921,6 +921,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;
 
@@ -942,11 +944,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"
@@ -955,7 +958,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;
 }
diff --git a/cogl/driver/gl/gl/cogl-driver-gl.c b/cogl/driver/gl/gl/cogl-driver-gl.c
index c944718..845e2fa 100644
--- a/cogl/driver/gl/gl/cogl-driver-gl.c
+++ b/cogl/driver/gl/gl/cogl-driver-gl.c
@@ -358,7 +358,6 @@ _cogl_driver_update_features (CoglContext *ctx,
   CoglPrivateFeatureFlags private_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*
@@ -441,11 +440,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;
diff --git a/cogl/driver/gl/gles/cogl-driver-gles.c b/cogl/driver/gl/gles/cogl-driver-gles.c
index 5630c66..d0988b4 100644
--- a/cogl/driver/gl/gles/cogl-driver-gles.c
+++ b/cogl/driver/gl/gles/cogl-driver-gles.c
@@ -191,7 +191,6 @@ _cogl_driver_update_features (CoglContext *context,
 {
   CoglPrivateFeatureFlags private_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
@@ -231,11 +230,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)
     {
-- 
1.7.11.3.g3c3efa5



More information about the Cogl mailing list