17117f1b4Smrg/*
27117f1b4Smrg * Mesa 3-D graphics library
37117f1b4Smrg *
47117f1b4Smrg * Copyright (C) 1999-2006  Brian Paul   All Rights Reserved.
57117f1b4Smrg *
67117f1b4Smrg * Permission is hereby granted, free of charge, to any person obtaining a
77117f1b4Smrg * copy of this software and associated documentation files (the "Software"),
87117f1b4Smrg * to deal in the Software without restriction, including without limitation
97117f1b4Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
107117f1b4Smrg * and/or sell copies of the Software, and to permit persons to whom the
117117f1b4Smrg * Software is furnished to do so, subject to the following conditions:
127117f1b4Smrg *
137117f1b4Smrg * The above copyright notice and this permission notice shall be included
147117f1b4Smrg * in all copies or substantial portions of the Software.
157117f1b4Smrg *
167117f1b4Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
177117f1b4Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
187117f1b4Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19af69d88dSmrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20af69d88dSmrg * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21af69d88dSmrg * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22af69d88dSmrg * OTHER DEALINGS IN THE SOFTWARE.
237117f1b4Smrg */
247117f1b4Smrg
257117f1b4Smrg
267117f1b4Smrg/*
277117f1b4Smrg * Implement the effect of glColorMask and glIndexMask in software.
287117f1b4Smrg */
297117f1b4Smrg
307117f1b4Smrg
31c1f859d4Smrg#include "main/glheader.h"
32c1f859d4Smrg#include "main/macros.h"
337117f1b4Smrg
347117f1b4Smrg#include "s_context.h"
357117f1b4Smrg#include "s_masking.h"
367117f1b4Smrg#include "s_span.h"
377117f1b4Smrg
387117f1b4Smrg
397117f1b4Smrg/**
407117f1b4Smrg * Apply the color mask to a span of rgba values.
417117f1b4Smrg */
427117f1b4Smrgvoid
433464ebd5Sriastradh_swrast_mask_rgba_span(struct gl_context *ctx, struct gl_renderbuffer *rb,
44cdc920a0Smrg                       SWspan *span, GLuint buf)
457117f1b4Smrg{
467117f1b4Smrg   const GLuint n = span->end;
477117f1b4Smrg   void *rbPixels;
487117f1b4Smrg
4901e04c3fSmrg   assert(n < SWRAST_MAX_WIDTH);
5001e04c3fSmrg   assert(span->arrayMask & SPAN_RGBA);
517117f1b4Smrg
527117f1b4Smrg   rbPixels = _swrast_get_dest_rgba(ctx, rb, span);
537117f1b4Smrg
547117f1b4Smrg   /*
557117f1b4Smrg    * Do component masking.
567117f1b4Smrg    * Note that we're not using span->array->mask[] here.  We could...
577117f1b4Smrg    */
587117f1b4Smrg   if (span->array->ChanType == GL_UNSIGNED_BYTE) {
5901e04c3fSmrg      const GLubyte colormask[4] = {
6001e04c3fSmrg         GET_COLORMASK_BIT(ctx->Color.ColorMask, buf, 0) ? 0xff : 0,
6101e04c3fSmrg         GET_COLORMASK_BIT(ctx->Color.ColorMask, buf, 1) ? 0xff : 0,
6201e04c3fSmrg         GET_COLORMASK_BIT(ctx->Color.ColorMask, buf, 2) ? 0xff : 0,
6301e04c3fSmrg         GET_COLORMASK_BIT(ctx->Color.ColorMask, buf, 3) ? 0xff : 0,
6401e04c3fSmrg      };
6501e04c3fSmrg      GLuint srcMask;
6601e04c3fSmrg      memcpy(&srcMask, colormask, sizeof(srcMask));
677117f1b4Smrg      const GLuint dstMask = ~srcMask;
687117f1b4Smrg      const GLuint *dst = (const GLuint *) rbPixels;
69c1f859d4Smrg      GLuint *src = (GLuint *) span->array->rgba8;
707117f1b4Smrg      GLuint i;
717117f1b4Smrg      for (i = 0; i < n; i++) {
727117f1b4Smrg         src[i] = (src[i] & srcMask) | (dst[i] & dstMask);
737117f1b4Smrg      }
747117f1b4Smrg   }
757117f1b4Smrg   else if (span->array->ChanType == GL_UNSIGNED_SHORT) {
767117f1b4Smrg      /* 2-byte components */
777117f1b4Smrg      /* XXX try to use 64-bit arithmetic someday */
7801e04c3fSmrg      const GLushort rMask = GET_COLORMASK_BIT(ctx->Color.ColorMask, buf, 0) ? 0xffff : 0x0;
7901e04c3fSmrg      const GLushort gMask = GET_COLORMASK_BIT(ctx->Color.ColorMask, buf, 1) ? 0xffff : 0x0;
8001e04c3fSmrg      const GLushort bMask = GET_COLORMASK_BIT(ctx->Color.ColorMask, buf, 2) ? 0xffff : 0x0;
8101e04c3fSmrg      const GLushort aMask = GET_COLORMASK_BIT(ctx->Color.ColorMask, buf, 3) ? 0xffff : 0x0;
827117f1b4Smrg      const GLushort (*dst)[4] = (const GLushort (*)[4]) rbPixels;
83c1f859d4Smrg      GLushort (*src)[4] = span->array->rgba16;
847117f1b4Smrg      GLuint i;
857117f1b4Smrg      for (i = 0; i < n; i++) {
867117f1b4Smrg         src[i][RCOMP] = (src[i][RCOMP] & rMask) | (dst[i][RCOMP] & ~rMask);
877117f1b4Smrg         src[i][GCOMP] = (src[i][GCOMP] & gMask) | (dst[i][GCOMP] & ~gMask);
887117f1b4Smrg         src[i][BCOMP] = (src[i][BCOMP] & bMask) | (dst[i][BCOMP] & ~bMask);
897117f1b4Smrg         src[i][ACOMP] = (src[i][ACOMP] & aMask) | (dst[i][ACOMP] & ~aMask);
907117f1b4Smrg      }
917117f1b4Smrg   }
927117f1b4Smrg   else {
937117f1b4Smrg      /* 4-byte components */
9401e04c3fSmrg      const GLuint rMask = GET_COLORMASK_BIT(ctx->Color.ColorMask, buf, 0) ? ~0x0 : 0x0;
9501e04c3fSmrg      const GLuint gMask = GET_COLORMASK_BIT(ctx->Color.ColorMask, buf, 1) ? ~0x0 : 0x0;
9601e04c3fSmrg      const GLuint bMask = GET_COLORMASK_BIT(ctx->Color.ColorMask, buf, 2) ? ~0x0 : 0x0;
9701e04c3fSmrg      const GLuint aMask = GET_COLORMASK_BIT(ctx->Color.ColorMask, buf, 3) ? ~0x0 : 0x0;
987117f1b4Smrg      const GLuint (*dst)[4] = (const GLuint (*)[4]) rbPixels;
99af69d88dSmrg      GLuint (*src)[4] = (GLuint (*)[4]) span->array->attribs[VARYING_SLOT_COL0];
1007117f1b4Smrg      GLuint i;
1017117f1b4Smrg      for (i = 0; i < n; i++) {
1027117f1b4Smrg         src[i][RCOMP] = (src[i][RCOMP] & rMask) | (dst[i][RCOMP] & ~rMask);
1037117f1b4Smrg         src[i][GCOMP] = (src[i][GCOMP] & gMask) | (dst[i][GCOMP] & ~gMask);
1047117f1b4Smrg         src[i][BCOMP] = (src[i][BCOMP] & bMask) | (dst[i][BCOMP] & ~bMask);
1057117f1b4Smrg         src[i][ACOMP] = (src[i][ACOMP] & aMask) | (dst[i][ACOMP] & ~aMask);
1067117f1b4Smrg      }
1077117f1b4Smrg   }
1087117f1b4Smrg}
109