s_logic.c revision 8f28f4850bbf4f32e84f25ee1a8d72b16b8a41d1
1/* $Id: s_logic.c,v 1.3 2001/02/13 23:50:25 brianp 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#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 */ 43static 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 gl_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 */ 168void 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 */ 184void 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 */ 208static 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 gl_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 */ 334void 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 gl_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 */ 350void 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} 362