lots of gl_*() to _mesa_*() namespace clean-up
[mesa.git] / src / mesa / swrast / s_alphabuf.c
1 /* $Id: s_alphabuf.c,v 1.5 2001/03/03 20:33:30 brianp Exp $ */
2
3 /*
4 * Mesa 3-D graphics library
5 * Version: 3.5
6 *
7 * Copyright (C) 1999-2001 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 "mem.h"
37
38 #include "s_alphabuf.h"
39
40
41
42
43 #define ALPHA_DRAW_ADDR(X,Y) \
44 (ctx->DrawBuffer->Alpha + (Y) * ctx->DrawBuffer->Width + (X))
45
46 #define ALPHA_READ_ADDR(X,Y) \
47 (ctx->ReadBuffer->Alpha + (Y) * ctx->ReadBuffer->Width + (X))
48
49
50
51 /*
52 * Allocate new front/back/left/right alpha buffers.
53 * Input: ctx - the context
54 *
55 */
56 static void
57 alloc_alpha_buffers( GLcontext *ctx, GLframebuffer *buf )
58 {
59 GLint bytes = buf->Width * buf->Height * sizeof(GLchan);
60
61 ASSERT(ctx->DrawBuffer->UseSoftwareAlphaBuffers);
62
63 if (buf->FrontLeftAlpha) {
64 FREE( buf->FrontLeftAlpha );
65 }
66 buf->FrontLeftAlpha = (GLchan *) MALLOC( bytes );
67 if (!buf->FrontLeftAlpha) {
68 /* out of memory */
69 _mesa_error( ctx, GL_OUT_OF_MEMORY,
70 "Couldn't allocate front-left alpha buffer" );
71 }
72
73 if (ctx->Visual.doubleBufferMode) {
74 if (buf->BackLeftAlpha) {
75 FREE( buf->BackLeftAlpha );
76 }
77 buf->BackLeftAlpha = (GLchan *) MALLOC( bytes );
78 if (!buf->BackLeftAlpha) {
79 /* out of memory */
80 _mesa_error( ctx, GL_OUT_OF_MEMORY,
81 "Couldn't allocate back-left alpha buffer" );
82 }
83 }
84
85 if (ctx->Visual.stereoMode) {
86 if (buf->FrontRightAlpha) {
87 FREE( buf->FrontRightAlpha );
88 }
89 buf->FrontRightAlpha = (GLchan *) MALLOC( bytes );
90 if (!buf->FrontRightAlpha) {
91 /* out of memory */
92 _mesa_error( ctx, GL_OUT_OF_MEMORY,
93 "Couldn't allocate front-right alpha buffer" );
94 }
95
96 if (ctx->Visual.doubleBufferMode) {
97 if (buf->BackRightAlpha) {
98 FREE( buf->BackRightAlpha );
99 }
100 buf->BackRightAlpha = (GLchan *) MALLOC( bytes );
101 if (!buf->BackRightAlpha) {
102 /* out of memory */
103 _mesa_error( ctx, GL_OUT_OF_MEMORY,
104 "Couldn't allocate back-right alpha buffer" );
105 }
106 }
107 }
108
109 if (ctx->Color.DriverDrawBuffer == GL_FRONT_LEFT)
110 buf->Alpha = buf->FrontLeftAlpha;
111 else if (ctx->Color.DriverDrawBuffer == GL_BACK_LEFT)
112 buf->Alpha = buf->BackLeftAlpha;
113 else if (ctx->Color.DriverDrawBuffer == GL_FRONT_RIGHT)
114 buf->Alpha = buf->FrontRightAlpha;
115 else if (ctx->Color.DriverDrawBuffer == GL_BACK_RIGHT)
116 buf->Alpha = buf->BackRightAlpha;
117 }
118
119
120 /*
121 * Allocate a new front and back alpha buffer.
122 */
123 void
124 _mesa_alloc_alpha_buffers( GLcontext *ctx )
125 {
126 alloc_alpha_buffers( ctx, ctx->DrawBuffer );
127 if (ctx->ReadBuffer != ctx->DrawBuffer) {
128 alloc_alpha_buffers( ctx, ctx->ReadBuffer );
129 }
130 }
131
132
133 /*
134 * Clear all the alpha buffers
135 */
136 void
137 _mesa_clear_alpha_buffers( GLcontext *ctx )
138 {
139 const GLchan aclear = ctx->Color.ClearColor[3];
140 GLuint bufferBit;
141
142 ASSERT(ctx->DrawBuffer->UseSoftwareAlphaBuffers);
143 ASSERT(ctx->Color.ColorMask[ACOMP]);
144
145 /* loop over four possible alpha buffers */
146 for (bufferBit = 1; bufferBit <= 8; bufferBit = bufferBit << 1) {
147 if (bufferBit & ctx->Color.DrawDestMask) {
148 GLchan *buffer;
149 if (bufferBit == FRONT_LEFT_BIT) {
150 buffer = ctx->DrawBuffer->FrontLeftAlpha;
151 }
152 else if (bufferBit == FRONT_RIGHT_BIT) {
153 buffer = ctx->DrawBuffer->FrontRightAlpha;
154 }
155 else if (bufferBit == BACK_LEFT_BIT) {
156 buffer = ctx->DrawBuffer->BackLeftAlpha;
157 }
158 else {
159 buffer = ctx->DrawBuffer->BackRightAlpha;
160 }
161
162 if (ctx->Scissor.Enabled) {
163 /* clear scissor region */
164 GLint j;
165 GLint rowLen = ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin + 1;
166 GLint rows = ctx->DrawBuffer->_Ymax - ctx->DrawBuffer->_Ymin + 1;
167 GLchan *aptr = buffer
168 + ctx->DrawBuffer->_Ymin * ctx->DrawBuffer->Width
169 + ctx->DrawBuffer->_Xmin;
170 for (j = 0; j < rows; j++) {
171 #if CHAN_BITS == 8
172 MEMSET( aptr, aclear, rowLen );
173 #elif CHAN_BITS == 16
174 MEMSET16( aptr, aclear, rowLen );
175 #else
176 #error unexpected CHAN_BITS value
177 #endif
178 aptr += rowLen;
179 }
180 }
181 else {
182 /* clear whole buffer */
183 GLuint bytes = ctx->DrawBuffer->Width * ctx->DrawBuffer->Height;
184 MEMSET( buffer, aclear, bytes );
185 }
186 }
187 }
188 }
189
190
191
192 void
193 _mesa_write_alpha_span( GLcontext *ctx, GLuint n, GLint x, GLint y,
194 CONST GLchan rgba[][4], const GLubyte mask[] )
195 {
196 GLchan *aptr = ALPHA_DRAW_ADDR( x, y );
197 GLuint i;
198
199 if (mask) {
200 for (i=0;i<n;i++) {
201 if (mask[i]) {
202 *aptr = rgba[i][ACOMP];
203 }
204 aptr++;
205 }
206 }
207 else {
208 for (i=0;i<n;i++) {
209 *aptr++ = rgba[i][ACOMP];
210 }
211 }
212 }
213
214
215 void
216 _mesa_write_mono_alpha_span( GLcontext *ctx, GLuint n, GLint x, GLint y,
217 GLchan alpha, const GLubyte mask[] )
218 {
219 GLchan *aptr = ALPHA_DRAW_ADDR( x, y );
220 GLuint i;
221
222 if (mask) {
223 for (i=0;i<n;i++) {
224 if (mask[i]) {
225 *aptr = alpha;
226 }
227 aptr++;
228 }
229 }
230 else {
231 for (i=0;i<n;i++) {
232 *aptr++ = alpha;
233 }
234 }
235 }
236
237
238 void
239 _mesa_write_alpha_pixels( GLcontext *ctx,
240 GLuint n, const GLint x[], const GLint y[],
241 CONST GLchan rgba[][4], const GLubyte mask[] )
242 {
243 GLuint i;
244
245 if (mask) {
246 for (i=0;i<n;i++) {
247 if (mask[i]) {
248 GLchan *aptr = ALPHA_DRAW_ADDR( x[i], y[i] );
249 *aptr = rgba[i][ACOMP];
250 }
251 }
252 }
253 else {
254 for (i=0;i<n;i++) {
255 GLchan *aptr = ALPHA_DRAW_ADDR( x[i], y[i] );
256 *aptr = rgba[i][ACOMP];
257 }
258 }
259 }
260
261
262 void
263 _mesa_write_mono_alpha_pixels( GLcontext *ctx,
264 GLuint n, const GLint x[], const GLint y[],
265 GLchan alpha, const GLubyte mask[] )
266 {
267 GLuint i;
268
269 if (mask) {
270 for (i=0;i<n;i++) {
271 if (mask[i]) {
272 GLchan *aptr = ALPHA_DRAW_ADDR( x[i], y[i] );
273 *aptr = alpha;
274 }
275 }
276 }
277 else {
278 for (i=0;i<n;i++) {
279 GLchan *aptr = ALPHA_DRAW_ADDR( x[i], y[i] );
280 *aptr = alpha;
281 }
282 }
283 }
284
285
286
287 void
288 _mesa_read_alpha_span( GLcontext *ctx,
289 GLuint n, GLint x, GLint y, GLchan rgba[][4] )
290 {
291 GLchan *aptr = ALPHA_READ_ADDR( x, y );
292 GLuint i;
293 for (i=0;i<n;i++) {
294 rgba[i][ACOMP] = *aptr++;
295 }
296 }
297
298
299 void
300 _mesa_read_alpha_pixels( GLcontext *ctx,
301 GLuint n, const GLint x[], const GLint y[],
302 GLchan rgba[][4], const GLubyte mask[] )
303 {
304 GLuint i;
305 for (i=0;i<n;i++) {
306 if (mask[i]) {
307 GLchan *aptr = ALPHA_READ_ADDR( x[i], y[i] );
308 rgba[i][ACOMP] = *aptr;
309 }
310 }
311 }
312
313
314