OSDN Git Service

3f12552fd8f57a55e792292b6ab5894232ac0a6f
[android-x86/external-mesa.git] / src / mesa / swrast / s_alpha.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  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
21  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
22  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23  * OTHER DEALINGS IN THE SOFTWARE.
24  */
25
26 /**
27  * \file swrast/s_alpha.c
28  * \brief Functions to apply alpha test.
29  */
30
31 #include "main/glheader.h"
32 #include "main/context.h"
33 #include "main/colormac.h"
34 #include "main/macros.h"
35
36 #include "s_alpha.h"
37 #include "s_context.h"
38
39
40 #define ALPHA_TEST(ALPHA, LOOP_CODE)            \
41 do {                                            \
42    switch (ctx->Color.AlphaFunc) {              \
43       case GL_LESS:                             \
44          for (i = 0; i < n; i++) {              \
45             mask[i] &= (ALPHA < ref);           \
46             LOOP_CODE;                          \
47          }                                      \
48          break;                                 \
49       case GL_LEQUAL:                           \
50          for (i = 0; i < n; i++) {              \
51             mask[i] &= (ALPHA <= ref);          \
52             LOOP_CODE;                          \
53          }                                      \
54          break;                                 \
55       case GL_GEQUAL:                           \
56          for (i = 0; i < n; i++) {              \
57             mask[i] &= (ALPHA >= ref);          \
58             LOOP_CODE;                          \
59          }                                      \
60          break;                                 \
61       case GL_GREATER:                          \
62          for (i = 0; i < n; i++) {              \
63             mask[i] &= (ALPHA > ref);           \
64             LOOP_CODE;                          \
65          }                                      \
66          break;                                 \
67       case GL_NOTEQUAL:                         \
68          for (i = 0; i < n; i++) {              \
69             mask[i] &= (ALPHA != ref);          \
70             LOOP_CODE;                          \
71          }                                      \
72          break;                                 \
73       case GL_EQUAL:                            \
74          for (i = 0; i < n; i++) {              \
75             mask[i] &= (ALPHA == ref);          \
76             LOOP_CODE;                          \
77          }                                      \
78          break;                                 \
79       default:                                  \
80          _mesa_problem(ctx, "Invalid alpha test in _swrast_alpha_test" ); \
81          return 0;                              \
82    }                                            \
83 } while (0)
84
85
86
87 /**
88  * Perform the alpha test for an array of pixels.
89  * For pixels that fail the test, mask[i] will be set to 0.
90  * \return  0 if all pixels in the span failed the alpha test,
91  *          1 if one or more pixels passed the alpha test.
92  */
93 GLint
94 _swrast_alpha_test(const struct gl_context *ctx, SWspan *span)
95 {
96    const GLuint n = span->end;
97    GLubyte *mask = span->array->mask;
98    GLuint i;
99
100    if (ctx->Color.AlphaFunc == GL_ALWAYS) {
101       /* do nothing */
102       return 1;
103    }
104    else if (ctx->Color.AlphaFunc == GL_NEVER) {
105       /* All pixels failed - caller should check for this return value and
106        * act accordingly.
107        */
108       span->writeAll = GL_FALSE;
109       return 0;
110    }
111
112    if (span->arrayMask & SPAN_RGBA) {
113       /* Use array's alpha values */
114       if (span->array->ChanType == GL_UNSIGNED_BYTE) {
115          GLubyte (*rgba)[4] = span->array->rgba8;
116          GLubyte ref;
117          CLAMPED_FLOAT_TO_UBYTE(ref, ctx->Color.AlphaRef);
118          ALPHA_TEST(rgba[i][ACOMP], ;);
119       }
120       else if (span->array->ChanType == GL_UNSIGNED_SHORT) {
121          GLushort (*rgba)[4] = span->array->rgba16;
122          GLushort ref;
123          CLAMPED_FLOAT_TO_USHORT(ref, ctx->Color.AlphaRef);
124          ALPHA_TEST(rgba[i][ACOMP], ;);
125       }
126       else {
127          GLfloat (*rgba)[4] = span->array->attribs[VARYING_SLOT_COL0];
128          const GLfloat ref = ctx->Color.AlphaRef;
129          ALPHA_TEST(rgba[i][ACOMP], ;);
130       }
131    }
132    else {
133       /* Interpolate alpha values */
134       ASSERT(span->interpMask & SPAN_RGBA);
135       if (span->array->ChanType == GL_UNSIGNED_BYTE) {
136          const GLfixed alphaStep = span->alphaStep;
137          GLfixed alpha = span->alpha;
138          GLubyte ref;
139          CLAMPED_FLOAT_TO_UBYTE(ref, ctx->Color.AlphaRef);
140          ALPHA_TEST(FixedToInt(alpha), alpha += alphaStep);
141       }
142       else if (span->array->ChanType == GL_UNSIGNED_SHORT) {
143          const GLfixed alphaStep = span->alphaStep;
144          GLfixed alpha = span->alpha;
145          GLushort ref;
146          CLAMPED_FLOAT_TO_USHORT(ref, ctx->Color.AlphaRef);
147          ALPHA_TEST(FixedToInt(alpha), alpha += alphaStep);
148       }
149       else {
150          const GLfloat alphaStep = FixedToFloat(span->alphaStep);
151          GLfloat alpha = FixedToFloat(span->alpha);
152          const GLfloat ref = ctx->Color.AlphaRef;
153          ALPHA_TEST(alpha, alpha += alphaStep);
154       }
155    }
156
157    span->writeAll = GL_FALSE;
158
159    /* XXX examine mask[] values? */
160    return 1;
161 }