1 /* $Id: buffers.c,v 1.21 2000/12/26 05:09:27 keithw Exp $ */
4 * Mesa 3-D graphics library
7 * Copyright (C) 1999-2000 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.
43 #include "swrast/swrast.h"
49 _mesa_ClearIndex( GLfloat c
)
51 GET_CURRENT_CONTEXT(ctx
);
52 ASSERT_OUTSIDE_BEGIN_END(ctx
);
54 if (ctx
->Color
.ClearIndex
== (GLuint
)c
)
58 FLUSH_VERTICES(ctx
, _NEW_COLOR
);
59 ctx
->Color
.ClearIndex
= (GLuint
) c
;
61 if (!ctx
->Visual
.RGBAflag
) {
62 /* it's OK to call glClearIndex in RGBA mode but it should be a NOP */
63 (*ctx
->Driver
.ClearIndex
)( ctx
, ctx
->Color
.ClearIndex
);
70 _mesa_ClearColor( GLclampf red
, GLclampf green
,
71 GLclampf blue
, GLclampf alpha
)
74 GET_CURRENT_CONTEXT(ctx
);
75 ASSERT_OUTSIDE_BEGIN_END(ctx
);
77 tmp
[0] = CLAMP( red
, 0.0, 1.0 );
78 tmp
[1] = CLAMP( green
, 0.0, 1.0 );
79 tmp
[2] = CLAMP( blue
, 0.0, 1.0 );
80 tmp
[3] = CLAMP( alpha
, 0.0, 1.0 );
82 if (TEST_EQ_4V(tmp
, ctx
->Color
.ClearColor
))
85 FLUSH_VERTICES(ctx
, _NEW_COLOR
);
86 COPY_4FV( ctx
->Color
.ClearColor
, tmp
);
88 if (ctx
->Visual
.RGBAflag
) {
89 GLchan r
= (GLint
) (ctx
->Color
.ClearColor
[0] * CHAN_MAXF
);
90 GLchan g
= (GLint
) (ctx
->Color
.ClearColor
[1] * CHAN_MAXF
);
91 GLchan b
= (GLint
) (ctx
->Color
.ClearColor
[2] * CHAN_MAXF
);
92 GLchan a
= (GLint
) (ctx
->Color
.ClearColor
[3] * CHAN_MAXF
);
93 (*ctx
->Driver
.ClearColor
)( ctx
, r
, g
, b
, a
);
103 _mesa_Clear( GLbitfield mask
)
105 GET_CURRENT_CONTEXT(ctx
);
106 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
108 if (MESA_VERBOSE
& VERBOSE_API
)
109 fprintf(stderr
, "glClear 0x%x\n", mask
);
112 gl_update_state( ctx
); /* update _Xmin, etc */
115 if (ctx
->RenderMode
==GL_RENDER
) {
116 const GLint x
= ctx
->DrawBuffer
->_Xmin
;
117 const GLint y
= ctx
->DrawBuffer
->_Ymin
;
118 const GLint height
= ctx
->DrawBuffer
->_Ymax
- ctx
->DrawBuffer
->_Ymin
;
119 const GLint width
= ctx
->DrawBuffer
->_Xmax
- ctx
->DrawBuffer
->_Xmin
;
123 /* don't clear depth buffer if depth writing disabled */
124 if (!ctx
->Depth
.Mask
)
125 CLEAR_BITS(mask
, GL_DEPTH_BUFFER_BIT
);
127 /* Build bitmask to send to driver Clear function */
128 ddMask
= mask
& (GL_DEPTH_BUFFER_BIT
|
129 GL_STENCIL_BUFFER_BIT
|
130 GL_ACCUM_BUFFER_BIT
);
131 if (mask
& GL_COLOR_BUFFER_BIT
) {
132 ddMask
|= ctx
->Color
.DrawDestMask
;
135 ASSERT(ctx
->Driver
.Clear
);
136 newMask
= (*ctx
->Driver
.Clear
)( ctx
, ddMask
, !ctx
->Scissor
.Enabled
,
137 x
, y
, width
, height
);
141 GLbitfield legalBits
= DD_FRONT_LEFT_BIT
|
148 assert((newMask
& (~legalBits
)) == 0);
153 _swrast_Clear( ctx
, newMask
, !ctx
->Scissor
.Enabled
,
154 x
, y
, width
, height
);
160 _mesa_DrawBuffer( GLenum mode
)
162 GET_CURRENT_CONTEXT(ctx
);
163 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
); /* too complex... */
166 if (MESA_VERBOSE
& VERBOSE_API
)
167 fprintf(stderr
, "glDrawBuffer %s\n", gl_lookup_enum_by_nr(mode
));
174 /* AUX buffers not implemented in Mesa at this time */
175 gl_error( ctx
, GL_INVALID_OPERATION
, "glDrawBuffer" );
178 if (!ctx
->Visual
.StereoFlag
) {
179 gl_error( ctx
, GL_INVALID_OPERATION
, "glDrawBuffer" );
181 if (ctx
->Visual
.DBflag
)
182 ctx
->Color
.DrawDestMask
= FRONT_RIGHT_BIT
| BACK_RIGHT_BIT
;
184 ctx
->Color
.DrawDestMask
= FRONT_RIGHT_BIT
;
187 if (!ctx
->Visual
.StereoFlag
) {
188 gl_error( ctx
, GL_INVALID_OPERATION
, "glDrawBuffer" );
191 ctx
->Color
.DrawDestMask
= FRONT_RIGHT_BIT
;
194 if (!ctx
->Visual
.StereoFlag
) {
195 gl_error( ctx
, GL_INVALID_OPERATION
, "glDrawBuffer" );
198 if (!ctx
->Visual
.DBflag
) {
199 gl_error( ctx
, GL_INVALID_OPERATION
, "glDrawBuffer" );
202 ctx
->Color
.DrawDestMask
= BACK_RIGHT_BIT
;
205 if (!ctx
->Visual
.DBflag
) {
206 gl_error( ctx
, GL_INVALID_OPERATION
, "glDrawBuffer" );
209 ctx
->Color
.DrawDestMask
= BACK_LEFT_BIT
;
211 case GL_FRONT_AND_BACK
:
212 if (!ctx
->Visual
.DBflag
) {
213 gl_error( ctx
, GL_INVALID_OPERATION
, "glDrawBuffer" );
216 if (ctx
->Visual
.StereoFlag
)
217 ctx
->Color
.DrawDestMask
= FRONT_LEFT_BIT
| BACK_LEFT_BIT
218 | FRONT_RIGHT_BIT
| BACK_RIGHT_BIT
;
220 ctx
->Color
.DrawDestMask
= FRONT_LEFT_BIT
| BACK_LEFT_BIT
;
223 if (!ctx
->Visual
.DBflag
) {
224 gl_error( ctx
, GL_INVALID_OPERATION
, "glDrawBuffer" );
227 if (ctx
->Visual
.StereoFlag
)
228 ctx
->Color
.DrawDestMask
= BACK_LEFT_BIT
| BACK_RIGHT_BIT
;
230 ctx
->Color
.DrawDestMask
= BACK_LEFT_BIT
;
234 if (ctx
->Visual
.DBflag
)
235 ctx
->Color
.DrawDestMask
= FRONT_LEFT_BIT
| BACK_LEFT_BIT
;
237 ctx
->Color
.DrawDestMask
= FRONT_LEFT_BIT
;
241 ctx
->Color
.DrawDestMask
= FRONT_LEFT_BIT
;
245 if (ctx
->Visual
.StereoFlag
)
246 ctx
->Color
.DrawDestMask
= FRONT_LEFT_BIT
| FRONT_RIGHT_BIT
;
248 ctx
->Color
.DrawDestMask
= FRONT_LEFT_BIT
;
252 ctx
->Color
.DrawDestMask
= 0;
255 gl_error( ctx
, GL_INVALID_ENUM
, "glDrawBuffer" );
260 * Make the dest buffer mode more precise if possible
262 if (mode
== GL_LEFT
&& !ctx
->Visual
.DBflag
)
263 ctx
->Color
.DriverDrawBuffer
= GL_FRONT_LEFT
;
264 else if (mode
== GL_RIGHT
&& !ctx
->Visual
.DBflag
)
265 ctx
->Color
.DriverDrawBuffer
= GL_FRONT_RIGHT
;
266 else if (mode
== GL_FRONT
&& !ctx
->Visual
.StereoFlag
)
267 ctx
->Color
.DriverDrawBuffer
= GL_FRONT_LEFT
;
268 else if (mode
== GL_BACK
&& !ctx
->Visual
.StereoFlag
)
269 ctx
->Color
.DriverDrawBuffer
= GL_BACK_LEFT
;
271 ctx
->Color
.DriverDrawBuffer
= mode
;
274 * Set current alpha buffer pointer
276 if (ctx
->DrawBuffer
->UseSoftwareAlphaBuffers
) {
277 if (ctx
->Color
.DriverDrawBuffer
== GL_FRONT_LEFT
)
278 ctx
->DrawBuffer
->Alpha
= ctx
->DrawBuffer
->FrontLeftAlpha
;
279 else if (ctx
->Color
.DriverDrawBuffer
== GL_BACK_LEFT
)
280 ctx
->DrawBuffer
->Alpha
= ctx
->DrawBuffer
->BackLeftAlpha
;
281 else if (ctx
->Color
.DriverDrawBuffer
== GL_FRONT_RIGHT
)
282 ctx
->DrawBuffer
->Alpha
= ctx
->DrawBuffer
->FrontRightAlpha
;
283 else if (ctx
->Color
.DriverDrawBuffer
== GL_BACK_RIGHT
)
284 ctx
->DrawBuffer
->Alpha
= ctx
->DrawBuffer
->BackRightAlpha
;
288 * If we get here there can't have been an error.
289 * Now see if device driver can implement the drawing to the target
290 * buffer(s). The driver may not be able to do GL_FRONT_AND_BACK mode
291 * for example. We'll take care of that in the core code by looping
292 * over the individual buffers.
294 ASSERT(ctx
->Driver
.SetDrawBuffer
);
295 if ( (*ctx
->Driver
.SetDrawBuffer
)(ctx
, ctx
->Color
.DriverDrawBuffer
) ) {
296 /* All OK, the driver will do all buffer writes */
297 ctx
->Color
.MultiDrawBuffer
= GL_FALSE
;
300 /* We'll have to loop over the multiple draw buffer targets */
301 ctx
->Color
.MultiDrawBuffer
= GL_TRUE
;
302 /* Set drawing buffer to front for now */
303 (void) (*ctx
->Driver
.SetDrawBuffer
)(ctx
, GL_FRONT_LEFT
);
306 ctx
->Color
.DrawBuffer
= mode
;
307 ctx
->NewState
|= _NEW_COLOR
;
313 _mesa_ReadBuffer( GLenum mode
)
315 GET_CURRENT_CONTEXT(ctx
);
316 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
318 if (MESA_VERBOSE
& VERBOSE_API
)
319 fprintf(stderr
, "glReadBuffer %s\n", gl_lookup_enum_by_nr(mode
));
326 /* AUX buffers not implemented in Mesa at this time */
327 gl_error( ctx
, GL_INVALID_OPERATION
, "glReadBuffer" );
332 /* Front-Left buffer, always exists */
333 ctx
->Pixel
.DriverReadBuffer
= GL_FRONT_LEFT
;
337 /* Back-Left buffer, requires double buffering */
338 if (!ctx
->Visual
.DBflag
) {
339 gl_error( ctx
, GL_INVALID_OPERATION
, "glReadBuffer" );
342 ctx
->Pixel
.DriverReadBuffer
= GL_BACK_LEFT
;
346 if (!ctx
->Visual
.StereoFlag
) {
347 gl_error( ctx
, GL_INVALID_OPERATION
, "glReadBuffer" );
350 ctx
->Pixel
.DriverReadBuffer
= GL_FRONT_RIGHT
;
353 if (!ctx
->Visual
.StereoFlag
|| !ctx
->Visual
.DBflag
) {
354 gl_error( ctx
, GL_INVALID_OPERATION
, "glReadBuffer" );
357 ctx
->Pixel
.DriverReadBuffer
= GL_BACK_RIGHT
;
360 gl_error( ctx
, GL_INVALID_ENUM
, "glReadBuffer" );
364 ctx
->Pixel
.ReadBuffer
= mode
;
365 ctx
->NewState
|= _NEW_PIXEL
;
370 * GL_MESA_resize_buffers extension
373 _mesa_ResizeBuffersMESA( void )
375 GLcontext
*ctx
= _mesa_get_current_context();
377 GLuint buf_width
, buf_height
;
379 if (MESA_VERBOSE
& VERBOSE_API
)
380 fprintf(stderr
, "glResizeBuffersMESA\n");
382 /* ask device driver for size of output buffer */
383 (*ctx
->Driver
.GetBufferSize
)( ctx
, &buf_width
, &buf_height
);
385 /* see if size of device driver's color buffer (window) has changed */
386 if (ctx
->DrawBuffer
->Width
== (GLint
) buf_width
&&
387 ctx
->DrawBuffer
->Height
== (GLint
) buf_height
)
390 ctx
->NewState
|= _NEW_BUFFERS
; /* to update scissor / window bounds */
392 /* save buffer size */
393 ctx
->DrawBuffer
->Width
= buf_width
;
394 ctx
->DrawBuffer
->Height
= buf_height
;
396 _swrast_alloc_buffers( ctx
);