ed7b9cbded1324186ca938adec774c9c33354fc0
3 * Mesa 3-D graphics library
6 * Copyright (C) 1999-2000 Brian Paul All Rights Reserved.
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the "Software"),
10 * to deal in the Software without restriction, including without limitation
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 * and/or sell copies of the Software, and to permit persons to whom the
13 * Software is furnished to do so, subject to the following conditions:
15 * The above copyright notice and this permission notice shall be included
16 * in all copies or substantial portions of the Software.
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
22 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
23 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28 * Software alpha planes. Many frame buffers don't have alpha bits so
29 * we simulate them in software.
37 #include "s_alphabuf.h"
42 #define ALPHA_DRAW_ADDR(X,Y) \
43 (ctx->DrawBuffer->Alpha + (Y) * ctx->DrawBuffer->Width + (X))
45 #define ALPHA_READ_ADDR(X,Y) \
46 (ctx->ReadBuffer->Alpha + (Y) * ctx->ReadBuffer->Width + (X))
51 * Allocate new front/back/left/right alpha buffers.
52 * Input: ctx - the context
56 alloc_alpha_buffers( GLcontext
*ctx
, GLframebuffer
*buf
)
58 GLint bytes
= buf
->Width
* buf
->Height
* sizeof(GLchan
);
60 ASSERT(ctx
->DrawBuffer
->UseSoftwareAlphaBuffers
);
62 if (buf
->FrontLeftAlpha
) {
63 FREE( buf
->FrontLeftAlpha
);
65 buf
->FrontLeftAlpha
= (GLchan
*) MALLOC( bytes
);
66 if (!buf
->FrontLeftAlpha
) {
68 gl_error( ctx
, GL_OUT_OF_MEMORY
,
69 "Couldn't allocate front-left alpha buffer" );
72 if (ctx
->Visual
.DBflag
) {
73 if (buf
->BackLeftAlpha
) {
74 FREE( buf
->BackLeftAlpha
);
76 buf
->BackLeftAlpha
= (GLchan
*) MALLOC( bytes
);
77 if (!buf
->BackLeftAlpha
) {
79 gl_error( ctx
, GL_OUT_OF_MEMORY
,
80 "Couldn't allocate back-left alpha buffer" );
84 if (ctx
->Visual
.StereoFlag
) {
85 if (buf
->FrontRightAlpha
) {
86 FREE( buf
->FrontRightAlpha
);
88 buf
->FrontRightAlpha
= (GLchan
*) MALLOC( bytes
);
89 if (!buf
->FrontRightAlpha
) {
91 gl_error( ctx
, GL_OUT_OF_MEMORY
,
92 "Couldn't allocate front-right alpha buffer" );
95 if (ctx
->Visual
.DBflag
) {
96 if (buf
->BackRightAlpha
) {
97 FREE( buf
->BackRightAlpha
);
99 buf
->BackRightAlpha
= (GLchan
*) MALLOC( bytes
);
100 if (!buf
->BackRightAlpha
) {
102 gl_error( ctx
, GL_OUT_OF_MEMORY
,
103 "Couldn't allocate back-right alpha buffer" );
108 if (ctx
->Color
.DriverDrawBuffer
== GL_FRONT_LEFT
)
109 buf
->Alpha
= buf
->FrontLeftAlpha
;
110 else if (ctx
->Color
.DriverDrawBuffer
== GL_BACK_LEFT
)
111 buf
->Alpha
= buf
->BackLeftAlpha
;
112 else if (ctx
->Color
.DriverDrawBuffer
== GL_FRONT_RIGHT
)
113 buf
->Alpha
= buf
->FrontRightAlpha
;
114 else if (ctx
->Color
.DriverDrawBuffer
== GL_BACK_RIGHT
)
115 buf
->Alpha
= buf
->BackRightAlpha
;
120 * Allocate a new front and back alpha buffer.
123 _mesa_alloc_alpha_buffers( GLcontext
*ctx
)
125 alloc_alpha_buffers( ctx
, ctx
->DrawBuffer
);
126 if (ctx
->ReadBuffer
!= ctx
->DrawBuffer
) {
127 alloc_alpha_buffers( ctx
, ctx
->ReadBuffer
);
133 * Clear all the alpha buffers
136 _mesa_clear_alpha_buffers( GLcontext
*ctx
)
138 const GLchan aclear
= (GLint
) (ctx
->Color
.ClearColor
[3] * CHAN_MAXF
);
141 ASSERT(ctx
->DrawBuffer
->UseSoftwareAlphaBuffers
);
142 ASSERT(ctx
->Color
.ColorMask
[ACOMP
]);
144 /* loop over four possible alpha buffers */
145 for (bufferBit
= 1; bufferBit
<= 8; bufferBit
= bufferBit
<< 1) {
146 if (bufferBit
& ctx
->Color
.DrawDestMask
) {
148 if (bufferBit
== FRONT_LEFT_BIT
) {
149 buffer
= ctx
->DrawBuffer
->FrontLeftAlpha
;
151 else if (bufferBit
== FRONT_RIGHT_BIT
) {
152 buffer
= ctx
->DrawBuffer
->FrontRightAlpha
;
154 else if (bufferBit
== BACK_LEFT_BIT
) {
155 buffer
= ctx
->DrawBuffer
->BackLeftAlpha
;
158 buffer
= ctx
->DrawBuffer
->BackRightAlpha
;
161 if (ctx
->Scissor
.Enabled
) {
162 /* clear scissor region */
164 GLint rowLen
= ctx
->DrawBuffer
->Xmax
- ctx
->DrawBuffer
->Xmin
+ 1;
165 GLint rows
= ctx
->DrawBuffer
->Ymax
- ctx
->DrawBuffer
->Ymin
+ 1;
166 GLchan
*aptr
= buffer
167 + ctx
->DrawBuffer
->Ymin
* ctx
->DrawBuffer
->Width
168 + ctx
->DrawBuffer
->Xmin
;
169 for (j
= 0; j
< rows
; j
++) {
171 MEMSET( aptr
, aclear
, rowLen
);
172 #elif CHAN_BITS == 16
173 MEMSET16( aptr
, aclear
, rowLen
);
175 #error unexpected CHAN_BITS value
181 /* clear whole buffer */
182 GLuint bytes
= ctx
->DrawBuffer
->Width
* ctx
->DrawBuffer
->Height
;
183 MEMSET( buffer
, aclear
, bytes
);
192 _mesa_write_alpha_span( GLcontext
*ctx
, GLuint n
, GLint x
, GLint y
,
193 CONST GLchan rgba
[][4], const GLubyte mask
[] )
195 GLchan
*aptr
= ALPHA_DRAW_ADDR( x
, y
);
201 *aptr
= rgba
[i
][ACOMP
];
208 *aptr
++ = rgba
[i
][ACOMP
];
215 _mesa_write_mono_alpha_span( GLcontext
*ctx
, GLuint n
, GLint x
, GLint y
,
216 GLchan alpha
, const GLubyte mask
[] )
218 GLchan
*aptr
= ALPHA_DRAW_ADDR( x
, y
);
238 _mesa_write_alpha_pixels( GLcontext
*ctx
,
239 GLuint n
, const GLint x
[], const GLint y
[],
240 CONST GLchan rgba
[][4], const GLubyte mask
[] )
247 GLchan
*aptr
= ALPHA_DRAW_ADDR( x
[i
], y
[i
] );
248 *aptr
= rgba
[i
][ACOMP
];
254 GLchan
*aptr
= ALPHA_DRAW_ADDR( x
[i
], y
[i
] );
255 *aptr
= rgba
[i
][ACOMP
];
262 _mesa_write_mono_alpha_pixels( GLcontext
*ctx
,
263 GLuint n
, const GLint x
[], const GLint y
[],
264 GLchan alpha
, const GLubyte mask
[] )
271 GLchan
*aptr
= ALPHA_DRAW_ADDR( x
[i
], y
[i
] );
278 GLchan
*aptr
= ALPHA_DRAW_ADDR( x
[i
], y
[i
] );
287 _mesa_read_alpha_span( GLcontext
*ctx
,
288 GLuint n
, GLint x
, GLint y
, GLchan rgba
[][4] )
290 GLchan
*aptr
= ALPHA_READ_ADDR( x
, y
);
293 rgba
[i
][ACOMP
] = *aptr
++;
299 _mesa_read_alpha_pixels( GLcontext
*ctx
,
300 GLuint n
, const GLint x
[], const GLint y
[],
301 GLchan rgba
[][4], const GLubyte mask
[] )
306 GLchan
*aptr
= ALPHA_READ_ADDR( x
[i
], y
[i
] );
307 rgba
[i
][ACOMP
] = *aptr
;