home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / mesa5.zip / mesa5src.zip / swrast / s_logic.cpp < prev    next >
C/C++ Source or Header  |  2002-10-24  |  12KB  |  499 lines

  1. /* $Id: s_logic.c,v 1.12 2002/10/24 23:57:24 brianp Exp $ */
  2.  
  3. /*
  4.  * Mesa 3-D graphics library
  5.  * Version:  4.1
  6.  *
  7.  * Copyright (C) 1999-2002  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 "imports.h"
  31. #include "macros.h"
  32.  
  33. #include "s_alphabuf.h"
  34. #include "s_context.h"
  35. #include "s_logic.h"
  36. #include "s_span.h"
  37.  
  38.  
  39.  
  40. /*
  41.  * Apply logic op to array of CI pixels.
  42.  */
  43. static void
  44. index_logicop( GLcontext *ctx, GLuint n, 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, const struct sw_span *span,
  170.                        GLuint index[] )
  171. {
  172.    SWcontext *swrast = SWRAST_CONTEXT(ctx);
  173.    GLuint dest[MAX_WIDTH];
  174.  
  175.    ASSERT(span->end < MAX_WIDTH);
  176.  
  177.    /* Read dest values from frame buffer */
  178.    if (span->arrayMask & SPAN_XY) {
  179.       (*swrast->Driver.ReadCI32Pixels)( ctx, span->end,
  180.                                         span->array->x, span->array->y,
  181.                                         dest, span->array->mask );
  182.    }
  183.    else {
  184.       (*swrast->Driver.ReadCI32Span)( ctx, span->end, span->x, span->y, dest );
  185.    }
  186.  
  187.    index_logicop( ctx, span->end, index, dest, span->array->mask );
  188. }
  189.  
  190.  
  191.  
  192. /*
  193.  * Apply logic operator to rgba pixels.
  194.  * Input:  ctx - the context
  195.  *         n - number of pixels
  196.  *         mask - pixel mask array
  197.  * In/Out:  src - incoming pixels which will be modified
  198.  * Input:  dest - frame buffer values
  199.  *
  200.  * Note:  Since the R, G, B, and A channels are all treated the same we
  201.  * process them as 4-byte GLuints instead of four GLubytes.
  202.  */
  203. static void
  204. rgba_logicop_ui( const GLcontext *ctx, GLuint n, const GLubyte mask[],
  205.                  GLuint src[], const GLuint dest[] )
  206. {
  207.    GLuint i;
  208.    switch (ctx->Color.LogicOp) {
  209.       case GL_CLEAR:
  210.          for (i=0;i<n;i++) {
  211.             if (mask[i]) {
  212.                src[i] = 0;
  213.             }
  214.          }
  215.          break;
  216.       case GL_SET:
  217.          for (i=0;i<n;i++) {
  218.             if (mask[i]) {
  219.                src[i] = ~0;
  220.             }
  221.          }
  222.          break;
  223.       case GL_COPY:
  224.          /* do nothing */
  225.          break;
  226.       case GL_COPY_INVERTED:
  227.          for (i=0;i<n;i++) {
  228.             if (mask[i]) {
  229.                src[i] = ~src[i];
  230.             }
  231.          }
  232.          break;
  233.       case GL_NOOP:
  234.          for (i=0;i<n;i++) {
  235.             if (mask[i]) {
  236.                src[i] = dest[i];
  237.             }
  238.          }
  239.          break;
  240.       case GL_INVERT:
  241.          for (i=0;i<n;i++) {
  242.             if (mask[i]) {
  243.                src[i] = ~dest[i];
  244.             }
  245.          }
  246.          break;
  247.       case GL_AND:
  248.          for (i=0;i<n;i++) {
  249.             if (mask[i]) {
  250.                src[i] &= dest[i];
  251.             }
  252.          }
  253.          break;
  254.       case GL_NAND:
  255.          for (i=0;i<n;i++) {
  256.             if (mask[i]) {
  257.                src[i] = ~(src[i] & dest[i]);
  258.             }
  259.          }
  260.          break;
  261.       case GL_OR:
  262.          for (i=0;i<n;i++) {
  263.             if (mask[i]) {
  264.                src[i]|= dest[i];
  265.             }
  266.          }
  267.          break;
  268.       case GL_NOR:
  269.          for (i=0;i<n;i++) {
  270.             if (mask[i]) {
  271.                src[i] = ~(src[i] | dest[i]);
  272.             }
  273.          }
  274.          break;
  275.       case GL_XOR:
  276.          for (i=0;i<n;i++) {
  277.             if (mask[i]) {
  278.                src[i] ^= dest[i];
  279.             }
  280.          }
  281.          break;
  282.       case GL_EQUIV:
  283.          for (i=0;i<n;i++) {
  284.             if (mask[i]) {
  285.                src[i] = ~(src[i] ^ dest[i]);
  286.             }
  287.          }
  288.          break;
  289.       case GL_AND_REVERSE:
  290.          for (i=0;i<n;i++) {
  291.             if (mask[i]) {
  292.                src[i] = src[i] & ~dest[i];
  293.             }
  294.          }
  295.          break;
  296.       case GL_AND_INVERTED:
  297.          for (i=0;i<n;i++) {
  298.             if (mask[i]) {
  299.                src[i] = ~src[i] & dest[i];
  300.             }
  301.          }
  302.          break;
  303.       case GL_OR_REVERSE:
  304.          for (i=0;i<n;i++) {
  305.             if (mask[i]) {
  306.                src[i] = src[i] | ~dest[i];
  307.             }
  308.          }
  309.          break;
  310.       case GL_OR_INVERTED:
  311.          for (i=0;i<n;i++) {
  312.             if (mask[i]) {
  313.                src[i] = ~src[i] | dest[i];
  314.             }
  315.          }
  316.          break;
  317.       default:
  318.          /* should never happen */
  319.          _mesa_problem(ctx, "Bad function in rgba_logicop");
  320.    }
  321. }
  322.  
  323.  
  324. /*
  325.  * As above, but operate on GLchan values
  326.  * Note: need to pass n = numPixels * 4.
  327.  */
  328. static void
  329. rgba_logicop_chan( const GLcontext *ctx, GLuint n, const GLubyte mask[],
  330.                    GLchan srcPtr[], const GLchan destPtr[] )
  331. {
  332. #if CHAN_TYPE == GL_FLOAT
  333.    GLuint *src = (GLuint *) srcPtr;
  334.    const GLuint *dest = (const GLuint *) destPtr;
  335.    GLuint i;
  336.    ASSERT(sizeof(GLfloat) == sizeof(GLuint));
  337. #else
  338.    GLchan *src = srcPtr;
  339.    const GLchan *dest = destPtr;
  340.    GLuint i;
  341. #endif
  342.  
  343.    switch (ctx->Color.LogicOp) {
  344.       case GL_CLEAR:
  345.          for (i=0;i<n;i++) {
  346.             if (mask[i]) {
  347.                src[i] = 0;
  348.             }
  349.          }
  350.          break;
  351.       case GL_SET:
  352.          for (i=0;i<n;i++) {
  353.             if (mask[i]) {
  354.                src[i] = ~0;
  355.             }
  356.          }
  357.          break;
  358.       case GL_COPY:
  359.          /* do nothing */
  360.          break;
  361.       case GL_COPY_INVERTED:
  362.          for (i=0;i<n;i++) {
  363.             if (mask[i]) {
  364.                src[i] = ~src[i];
  365.             }
  366.          }
  367.          break;
  368.       case GL_NOOP:
  369.          for (i=0;i<n;i++) {
  370.             if (mask[i]) {
  371.                src[i] = dest[i];
  372.             }
  373.          }
  374.          break;
  375.       case GL_INVERT:
  376.          for (i=0;i<n;i++) {
  377.             if (mask[i]) {
  378.                src[i] = ~dest[i];
  379.             }
  380.          }
  381.          break;
  382.       case GL_AND:
  383.          for (i=0;i<n;i++) {
  384.             if (mask[i]) {
  385.                src[i] &= dest[i];
  386.             }
  387.          }
  388.          break;
  389.       case GL_NAND:
  390.          for (i=0;i<n;i++) {
  391.             if (mask[i]) {
  392.                src[i] = ~(src[i] & dest[i]);
  393.             }
  394.          }
  395.          break;
  396.       case GL_OR:
  397.          for (i=0;i<n;i++) {
  398.             if (mask[i]) {
  399.                src[i]|= dest[i];
  400.             }
  401.          }
  402.          break;
  403.       case GL_NOR:
  404.          for (i=0;i<n;i++) {
  405.             if (mask[i]) {
  406.                src[i] = ~(src[i] | dest[i]);
  407.             }
  408.          }
  409.          break;
  410.       case GL_XOR:
  411.          for (i=0;i<n;i++) {
  412.             if (mask[i]) {
  413.                src[i] ^= dest[i];
  414.             }
  415.          }
  416.          break;
  417.       case GL_EQUIV:
  418.          for (i=0;i<n;i++) {
  419.             if (mask[i]) {
  420.                src[i] = ~(src[i] ^ dest[i]);
  421.             }
  422.          }
  423.          break;
  424.       case GL_AND_REVERSE:
  425.          for (i=0;i<n;i++) {
  426.             if (mask[i]) {
  427.                src[i] = src[i] & ~dest[i];
  428.             }
  429.          }
  430.          break;
  431.       case GL_AND_INVERTED:
  432.          for (i=0;i<n;i++) {
  433.             if (mask[i]) {
  434.                src[i] = ~src[i] & dest[i];
  435.             }
  436.          }
  437.          break;
  438.       case GL_OR_REVERSE:
  439.          for (i=0;i<n;i++) {
  440.             if (mask[i]) {
  441.                src[i] = src[i] | ~dest[i];
  442.             }
  443.          }
  444.          break;
  445.       case GL_OR_INVERTED:
  446.          for (i=0;i<n;i++) {
  447.             if (mask[i]) {
  448.                src[i] = ~src[i] | dest[i];
  449.             }
  450.          }
  451.          break;
  452.       default:
  453.          /* should never happen */
  454.          _mesa_problem(ctx, "Bad function in rgba_logicop");
  455.    }
  456. }
  457.  
  458.  
  459.  
  460. /*
  461.  * Apply the current logic operator to a span of RGBA pixels.
  462.  * We can handle horizontal runs of pixels (spans) or arrays of x/y
  463.  * pixel coordinates.
  464.  */
  465. void
  466. _mesa_logicop_rgba_span( GLcontext *ctx, const struct sw_span *span,
  467.                          GLchan rgba[][4] )
  468. {
  469.    SWcontext *swrast = SWRAST_CONTEXT(ctx);
  470.    GLchan dest[MAX_WIDTH][4];
  471.  
  472.    ASSERT(span->end < MAX_WIDTH);
  473.    ASSERT(span->arrayMask & SPAN_RGBA);
  474.  
  475.    if (span->arrayMask & SPAN_XY) {
  476.       (*swrast->Driver.ReadRGBAPixels)(ctx, span->end,
  477.                                        span->array->x, span->array->y,
  478.                                        dest, span->array->mask);
  479.       if (SWRAST_CONTEXT(ctx)->_RasterMask & ALPHABUF_BIT) {
  480.          _mesa_read_alpha_pixels(ctx, span->end,
  481.                                  span->array->x, span->array->y,
  482.                                  dest, span->array->mask);
  483.       }
  484.    }
  485.    else {
  486.       _mesa_read_rgba_span(ctx, ctx->DrawBuffer, span->end,
  487.                            span->x, span->y, dest);
  488.    }
  489.  
  490.    if (sizeof(GLchan) * 4 == sizeof(GLuint)) {
  491.       rgba_logicop_ui(ctx, span->end, span->array->mask,
  492.                       (GLuint *) rgba, (const GLuint *) dest);
  493.    }
  494.    else {
  495.       rgba_logicop_chan(ctx, 4 * span->end, span->array->mask,
  496.                         (GLchan *) rgba, (const GLchan *) dest);
  497.    }
  498. }
  499.