Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  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.  
  26. #include "main/glheader.h"
  27. #include "main/context.h"
  28. #include "main/imports.h"
  29. #include "main/macros.h"
  30.  
  31. #include "s_context.h"
  32. #include "s_logic.h"
  33. #include "s_span.h"
  34.  
  35.  
  36. /**
  37.  * We do all logic ops on 4-byte GLuints.
  38.  * Depending on bytes per pixel, the mask array elements correspond to
  39.  * 1, 2 or 4 GLuints.
  40.  */
  41. #define LOGIC_OP_LOOP(MODE, MASKSTRIDE)         \
  42. do {                                            \
  43.    GLuint i;                                    \
  44.    switch (MODE) {                              \
  45.       case GL_CLEAR:                            \
  46.          for (i = 0; i < n; i++) {              \
  47.             if (mask[i / MASKSTRIDE]) {         \
  48.                src[i] = 0;                      \
  49.             }                                   \
  50.          }                                      \
  51.          break;                                 \
  52.       case GL_SET:                              \
  53.          for (i = 0; i < n; i++) {              \
  54.             if (mask[i / MASKSTRIDE]) {         \
  55.                src[i] = ~0;                     \
  56.             }                                   \
  57.          }                                      \
  58.          break;                                 \
  59.       case GL_COPY:                             \
  60.          /* do nothing */                       \
  61.          break;                                 \
  62.       case GL_COPY_INVERTED:                    \
  63.          for (i = 0; i < n; i++) {              \
  64.             if (mask[i / MASKSTRIDE]) {         \
  65.                src[i] = ~src[i];                \
  66.             }                                   \
  67.          }                                      \
  68.          break;                                 \
  69.       case GL_NOOP:                             \
  70.          for (i = 0; i < n; i++) {              \
  71.             if (mask[i / MASKSTRIDE]) {         \
  72.                src[i] = dest[i];                \
  73.             }                                   \
  74.          }                                      \
  75.          break;                                 \
  76.       case GL_INVERT:                           \
  77.          for (i = 0; i < n; i++) {              \
  78.             if (mask[i / MASKSTRIDE]) {         \
  79.                src[i] = ~dest[i];               \
  80.             }                                   \
  81.          }                                      \
  82.          break;                                 \
  83.       case GL_AND:                              \
  84.          for (i = 0; i < n; i++) {              \
  85.             if (mask[i / MASKSTRIDE]) {         \
  86.                src[i] &= dest[i];               \
  87.             }                                   \
  88.          }                                      \
  89.          break;                                 \
  90.       case GL_NAND:                             \
  91.          for (i = 0; i < n; i++) {              \
  92.             if (mask[i / MASKSTRIDE]) {         \
  93.                src[i] = ~(src[i] & dest[i]);    \
  94.             }                                   \
  95.          }                                      \
  96.          break;                                 \
  97.       case GL_OR:                               \
  98.          for (i = 0; i < n; i++) {              \
  99.             if (mask[i / MASKSTRIDE]) {         \
  100.                src[i] |= dest[i];               \
  101.             }                                   \
  102.          }                                      \
  103.          break;                                 \
  104.       case GL_NOR:                              \
  105.          for (i = 0; i < n; i++) {              \
  106.             if (mask[i / MASKSTRIDE]) {         \
  107.                src[i] = ~(src[i] | dest[i]);    \
  108.             }                                   \
  109.          }                                      \
  110.          break;                                 \
  111.       case GL_XOR:                              \
  112.          for (i = 0; i < n; i++) {              \
  113.             if (mask[i / MASKSTRIDE]) {         \
  114.                src[i] ^= dest[i];               \
  115.             }                                   \
  116.          }                                      \
  117.          break;                                 \
  118.       case GL_EQUIV:                            \
  119.          for (i = 0; i < n; i++) {              \
  120.             if (mask[i / MASKSTRIDE]) {         \
  121.                src[i] = ~(src[i] ^ dest[i]);    \
  122.             }                                   \
  123.          }                                      \
  124.          break;                                 \
  125.       case GL_AND_REVERSE:                      \
  126.          for (i = 0; i < n; i++) {              \
  127.             if (mask[i / MASKSTRIDE]) {         \
  128.                src[i] = src[i] & ~dest[i];      \
  129.             }                                   \
  130.          }                                      \
  131.          break;                                 \
  132.       case GL_AND_INVERTED:                     \
  133.          for (i = 0; i < n; i++) {              \
  134.             if (mask[i / MASKSTRIDE]) {         \
  135.                src[i] = ~src[i] & dest[i];      \
  136.             }                                   \
  137.          }                                      \
  138.          break;                                 \
  139.       case GL_OR_REVERSE:                       \
  140.          for (i = 0; i < n; i++) {              \
  141.             if (mask[i / MASKSTRIDE]) {         \
  142.                src[i] = src[i] | ~dest[i];      \
  143.             }                                   \
  144.          }                                      \
  145.          break;                                 \
  146.       case GL_OR_INVERTED:                      \
  147.          for (i = 0; i < n; i++) {              \
  148.             if (mask[i / MASKSTRIDE]) {         \
  149.                src[i] = ~src[i] | dest[i];      \
  150.             }                                   \
  151.          }                                      \
  152.          break;                                 \
  153.       default:                                  \
  154.          _mesa_problem(ctx, "bad logicop mode");\
  155.    }                                            \
  156. } while (0)
  157.  
  158.  
  159.  
  160. static INLINE void
  161. logicop_uint1(struct gl_context *ctx, GLuint n, GLuint src[], const GLuint dest[],
  162.               const GLubyte mask[])
  163. {
  164.    LOGIC_OP_LOOP(ctx->Color.LogicOp, 1);
  165. }
  166.  
  167.  
  168. static INLINE void
  169. logicop_uint2(struct gl_context *ctx, GLuint n, GLuint src[], const GLuint dest[],
  170.               const GLubyte mask[])
  171. {
  172.    LOGIC_OP_LOOP(ctx->Color.LogicOp, 2);
  173. }
  174.  
  175.  
  176. static INLINE void
  177. logicop_uint4(struct gl_context *ctx, GLuint n, GLuint src[], const GLuint dest[],
  178.               const GLubyte mask[])
  179. {
  180.    LOGIC_OP_LOOP(ctx->Color.LogicOp, 4);
  181. }
  182.  
  183.  
  184.  
  185. /**
  186.  * Apply the current logic operator to a span of RGBA pixels.
  187.  * We can handle horizontal runs of pixels (spans) or arrays of x/y
  188.  * pixel coordinates.
  189.  */
  190. void
  191. _swrast_logicop_rgba_span(struct gl_context *ctx, struct gl_renderbuffer *rb,
  192.                           SWspan *span)
  193. {
  194.    void *rbPixels;
  195.  
  196.    ASSERT(span->end < MAX_WIDTH);
  197.    ASSERT(span->arrayMask & SPAN_RGBA);
  198.    ASSERT(rb->DataType == span->array->ChanType);
  199.  
  200.    rbPixels = _swrast_get_dest_rgba(ctx, rb, span);
  201.  
  202.    if (span->array->ChanType == GL_UNSIGNED_BYTE) {
  203.       /* treat 4*GLubyte as GLuint */
  204.       logicop_uint1(ctx, span->end,
  205.                     (GLuint *) span->array->rgba8,
  206.                     (const GLuint *) rbPixels, span->array->mask);
  207.    }
  208.    else if (span->array->ChanType == GL_UNSIGNED_SHORT) {
  209.       /* treat 2*GLushort as GLuint */
  210.       logicop_uint2(ctx, 2 * span->end,
  211.                     (GLuint *) span->array->rgba16,
  212.                     (const GLuint *) rbPixels, span->array->mask);
  213.    }
  214.    else {
  215.       logicop_uint4(ctx, 4 * span->end,
  216.                     (GLuint *) span->array->attribs[FRAG_ATTRIB_COL0],
  217.                     (const GLuint *) rbPixels, span->array->mask);
  218.    }
  219. }
  220.