Reorganized software rasterizer as a module which manages its own state,
[mesa.git] / src / mesa / swrast / s_masking.c
1 /* $Id: s_masking.c,v 1.2 2000/11/05 18:24:40 keithw Exp $ */
2
3 /*
4 * Mesa 3-D graphics library
5 * Version: 3.5
6 *
7 * Copyright (C) 1999-2000 Brian Paul All Rights Reserved.
8 *
9 * Permission is hereby granted, free of charge, to any person obtaining a
10 * copy of this software and associated documentation files (the "Software"),
11 * to deal in the Software without restriction, including without limitation
12 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 * and/or sell copies of the Software, and to permit persons to whom the
14 * Software is furnished to do so, subject to the following conditions:
15 *
16 * The above copyright notice and this permission notice shall be included
17 * in all copies or substantial portions of the Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
23 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 */
26
27
28 /*
29 * Implement the effect of glColorMask and glIndexMask in software.
30 */
31
32
33 #include "glheader.h"
34 #include "enums.h"
35 #include "macros.h"
36
37 #include "s_alphabuf.h"
38 #include "s_context.h"
39 #include "s_masking.h"
40 #include "s_pb.h"
41 #include "s_span.h"
42
43
44 /*
45 * Apply glColorMask to a span of RGBA pixels.
46 */
47 void
48 _mesa_mask_rgba_span( GLcontext *ctx,
49 GLuint n, GLint x, GLint y, GLchan rgba[][4] )
50 {
51 GLchan dest[MAX_WIDTH][4];
52 GLuint i;
53
54 #if CHAN_BITS == 8
55
56 GLuint srcMask = *((GLuint*)ctx->Color.ColorMask);
57 GLuint dstMask = ~srcMask;
58 GLuint *rgba32 = (GLuint *) rgba;
59 GLuint *dest32 = (GLuint *) dest;
60
61 gl_read_rgba_span( ctx, ctx->DrawBuffer, n, x, y, dest );
62 for (i = 0; i < n; i++) {
63 rgba32[i] = (rgba32[i] & srcMask) | (dest32[i] & dstMask);
64 }
65
66 #else
67
68 const GLint rMask = ctx->Color.ColorMask[RCOMP];
69 const GLint gMask = ctx->Color.ColorMask[GCOMP];
70 const GLint bMask = ctx->Color.ColorMask[BCOMP];
71 const GLint aMask = ctx->Color.ColorMask[ACOMP];
72
73 gl_read_rgba_span( ctx, ctx->DrawBuffer, n, x, y, dest );
74 for (i = 0; i < n; i++) {
75 if (!rMask) rgba[i][RCOMP] = dest[i][RCOMP];
76 if (!gMask) rgba[i][GCOMP] = dest[i][GCOMP];
77 if (!bMask) rgba[i][BCOMP] = dest[i][BCOMP];
78 if (!aMask) rgba[i][ACOMP] = dest[i][ACOMP];
79 }
80
81 #endif
82 }
83
84
85
86 /*
87 * Apply glColorMask to an array of RGBA pixels.
88 */
89 void
90 _mesa_mask_rgba_pixels( GLcontext *ctx,
91 GLuint n, const GLint x[], const GLint y[],
92 GLchan rgba[][4], const GLubyte mask[] )
93 {
94 GLchan dest[PB_SIZE][4];
95 GLuint i;
96
97 #if CHAN_BITS == 8
98
99 GLuint srcMask = *((GLuint*)ctx->Color.ColorMask);
100 GLuint dstMask = ~srcMask;
101 GLuint *rgba32 = (GLuint *) rgba;
102 GLuint *dest32 = (GLuint *) dest;
103
104 (*ctx->Driver.ReadRGBAPixels)( ctx, n, x, y, dest, mask );
105 if (SWRAST_CONTEXT(ctx)->_RasterMask & ALPHABUF_BIT) {
106 _mesa_read_alpha_pixels( ctx, n, x, y, dest, mask );
107 }
108
109 for (i=0; i<n; i++) {
110 rgba32[i] = (rgba32[i] & srcMask) | (dest32[i] & dstMask);
111 }
112
113 #else
114
115 const GLint rMask = ctx->Color.ColorMask[RCOMP];
116 const GLint gMask = ctx->Color.ColorMask[GCOMP];
117 const GLint bMask = ctx->Color.ColorMask[BCOMP];
118 const GLint aMask = ctx->Color.ColorMask[ACOMP];
119
120 (*ctx->Driver.ReadRGBAPixels)( ctx, n, x, y, dest, mask );
121 if (SWRAST_CONTEXT(ctx)->_RasterMask & ALPHABUF_BIT) {
122 _mesa_read_alpha_pixels( ctx, n, x, y, dest, mask );
123 }
124
125 for (i = 0; i < n; i++) {
126 if (!rMask) rgba[i][RCOMP] = dest[i][RCOMP];
127 if (!gMask) rgba[i][GCOMP] = dest[i][GCOMP];
128 if (!bMask) rgba[i][BCOMP] = dest[i][BCOMP];
129 if (!aMask) rgba[i][ACOMP] = dest[i][ACOMP];
130 }
131
132 #endif
133 }
134
135
136
137 /*
138 * Apply glIndexMask to a span of CI pixels.
139 */
140 void
141 _mesa_mask_index_span( GLcontext *ctx,
142 GLuint n, GLint x, GLint y, GLuint index[] )
143 {
144 GLuint i;
145 GLuint fbindexes[MAX_WIDTH];
146 GLuint msrc, mdest;
147
148 gl_read_index_span( ctx, ctx->DrawBuffer, n, x, y, fbindexes );
149
150 msrc = ctx->Color.IndexMask;
151 mdest = ~msrc;
152
153 for (i=0;i<n;i++) {
154 index[i] = (index[i] & msrc) | (fbindexes[i] & mdest);
155 }
156 }
157
158
159
160 /*
161 * Apply glIndexMask to an array of CI pixels.
162 */
163 void
164 _mesa_mask_index_pixels( GLcontext *ctx,
165 GLuint n, const GLint x[], const GLint y[],
166 GLuint index[], const GLubyte mask[] )
167 {
168 GLuint i;
169 GLuint fbindexes[PB_SIZE];
170 GLuint msrc, mdest;
171
172 (*ctx->Driver.ReadCI32Pixels)( ctx, n, x, y, fbindexes, mask );
173
174 msrc = ctx->Color.IndexMask;
175 mdest = ~msrc;
176
177 for (i=0;i<n;i++) {
178 index[i] = (index[i] & msrc) | (fbindexes[i] & mdest);
179 }
180 }
181