Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
4358 Serge 1
/*
2
 * Mesa 3-D graphics library
3
 *
4
 * Copyright (C) 1999-2006  Brian Paul   All Rights Reserved.
5
 *
6
 * Permission is hereby granted, free of charge, to any person obtaining a
7
 * copy of this software and associated documentation files (the "Software"),
8
 * to deal in the Software without restriction, including without limitation
9
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10
 * and/or sell copies of the Software, and to permit persons to whom the
11
 * Software is furnished to do so, subject to the following conditions:
12
 *
13
 * The above copyright notice and this permission notice shall be included
14
 * in all copies or substantial portions of the Software.
15
 *
16
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22
 * 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 < SWRAST_MAX_WIDTH);
197
   ASSERT(span->arrayMask & SPAN_RGBA);
198
 
199
   rbPixels = _swrast_get_dest_rgba(ctx, rb, span);
200
 
201
   if (span->array->ChanType == GL_UNSIGNED_BYTE) {
202
      /* treat 4*GLubyte as GLuint */
203
      logicop_uint1(ctx, span->end,
204
                    (GLuint *) span->array->rgba8,
205
                    (const GLuint *) rbPixels, span->array->mask);
206
   }
207
   else if (span->array->ChanType == GL_UNSIGNED_SHORT) {
208
      /* treat 2*GLushort as GLuint */
209
      logicop_uint2(ctx, 2 * span->end,
210
                    (GLuint *) span->array->rgba16,
211
                    (const GLuint *) rbPixels, span->array->mask);
212
   }
213
   else {
214
      logicop_uint4(ctx, 4 * span->end,
215
                    (GLuint *) span->array->attribs[VARYING_SLOT_COL0],
216
                    (const GLuint *) rbPixels, span->array->mask);
217
   }
218
}