2 * Mesa 3-D graphics library
5 * Copyright (C) 1999-2004 Brian Paul All Rights Reserved.
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32 #include "s_alphabuf.h"
33 #include "s_context.h"
35 #include "s_masking.h"
36 #include "s_stencil.h"
42 * Clear the color buffer when glColorMask or glIndexMask is in effect.
45 clear_color_buffer_with_masking( GLcontext
*ctx
)
47 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
48 const GLint x
= ctx
->DrawBuffer
->_Xmin
;
49 const GLint y
= ctx
->DrawBuffer
->_Ymin
;
50 const GLint height
= ctx
->DrawBuffer
->_Ymax
- ctx
->DrawBuffer
->_Ymin
;
51 const GLint width
= ctx
->DrawBuffer
->_Xmax
- ctx
->DrawBuffer
->_Xmin
;
53 if (ctx
->Visual
.rgbMode
) {
57 CLAMPED_FLOAT_TO_CHAN(clearColor
[RCOMP
], ctx
->Color
.ClearColor
[0]);
58 CLAMPED_FLOAT_TO_CHAN(clearColor
[GCOMP
], ctx
->Color
.ClearColor
[1]);
59 CLAMPED_FLOAT_TO_CHAN(clearColor
[BCOMP
], ctx
->Color
.ClearColor
[2]);
60 CLAMPED_FLOAT_TO_CHAN(clearColor
[ACOMP
], ctx
->Color
.ClearColor
[3]);
61 for (i
= 0; i
< height
; i
++) {
62 GLchan rgba
[MAX_WIDTH
][4];
64 for (j
= 0; j
< width
; j
++) {
65 COPY_CHAN4(rgba
[j
], clearColor
);
67 _swrast_mask_rgba_array( ctx
, width
, x
, y
+ i
, rgba
);
68 (*swrast
->Driver
.WriteRGBASpan
)( ctx
, width
, x
, y
+ i
,
69 (CONST
GLchan (*)[4]) rgba
, NULL
);
73 /* Color index mode */
74 GLuint span
[MAX_WIDTH
];
75 GLubyte mask
[MAX_WIDTH
];
77 MEMSET( mask
, 1, width
);
78 for (i
=0;i
<height
;i
++) {
79 for (j
=0;j
<width
;j
++) {
80 span
[j
] = ctx
->Color
.ClearIndex
;
82 _swrast_mask_index_array( ctx
, width
, x
, y
+ i
, span
);
83 (*swrast
->Driver
.WriteCI32Span
)( ctx
, width
, x
, y
+ i
, span
, mask
);
91 * Clear a color buffer without index/channel masking.
94 clear_color_buffer(GLcontext
*ctx
)
96 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
97 const GLint x
= ctx
->DrawBuffer
->_Xmin
;
98 const GLint y
= ctx
->DrawBuffer
->_Ymin
;
99 const GLint height
= ctx
->DrawBuffer
->_Ymax
- ctx
->DrawBuffer
->_Ymin
;
100 const GLint width
= ctx
->DrawBuffer
->_Xmax
- ctx
->DrawBuffer
->_Xmin
;
102 if (ctx
->Visual
.rgbMode
) {
104 GLchan clearColor
[4];
107 CLAMPED_FLOAT_TO_CHAN(clearColor
[RCOMP
], ctx
->Color
.ClearColor
[0]);
108 CLAMPED_FLOAT_TO_CHAN(clearColor
[GCOMP
], ctx
->Color
.ClearColor
[1]);
109 CLAMPED_FLOAT_TO_CHAN(clearColor
[BCOMP
], ctx
->Color
.ClearColor
[2]);
110 CLAMPED_FLOAT_TO_CHAN(clearColor
[ACOMP
], ctx
->Color
.ClearColor
[3]);
112 ASSERT(*((GLuint
*) &ctx
->Color
.ColorMask
) == 0xffffffff);
113 ASSERT(swrast
->Driver
.WriteRGBASpan
);
115 for (i
= 0; i
< height
; i
++) {
116 (*swrast
->Driver
.WriteMonoRGBASpan
)( ctx
, width
, x
, y
+ i
,
121 /* Color index mode */
123 ASSERT((ctx
->Color
.IndexMask
& ((1 << ctx
->Visual
.indexBits
) - 1))
124 == (GLuint
) ((1 << ctx
->Visual
.indexBits
) - 1));
125 ASSERT(swrast
->Driver
.WriteMonoCISpan
);
126 for (i
= 0; i
< height
; i
++) {
127 (*swrast
->Driver
.WriteMonoCISpan
)( ctx
, width
, x
, y
+ i
,
128 ctx
->Color
.ClearIndex
, NULL
);
136 * Clear the front/back/left/right color buffers.
137 * This function is usually only called if we need to clear the
138 * buffers with masking.
141 clear_color_buffers(GLcontext
*ctx
)
143 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
144 const GLuint colorMask
= *((GLuint
*) &ctx
->Color
.ColorMask
);
147 /* loop over four possible dest color buffers */
148 for (bufferBit
= 1; bufferBit
<= 8; bufferBit
= bufferBit
<< 1) {
149 if (bufferBit
& ctx
->Color
._DrawDestMask
) {
150 (*swrast
->Driver
.SetBuffer
)(ctx
, ctx
->DrawBuffer
, bufferBit
);
152 if (colorMask
!= 0xffffffff) {
153 clear_color_buffer_with_masking(ctx
);
156 clear_color_buffer(ctx
);
161 /* restore default read/draw buffer */
162 _swrast_use_draw_buffer(ctx
);
168 _swrast_Clear( GLcontext
*ctx
, GLbitfield mask
,
170 GLint x
, GLint y
, GLint width
, GLint height
)
172 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
175 GLbitfield legalBits
= DD_FRONT_LEFT_BIT
|
182 assert((mask
& (~legalBits
)) == 0);
186 RENDER_START(swrast
,ctx
);
188 /* do software clearing here */
190 if (mask
& ctx
->Color
._DrawDestMask
) clear_color_buffers(ctx
);
191 if (mask
& GL_DEPTH_BUFFER_BIT
) _swrast_clear_depth_buffer(ctx
);
192 if (mask
& GL_ACCUM_BUFFER_BIT
) _swrast_clear_accum_buffer(ctx
);
193 if (mask
& GL_STENCIL_BUFFER_BIT
) _swrast_clear_stencil_buffer(ctx
);
196 /* clear software-based alpha buffer(s) */
197 if ( (mask
& GL_COLOR_BUFFER_BIT
)
198 && ctx
->DrawBuffer
->UseSoftwareAlphaBuffers
199 && ctx
->Color
.ColorMask
[ACOMP
]) {
200 _swrast_clear_alpha_buffers( ctx
);
203 RENDER_FINISH(swrast
,ctx
);
208 _swrast_alloc_buffers( GLframebuffer
*buffer
)
210 /* Reallocate other buffers if needed. */
211 if (buffer
->UseSoftwareDepthBuffer
) {
212 _swrast_alloc_depth_buffer( buffer
);
214 if (buffer
->UseSoftwareStencilBuffer
) {
215 _swrast_alloc_stencil_buffer( buffer
);
217 if (buffer
->UseSoftwareAccumBuffer
) {
218 _swrast_alloc_accum_buffer( buffer
);
220 if (buffer
->UseSoftwareAlphaBuffers
) {
221 _swrast_alloc_alpha_buffers( buffer
);
227 * Fallback for ctx->Driver.DrawBuffer()
230 _swrast_DrawBuffer( GLcontext
*ctx
, GLenum mode
)
232 _swrast_use_draw_buffer(ctx
);
237 * Setup things so that we read/write spans from the user-designated
238 * read buffer (set via glReadPixels). We usually just have to call
239 * this for glReadPixels, glCopyPixels, etc.
242 _swrast_use_read_buffer( GLcontext
*ctx
)
244 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
246 /* Do this so the software-emulated alpha plane span functions work! */
247 swrast
->CurrentBuffer
= ctx
->Pixel
._ReadSrcMask
;
248 /* Tell the device driver where to read/write spans */
249 (*swrast
->Driver
.SetBuffer
)( ctx
, ctx
->ReadBuffer
, swrast
->CurrentBuffer
);
254 * Setup things so that we read/write spans from the default draw buffer.
255 * This is the usual mode that Mesa's software rasterizer operates in.
258 _swrast_use_draw_buffer( GLcontext
*ctx
)
260 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
262 /* The user can specify rendering to zero, one, two, or four color
263 * buffers simultaneously with glDrawBuffer()!
264 * We don't expect the span/point/line/triangle functions to deal with
265 * that mess so we'll iterate over the multiple buffers as needed.
266 * But usually we only render to one color buffer at a time.
267 * We set ctx->Color._DriverDrawBuffer to that buffer and tell the
268 * device driver to use that buffer.
269 * Look in s_span.c's multi_write_rgba_span() function to see how
270 * we loop over multiple color buffers when needed.
273 if (ctx
->Color
._DrawDestMask
& FRONT_LEFT_BIT
)
274 swrast
->CurrentBuffer
= FRONT_LEFT_BIT
;
275 else if (ctx
->Color
._DrawDestMask
& BACK_LEFT_BIT
)
276 swrast
->CurrentBuffer
= BACK_LEFT_BIT
;
277 else if (ctx
->Color
._DrawDestMask
& FRONT_RIGHT_BIT
)
278 swrast
->CurrentBuffer
= FRONT_RIGHT_BIT
;
279 else if (ctx
->Color
._DrawDestMask
& BACK_RIGHT_BIT
)
280 swrast
->CurrentBuffer
= BACK_RIGHT_BIT
;
282 /* glDrawBuffer(GL_NONE) */
283 swrast
->CurrentBuffer
= FRONT_LEFT_BIT
; /* we always have this buffer */
285 (*swrast
->Driver
.SetBuffer
)( ctx
, ctx
->DrawBuffer
, swrast
->CurrentBuffer
);