Fixed typo
[reactos.git] / dll / opengl / mesa / swrast / s_logic.c
1 /*
2 * Mesa 3-D graphics library
3 * Version: 6.5.2
4 *
5 * Copyright (C) 1999-2006 Brian Paul All Rights Reserved.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 */
24
25 #include <precomp.h>
26
27 /**
28 * We do all logic ops on 4-byte GLuints.
29 * Depending on bytes per pixel, the mask array elements correspond to
30 * 1, 2 or 4 GLuints.
31 */
32 #define LOGIC_OP_LOOP(MODE, MASKSTRIDE) \
33 do { \
34 GLuint i; \
35 switch (MODE) { \
36 case GL_CLEAR: \
37 for (i = 0; i < n; i++) { \
38 if (mask[i / MASKSTRIDE]) { \
39 src[i] = 0; \
40 } \
41 } \
42 break; \
43 case GL_SET: \
44 for (i = 0; i < n; i++) { \
45 if (mask[i / MASKSTRIDE]) { \
46 src[i] = ~0; \
47 } \
48 } \
49 break; \
50 case GL_COPY: \
51 /* do nothing */ \
52 break; \
53 case GL_COPY_INVERTED: \
54 for (i = 0; i < n; i++) { \
55 if (mask[i / MASKSTRIDE]) { \
56 src[i] = ~src[i]; \
57 } \
58 } \
59 break; \
60 case GL_NOOP: \
61 for (i = 0; i < n; i++) { \
62 if (mask[i / MASKSTRIDE]) { \
63 src[i] = dest[i]; \
64 } \
65 } \
66 break; \
67 case GL_INVERT: \
68 for (i = 0; i < n; i++) { \
69 if (mask[i / MASKSTRIDE]) { \
70 src[i] = ~dest[i]; \
71 } \
72 } \
73 break; \
74 case GL_AND: \
75 for (i = 0; i < n; i++) { \
76 if (mask[i / MASKSTRIDE]) { \
77 src[i] &= dest[i]; \
78 } \
79 } \
80 break; \
81 case GL_NAND: \
82 for (i = 0; i < n; i++) { \
83 if (mask[i / MASKSTRIDE]) { \
84 src[i] = ~(src[i] & dest[i]); \
85 } \
86 } \
87 break; \
88 case GL_OR: \
89 for (i = 0; i < n; i++) { \
90 if (mask[i / MASKSTRIDE]) { \
91 src[i] |= dest[i]; \
92 } \
93 } \
94 break; \
95 case GL_NOR: \
96 for (i = 0; i < n; i++) { \
97 if (mask[i / MASKSTRIDE]) { \
98 src[i] = ~(src[i] | dest[i]); \
99 } \
100 } \
101 break; \
102 case GL_XOR: \
103 for (i = 0; i < n; i++) { \
104 if (mask[i / MASKSTRIDE]) { \
105 src[i] ^= dest[i]; \
106 } \
107 } \
108 break; \
109 case GL_EQUIV: \
110 for (i = 0; i < n; i++) { \
111 if (mask[i / MASKSTRIDE]) { \
112 src[i] = ~(src[i] ^ dest[i]); \
113 } \
114 } \
115 break; \
116 case GL_AND_REVERSE: \
117 for (i = 0; i < n; i++) { \
118 if (mask[i / MASKSTRIDE]) { \
119 src[i] = src[i] & ~dest[i]; \
120 } \
121 } \
122 break; \
123 case GL_AND_INVERTED: \
124 for (i = 0; i < n; i++) { \
125 if (mask[i / MASKSTRIDE]) { \
126 src[i] = ~src[i] & dest[i]; \
127 } \
128 } \
129 break; \
130 case GL_OR_REVERSE: \
131 for (i = 0; i < n; i++) { \
132 if (mask[i / MASKSTRIDE]) { \
133 src[i] = src[i] | ~dest[i]; \
134 } \
135 } \
136 break; \
137 case GL_OR_INVERTED: \
138 for (i = 0; i < n; i++) { \
139 if (mask[i / MASKSTRIDE]) { \
140 src[i] = ~src[i] | dest[i]; \
141 } \
142 } \
143 break; \
144 default: \
145 _mesa_problem(ctx, "bad logicop mode");\
146 } \
147 } while (0)
148
149
150
151 static inline void
152 logicop_uint1(struct gl_context *ctx, GLuint n, GLuint src[], const GLuint dest[],
153 const GLubyte mask[])
154 {
155 LOGIC_OP_LOOP(ctx->Color.LogicOp, 1);
156 }
157
158
159 static inline void
160 logicop_uint2(struct gl_context *ctx, GLuint n, GLuint src[], const GLuint dest[],
161 const GLubyte mask[])
162 {
163 LOGIC_OP_LOOP(ctx->Color.LogicOp, 2);
164 }
165
166
167 static inline void
168 logicop_uint4(struct gl_context *ctx, GLuint n, GLuint src[], const GLuint dest[],
169 const GLubyte mask[])
170 {
171 LOGIC_OP_LOOP(ctx->Color.LogicOp, 4);
172 }
173
174
175
176 /**
177 * Apply the current logic operator to a span of RGBA pixels.
178 * We can handle horizontal runs of pixels (spans) or arrays of x/y
179 * pixel coordinates.
180 */
181 void
182 _swrast_logicop_rgba_span(struct gl_context *ctx, struct gl_renderbuffer *rb,
183 SWspan *span)
184 {
185 void *rbPixels;
186
187 ASSERT(span->end < MAX_WIDTH);
188 ASSERT(span->arrayMask & SPAN_RGBA);
189
190 rbPixels = _swrast_get_dest_rgba(ctx, rb, span);
191
192 if (span->array->ChanType == GL_UNSIGNED_BYTE) {
193 /* treat 4*GLubyte as GLuint */
194 logicop_uint1(ctx, span->end,
195 (GLuint *) span->array->rgba8,
196 (const GLuint *) rbPixels, span->array->mask);
197 }
198 else if (span->array->ChanType == GL_UNSIGNED_SHORT) {
199 /* treat 2*GLushort as GLuint */
200 logicop_uint2(ctx, 2 * span->end,
201 (GLuint *) span->array->rgba16,
202 (const GLuint *) rbPixels, span->array->mask);
203 }
204 else {
205 logicop_uint4(ctx, 4 * span->end,
206 (GLuint *) span->array->attribs[FRAG_ATTRIB_COL],
207 (const GLuint *) rbPixels, span->array->mask);
208 }
209 }