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
pgpdmkorjeWk9.pgp
Description: PGP signature
_______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev