Header file clean-up:
[mesa.git] / src / mesa / swrast / s_alphabuf.c
1 /* $Id: s_alphabuf.c,v 1.15 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 /*
29 * Software alpha planes. Many frame buffers don't have alpha bits so
30 * we simulate them in software.
31 */
32
33
34 #include "glheader.h"
35 #include "context.h"
36 #include "imports.h"
37
38 #include "s_context.h"
39 #include "s_alphabuf.h"
40
41
42 /*
43 * Allocate a new front and back alpha buffer.
44 */
45 void
46 _mesa_alloc_alpha_buffers( GLframebuffer *buffer )
47 {
48 const GLint bytes = buffer->Width * buffer->Height * sizeof(GLchan);
49
50 ASSERT(buffer->UseSoftwareAlphaBuffers);
51
52 if (buffer->FrontLeftAlpha) {
53 MESA_PBUFFER_FREE( buffer->FrontLeftAlpha );
54 }
55 buffer->FrontLeftAlpha = MESA_PBUFFER_ALLOC( bytes );
56 if (!buffer->FrontLeftAlpha) {
57 /* out of memory */
58 _mesa_error( NULL, GL_OUT_OF_MEMORY,
59 "Couldn't allocate front-left alpha buffer" );
60 }
61
62 if (buffer->Visual.doubleBufferMode) {
63 if (buffer->BackLeftAlpha) {
64 MESA_PBUFFER_FREE( buffer->BackLeftAlpha );
65 }
66 buffer->BackLeftAlpha = MESA_PBUFFER_ALLOC( bytes );
67 if (!buffer->BackLeftAlpha) {
68 /* out of memory */
69 _mesa_error( NULL, GL_OUT_OF_MEMORY,
70 "Couldn't allocate back-left alpha buffer" );
71 }
72 }
73
74 if (buffer->Visual.stereoMode) {
75 if (buffer->FrontRightAlpha) {
76 MESA_PBUFFER_FREE( buffer->FrontRightAlpha );
77 }
78 buffer->FrontRightAlpha = MESA_PBUFFER_ALLOC( bytes );
79 if (!buffer->FrontRightAlpha) {
80 /* out of memory */
81 _mesa_error( NULL, GL_OUT_OF_MEMORY,
82 "Couldn't allocate front-right alpha buffer" );
83 }
84
85 if (buffer->Visual.doubleBufferMode) {
86 if (buffer->BackRightAlpha) {
87 MESA_PBUFFER_FREE( buffer->BackRightAlpha );
88 }
89 buffer->BackRightAlpha = MESA_PBUFFER_ALLOC( bytes );
90 if (!buffer->BackRightAlpha) {
91 /* out of memory */
92 _mesa_error( NULL, GL_OUT_OF_MEMORY,
93 "Couldn't allocate back-right alpha buffer" );
94 }
95 }
96 }
97 }
98
99
100 /*
101 * Clear all the alpha buffers
102 */
103 void
104 _mesa_clear_alpha_buffers( GLcontext *ctx )
105 {
106 const GLchan aclear = (GLchan) ctx->Color.ClearColor[3];
107 GLuint bufferBit;
108
109 ASSERT(ctx->DrawBuffer->UseSoftwareAlphaBuffers);
110 ASSERT(ctx->Color.ColorMask[ACOMP]);
111
112 /* loop over four possible alpha buffers */
113 for (bufferBit = 1; bufferBit <= 8; bufferBit = bufferBit << 1) {
114 if (bufferBit & ctx->Color._DrawDestMask) {
115 GLchan *buffer;
116 if (bufferBit == FRONT_LEFT_BIT) {
117 buffer = (GLchan *) ctx->DrawBuffer->FrontLeftAlpha;
118 }
119 else if (bufferBit == FRONT_RIGHT_BIT) {
120 buffer = (GLchan *) ctx->DrawBuffer->FrontRightAlpha;
121 }
122 else if (bufferBit == BACK_LEFT_BIT) {
123 buffer = (GLchan *) ctx->DrawBuffer->BackLeftAlpha;
124 }
125 else {
126 buffer = (GLchan *) ctx->DrawBuffer->BackRightAlpha;
127 }
128
129 if (ctx->Scissor.Enabled) {
130 /* clear scissor region */
131 GLint j;
132 GLint rowLen = ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin;
133 GLint rows = ctx->DrawBuffer->_Ymax - ctx->DrawBuffer->_Ymin;
134 GLint width = ctx->DrawBuffer->Width;
135 GLchan *aptr = buffer
136 + ctx->DrawBuffer->_Ymin * ctx->DrawBuffer->Width
137 + ctx->DrawBuffer->_Xmin;
138 for (j = 0; j < rows; j++) {
139 #if CHAN_BITS == 8
140 MEMSET( aptr, aclear, rowLen );
141 #elif CHAN_BITS == 16
142 MEMSET16( aptr, aclear, rowLen );
143 #else
144 GLint i;
145 for (i = 0; i < rowLen; i++) {
146 aptr[i] = aclear;
147 }
148 #endif
149 aptr += width;
150 }
151 }
152 else {
153 /* clear whole buffer */
154 GLuint pixels = ctx->DrawBuffer->Width * ctx->DrawBuffer->Height;
155 #if CHAN_BITS == 8
156 MEMSET(buffer, aclear, pixels);
157 #elif CHAN_BITS == 16
158 MEMSET16(buffer, aclear, pixels);
159 #else
160 GLuint i;
161 for (i = 0; i < pixels; i++) {
162 buffer[i] = aclear;
163 }
164 #endif
165 }
166 }
167 }
168 }
169
170
171
172 static INLINE
173 GLchan *get_alpha_buffer( GLcontext *ctx )
174 {
175 SWcontext *swrast = SWRAST_CONTEXT(ctx);
176
177 switch (swrast->CurrentBuffer) {
178 case FRONT_LEFT_BIT:
179 return (GLchan *) ctx->DrawBuffer->FrontLeftAlpha;
180 break;
181 case BACK_LEFT_BIT:
182 return (GLchan *) ctx->DrawBuffer->BackLeftAlpha;
183 break;
184 case FRONT_RIGHT_BIT:
185 return (GLchan *) ctx->DrawBuffer->FrontRightAlpha;
186 break;
187 case BACK_RIGHT_BIT:
188 return (GLchan *) ctx->DrawBuffer->BackRightAlpha;
189 break;
190 default:
191 _mesa_problem(ctx, "Bad CurrentBuffer in get_alpha_buffer()");
192 return (GLchan *) ctx->DrawBuffer->FrontLeftAlpha;
193 }
194 }
195
196
197 void
198 _mesa_write_alpha_span( GLcontext *ctx, GLuint n, GLint x, GLint y,
199 CONST GLchan rgba[][4], const GLubyte mask[] )
200 {
201 GLchan *buffer, *aptr;
202 GLuint i;
203
204 buffer = get_alpha_buffer(ctx);
205 aptr = buffer + y * ctx->DrawBuffer->Width + x;
206
207 if (mask) {
208 for (i=0;i<n;i++) {
209 if (mask[i]) {
210 *aptr = rgba[i][ACOMP];
211 }
212 aptr++;
213 }
214 }
215 else {
216 for (i=0;i<n;i++) {
217 *aptr++ = rgba[i][ACOMP];
218 }
219 }
220 }
221
222
223 void
224 _mesa_write_mono_alpha_span( GLcontext *ctx, GLuint n, GLint x, GLint y,
225 GLchan alpha, const GLubyte mask[] )
226 {
227 GLchan *buffer, *aptr;
228 GLuint i;
229
230 buffer = get_alpha_buffer(ctx);
231 aptr = buffer + y * ctx->DrawBuffer->Width + x;
232
233 if (mask) {
234 for (i=0;i<n;i++) {
235 if (mask[i]) {
236 *aptr = alpha;
237 }
238 aptr++;
239 }
240 }
241 else {
242 for (i=0;i<n;i++) {
243 *aptr++ = alpha;
244 }
245 }
246 }
247
248
249 void
250 _mesa_write_alpha_pixels( GLcontext *ctx,
251 GLuint n, const GLint x[], const GLint y[],
252 CONST GLchan rgba[][4], const GLubyte mask[] )
253 {
254 GLchan *buffer;
255 GLuint i;
256
257 buffer = get_alpha_buffer(ctx);
258
259 if (mask) {
260 for (i=0;i<n;i++) {
261 if (mask[i]) {
262 GLchan *aptr = buffer + y[i] * ctx->DrawBuffer->Width + x[i];
263 *aptr = rgba[i][ACOMP];
264 }
265 }
266 }
267 else {
268 for (i=0;i<n;i++) {
269 GLchan *aptr = buffer + y[i] * ctx->DrawBuffer->Width + x[i];
270 *aptr = rgba[i][ACOMP];
271 }
272 }
273 }
274
275
276 void
277 _mesa_write_mono_alpha_pixels( GLcontext *ctx,
278 GLuint n, const GLint x[], const GLint y[],
279 GLchan alpha, const GLubyte mask[] )
280 {
281 GLchan *buffer;
282 GLuint i;
283
284 buffer = get_alpha_buffer(ctx);
285
286 if (mask) {
287 for (i=0;i<n;i++) {
288 if (mask[i]) {
289 GLchan *aptr = buffer + y[i] * ctx->DrawBuffer->Width + x[i];
290 *aptr = alpha;
291 }
292 }
293 }
294 else {
295 for (i=0;i<n;i++) {
296 GLchan *aptr = buffer + y[i] * ctx->DrawBuffer->Width + x[i];
297 *aptr = alpha;
298 }
299 }
300 }
301
302
303
304 void
305 _mesa_read_alpha_span( GLcontext *ctx,
306 GLuint n, GLint x, GLint y, GLchan rgba[][4] )
307 {
308 const GLchan *buffer, *aptr;
309 GLuint i;
310
311 buffer = get_alpha_buffer(ctx);
312 aptr = buffer + y * ctx->DrawBuffer->Width + x;
313
314 for (i = 0; i < n; i++)
315 rgba[i][ACOMP] = *aptr++;
316 }
317
318
319 void
320 _mesa_read_alpha_pixels( GLcontext *ctx,
321 GLuint n, const GLint x[], const GLint y[],
322 GLchan rgba[][4], const GLubyte mask[] )
323 {
324 const GLchan *buffer;
325 GLuint i;
326
327 buffer = get_alpha_buffer(ctx);
328
329 for (i = 0; i < n; i++) {
330 if (mask[i]) {
331 const GLchan *aptr = buffer + y[i] * ctx->DrawBuffer->Width + x[i];
332 rgba[i][ACOMP] = *aptr;
333 }
334 }
335 }