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



commit e928d21516a6c07798655341f4f0f8e3c1d1686c
Author: Neil Roberts <neil linux intel com>
Date:   Thu Dec 13 15:49:38 2012 +0000

    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>

 cogl/cogl-framebuffer-private.h        |   15 +++++++++++
 cogl/cogl-framebuffer.c                |   11 ++++++++
 cogl/cogl-path.c                       |    4 +-
 cogl/cogl-private.h                    |   43 +++++++++++++++----------------
 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 bdff221..cd2739a 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 f43bca7..fdd6c6f 100644
--- a/cogl/cogl-framebuffer.c
+++ b/cogl/cogl-framebuffer.c
@@ -896,6 +896,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-path.c b/cogl/cogl-path.c
index 2e49a5d..7cd66bd 100644
--- a/cogl/cogl-path.c
+++ b/cogl/cogl-path.c
@@ -270,8 +270,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/cogl-private.h b/cogl/cogl-private.h
index ca508a4..ea7c8d2 100644
--- a/cogl/cogl-private.h
+++ b/cogl/cogl-private.h
@@ -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
diff --git a/cogl/driver/gl/cogl-framebuffer-gl.c b/cogl/driver/gl/cogl-framebuffer-gl.c
index cb1c203..2be8b96 100644
--- a/cogl/driver/gl/cogl-framebuffer-gl.c
+++ b/cogl/driver/gl/cogl-framebuffer-gl.c
@@ -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;
 }
diff --git a/cogl/driver/gl/gl/cogl-driver-gl.c b/cogl/driver/gl/gl/cogl-driver-gl.c
index c1ab3d2..2389892 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 ad07c0a..cde0a68 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)
     {



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