1 /* $Id: s_alphabuf.c,v 1.12 2002/10/04 19:10:12 brianp Exp $ */
4 * Mesa 3-D graphics library
7 * Copyright (C) 1999-2002 Brian Paul All Rights Reserved.
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:
16 * The above copyright notice and this permission notice shall be included
17 * in all copies or substantial portions of the Software.
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.
29 * Software alpha planes. Many frame buffers don't have alpha bits so
30 * we simulate them in software.
38 #include "s_alphabuf.h"
42 * Allocate a new front and back alpha buffer.
45 _mesa_alloc_alpha_buffers( GLframebuffer
*buffer
)
47 const GLint bytes
= buffer
->Width
* buffer
->Height
* sizeof(GLchan
);
49 ASSERT(buffer
->UseSoftwareAlphaBuffers
);
51 if (buffer
->FrontLeftAlpha
) {
52 MESA_PBUFFER_FREE( buffer
->FrontLeftAlpha
);
54 buffer
->FrontLeftAlpha
= MESA_PBUFFER_ALLOC( bytes
);
55 if (!buffer
->FrontLeftAlpha
) {
57 _mesa_error( NULL
, GL_OUT_OF_MEMORY
,
58 "Couldn't allocate front-left alpha buffer" );
61 if (buffer
->Visual
.doubleBufferMode
) {
62 if (buffer
->BackLeftAlpha
) {
63 MESA_PBUFFER_FREE( buffer
->BackLeftAlpha
);
65 buffer
->BackLeftAlpha
= MESA_PBUFFER_ALLOC( bytes
);
66 if (!buffer
->BackLeftAlpha
) {
68 _mesa_error( NULL
, GL_OUT_OF_MEMORY
,
69 "Couldn't allocate back-left alpha buffer" );
73 if (buffer
->Visual
.stereoMode
) {
74 if (buffer
->FrontRightAlpha
) {
75 MESA_PBUFFER_FREE( buffer
->FrontRightAlpha
);
77 buffer
->FrontRightAlpha
= MESA_PBUFFER_ALLOC( bytes
);
78 if (!buffer
->FrontRightAlpha
) {
80 _mesa_error( NULL
, GL_OUT_OF_MEMORY
,
81 "Couldn't allocate front-right alpha buffer" );
84 if (buffer
->Visual
.doubleBufferMode
) {
85 if (buffer
->BackRightAlpha
) {
86 MESA_PBUFFER_FREE( buffer
->BackRightAlpha
);
88 buffer
->BackRightAlpha
= MESA_PBUFFER_ALLOC( bytes
);
89 if (!buffer
->BackRightAlpha
) {
91 _mesa_error( NULL
, GL_OUT_OF_MEMORY
,
92 "Couldn't allocate back-right alpha buffer" );
100 * Clear all the alpha buffers
103 _mesa_clear_alpha_buffers( GLcontext
*ctx
)
105 const GLchan aclear
= ctx
->Color
.ClearColor
[3];
108 ASSERT(ctx
->DrawBuffer
->UseSoftwareAlphaBuffers
);
109 ASSERT(ctx
->Color
.ColorMask
[ACOMP
]);
111 /* loop over four possible alpha buffers */
112 for (bufferBit
= 1; bufferBit
<= 8; bufferBit
= bufferBit
<< 1) {
113 if (bufferBit
& ctx
->Color
._DrawDestMask
) {
115 if (bufferBit
== FRONT_LEFT_BIT
) {
116 buffer
= (GLchan
*) ctx
->DrawBuffer
->FrontLeftAlpha
;
118 else if (bufferBit
== FRONT_RIGHT_BIT
) {
119 buffer
= (GLchan
*) ctx
->DrawBuffer
->FrontRightAlpha
;
121 else if (bufferBit
== BACK_LEFT_BIT
) {
122 buffer
= (GLchan
*) ctx
->DrawBuffer
->BackLeftAlpha
;
125 buffer
= (GLchan
*) ctx
->DrawBuffer
->BackRightAlpha
;
128 if (ctx
->Scissor
.Enabled
) {
129 /* clear scissor region */
131 GLint rowLen
= ctx
->DrawBuffer
->_Xmax
- ctx
->DrawBuffer
->_Xmin
;
132 GLint rows
= ctx
->DrawBuffer
->_Ymax
- ctx
->DrawBuffer
->_Ymin
;
133 GLint width
= ctx
->DrawBuffer
->Width
;
134 GLchan
*aptr
= buffer
135 + ctx
->DrawBuffer
->_Ymin
* ctx
->DrawBuffer
->Width
136 + ctx
->DrawBuffer
->_Xmin
;
137 for (j
= 0; j
< rows
; j
++) {
139 MEMSET( aptr
, aclear
, rowLen
);
140 #elif CHAN_BITS == 16
141 MEMSET16( aptr
, aclear
, rowLen
);
144 for (i
= 0; i
< rowLen
; i
++) {
152 /* clear whole buffer */
153 GLuint pixels
= ctx
->DrawBuffer
->Width
* ctx
->DrawBuffer
->Height
;
155 MEMSET(buffer
, aclear
, pixels
);
156 #elif CHAN_BITS == 16
157 MEMSET16(buffer
, aclear
, pixels
);
160 for (i
= 0; i
< pixels
; i
++) {
172 GLchan
*get_alpha_buffer( GLcontext
*ctx
)
174 switch (ctx
->Color
._DriverDrawBuffer
) {
176 return (GLchan
*) ctx
->DrawBuffer
->FrontLeftAlpha
;
179 return (GLchan
*) ctx
->DrawBuffer
->BackLeftAlpha
;
182 return (GLchan
*) ctx
->DrawBuffer
->FrontRightAlpha
;
185 return (GLchan
*) ctx
->DrawBuffer
->BackRightAlpha
;
188 _mesa_problem(ctx
, "Bad DriverDrawBuffer in _mesa_write_alpha_span()");
189 return (GLchan
*) ctx
->DrawBuffer
->FrontLeftAlpha
; /* aribitrary */
195 _mesa_write_alpha_span( GLcontext
*ctx
, GLuint n
, GLint x
, GLint y
,
196 CONST GLchan rgba
[][4], const GLubyte mask
[] )
198 GLchan
*buffer
, *aptr
;
201 buffer
= get_alpha_buffer(ctx
);
202 aptr
= buffer
+ y
* ctx
->DrawBuffer
->Width
+ x
;
207 *aptr
= rgba
[i
][ACOMP
];
214 *aptr
++ = rgba
[i
][ACOMP
];
221 _mesa_write_mono_alpha_span( GLcontext
*ctx
, GLuint n
, GLint x
, GLint y
,
222 GLchan alpha
, const GLubyte mask
[] )
224 GLchan
*buffer
, *aptr
;
227 buffer
= get_alpha_buffer(ctx
);
228 aptr
= buffer
+ y
* ctx
->DrawBuffer
->Width
+ x
;
247 _mesa_write_alpha_pixels( GLcontext
*ctx
,
248 GLuint n
, const GLint x
[], const GLint y
[],
249 CONST GLchan rgba
[][4], const GLubyte mask
[] )
254 buffer
= get_alpha_buffer(ctx
);
259 GLchan
*aptr
= buffer
+ y
[i
] * ctx
->DrawBuffer
->Width
+ x
[i
];
260 *aptr
= rgba
[i
][ACOMP
];
266 GLchan
*aptr
= buffer
+ y
[i
] * ctx
->DrawBuffer
->Width
+ x
[i
];
267 *aptr
= rgba
[i
][ACOMP
];
274 _mesa_write_mono_alpha_pixels( GLcontext
*ctx
,
275 GLuint n
, const GLint x
[], const GLint y
[],
276 GLchan alpha
, const GLubyte mask
[] )
281 buffer
= get_alpha_buffer(ctx
);
286 GLchan
*aptr
= buffer
+ y
[i
] * ctx
->DrawBuffer
->Width
+ x
[i
];
293 GLchan
*aptr
= buffer
+ y
[i
] * ctx
->DrawBuffer
->Width
+ x
[i
];
302 _mesa_read_alpha_span( GLcontext
*ctx
,
303 GLuint n
, GLint x
, GLint y
, GLchan rgba
[][4] )
305 const GLchan
*buffer
, *aptr
;
308 buffer
= get_alpha_buffer(ctx
);
309 aptr
= buffer
+ y
* ctx
->DrawBuffer
->Width
+ x
;
311 for (i
= 0; i
< n
; i
++)
312 rgba
[i
][ACOMP
] = *aptr
++;
317 _mesa_read_alpha_pixels( GLcontext
*ctx
,
318 GLuint n
, const GLint x
[], const GLint y
[],
319 GLchan rgba
[][4], const GLubyte mask
[] )
321 const GLchan
*buffer
;
324 buffer
= get_alpha_buffer(ctx
);
326 for (i
= 0; i
< n
; i
++) {
328 const GLchan
*aptr
= buffer
+ y
[i
] * ctx
->DrawBuffer
->Width
+ x
[i
];
329 rgba
[i
][ACOMP
] = *aptr
;