removed unused var
[mesa.git] / src / mesa / main / buffers.c
1 /* $Id: buffers.c,v 1.18 2000/10/31 18:09:44 keithw Exp $ */
2
3 /*
4 * Mesa 3-D graphics library
5 * Version: 3.5
6 *
7 * Copyright (C) 1999-2000 Brian Paul All Rights Reserved.
8 *
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:
15 *
16 * The above copyright notice and this permission notice shall be included
17 * in all copies or substantial portions of the Software.
18 *
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.
25 */
26
27
28 #ifdef PC_HEADER
29 #include "all.h"
30 #else
31 #include "glheader.h"
32 #include "accum.h"
33 #include "buffers.h"
34 #include "context.h"
35 #include "depth.h"
36 #include "enums.h"
37 #include "macros.h"
38 #include "masking.h"
39 #include "mem.h"
40 #include "stencil.h"
41 #include "state.h"
42 #include "types.h"
43 #include "swrast/swrast.h"
44 #endif
45
46
47
48 void
49 _mesa_ClearIndex( GLfloat c )
50 {
51 GET_CURRENT_CONTEXT(ctx);
52 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glClearIndex");
53 ctx->Color.ClearIndex = (GLuint) c;
54 ctx->NewState |= _NEW_COLOR;
55
56 if (!ctx->Visual.RGBAflag) {
57 /* it's OK to call glClearIndex in RGBA mode but it should be a NOP */
58 (*ctx->Driver.ClearIndex)( ctx, ctx->Color.ClearIndex );
59 }
60 }
61
62
63
64 void
65 _mesa_ClearColor( GLclampf red, GLclampf green,
66 GLclampf blue, GLclampf alpha )
67 {
68 GET_CURRENT_CONTEXT(ctx);
69 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glClearColor");
70
71 ctx->Color.ClearColor[0] = CLAMP( red, 0.0F, 1.0F );
72 ctx->Color.ClearColor[1] = CLAMP( green, 0.0F, 1.0F );
73 ctx->Color.ClearColor[2] = CLAMP( blue, 0.0F, 1.0F );
74 ctx->Color.ClearColor[3] = CLAMP( alpha, 0.0F, 1.0F );
75 ctx->NewState |= _NEW_COLOR;
76
77 if (ctx->Visual.RGBAflag) {
78 GLchan r = (GLint) (ctx->Color.ClearColor[0] * CHAN_MAXF);
79 GLchan g = (GLint) (ctx->Color.ClearColor[1] * CHAN_MAXF);
80 GLchan b = (GLint) (ctx->Color.ClearColor[2] * CHAN_MAXF);
81 GLchan a = (GLint) (ctx->Color.ClearColor[3] * CHAN_MAXF);
82 (*ctx->Driver.ClearColor)( ctx, r, g, b, a );
83 }
84 }
85
86
87
88
89
90
91 void
92 _mesa_Clear( GLbitfield mask )
93 {
94 GET_CURRENT_CONTEXT(ctx);
95 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glClear");
96
97 if (MESA_VERBOSE & VERBOSE_API)
98 fprintf(stderr, "glClear 0x%x\n", mask);
99
100 if (ctx->NewState) {
101 gl_update_state( ctx );
102 }
103
104 if (ctx->RenderMode==GL_RENDER) {
105 const GLint x = ctx->DrawBuffer->Xmin;
106 const GLint y = ctx->DrawBuffer->Ymin;
107 const GLint height = ctx->DrawBuffer->Ymax - ctx->DrawBuffer->Ymin;
108 const GLint width = ctx->DrawBuffer->Xmax - ctx->DrawBuffer->Xmin;
109 GLbitfield ddMask;
110 GLbitfield newMask;
111
112 /* don't clear depth buffer if depth writing disabled */
113 if (!ctx->Depth.Mask)
114 CLEAR_BITS(mask, GL_DEPTH_BUFFER_BIT);
115
116 /* Build bitmask to send to driver Clear function */
117 ddMask = mask & (GL_DEPTH_BUFFER_BIT |
118 GL_STENCIL_BUFFER_BIT |
119 GL_ACCUM_BUFFER_BIT);
120 if (mask & GL_COLOR_BUFFER_BIT) {
121 ddMask |= ctx->Color.DrawDestMask;
122 }
123
124 ASSERT(ctx->Driver.Clear);
125 newMask = (*ctx->Driver.Clear)( ctx, ddMask, !ctx->Scissor.Enabled,
126 x, y, width, height );
127
128 #ifdef DEBUG
129 {
130 GLbitfield legalBits = DD_FRONT_LEFT_BIT |
131 DD_FRONT_RIGHT_BIT |
132 DD_BACK_LEFT_BIT |
133 DD_BACK_RIGHT_BIT |
134 DD_DEPTH_BIT |
135 DD_STENCIL_BIT |
136 DD_ACCUM_BIT;
137 assert((newMask & (~legalBits)) == 0);
138 }
139 #endif
140
141 if (newMask)
142 _swrast_Clear( ctx, newMask, !ctx->Scissor.Enabled,
143 x, y, width, height );
144 }
145 }
146
147
148 void
149 _mesa_DrawBuffer( GLenum mode )
150 {
151 GET_CURRENT_CONTEXT(ctx);
152 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glDrawBuffer");
153
154 if (MESA_VERBOSE & VERBOSE_API)
155 fprintf(stderr, "glDrawBuffer %s\n", gl_lookup_enum_by_nr(mode));
156
157 switch (mode) {
158 case GL_AUX0:
159 case GL_AUX1:
160 case GL_AUX2:
161 case GL_AUX3:
162 /* AUX buffers not implemented in Mesa at this time */
163 gl_error( ctx, GL_INVALID_OPERATION, "glDrawBuffer" );
164 return;
165 case GL_RIGHT:
166 if (!ctx->Visual.StereoFlag) {
167 gl_error( ctx, GL_INVALID_OPERATION, "glDrawBuffer" );
168 return;}
169 if (ctx->Visual.DBflag)
170 ctx->Color.DrawDestMask = FRONT_RIGHT_BIT | BACK_RIGHT_BIT;
171 else
172 ctx->Color.DrawDestMask = FRONT_RIGHT_BIT;
173 break;
174 case GL_FRONT_RIGHT:
175 if (!ctx->Visual.StereoFlag) {
176 gl_error( ctx, GL_INVALID_OPERATION, "glDrawBuffer" );
177 return;
178 }
179 ctx->Color.DrawDestMask = FRONT_RIGHT_BIT;
180 break;
181 case GL_BACK_RIGHT:
182 if (!ctx->Visual.StereoFlag) {
183 gl_error( ctx, GL_INVALID_OPERATION, "glDrawBuffer" );
184 return;
185 }
186 if (!ctx->Visual.DBflag) {
187 gl_error( ctx, GL_INVALID_OPERATION, "glDrawBuffer" );
188 return;
189 }
190 ctx->Color.DrawDestMask = BACK_RIGHT_BIT;
191 break;
192 case GL_BACK_LEFT:
193 if (!ctx->Visual.DBflag) {
194 gl_error( ctx, GL_INVALID_OPERATION, "glDrawBuffer" );
195 return;
196 }
197 ctx->Color.DrawDestMask = BACK_LEFT_BIT;
198 break;
199 case GL_FRONT_AND_BACK:
200 if (!ctx->Visual.DBflag) {
201 gl_error( ctx, GL_INVALID_OPERATION, "glDrawBuffer" );
202 return;
203 }
204 if (ctx->Visual.StereoFlag)
205 ctx->Color.DrawDestMask = FRONT_LEFT_BIT | BACK_LEFT_BIT
206 | FRONT_RIGHT_BIT | BACK_RIGHT_BIT;
207 else
208 ctx->Color.DrawDestMask = FRONT_LEFT_BIT | BACK_LEFT_BIT;
209 break;
210 case GL_BACK:
211 if (!ctx->Visual.DBflag) {
212 gl_error( ctx, GL_INVALID_OPERATION, "glDrawBuffer" );
213 return;
214 }
215 if (ctx->Visual.StereoFlag)
216 ctx->Color.DrawDestMask = BACK_LEFT_BIT | BACK_RIGHT_BIT;
217 else
218 ctx->Color.DrawDestMask = BACK_LEFT_BIT;
219 break;
220 case GL_LEFT:
221 /* never an error */
222 if (ctx->Visual.DBflag)
223 ctx->Color.DrawDestMask = FRONT_LEFT_BIT | BACK_LEFT_BIT;
224 else
225 ctx->Color.DrawDestMask = FRONT_LEFT_BIT;
226 break;
227 case GL_FRONT_LEFT:
228 /* never an error */
229 ctx->Color.DrawDestMask = FRONT_LEFT_BIT;
230 break;
231 case GL_FRONT:
232 /* never an error */
233 if (ctx->Visual.StereoFlag)
234 ctx->Color.DrawDestMask = FRONT_LEFT_BIT | FRONT_RIGHT_BIT;
235 else
236 ctx->Color.DrawDestMask = FRONT_LEFT_BIT;
237 break;
238 case GL_NONE:
239 /* never an error */
240 ctx->Color.DrawDestMask = 0;
241 break;
242 default:
243 gl_error( ctx, GL_INVALID_ENUM, "glDrawBuffer" );
244 return;
245 }
246
247 /*
248 * Make the dest buffer mode more precise if possible
249 */
250 if (mode == GL_LEFT && !ctx->Visual.DBflag)
251 ctx->Color.DriverDrawBuffer = GL_FRONT_LEFT;
252 else if (mode == GL_RIGHT && !ctx->Visual.DBflag)
253 ctx->Color.DriverDrawBuffer = GL_FRONT_RIGHT;
254 else if (mode == GL_FRONT && !ctx->Visual.StereoFlag)
255 ctx->Color.DriverDrawBuffer = GL_FRONT_LEFT;
256 else if (mode == GL_BACK && !ctx->Visual.StereoFlag)
257 ctx->Color.DriverDrawBuffer = GL_BACK_LEFT;
258 else
259 ctx->Color.DriverDrawBuffer = mode;
260
261 /*
262 * Set current alpha buffer pointer
263 */
264 if (ctx->DrawBuffer->UseSoftwareAlphaBuffers) {
265 if (ctx->Color.DriverDrawBuffer == GL_FRONT_LEFT)
266 ctx->DrawBuffer->Alpha = ctx->DrawBuffer->FrontLeftAlpha;
267 else if (ctx->Color.DriverDrawBuffer == GL_BACK_LEFT)
268 ctx->DrawBuffer->Alpha = ctx->DrawBuffer->BackLeftAlpha;
269 else if (ctx->Color.DriverDrawBuffer == GL_FRONT_RIGHT)
270 ctx->DrawBuffer->Alpha = ctx->DrawBuffer->FrontRightAlpha;
271 else if (ctx->Color.DriverDrawBuffer == GL_BACK_RIGHT)
272 ctx->DrawBuffer->Alpha = ctx->DrawBuffer->BackRightAlpha;
273 }
274
275 /*
276 * If we get here there can't have been an error.
277 * Now see if device driver can implement the drawing to the target
278 * buffer(s). The driver may not be able to do GL_FRONT_AND_BACK mode
279 * for example. We'll take care of that in the core code by looping
280 * over the individual buffers.
281 */
282 ASSERT(ctx->Driver.SetDrawBuffer);
283 if ( (*ctx->Driver.SetDrawBuffer)(ctx, ctx->Color.DriverDrawBuffer) ) {
284 /* All OK, the driver will do all buffer writes */
285 ctx->Color.MultiDrawBuffer = GL_FALSE;
286 }
287 else {
288 /* We'll have to loop over the multiple draw buffer targets */
289 ctx->Color.MultiDrawBuffer = GL_TRUE;
290 /* Set drawing buffer to front for now */
291 (void) (*ctx->Driver.SetDrawBuffer)(ctx, GL_FRONT_LEFT);
292 }
293
294 ctx->Color.DrawBuffer = mode;
295 ctx->NewState |= _NEW_COLOR;
296 }
297
298
299
300 void
301 _mesa_ReadBuffer( GLenum mode )
302 {
303 GET_CURRENT_CONTEXT(ctx);
304 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glReadBuffer");
305
306 if (MESA_VERBOSE & VERBOSE_API)
307 fprintf(stderr, "glReadBuffer %s\n", gl_lookup_enum_by_nr(mode));
308
309 switch (mode) {
310 case GL_AUX0:
311 case GL_AUX1:
312 case GL_AUX2:
313 case GL_AUX3:
314 /* AUX buffers not implemented in Mesa at this time */
315 gl_error( ctx, GL_INVALID_OPERATION, "glReadBuffer" );
316 return;
317 case GL_LEFT:
318 case GL_FRONT:
319 case GL_FRONT_LEFT:
320 /* Front-Left buffer, always exists */
321 ctx->Pixel.DriverReadBuffer = GL_FRONT_LEFT;
322 break;
323 case GL_BACK:
324 case GL_BACK_LEFT:
325 /* Back-Left buffer, requires double buffering */
326 if (!ctx->Visual.DBflag) {
327 gl_error( ctx, GL_INVALID_OPERATION, "glReadBuffer" );
328 return;
329 }
330 ctx->Pixel.DriverReadBuffer = GL_BACK_LEFT;
331 break;
332 case GL_FRONT_RIGHT:
333 case GL_RIGHT:
334 if (!ctx->Visual.StereoFlag) {
335 gl_error( ctx, GL_INVALID_OPERATION, "glReadBuffer" );
336 return;
337 }
338 ctx->Pixel.DriverReadBuffer = GL_FRONT_RIGHT;
339 break;
340 case GL_BACK_RIGHT:
341 if (!ctx->Visual.StereoFlag || !ctx->Visual.DBflag) {
342 gl_error( ctx, GL_INVALID_OPERATION, "glReadBuffer" );
343 return;
344 }
345 ctx->Pixel.DriverReadBuffer = GL_BACK_RIGHT;
346 break;
347 default:
348 gl_error( ctx, GL_INVALID_ENUM, "glReadBuffer" );
349 return;
350 }
351
352 ctx->Pixel.ReadBuffer = mode;
353 ctx->NewState |= _NEW_PIXEL;
354 }
355
356
357 /*
358 * GL_MESA_resize_buffers extension
359 */
360 void
361 _mesa_ResizeBuffersMESA( void )
362 {
363 GLcontext *ctx = _mesa_get_current_context();
364
365 GLuint buf_width, buf_height;
366
367 if (MESA_VERBOSE & VERBOSE_API)
368 fprintf(stderr, "glResizeBuffersMESA\n");
369
370 /* ask device driver for size of output buffer */
371 (*ctx->Driver.GetBufferSize)( ctx, &buf_width, &buf_height );
372
373 /* see if size of device driver's color buffer (window) has changed */
374 if (ctx->DrawBuffer->Width == (GLint) buf_width &&
375 ctx->DrawBuffer->Height == (GLint) buf_height)
376 return;
377
378 ctx->NewState |= _NEW_BUFFERS; /* to update scissor / window bounds */
379
380 /* save buffer size */
381 ctx->DrawBuffer->Width = buf_width;
382 ctx->DrawBuffer->Height = buf_height;
383
384 _swrast_alloc_buffers( ctx );
385 }