1 /* $Id: s_buffers.c,v 1.8 2001/03/19 02:25:36 keithw Exp $ */
4 * Mesa 3-D graphics library
7 * Copyright (C) 1999-2001 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.
33 #include "s_alphabuf.h"
34 #include "s_context.h"
36 #include "s_masking.h"
37 #include "s_stencil.h"
43 * Clear the color buffer when glColorMask or glIndexMask is in effect.
46 clear_color_buffer_with_masking( GLcontext
*ctx
)
48 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
49 const GLint x
= ctx
->DrawBuffer
->_Xmin
;
50 const GLint y
= ctx
->DrawBuffer
->_Ymin
;
51 const GLint height
= ctx
->DrawBuffer
->_Ymax
- ctx
->DrawBuffer
->_Ymin
;
52 const GLint width
= ctx
->DrawBuffer
->_Xmax
- ctx
->DrawBuffer
->_Xmin
;
54 if (ctx
->Visual
.rgbMode
) {
56 const GLchan r
= ctx
->Color
.ClearColor
[0];
57 const GLchan g
= ctx
->Color
.ClearColor
[1];
58 const GLchan b
= ctx
->Color
.ClearColor
[2];
59 const GLchan a
= ctx
->Color
.ClearColor
[3];
61 for (i
= 0; i
< height
; i
++) {
62 GLchan rgba
[MAX_WIDTH
][4];
64 for (j
= 0; j
< width
; j
++) {
70 _mesa_mask_rgba_span( ctx
, width
, x
, y
+ i
, rgba
);
71 (*swrast
->Driver
.WriteRGBASpan
)( ctx
, width
, x
, y
+ i
,
72 (CONST
GLchan (*)[4]) rgba
, NULL
);
76 /* Color index mode */
77 GLuint span
[MAX_WIDTH
];
78 GLubyte mask
[MAX_WIDTH
];
80 MEMSET( mask
, 1, width
);
81 for (i
=0;i
<height
;i
++) {
82 for (j
=0;j
<width
;j
++) {
83 span
[j
] = ctx
->Color
.ClearIndex
;
85 _mesa_mask_index_span( ctx
, width
, x
, y
+ i
, span
);
86 (*swrast
->Driver
.WriteCI32Span
)( ctx
, width
, x
, y
+ i
, span
, mask
);
94 * Clear a color buffer without index/channel masking.
97 clear_color_buffer(GLcontext
*ctx
)
99 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
100 const GLint x
= ctx
->DrawBuffer
->_Xmin
;
101 const GLint y
= ctx
->DrawBuffer
->_Ymin
;
102 const GLint height
= ctx
->DrawBuffer
->_Ymax
- ctx
->DrawBuffer
->_Ymin
;
103 const GLint width
= ctx
->DrawBuffer
->_Xmax
- ctx
->DrawBuffer
->_Xmin
;
105 if (ctx
->Visual
.rgbMode
) {
107 const GLchan r
= ctx
->Color
.ClearColor
[0];
108 const GLchan g
= ctx
->Color
.ClearColor
[1];
109 const GLchan b
= ctx
->Color
.ClearColor
[2];
110 const GLchan a
= ctx
->Color
.ClearColor
[3];
111 GLchan span
[MAX_WIDTH
][4];
114 ASSERT(*((GLuint
*) &ctx
->Color
.ColorMask
) == 0xffffffff);
116 for (i
= 0; i
< width
; i
++) {
122 for (i
= 0; i
< height
; i
++) {
123 (*swrast
->Driver
.WriteRGBASpan
)( ctx
, width
, x
, y
+ i
,
124 (CONST
GLchan (*)[4]) span
, NULL
);
128 /* Color index mode */
129 ASSERT((ctx
->Color
.IndexMask
& ((1 << ctx
->Visual
.indexBits
) - 1))
130 == (GLuint
) ((1 << ctx
->Visual
.indexBits
) - 1));
131 if (ctx
->Visual
.indexBits
== 8) {
133 GLubyte span
[MAX_WIDTH
];
135 MEMSET(span
, ctx
->Color
.ClearIndex
, width
);
136 for (i
= 0; i
< height
; i
++) {
137 (*swrast
->Driver
.WriteCI8Span
)( ctx
, width
, x
, y
+ i
, span
, NULL
);
141 /* non 8-bit clear */
142 GLuint span
[MAX_WIDTH
];
144 for (i
= 0; i
< width
; i
++) {
145 span
[i
] = ctx
->Color
.ClearIndex
;
147 for (i
= 0; i
< height
; i
++) {
148 (*swrast
->Driver
.WriteCI32Span
)( ctx
, width
, x
, y
+ i
, span
, NULL
);
157 * Clear the front/back/left/right color buffers.
158 * This function is usually only called if we need to clear the
159 * buffers with masking.
162 clear_color_buffers(GLcontext
*ctx
)
164 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
165 const GLuint colorMask
= *((GLuint
*) &ctx
->Color
.ColorMask
);
168 /* loop over four possible dest color buffers */
169 for (bufferBit
= 1; bufferBit
<= 8; bufferBit
= bufferBit
<< 1) {
170 if (bufferBit
& ctx
->Color
.DrawDestMask
) {
171 if (bufferBit
== FRONT_LEFT_BIT
) {
172 (void) (*ctx
->Driver
.SetDrawBuffer
)( ctx
, GL_FRONT_LEFT
);
173 (void) (*swrast
->Driver
.SetReadBuffer
)( ctx
, ctx
->DrawBuffer
, GL_FRONT_LEFT
);
175 else if (bufferBit
== FRONT_RIGHT_BIT
) {
176 (void) (*ctx
->Driver
.SetDrawBuffer
)( ctx
, GL_FRONT_RIGHT
);
177 (void) (*swrast
->Driver
.SetReadBuffer
)( ctx
, ctx
->DrawBuffer
, GL_FRONT_RIGHT
);
179 else if (bufferBit
== BACK_LEFT_BIT
) {
180 (void) (*ctx
->Driver
.SetDrawBuffer
)( ctx
, GL_BACK_LEFT
);
181 (void) (*swrast
->Driver
.SetReadBuffer
)( ctx
, ctx
->DrawBuffer
, GL_BACK_LEFT
);
184 (void) (*ctx
->Driver
.SetDrawBuffer
)( ctx
, GL_BACK_RIGHT
);
185 (void) (*swrast
->Driver
.SetReadBuffer
)( ctx
, ctx
->DrawBuffer
, GL_BACK_RIGHT
);
188 if (colorMask
!= 0xffffffff) {
189 clear_color_buffer_with_masking(ctx
);
192 clear_color_buffer(ctx
);
197 /* restore default read/draw buffers */
198 (void) (*ctx
->Driver
.SetDrawBuffer
)( ctx
, ctx
->Color
.DriverDrawBuffer
);
199 (void) (*swrast
->Driver
.SetReadBuffer
)( ctx
, ctx
->ReadBuffer
, ctx
->Pixel
.DriverReadBuffer
);
205 _swrast_Clear( GLcontext
*ctx
, GLbitfield mask
,
207 GLint x
, GLint y
, GLint width
, GLint height
)
209 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
212 GLbitfield legalBits
= DD_FRONT_LEFT_BIT
|
219 assert((mask
& (~legalBits
)) == 0);
223 RENDER_START(swrast
,ctx
);
225 /* do software clearing here */
227 if (mask
& ctx
->Color
.DrawDestMask
) clear_color_buffers(ctx
);
228 if (mask
& GL_DEPTH_BUFFER_BIT
) _mesa_clear_depth_buffer(ctx
);
229 if (mask
& GL_ACCUM_BUFFER_BIT
) _mesa_clear_accum_buffer(ctx
);
230 if (mask
& GL_STENCIL_BUFFER_BIT
) _mesa_clear_stencil_buffer(ctx
);
233 /* clear software-based alpha buffer(s) */
234 if ( (mask
& GL_COLOR_BUFFER_BIT
)
235 && ctx
->DrawBuffer
->UseSoftwareAlphaBuffers
236 && ctx
->Color
.ColorMask
[ACOMP
]) {
237 _mesa_clear_alpha_buffers( ctx
);
240 RENDER_FINISH(swrast
,ctx
);
245 _swrast_alloc_buffers( GLcontext
*ctx
)
247 /* Reallocate other buffers if needed. */
248 if (ctx
->DrawBuffer
->UseSoftwareDepthBuffer
) {
249 _mesa_alloc_depth_buffer( ctx
);
251 if (ctx
->DrawBuffer
->UseSoftwareStencilBuffer
) {
252 _mesa_alloc_stencil_buffer( ctx
);
254 if (ctx
->DrawBuffer
->UseSoftwareAccumBuffer
) {
255 _mesa_alloc_accum_buffer( ctx
);
257 if (ctx
->DrawBuffer
->UseSoftwareAlphaBuffers
) {
258 _mesa_alloc_alpha_buffers( ctx
);