Consistent copyright info (version number, date) across all files.
[mesa.git] / src / mesa / swrast / s_logic.c
1 /* $Id: s_logic.c,v 1.5 2001/03/12 00:48:42 gareth Exp $ */
2
3 /*
4 * Mesa 3-D graphics library
5 * Version: 3.5
6 *
7 * Copyright (C) 1999-2001 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 #include "glheader.h"
29 #include "context.h"
30 #include "macros.h"
31
32 #include "s_alphabuf.h"
33 #include "s_context.h"
34 #include "s_logic.h"
35 #include "s_pb.h"
36 #include "s_span.h"
37
38
39
40 /*
41 * Apply logic op to array of CI pixels.
42 */
43 static void index_logicop( GLcontext *ctx, GLuint n,
44 GLuint index[], const GLuint dest[],
45 const GLubyte mask[] )
46 {
47 GLuint i;
48 switch (ctx->Color.LogicOp) {
49 case GL_CLEAR:
50 for (i=0;i<n;i++) {
51 if (mask[i]) {
52 index[i] = 0;
53 }
54 }
55 break;
56 case GL_SET:
57 for (i=0;i<n;i++) {
58 if (mask[i]) {
59 index[i] = ~0;
60 }
61 }
62 break;
63 case GL_COPY:
64 /* do nothing */
65 break;
66 case GL_COPY_INVERTED:
67 for (i=0;i<n;i++) {
68 if (mask[i]) {
69 index[i] = ~index[i];
70 }
71 }
72 break;
73 case GL_NOOP:
74 for (i=0;i<n;i++) {
75 if (mask[i]) {
76 index[i] = dest[i];
77 }
78 }
79 break;
80 case GL_INVERT:
81 for (i=0;i<n;i++) {
82 if (mask[i]) {
83 index[i] = ~dest[i];
84 }
85 }
86 break;
87 case GL_AND:
88 for (i=0;i<n;i++) {
89 if (mask[i]) {
90 index[i] &= dest[i];
91 }
92 }
93 break;
94 case GL_NAND:
95 for (i=0;i<n;i++) {
96 if (mask[i]) {
97 index[i] = ~(index[i] & dest[i]);
98 }
99 }
100 break;
101 case GL_OR:
102 for (i=0;i<n;i++) {
103 if (mask[i]) {
104 index[i] |= dest[i];
105 }
106 }
107 break;
108 case GL_NOR:
109 for (i=0;i<n;i++) {
110 if (mask[i]) {
111 index[i] = ~(index[i] | dest[i]);
112 }
113 }
114 break;
115 case GL_XOR:
116 for (i=0;i<n;i++) {
117 if (mask[i]) {
118 index[i] ^= dest[i];
119 }
120 }
121 break;
122 case GL_EQUIV:
123 for (i=0;i<n;i++) {
124 if (mask[i]) {
125 index[i] = ~(index[i] ^ dest[i]);
126 }
127 }
128 break;
129 case GL_AND_REVERSE:
130 for (i=0;i<n;i++) {
131 if (mask[i]) {
132 index[i] = index[i] & ~dest[i];
133 }
134 }
135 break;
136 case GL_AND_INVERTED:
137 for (i=0;i<n;i++) {
138 if (mask[i]) {
139 index[i] = ~index[i] & dest[i];
140 }
141 }
142 break;
143 case GL_OR_REVERSE:
144 for (i=0;i<n;i++) {
145 if (mask[i]) {
146 index[i] = index[i] | ~dest[i];
147 }
148 }
149 break;
150 case GL_OR_INVERTED:
151 for (i=0;i<n;i++) {
152 if (mask[i]) {
153 index[i] = ~index[i] | dest[i];
154 }
155 }
156 break;
157 default:
158 _mesa_problem(ctx, "bad mode in index_logic()");
159 }
160 }
161
162
163
164 /*
165 * Apply the current logic operator to a span of CI pixels. This is only
166 * used if the device driver can't do logic ops.
167 */
168 void
169 _mesa_logicop_ci_span( GLcontext *ctx, GLuint n, GLint x, GLint y,
170 GLuint index[], const GLubyte mask[] )
171 {
172 GLuint dest[MAX_WIDTH];
173 /* Read dest values from frame buffer */
174 (*ctx->Driver.ReadCI32Span)( ctx, n, x, y, dest );
175 index_logicop( ctx, n, index, dest, mask );
176 }
177
178
179
180 /*
181 * Apply the current logic operator to an array of CI pixels. This is only
182 * used if the device driver can't do logic ops.
183 */
184 void
185 _mesa_logicop_ci_pixels( GLcontext *ctx,
186 GLuint n, const GLint x[], const GLint y[],
187 GLuint index[], const GLubyte mask[] )
188 {
189 GLuint dest[PB_SIZE];
190 /* Read dest values from frame buffer */
191 (*ctx->Driver.ReadCI32Pixels)( ctx, n, x, y, dest, mask );
192 index_logicop( ctx, n, index, dest, mask );
193 }
194
195
196
197 /*
198 * Apply logic operator to rgba pixels.
199 * Input: ctx - the context
200 * n - number of pixels
201 * mask - pixel mask array
202 * In/Out: src - incoming pixels which will be modified
203 * Input: dest - frame buffer values
204 *
205 * Note: Since the R, G, B, and A channels are all treated the same we
206 * process them as 4-byte GLuints instead of four GLubytes.
207 */
208 static void rgba_logicop( const GLcontext *ctx, GLuint n,
209 const GLubyte mask[],
210 GLuint src[], const GLuint dest[] )
211 {
212 GLuint i;
213 switch (ctx->Color.LogicOp) {
214 case GL_CLEAR:
215 for (i=0;i<n;i++) {
216 if (mask[i]) {
217 src[i] = 0;
218 }
219 }
220 break;
221 case GL_SET:
222 for (i=0;i<n;i++) {
223 if (mask[i]) {
224 src[i] = ~0;
225 }
226 }
227 break;
228 case GL_COPY:
229 /* do nothing */
230 break;
231 case GL_COPY_INVERTED:
232 for (i=0;i<n;i++) {
233 if (mask[i]) {
234 src[i] = ~src[i];
235 }
236 }
237 break;
238 case GL_NOOP:
239 for (i=0;i<n;i++) {
240 if (mask[i]) {
241 src[i] = dest[i];
242 }
243 }
244 break;
245 case GL_INVERT:
246 for (i=0;i<n;i++) {
247 if (mask[i]) {
248 src[i] = ~dest[i];
249 }
250 }
251 break;
252 case GL_AND:
253 for (i=0;i<n;i++) {
254 if (mask[i]) {
255 src[i] &= dest[i];
256 }
257 }
258 break;
259 case GL_NAND:
260 for (i=0;i<n;i++) {
261 if (mask[i]) {
262 src[i] = ~(src[i] & src[i]);
263 }
264 }
265 break;
266 case GL_OR:
267 for (i=0;i<n;i++) {
268 if (mask[i]) {
269 src[i]|= dest[i];
270 }
271 }
272 break;
273 case GL_NOR:
274 for (i=0;i<n;i++) {
275 if (mask[i]) {
276 src[i] = ~(src[i] | dest[i]);
277 }
278 }
279 break;
280 case GL_XOR:
281 for (i=0;i<n;i++) {
282 if (mask[i]) {
283 src[i] ^= dest[i];
284 }
285 }
286 break;
287 case GL_EQUIV:
288 for (i=0;i<n;i++) {
289 if (mask[i]) {
290 src[i] = ~(src[i] ^ dest[i]);
291 }
292 }
293 break;
294 case GL_AND_REVERSE:
295 for (i=0;i<n;i++) {
296 if (mask[i]) {
297 src[i] = src[i] & ~dest[i];
298 }
299 }
300 break;
301 case GL_AND_INVERTED:
302 for (i=0;i<n;i++) {
303 if (mask[i]) {
304 src[i] = ~src[i] & dest[i];
305 }
306 }
307 break;
308 case GL_OR_REVERSE:
309 for (i=0;i<n;i++) {
310 if (mask[i]) {
311 src[i] = src[i] | ~dest[i];
312 }
313 }
314 break;
315 case GL_OR_INVERTED:
316 for (i=0;i<n;i++) {
317 if (mask[i]) {
318 src[i] = ~src[i] | dest[i];
319 }
320 }
321 break;
322 default:
323 /* should never happen */
324 _mesa_problem(ctx, "Bad function in rgba_logicop");
325 }
326 }
327
328
329
330 /*
331 * Apply the current logic operator to a span of RGBA pixels.
332 * This is only used if the device driver can't do logic ops.
333 */
334 void
335 _mesa_logicop_rgba_span( GLcontext *ctx,
336 GLuint n, GLint x, GLint y,
337 GLchan rgba[][4], const GLubyte mask[] )
338 {
339 GLchan dest[MAX_WIDTH][4];
340 _mesa_read_rgba_span( ctx, ctx->DrawBuffer, n, x, y, dest );
341 rgba_logicop( ctx, n, mask, (GLuint *) rgba, (const GLuint *) dest );
342 }
343
344
345
346 /*
347 * Apply the current logic operator to an array of RGBA pixels.
348 * This is only used if the device driver can't do logic ops.
349 */
350 void
351 _mesa_logicop_rgba_pixels( GLcontext *ctx,
352 GLuint n, const GLint x[], const GLint y[],
353 GLchan rgba[][4], const GLubyte mask[] )
354 {
355 GLchan dest[PB_SIZE][4];
356 (*ctx->Driver.ReadRGBAPixels)( ctx, n, x, y, dest, mask );
357 if (SWRAST_CONTEXT(ctx)->_RasterMask & ALPHABUF_BIT) {
358 _mesa_read_alpha_pixels( ctx, n, x, y, dest, mask );
359 }
360 rgba_logicop( ctx, n, mask, (GLuint *) rgba, (const GLuint *) dest );
361 }