Brian Paul <bri...@vmware.com> writes:

> Unless a fragment shader is active (very rare), all the fragments
> emitted for a bitmap should have the same RGBA color.  So the only two
> possible outcomes of applying the alpha test to glBitmap is either the
> bitmap is drawn normally (as if alpha test is disabled) or nothing is
> drawn at all.  I think we could test for this and either no-op the
> glBitmap or draw the bitmap with the current code as-is.
>
> What do you think?
>
Yeah, that makes sense, fixed patch follows. Thank you for the review.

> -Brian

From ce79202f9bed892666539ef626ad49808c0428f9 Mon Sep 17 00:00:00 2001
From: Francisco Jerez <curroje...@riseup.net>
Date: Fri, 29 Oct 2010 21:20:34 +0200
Subject: [PATCH] meta: Handle bitmaps with alpha test enabled.

---
 src/mesa/drivers/common/meta.c |   56 +++++++++++++++++++++++++++++++++------
 1 files changed, 47 insertions(+), 9 deletions(-)

diff --git a/src/mesa/drivers/common/meta.c b/src/mesa/drivers/common/meta.c
index 9615b52..8ebf5cf 100644
--- a/src/mesa/drivers/common/meta.c
+++ b/src/mesa/drivers/common/meta.c
@@ -104,6 +104,8 @@ struct save_state
 
    /** META_ALPHA_TEST */
    GLboolean AlphaEnabled;
+   GLenum AlphaFunc;
+   GLclampf AlphaRef;
 
    /** META_BLEND */
    GLbitfield BlendEnabled;
@@ -328,6 +330,8 @@ _mesa_meta_begin(struct gl_context *ctx, GLbitfield state)
 
    if (state & META_ALPHA_TEST) {
       save->AlphaEnabled = ctx->Color.AlphaEnabled;
+      save->AlphaFunc = ctx->Color.AlphaFunc;
+      save->AlphaRef = ctx->Color.AlphaRef;
       if (ctx->Color.AlphaEnabled)
          _mesa_set_enable(ctx, GL_ALPHA_TEST, GL_FALSE);
    }
@@ -577,6 +581,7 @@ _mesa_meta_end(struct gl_context *ctx)
    if (state & META_ALPHA_TEST) {
       if (ctx->Color.AlphaEnabled != save->AlphaEnabled)
          _mesa_set_enable(ctx, GL_ALPHA_TEST, save->AlphaEnabled);
+      _mesa_AlphaFunc(save->AlphaFunc, save->AlphaRef);
    }
 
    if (state & META_BLEND) {
@@ -1975,13 +1980,41 @@ _mesa_meta_DrawPixels(struct gl_context *ctx,
    _mesa_meta_end(ctx);
 }
 
+static GLboolean
+alpha_test_bitmap(struct gl_context *ctx)
+{
+   struct gl_colorbuffer_attrib *color = &ctx->Color;
+   GLenum func = (color->AlphaEnabled ? color->AlphaFunc : GL_ALWAYS);
+   GLubyte ref = FLOAT_TO_UBYTE(color->AlphaRef);
+   GLubyte alpha = FLOAT_TO_UBYTE(ctx->Current.RasterColor[ACOMP]);
+
+   switch (func) {
+      case GL_NEVER:
+	 return GL_FALSE;
+      case GL_LESS:
+	 return alpha < ref;
+      case GL_EQUAL:
+	 return alpha == ref;
+      case GL_LEQUAL:
+	 return alpha <= ref;
+      case GL_GREATER:
+	 return alpha > ref;
+      case GL_NOTEQUAL:
+	 return alpha != ref;
+      case GL_GEQUAL:
+	 return alpha >= ref;
+      case GL_ALWAYS:
+	 return GL_TRUE;
+      default:
+	 assert(0);
+	 return GL_FALSE;
+   }
+}
 
 /**
- * Do glBitmap with a alpha texture quad.  Use the alpha test to
- * cull the 'off' bits.  If alpha test is already enabled, fall back
- * to swrast (should be a rare case).
- * A bitmap cache as in the gallium/mesa state tracker would
- * improve performance a lot.
+ * Do glBitmap with a alpha texture quad.  Use the alpha test to cull
+ * the 'off' bits.  A bitmap cache as in the gallium/mesa state
+ * tracker would improve performance a lot.
  */
 void
 _mesa_meta_Bitmap(struct gl_context *ctx,
@@ -1993,6 +2026,7 @@ _mesa_meta_Bitmap(struct gl_context *ctx,
    struct temp_texture *tex = get_bitmap_temp_texture(ctx);
    const GLenum texIntFormat = GL_ALPHA;
    const struct gl_pixelstore_attrib unpackSave = *unpack;
+   GLubyte alpha = FLOAT_TO_UBYTE(ctx->Current.RasterColor[ACOMP]);
    struct vertex {
       GLfloat x, y, z, s, t, r, g, b, a;
    };
@@ -2004,7 +2038,7 @@ _mesa_meta_Bitmap(struct gl_context *ctx,
     * Check if swrast fallback is needed.
     */
    if (ctx->_ImageTransferState ||
-       ctx->Color.AlphaEnabled ||
+       ctx->FragmentProgram._Enabled ||
        ctx->Fog.Enabled ||
        ctx->Texture._EnabledUnits ||
        width > tex->MaxSize ||
@@ -2013,6 +2047,9 @@ _mesa_meta_Bitmap(struct gl_context *ctx,
       return;
    }
 
+   if (!alpha_test_bitmap(ctx))
+      return;
+
    /* Most GL state applies to glBitmap (like blending, stencil, etc),
     * but a there's a few things we need to override:
     */
@@ -2100,15 +2137,16 @@ _mesa_meta_Bitmap(struct gl_context *ctx,
       return;
    }
 
-   bitmap8 = (GLubyte *) calloc(1, width * height);
+   bitmap8 = (GLubyte *) malloc(width * height);
    if (bitmap8) {
+      memset(bitmap8, ~alpha, width * height);
       _mesa_expand_bitmap(width, height, &unpackSave, bitmap1,
-                          bitmap8, width, 0xff);
+                          bitmap8, width, alpha);
 
       _mesa_set_enable(ctx, tex->Target, GL_TRUE);
 
       _mesa_set_enable(ctx, GL_ALPHA_TEST, GL_TRUE);
-      _mesa_AlphaFunc(GL_GREATER, 0.0);
+      _mesa_AlphaFunc(GL_EQUAL, ctx->Current.RasterColor[ACOMP]);
 
       setup_drawpix_texture(ctx, tex, newTex, texIntFormat, width, height,
                             GL_ALPHA, GL_UNSIGNED_BYTE, bitmap8);
-- 
1.6.4.4

Attachment: pgpdmkorjeWk9.pgp
Description: PGP signature

_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to