Some groundwork for supporting GLhalf datatype.
[mesa.git] / src / mesa / main / context.c
1 /**
2 * \file context.c
3 * Mesa context/visual/framebuffer management functions.
4 * \author Brian Paul
5 */
6
7 /*
8 * Mesa 3-D graphics library
9 * Version: 5.1
10 *
11 * Copyright (C) 1999-2002 Brian Paul All Rights Reserved.
12 *
13 * Permission is hereby granted, free of charge, to any person obtaining a
14 * copy of this software and associated documentation files (the "Software"),
15 * to deal in the Software without restriction, including without limitation
16 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
17 * and/or sell copies of the Software, and to permit persons to whom the
18 * Software is furnished to do so, subject to the following conditions:
19 *
20 * The above copyright notice and this permission notice shall be included
21 * in all copies or substantial portions of the Software.
22 *
23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
24 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
26 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
27 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
28 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 */
30
31
32 /**
33 * \mainpage Mesa Core Module
34 *
35 * \section CoreIntroduction Introduction
36 *
37 * The Mesa core module consists of all the top-level files in the src
38 * directory. The core module basically takes care of API dispatch,
39 * and OpenGL state management.
40 *
41 * For example, calls to glPolygonMode() are routed to _mesa_PolygonMode()
42 * which updates the state related to polygonmode. Furthermore, dirty
43 * state flags related to polygon mode are set and if the device driver
44 * implements a special routine for PolygonMode, it will be called.
45 *
46 *
47 * \section AboutDoxygen About Doxygen
48 *
49 * If you're viewing this information as Doxygen-generated HTML you'll
50 * see the documentation index at the top of this page.
51 *
52 * The first line lists the Mesa source code modules.
53 * The second line lists the indexes available for viewing the documentation
54 * for each module.
55 *
56 * Selecting the <b>Main page</b> link will display a summary of the module
57 * (this page).
58 *
59 * Selecting <b>Data Structures</b> will list all C structures.
60 *
61 * Selecting the <b>File List</b> link will list all the source files in
62 * the module.
63 * Selecting a filename will show a list of all functions defined in that file.
64 *
65 * Selecting the <b>Data Fields</b> link will display a list of all
66 * documented structure members.
67 *
68 * Selecting the <b>Globals</b> link will display a list
69 * of all functions, structures, global variables and macros in the module.
70 *
71 */
72
73
74 #include "glheader.h"
75 #include "imports.h"
76 #include "accum.h"
77 #include "attrib.h"
78 #include "blend.h"
79 #include "buffers.h"
80 #include "bufferobj.h"
81 #include "colortab.h"
82 #include "context.h"
83 #include "debug.h"
84 #include "depth.h"
85 #include "dlist.h"
86 #include "eval.h"
87 #include "enums.h"
88 #include "extensions.h"
89 #include "feedback.h"
90 #include "fog.h"
91 #include "get.h"
92 #include "glthread.h"
93 #include "glapioffsets.h"
94 #include "histogram.h"
95 #include "hint.h"
96 #include "hash.h"
97 #include "light.h"
98 #include "lines.h"
99 #include "macros.h"
100 #include "matrix.h"
101 #include "occlude.h"
102 #include "pixel.h"
103 #include "points.h"
104 #include "polygon.h"
105 #if FEATURE_NV_vertex_program || FEATURE_NV_fragment_program
106 #include "program.h"
107 #endif
108 #include "rastpos.h"
109 #include "simple_list.h"
110 #include "state.h"
111 #include "stencil.h"
112 #include "teximage.h"
113 #include "texobj.h"
114 #include "texstate.h"
115 #include "mtypes.h"
116 #include "varray.h"
117 #include "vtxfmt.h"
118 #if _HAVE_FULL_GL
119 #include "math/m_translate.h"
120 #include "math/m_matrix.h"
121 #include "math/m_xform.h"
122 #include "math/mathmod.h"
123 #endif
124
125 #ifdef USE_SPARC_ASM
126 #include "SPARC/sparc.h"
127 #endif
128
129 #ifndef MESA_VERBOSE
130 int MESA_VERBOSE = 0;
131 #endif
132
133 #ifndef MESA_DEBUG_FLAGS
134 int MESA_DEBUG_FLAGS = 0;
135 #endif
136
137
138 /* ubyte -> float conversion */
139 GLfloat _mesa_ubyte_to_float_color_tab[256];
140
141 static void
142 free_shared_state( GLcontext *ctx, struct gl_shared_state *ss );
143
144
145 /**********************************************************************/
146 /** \name OpenGL SI-style interface (new in Mesa 3.5)
147 *
148 * \if subset
149 * \note Most of these functions are never called in the Mesa subset.
150 * \endif
151 */
152 /*@{*/
153
154 /**
155 * Destroy context callback.
156 *
157 * \param gc context.
158 * \return GL_TRUE on success, or GL_FALSE on failure.
159 *
160 * \ifnot subset
161 * Called by window system/device driver (via __GLexports::destroyCurrent) when
162 * the rendering context is to be destroyed.
163 * \endif
164 *
165 * Frees the context data and the context structure.
166 */
167 GLboolean
168 _mesa_destroyContext(__GLcontext *gc)
169 {
170 if (gc) {
171 _mesa_free_context_data(gc);
172 _mesa_free(gc);
173 }
174 return GL_TRUE;
175 }
176
177 /**
178 * Unbind context callback.
179 *
180 * \param gc context.
181 * \return GL_TRUE on success, or GL_FALSE on failure.
182 *
183 * \ifnot subset
184 * Called by window system/device driver (via __GLexports::loseCurrent)
185 * when the rendering context is made non-current.
186 * \endif
187 *
188 * No-op
189 */
190 GLboolean
191 _mesa_loseCurrent(__GLcontext *gc)
192 {
193 /* XXX unbind context from thread */
194 return GL_TRUE;
195 }
196
197 /**
198 * Bind context callback.
199 *
200 * \param gc context.
201 * \return GL_TRUE on success, or GL_FALSE on failure.
202 *
203 * \ifnot subset
204 * Called by window system/device driver (via __GLexports::makeCurrent)
205 * when the rendering context is made current.
206 * \endif
207 *
208 * No-op
209 */
210 GLboolean
211 _mesa_makeCurrent(__GLcontext *gc)
212 {
213 /* XXX bind context to thread */
214 return GL_TRUE;
215 }
216
217 /**
218 * Share context callback.
219 *
220 * \param gc context.
221 * \param gcShare shared context.
222 * \return GL_TRUE on success, or GL_FALSE on failure.
223 *
224 * \ifnot subset
225 * Called by window system/device driver (via __GLexports::shareContext)
226 * \endif
227 *
228 * Update the shared context reference count, gl_shared_state::RefCount.
229 */
230 GLboolean
231 _mesa_shareContext(__GLcontext *gc, __GLcontext *gcShare)
232 {
233 if (gc && gcShare && gc->Shared && gcShare->Shared) {
234 gc->Shared->RefCount--;
235 if (gc->Shared->RefCount == 0) {
236 free_shared_state(gc, gc->Shared);
237 }
238 gc->Shared = gcShare->Shared;
239 gc->Shared->RefCount++;
240 return GL_TRUE;
241 }
242 else {
243 return GL_FALSE;
244 }
245 }
246
247
248 #if _HAVE_FULL_GL
249 /**
250 * Copy context callback.
251 */
252 GLboolean
253 _mesa_copyContext(__GLcontext *dst, const __GLcontext *src, GLuint mask)
254 {
255 if (dst && src) {
256 _mesa_copy_context( src, dst, mask );
257 return GL_TRUE;
258 }
259 else {
260 return GL_FALSE;
261 }
262 }
263 #endif
264
265 /** No-op */
266 GLboolean
267 _mesa_forceCurrent(__GLcontext *gc)
268 {
269 return GL_TRUE;
270 }
271
272 /**
273 * Windows/buffer resizing notification callback.
274 *
275 * \param gc GL context.
276 * \return GL_TRUE on success, or GL_FALSE on failure.
277 */
278 GLboolean
279 _mesa_notifyResize(__GLcontext *gc)
280 {
281 GLint x, y;
282 GLuint width, height;
283 __GLdrawablePrivate *d = gc->imports.getDrawablePrivate(gc);
284 if (!d || !d->getDrawableSize)
285 return GL_FALSE;
286 d->getDrawableSize( d, &x, &y, &width, &height );
287 /* update viewport, resize software buffers, etc. */
288 return GL_TRUE;
289 }
290
291 /**
292 * Window/buffer destruction notification callback.
293 *
294 * \param gc GL context.
295 *
296 * Called when the context's window/buffer is going to be destroyed.
297 *
298 * No-op
299 */
300 void
301 _mesa_notifyDestroy(__GLcontext *gc)
302 {
303 /* Unbind from it. */
304 }
305
306 /**
307 * Swap buffers notification callback.
308 *
309 * \param gc GL context.
310 *
311 * Called by window system just before swapping buffers.
312 * We have to finish any pending rendering.
313 */
314 void
315 _mesa_notifySwapBuffers(__GLcontext *gc)
316 {
317 FLUSH_VERTICES( gc, 0 );
318 }
319
320 /** No-op */
321 struct __GLdispatchStateRec *
322 _mesa_dispatchExec(__GLcontext *gc)
323 {
324 return NULL;
325 }
326
327 /** No-op */
328 void
329 _mesa_beginDispatchOverride(__GLcontext *gc)
330 {
331 }
332
333 /** No-op */
334 void
335 _mesa_endDispatchOverride(__GLcontext *gc)
336 {
337 }
338
339 /**
340 * \ifnot subset
341 * Setup the exports.
342 *
343 * The window system will call these functions when it needs Mesa to do
344 * something.
345 *
346 * \note Device drivers should override these functions! For example,
347 * the Xlib driver should plug in the XMesa*-style functions into this
348 * structure. The XMesa-style functions should then call the _mesa_*
349 * version of these functions. This is an approximation to OO design
350 * (inheritance and virtual functions).
351 * \endif
352 *
353 * \if subset
354 * No-op.
355 *
356 * \endif
357 */
358 static void
359 _mesa_init_default_exports(__GLexports *exports)
360 {
361 #if _HAVE_FULL_GL
362 exports->destroyContext = _mesa_destroyContext;
363 exports->loseCurrent = _mesa_loseCurrent;
364 exports->makeCurrent = _mesa_makeCurrent;
365 exports->shareContext = _mesa_shareContext;
366 exports->copyContext = _mesa_copyContext;
367 exports->forceCurrent = _mesa_forceCurrent;
368 exports->notifyResize = _mesa_notifyResize;
369 exports->notifyDestroy = _mesa_notifyDestroy;
370 exports->notifySwapBuffers = _mesa_notifySwapBuffers;
371 exports->dispatchExec = _mesa_dispatchExec;
372 exports->beginDispatchOverride = _mesa_beginDispatchOverride;
373 exports->endDispatchOverride = _mesa_endDispatchOverride;
374 #endif
375 }
376
377 /**
378 * Exported OpenGL SI interface.
379 */
380 __GLcontext *
381 __glCoreCreateContext(__GLimports *imports, __GLcontextModes *modes)
382 {
383 GLcontext *ctx;
384
385 ctx = (GLcontext *) (*imports->calloc)(NULL, 1, sizeof(GLcontext));
386 if (ctx == NULL) {
387 return NULL;
388 }
389
390 _mesa_initialize_context(ctx, modes, NULL, imports, GL_FALSE);
391 ctx->imports = *imports;
392
393 return ctx;
394 }
395
396 /**
397 * Exported OpenGL SI interface.
398 */
399 void
400 __glCoreNopDispatch(void)
401 {
402 #if 0
403 /* SI */
404 __gl_dispatch = __glNopDispatchState;
405 #else
406 /* Mesa */
407 _glapi_set_dispatch(NULL);
408 #endif
409 }
410
411 /*@}*/
412
413
414 /**********************************************************************/
415 /** \name GL Visual allocation/destruction */
416 /**********************************************************************/
417 /*@{*/
418
419 /**
420 * Allocate a new GLvisual object.
421 *
422 * \param rgbFlag GL_TRUE for RGB(A) mode, GL_FALSE for Color Index mode.
423 * \param dbFlag double buffering
424 * \param stereoFlag stereo buffer
425 * \param depthBits requested bits per depth buffer value. Any value in [0, 32]
426 * is acceptable but the actual depth type will be GLushort or GLuint as
427 * needed.
428 * \param stencilBits requested minimum bits per stencil buffer value
429 * \param accumRedBits, accumGreenBits, accumBlueBits, accumAlphaBits number of bits per color component in accum buffer.
430 * \param indexBits number of bits per pixel if \p rgbFlag is GL_FALSE
431 * \param redBits number of bits per color component in frame buffer for RGB(A)
432 * mode. We always use 8 in core Mesa though.
433 * \param greenBits same as above.
434 * \param blueBits same as above.
435 * \param alphaBits same as above.
436 * \param numSamples not really used.
437 *
438 * \return pointer to new GLvisual or NULL if requested parameters can't be
439 * met.
440 *
441 * Allocates a GLvisual structure and initializes it via
442 * _mesa_initialize_visual().
443 */
444 GLvisual *
445 _mesa_create_visual( GLboolean rgbFlag,
446 GLboolean dbFlag,
447 GLboolean stereoFlag,
448 GLint redBits,
449 GLint greenBits,
450 GLint blueBits,
451 GLint alphaBits,
452 GLint indexBits,
453 GLint depthBits,
454 GLint stencilBits,
455 GLint accumRedBits,
456 GLint accumGreenBits,
457 GLint accumBlueBits,
458 GLint accumAlphaBits,
459 GLint numSamples )
460 {
461 GLvisual *vis = (GLvisual *) CALLOC( sizeof(GLvisual) );
462 if (vis) {
463 if (!_mesa_initialize_visual(vis, rgbFlag, dbFlag, stereoFlag,
464 redBits, greenBits, blueBits, alphaBits,
465 indexBits, depthBits, stencilBits,
466 accumRedBits, accumGreenBits,
467 accumBlueBits, accumAlphaBits,
468 numSamples)) {
469 FREE(vis);
470 return NULL;
471 }
472 }
473 return vis;
474 }
475
476 /**
477 * Initialize the fields of the given GLvisual.
478 *
479 * \return GL_TRUE on success, or GL_FALSE on failure.
480 *
481 * \sa _mesa_create_visual() above for the parameter description.
482 *
483 * Makes some sanity checks and fills in the fields of the
484 * GLvisual structure with the given parameters.
485 */
486 GLboolean
487 _mesa_initialize_visual( GLvisual *vis,
488 GLboolean rgbFlag,
489 GLboolean dbFlag,
490 GLboolean stereoFlag,
491 GLint redBits,
492 GLint greenBits,
493 GLint blueBits,
494 GLint alphaBits,
495 GLint indexBits,
496 GLint depthBits,
497 GLint stencilBits,
498 GLint accumRedBits,
499 GLint accumGreenBits,
500 GLint accumBlueBits,
501 GLint accumAlphaBits,
502 GLint numSamples )
503 {
504 (void) numSamples;
505
506 assert(vis);
507
508 /* This is to catch bad values from device drivers not updated for
509 * Mesa 3.3. Some device drivers just passed 1. That's a REALLY
510 * bad value now (a 1-bit depth buffer!?!).
511 */
512 assert(depthBits == 0 || depthBits > 1);
513
514 if (depthBits < 0 || depthBits > 32) {
515 return GL_FALSE;
516 }
517 if (stencilBits < 0 || stencilBits > (GLint) (8 * sizeof(GLstencil))) {
518 return GL_FALSE;
519 }
520 if (accumRedBits < 0 || accumRedBits > (GLint) (8 * sizeof(GLaccum))) {
521 return GL_FALSE;
522 }
523 if (accumGreenBits < 0 || accumGreenBits > (GLint) (8 * sizeof(GLaccum))) {
524 return GL_FALSE;
525 }
526 if (accumBlueBits < 0 || accumBlueBits > (GLint) (8 * sizeof(GLaccum))) {
527 return GL_FALSE;
528 }
529 if (accumAlphaBits < 0 || accumAlphaBits > (GLint) (8 * sizeof(GLaccum))) {
530 return GL_FALSE;
531 }
532
533 vis->rgbMode = rgbFlag;
534 vis->doubleBufferMode = dbFlag;
535 vis->stereoMode = stereoFlag;
536
537 vis->redBits = redBits;
538 vis->greenBits = greenBits;
539 vis->blueBits = blueBits;
540 vis->alphaBits = alphaBits;
541
542 vis->indexBits = indexBits;
543 vis->depthBits = depthBits;
544 vis->accumRedBits = (accumRedBits > 0) ? (8 * sizeof(GLaccum)) : 0;
545 vis->accumGreenBits = (accumGreenBits > 0) ? (8 * sizeof(GLaccum)) : 0;
546 vis->accumBlueBits = (accumBlueBits > 0) ? (8 * sizeof(GLaccum)) : 0;
547 vis->accumAlphaBits = (accumAlphaBits > 0) ? (8 * sizeof(GLaccum)) : 0;
548 vis->stencilBits = (stencilBits > 0) ? (8 * sizeof(GLstencil)) : 0;
549
550 vis->haveAccumBuffer = accumRedBits > 0;
551 vis->haveDepthBuffer = depthBits > 0;
552 vis->haveStencilBuffer = stencilBits > 0;
553
554 vis->numAuxBuffers = 0;
555 vis->level = 0;
556 vis->pixmapMode = 0;
557
558 return GL_TRUE;
559 }
560
561 /**
562 * Destroy a visual.
563 *
564 * \param vis visual.
565 *
566 * Frees the visual structure.
567 */
568 void
569 _mesa_destroy_visual( GLvisual *vis )
570 {
571 FREE(vis);
572 }
573
574 /*@}*/
575
576
577 /**********************************************************************/
578 /** \name GL Framebuffer allocation/destruction */
579 /**********************************************************************/
580 /*@{*/
581
582 /**
583 * Create a new framebuffer.
584 *
585 * A GLframebuffer is a structure which encapsulates the depth, stencil and
586 * accum buffers and related parameters.
587 *
588 * \param visual a GLvisual pointer (we copy the struct contents)
589 * \param softwareDepth create/use a software depth buffer?
590 * \param softwareStencil create/use a software stencil buffer?
591 * \param softwareAccum create/use a software accum buffer?
592 * \param softwareAlpha create/use a software alpha buffer?
593 *
594 * \return pointer to new GLframebuffer struct or NULL if error.
595 *
596 * Allocate a GLframebuffer structure and initializes it via
597 * _mesa_initialize_framebuffer().
598 */
599 GLframebuffer *
600 _mesa_create_framebuffer( const GLvisual *visual,
601 GLboolean softwareDepth,
602 GLboolean softwareStencil,
603 GLboolean softwareAccum,
604 GLboolean softwareAlpha )
605 {
606 GLframebuffer *buffer = CALLOC_STRUCT(gl_frame_buffer);
607 assert(visual);
608 if (buffer) {
609 _mesa_initialize_framebuffer(buffer, visual,
610 softwareDepth, softwareStencil,
611 softwareAccum, softwareAlpha );
612 }
613 return buffer;
614 }
615
616 /**
617 * Initialize a GLframebuffer object.
618 *
619 * \sa _mesa_create_framebuffer() above for the parameter description.
620 *
621 * Makes some sanity checks and fills in the fields of the
622 * GLframebuffer structure with the given parameters.
623 */
624 void
625 _mesa_initialize_framebuffer( GLframebuffer *buffer,
626 const GLvisual *visual,
627 GLboolean softwareDepth,
628 GLboolean softwareStencil,
629 GLboolean softwareAccum,
630 GLboolean softwareAlpha )
631 {
632 assert(buffer);
633 assert(visual);
634
635 _mesa_bzero(buffer, sizeof(GLframebuffer));
636
637 /* sanity checks */
638 if (softwareDepth ) {
639 assert(visual->depthBits > 0);
640 }
641 if (softwareStencil) {
642 assert(visual->stencilBits > 0);
643 }
644 if (softwareAccum) {
645 assert(visual->rgbMode);
646 assert(visual->accumRedBits > 0);
647 assert(visual->accumGreenBits > 0);
648 assert(visual->accumBlueBits > 0);
649 }
650 if (softwareAlpha) {
651 assert(visual->rgbMode);
652 assert(visual->alphaBits > 0);
653 }
654
655 buffer->Visual = *visual;
656 buffer->UseSoftwareDepthBuffer = softwareDepth;
657 buffer->UseSoftwareStencilBuffer = softwareStencil;
658 buffer->UseSoftwareAccumBuffer = softwareAccum;
659 buffer->UseSoftwareAlphaBuffers = softwareAlpha;
660 }
661
662 /**
663 * Free a framebuffer struct and its buffers.
664 *
665 * Calls _mesa_free_framebuffer_data() and frees the structure.
666 */
667 void
668 _mesa_destroy_framebuffer( GLframebuffer *buffer )
669 {
670 if (buffer) {
671 _mesa_free_framebuffer_data(buffer);
672 FREE(buffer);
673 }
674 }
675
676 /**
677 * Free the data hanging off of \p buffer, but not \p buffer itself.
678 *
679 * \param buffer framebuffer.
680 *
681 * Frees all the buffers associated with the structure.
682 */
683 void
684 _mesa_free_framebuffer_data( GLframebuffer *buffer )
685 {
686 if (!buffer)
687 return;
688
689 if (buffer->UseSoftwareDepthBuffer && buffer->DepthBuffer) {
690 MESA_PBUFFER_FREE( buffer->DepthBuffer );
691 buffer->DepthBuffer = NULL;
692 }
693 if (buffer->UseSoftwareAccumBuffer && buffer->Accum) {
694 MESA_PBUFFER_FREE( buffer->Accum );
695 buffer->Accum = NULL;
696 }
697 if (buffer->UseSoftwareStencilBuffer && buffer->Stencil) {
698 MESA_PBUFFER_FREE( buffer->Stencil );
699 buffer->Stencil = NULL;
700 }
701 if (buffer->UseSoftwareAlphaBuffers){
702 if (buffer->FrontLeftAlpha) {
703 MESA_PBUFFER_FREE( buffer->FrontLeftAlpha );
704 buffer->FrontLeftAlpha = NULL;
705 }
706 if (buffer->BackLeftAlpha) {
707 MESA_PBUFFER_FREE( buffer->BackLeftAlpha );
708 buffer->BackLeftAlpha = NULL;
709 }
710 if (buffer->FrontRightAlpha) {
711 MESA_PBUFFER_FREE( buffer->FrontRightAlpha );
712 buffer->FrontRightAlpha = NULL;
713 }
714 if (buffer->BackRightAlpha) {
715 MESA_PBUFFER_FREE( buffer->BackRightAlpha );
716 buffer->BackRightAlpha = NULL;
717 }
718 }
719 }
720
721 /*@}*/
722
723
724 /**********************************************************************/
725 /** \name Context allocation, initialization, destroying
726 *
727 * The purpose of the most initialization functions here is to provide the
728 * default state values according to the OpenGL specification.
729 */
730 /**********************************************************************/
731 /*@{*/
732
733 /**
734 * One-time initialization mutex lock.
735 *
736 * \sa Used by one_time_init().
737 */
738 _glthread_DECLARE_STATIC_MUTEX(OneTimeLock);
739
740 /**
741 * Calls all the various one-time-init functions in Mesa.
742 *
743 * While holding a global mutex lock, calls several initialization functions,
744 * and sets the glapi callbacks if the \c MESA_DEBUG environment variable is
745 * defined.
746 *
747 * \sa _mesa_init_lists(), _math_init().
748 */
749 static void
750 one_time_init( GLcontext *ctx )
751 {
752 static GLboolean alreadyCalled = GL_FALSE;
753 _glthread_LOCK_MUTEX(OneTimeLock);
754 if (!alreadyCalled) {
755 GLuint i;
756
757 /* do some implementation tests */
758 assert( sizeof(GLbyte) == 1 );
759 assert( sizeof(GLshort) >= 2 );
760 assert( sizeof(GLint) >= 4 );
761 assert( sizeof(GLubyte) == 1 );
762 assert( sizeof(GLushort) >= 2 );
763 assert( sizeof(GLuint) >= 4 );
764
765 _mesa_init_lists();
766
767 #if _HAVE_FULL_GL
768 _math_init();
769
770 for (i = 0; i < 256; i++) {
771 _mesa_ubyte_to_float_color_tab[i] = (float) i / 255.0F;
772 }
773 #endif
774
775 #ifdef USE_SPARC_ASM
776 _mesa_init_sparc_glapi_relocs();
777 #endif
778 if (_mesa_getenv("MESA_DEBUG")) {
779 _glapi_noop_enable_warnings(GL_TRUE);
780 #ifndef GLX_DIRECT_RENDERING
781 /* libGL from before 2002/06/28 don't have this function. Someday,
782 * when newer libGL libs are common, remove the #ifdef test. This
783 * only serves to print warnings when calling undefined GL functions.
784 */
785 _glapi_set_warning_func( (_glapi_warning_func) _mesa_warning );
786 #endif
787 }
788 else {
789 _glapi_noop_enable_warnings(GL_FALSE);
790 }
791
792 #if defined(DEBUG) && defined(__DATE__) && defined(__TIME__)
793 _mesa_debug(ctx, "Mesa DEBUG build %s %s\n", __DATE__, __TIME__);
794 #endif
795
796 alreadyCalled = GL_TRUE;
797 }
798 _glthread_UNLOCK_MUTEX(OneTimeLock);
799 }
800
801 /**
802 * Allocate and initialize a shared context state structure.
803 *
804 * \return pointer to a gl_shared_state structure on success, or NULL on
805 * failure.
806 *
807 * Initializes the display list, texture objects and vertex programs hash
808 * tables, allocates the texture objects. If it runs out of memory, frees
809 * everything already allocated before returning NULL.
810 */
811 static GLboolean
812 alloc_shared_state( GLcontext *ctx )
813 {
814 struct gl_shared_state *ss = CALLOC_STRUCT(gl_shared_state);
815 if (!ss)
816 return GL_FALSE;
817
818 ctx->Shared = ss;
819
820 _glthread_INIT_MUTEX(ss->Mutex);
821
822 ss->DisplayList = _mesa_NewHashTable();
823 ss->TexObjects = _mesa_NewHashTable();
824 #if FEATURE_NV_vertex_program || FEATURE_NV_fragment_program
825 ss->Programs = _mesa_NewHashTable();
826 #endif
827
828 #if FEATURE_ARB_vertex_program
829 ss->DefaultVertexProgram = _mesa_alloc_program(ctx, GL_VERTEX_PROGRAM_ARB, 0);
830 if (!ss->DefaultVertexProgram)
831 goto cleanup;
832 #endif
833 #if FEATURE_ARB_fragment_program
834 ss->DefaultFragmentProgram = _mesa_alloc_program(ctx, GL_FRAGMENT_PROGRAM_ARB, 0);
835 if (!ss->DefaultFragmentProgram)
836 goto cleanup;
837 #endif
838
839 ss->BufferObjects = _mesa_NewHashTable();
840
841 ss->Default1D = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_1D);
842 if (!ss->Default1D)
843 goto cleanup;
844
845 ss->Default2D = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_2D);
846 if (!ss->Default2D)
847 goto cleanup;
848
849 ss->Default3D = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_3D);
850 if (!ss->Default3D)
851 goto cleanup;
852
853 ss->DefaultCubeMap = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_CUBE_MAP_ARB);
854 if (!ss->DefaultCubeMap)
855 goto cleanup;
856
857 ss->DefaultRect = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_RECTANGLE_NV);
858 if (!ss->DefaultRect)
859 goto cleanup;
860
861 #if 0
862 _mesa_save_texture_object(ctx, ss->Default1D);
863 _mesa_save_texture_object(ctx, ss->Default2D);
864 _mesa_save_texture_object(ctx, ss->Default3D);
865 _mesa_save_texture_object(ctx, ss->DefaultCubeMap);
866 _mesa_save_texture_object(ctx, ss->DefaultRect);
867 #endif
868
869 /* Effectively bind the default textures to all texture units */
870 ss->Default1D->RefCount += MAX_TEXTURE_IMAGE_UNITS;
871 ss->Default2D->RefCount += MAX_TEXTURE_IMAGE_UNITS;
872 ss->Default3D->RefCount += MAX_TEXTURE_IMAGE_UNITS;
873 ss->DefaultCubeMap->RefCount += MAX_TEXTURE_IMAGE_UNITS;
874 ss->DefaultRect->RefCount += MAX_TEXTURE_IMAGE_UNITS;
875
876 return GL_TRUE;
877
878 cleanup:
879 /* Ran out of memory at some point. Free everything and return NULL */
880 if (ss->DisplayList)
881 _mesa_DeleteHashTable(ss->DisplayList);
882 if (ss->TexObjects)
883 _mesa_DeleteHashTable(ss->TexObjects);
884 #if FEATURE_NV_vertex_program
885 if (ss->Programs)
886 _mesa_DeleteHashTable(ss->Programs);
887 #endif
888 #if FEATURE_ARB_vertex_program
889 if (ss->DefaultVertexProgram)
890 _mesa_delete_program(ctx, ss->DefaultVertexProgram);
891 #endif
892 #if FEATURE_ARB_fragment_program
893 if (ss->DefaultFragmentProgram)
894 _mesa_delete_program(ctx, ss->DefaultFragmentProgram);
895 #endif
896 if (ss->BufferObjects)
897 _mesa_DeleteHashTable(ss->BufferObjects);
898
899 if (ss->Default1D)
900 (*ctx->Driver.DeleteTexture)(ctx, ss->Default1D);
901 if (ss->Default2D)
902 (*ctx->Driver.DeleteTexture)(ctx, ss->Default2D);
903 if (ss->Default3D)
904 (*ctx->Driver.DeleteTexture)(ctx, ss->Default3D);
905 if (ss->DefaultCubeMap)
906 (*ctx->Driver.DeleteTexture)(ctx, ss->DefaultCubeMap);
907 if (ss->DefaultRect)
908 (*ctx->Driver.DeleteTexture)(ctx, ss->DefaultRect);
909 if (ss)
910 _mesa_free(ss);
911 return GL_FALSE;
912 }
913
914 /**
915 * Deallocate a shared state context and all children structures.
916 *
917 * \param ctx GL context.
918 * \param ss shared state pointer.
919 *
920 * Frees the display lists, the texture objects (calling the driver texture
921 * deletion callback to free its private data) and the vertex programs, as well
922 * as their hash tables.
923 *
924 * \sa alloc_shared_state().
925 */
926 static void
927 free_shared_state( GLcontext *ctx, struct gl_shared_state *ss )
928 {
929 /* Free display lists */
930 while (1) {
931 GLuint list = _mesa_HashFirstEntry(ss->DisplayList);
932 if (list) {
933 _mesa_destroy_list(ctx, list);
934 }
935 else {
936 break;
937 }
938 }
939 _mesa_DeleteHashTable(ss->DisplayList);
940
941 /* Free texture objects */
942 ASSERT(ctx->Driver.DeleteTexture);
943 while (1) {
944 GLuint texName = _mesa_HashFirstEntry(ss->TexObjects);
945 if (texName) {
946 struct gl_texture_object *texObj = (struct gl_texture_object *)
947 _mesa_HashLookup(ss->TexObjects, texName);
948 ASSERT(texObj);
949 (*ctx->Driver.DeleteTexture)(ctx, texObj);
950 _mesa_HashRemove(ss->TexObjects, texName);
951 }
952 else {
953 break;
954 }
955 }
956 _mesa_DeleteHashTable(ss->TexObjects);
957
958 #if FEATURE_NV_vertex_program
959 /* Free vertex programs */
960 while (1) {
961 GLuint prog = _mesa_HashFirstEntry(ss->Programs);
962 if (prog) {
963 struct program *p = (struct program *) _mesa_HashLookup(ss->Programs,
964 prog);
965 ASSERT(p);
966 _mesa_delete_program(ctx, p);
967 _mesa_HashRemove(ss->Programs, prog);
968 }
969 else {
970 break;
971 }
972 }
973 _mesa_DeleteHashTable(ss->Programs);
974 #endif
975
976 _mesa_DeleteHashTable(ss->BufferObjects);
977
978 _glthread_DESTROY_MUTEX(ss->Mutex);
979
980 FREE(ss);
981 }
982
983
984 static void _mesa_init_current( GLcontext *ctx )
985 {
986 int i;
987
988 /* Current group */
989 for (i = 0; i < VERT_ATTRIB_MAX; i++) {
990 ASSIGN_4V( ctx->Current.Attrib[i], 0.0, 0.0, 0.0, 1.0 );
991 }
992 /* special cases: */
993 ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_WEIGHT], 1.0, 0.0, 0.0, 1.0 );
994 ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_NORMAL], 0.0, 0.0, 1.0, 1.0 );
995 ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_COLOR0], 1.0, 1.0, 1.0, 1.0 );
996 ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_COLOR1], 0.0, 0.0, 0.0, 0.0 );
997 ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_FOG], 0.0, 0.0, 0.0, 0.0 );
998 for (i = 0; i < MAX_TEXTURE_UNITS; i++)
999 ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_TEX0 + i], 0.0, 0.0, 0.0, 1.0);
1000 ctx->Current.Index = 1;
1001 ctx->Current.EdgeFlag = GL_TRUE;
1002 }
1003
1004
1005 static void
1006 _mesa_init_constants( GLcontext *ctx )
1007 {
1008 assert(ctx);
1009
1010 assert(MAX_TEXTURE_LEVELS >= MAX_3D_TEXTURE_LEVELS);
1011 assert(MAX_TEXTURE_LEVELS >= MAX_CUBE_TEXTURE_LEVELS);
1012
1013 /* Constants, may be overriden by device drivers */
1014 ctx->Const.MaxTextureLevels = MAX_TEXTURE_LEVELS;
1015 ctx->Const.Max3DTextureLevels = MAX_3D_TEXTURE_LEVELS;
1016 ctx->Const.MaxCubeTextureLevels = MAX_CUBE_TEXTURE_LEVELS;
1017 ctx->Const.MaxTextureRectSize = MAX_TEXTURE_RECT_SIZE;
1018 ctx->Const.MaxTextureUnits = MAX_TEXTURE_UNITS;
1019 ctx->Const.MaxTextureCoordUnits = MAX_TEXTURE_COORD_UNITS;
1020 ctx->Const.MaxTextureImageUnits = MAX_TEXTURE_IMAGE_UNITS;
1021 ctx->Const.MaxTextureMaxAnisotropy = MAX_TEXTURE_MAX_ANISOTROPY;
1022 ctx->Const.MaxTextureLodBias = MAX_TEXTURE_LOD_BIAS;
1023 ctx->Const.MaxArrayLockSize = MAX_ARRAY_LOCK_SIZE;
1024 ctx->Const.SubPixelBits = SUB_PIXEL_BITS;
1025 ctx->Const.MinPointSize = MIN_POINT_SIZE;
1026 ctx->Const.MaxPointSize = MAX_POINT_SIZE;
1027 ctx->Const.MinPointSizeAA = MIN_POINT_SIZE;
1028 ctx->Const.MaxPointSizeAA = MAX_POINT_SIZE;
1029 ctx->Const.PointSizeGranularity = (GLfloat) POINT_SIZE_GRANULARITY;
1030 ctx->Const.MinLineWidth = MIN_LINE_WIDTH;
1031 ctx->Const.MaxLineWidth = MAX_LINE_WIDTH;
1032 ctx->Const.MinLineWidthAA = MIN_LINE_WIDTH;
1033 ctx->Const.MaxLineWidthAA = MAX_LINE_WIDTH;
1034 ctx->Const.LineWidthGranularity = (GLfloat) LINE_WIDTH_GRANULARITY;
1035 ctx->Const.NumAuxBuffers = NUM_AUX_BUFFERS;
1036 ctx->Const.MaxColorTableSize = MAX_COLOR_TABLE_SIZE;
1037 ctx->Const.MaxConvolutionWidth = MAX_CONVOLUTION_WIDTH;
1038 ctx->Const.MaxConvolutionHeight = MAX_CONVOLUTION_HEIGHT;
1039 ctx->Const.MaxClipPlanes = MAX_CLIP_PLANES;
1040 ctx->Const.MaxLights = MAX_LIGHTS;
1041 ctx->Const.MaxSpotExponent = 128.0;
1042 ctx->Const.MaxShininess = 128.0;
1043 #if FEATURE_ARB_vertex_program
1044 ctx->Const.MaxVertexProgramInstructions = MAX_NV_VERTEX_PROGRAM_INSTRUCTIONS;
1045 ctx->Const.MaxVertexProgramAttribs = MAX_NV_VERTEX_PROGRAM_INPUTS;
1046 ctx->Const.MaxVertexProgramTemps = MAX_NV_VERTEX_PROGRAM_TEMPS;
1047 ctx->Const.MaxVertexProgramLocalParams = MAX_NV_VERTEX_PROGRAM_PARAMS;
1048 ctx->Const.MaxVertexProgramEnvParams = MAX_NV_VERTEX_PROGRAM_PARAMS;/*XXX*/
1049 ctx->Const.MaxVertexProgramAddressRegs = MAX_VERTEX_PROGRAM_ADDRESS_REGS;
1050 #endif
1051 #if FEATURE_ARB_fragment_program
1052 ctx->Const.MaxFragmentProgramInstructions = MAX_NV_FRAGMENT_PROGRAM_INSTRUCTIONS;
1053 ctx->Const.MaxFragmentProgramAttribs = MAX_NV_FRAGMENT_PROGRAM_INPUTS;
1054 ctx->Const.MaxFragmentProgramTemps = MAX_NV_FRAGMENT_PROGRAM_TEMPS;
1055 ctx->Const.MaxFragmentProgramLocalParams = MAX_NV_FRAGMENT_PROGRAM_PARAMS;
1056 ctx->Const.MaxFragmentProgramEnvParams = MAX_NV_FRAGMENT_PROGRAM_PARAMS;/*XXX*/
1057 ctx->Const.MaxFragmentProgramAddressRegs = MAX_FRAGMENT_PROGRAM_ADDRESS_REGS;
1058 ctx->Const.MaxFragmentProgramAluInstructions = MAX_FRAGMENT_PROGRAM_ALU_INSTRUCTIONS;
1059 ctx->Const.MaxFragmentProgramTexInstructions = MAX_FRAGMENT_PROGRAM_TEX_INSTRUCTIONS;
1060 ctx->Const.MaxFragmentProgramTexIndirections = MAX_FRAGMENT_PROGRAM_TEX_INDIRECTIONS;
1061 #endif
1062 ctx->Const.MaxProgramMatrices = MAX_PROGRAM_MATRICES;
1063 ctx->Const.MaxProgramMatrixStackDepth = MAX_PROGRAM_MATRIX_STACK_DEPTH;
1064
1065 /* If we're running in the X server, do bounds checking to prevent
1066 * segfaults and server crashes!
1067 */
1068 #if defined(XFree86LOADER) && defined(IN_MODULE)
1069 ctx->Const.CheckArrayBounds = GL_TRUE;
1070 #else
1071 ctx->Const.CheckArrayBounds = GL_FALSE;
1072 #endif
1073
1074 ASSERT(ctx->Const.MaxTextureUnits == MAX2(ctx->Const.MaxTextureImageUnits, ctx->Const.MaxTextureCoordUnits));
1075 }
1076
1077 /**
1078 * Initialize the attribute groups in a GL context.
1079 *
1080 * \param ctx GL context.
1081 *
1082 * Initializes all the attributes, calling the respective <tt>init*</tt>
1083 * functions for the more complex data structures.
1084 */
1085 static GLboolean
1086 init_attrib_groups( GLcontext *ctx )
1087 {
1088 assert(ctx);
1089
1090 /* Constants */
1091 _mesa_init_constants( ctx );
1092
1093 /* Extensions */
1094 _mesa_init_extensions( ctx );
1095
1096 /* Attribute Groups */
1097 _mesa_init_accum( ctx );
1098 _mesa_init_attrib( ctx );
1099 _mesa_init_buffers( ctx );
1100 _mesa_init_buffer_objects( ctx );
1101 _mesa_init_color( ctx );
1102 _mesa_init_colortables( ctx );
1103 _mesa_init_current( ctx );
1104 _mesa_init_depth( ctx );
1105 _mesa_init_debug( ctx );
1106 _mesa_init_display_list( ctx );
1107 _mesa_init_eval( ctx );
1108 _mesa_init_feedback( ctx );
1109 _mesa_init_fog( ctx );
1110 _mesa_init_histogram( ctx );
1111 _mesa_init_hint( ctx );
1112 _mesa_init_line( ctx );
1113 _mesa_init_lighting( ctx );
1114 _mesa_init_matrix( ctx );
1115 _mesa_init_occlude( ctx );
1116 _mesa_init_pixel( ctx );
1117 _mesa_init_point( ctx );
1118 _mesa_init_polygon( ctx );
1119 _mesa_init_program( ctx );
1120 _mesa_init_rastpos( ctx );
1121 _mesa_init_stencil( ctx );
1122 _mesa_init_transform( ctx );
1123 _mesa_init_varray( ctx );
1124 _mesa_init_viewport( ctx );
1125
1126 if (!_mesa_init_texture( ctx ))
1127 return GL_FALSE;
1128
1129 /* Miscellaneous */
1130 ctx->NewState = _NEW_ALL;
1131 ctx->ErrorValue = (GLenum) GL_NO_ERROR;
1132 ctx->CatchSignals = GL_TRUE;
1133 ctx->_Facing = 0;
1134
1135 return GL_TRUE;
1136 }
1137
1138
1139 /**
1140 * If the DRI libGL.so library is old, it may not have the entrypoints for
1141 * some recent OpenGL extensions. Dynamically add them now.
1142 * If we're building stand-alone Mesa where libGL.so has both the dispatcher
1143 * and driver code, this won't be an issue (and calling this function won't
1144 * do any harm).
1145 */
1146 static void
1147 add_newer_entrypoints(void)
1148 {
1149 unsigned i;
1150 static const struct {
1151 const char * const name;
1152 unsigned offset;
1153 }
1154 newer_entrypoints[] = {
1155 /* GL_ARB_window_pos aliases with GL_MESA_window_pos */
1156 { "glWindowPos2dARB", 513 },
1157 { "glWindowPos2dvARB", 514 },
1158 { "glWindowPos2fARB", 515 },
1159 { "glWindowPos2fvARB", 516 },
1160 { "glWindowPos2iARB", 517 },
1161 { "glWindowPos2ivARB", 518 },
1162 { "glWindowPos2sARB", 519 },
1163 { "glWindowPos2svARB", 520 },
1164 { "glWindowPos3dARB", 521 },
1165 { "glWindowPos3dvARB", 522 },
1166 { "glWindowPos3fARB", 523 },
1167 { "glWindowPos3fvARB", 524 },
1168 { "glWindowPos3iARB", 525 },
1169 { "glWindowPos3ivARB", 526 },
1170 { "glWindowPos3sARB", 527 },
1171 { "glWindowPos3svARB", 528 },
1172 #if FEATURE_NV_vertex_program
1173 { "glAreProgramsResidentNV", 578 },
1174 { "glBindProgramNV", 579 },
1175 { "glDeleteProgramsNV", 580 },
1176 { "glExecuteProgramNV", 581 },
1177 { "glGenProgramsNV", 582 },
1178 { "glGetProgramParameterdvNV", 583 },
1179 { "glGetProgramParameterfvNV", 584 },
1180 { "glGetProgramivNV", 585 },
1181 { "glGetProgramStringNV", 586 },
1182 { "glGetTrackMatrixivNV", 587 },
1183 { "glGetVertexAttribdvNV", 588 },
1184 { "glGetVertexAttribfvNV", 589 },
1185 { "glGetVertexAttribivNV", 590 },
1186 { "glGetVertexAttribPointervNV", 591 },
1187 { "glIsProgramNV", 592 },
1188 { "glLoadProgramNV", 593 },
1189 { "glProgramParameter4dNV", 594 },
1190 { "glProgramParameter4dvNV", 595 },
1191 { "glProgramParameter4fNV", 596 },
1192 { "glProgramParameter4fvNV", 597 },
1193 { "glProgramParameters4dvNV", 598 },
1194 { "glProgramParameters4fvNV", 599 },
1195 { "glRequestResidentProgramsNV", 600 },
1196 { "glTrackMatrixNV", 601 },
1197 { "glVertexAttribPointerNV", 602 },
1198 { "glVertexAttrib1dNV", 603 },
1199 { "glVertexAttrib1dvNV", 604 },
1200 { "glVertexAttrib1fNV", 605 },
1201 { "glVertexAttrib1fvNV", 606 },
1202 { "glVertexAttrib1sNV", 607 },
1203 { "glVertexAttrib1svNV", 608 },
1204 { "glVertexAttrib2dNV", 609 },
1205 { "glVertexAttrib2dvNV", 610 },
1206 { "glVertexAttrib2fNV", 611 },
1207 { "glVertexAttrib2fvNV", 612 },
1208 { "glVertexAttrib2sNV", 613 },
1209 { "glVertexAttrib2svNV", 614 },
1210 { "glVertexAttrib3dNV", 615 },
1211 { "glVertexAttrib3dvNV", 616 },
1212 { "glVertexAttrib3fNV", 617 },
1213 { "glVertexAttrib3fvNV", 618 },
1214 { "glVertexAttrib3sNV", 619 },
1215 { "glVertexAttrib3svNV", 620 },
1216 { "glVertexAttrib4dNV", 621 },
1217 { "glVertexAttrib4dvNV", 622 },
1218 { "glVertexAttrib4fNV", 623 },
1219 { "glVertexAttrib4fvNV", 624 },
1220 { "glVertexAttrib4sNV", 625 },
1221 { "glVertexAttrib4svNV", 626 },
1222 { "glVertexAttrib4ubNV", 627 },
1223 { "glVertexAttrib4ubvNV", 628 },
1224 { "glVertexAttribs1dvNV", 629 },
1225 { "glVertexAttribs1fvNV", 630 },
1226 { "glVertexAttribs1svNV", 631 },
1227 { "glVertexAttribs2dvNV", 632 },
1228 { "glVertexAttribs2fvNV", 633 },
1229 { "glVertexAttribs2svNV", 634 },
1230 { "glVertexAttribs3dvNV", 635 },
1231 { "glVertexAttribs3fvNV", 636 },
1232 { "glVertexAttribs3svNV", 637 },
1233 { "glVertexAttribs4dvNV", 638 },
1234 { "glVertexAttribs4fvNV", 639 },
1235 { "glVertexAttribs4svNV", 640 },
1236 { "glVertexAttribs4ubvNV", 641 },
1237 #endif
1238 { "glPointParameteriNV", 642 },
1239 { "glPointParameterivNV", 643 },
1240 { "glMultiDrawArraysEXT", 644 },
1241 { "glMultiDrawElementsEXT", 645 },
1242 { "glMultiDrawArraysSUN", _gloffset_MultiDrawArraysEXT },
1243 { "glMultiDrawElementsSUN", _gloffset_MultiDrawElementsEXT },
1244 { "glActiveStencilFaceEXT", 646 },
1245 #if FEATURE_NV_fence
1246 { "glDeleteFencesNV", 647 },
1247 { "glGenFencesNV", 648 },
1248 { "glIsFenceNV", 649 },
1249 { "glTestFenceNV", 650 },
1250 { "glGetFenceivNV", 651 },
1251 { "glFinishFenceNV", 652 },
1252 { "glSetFenceNV", 653 },
1253 #endif
1254 #if FEATURE_NV_fragment_program
1255 { "glProgramNamedParameter4fNV", 682 },
1256 { "glProgramNamedParameter4dNV", 683 },
1257 { "glProgramNamedParameter4fvNV", 683 },
1258 { "glProgramNamedParameter4dvNV", 684 },
1259 { "glGetProgramNamedParameterfvNV", 685 },
1260 { "glGetProgramNamedParameterdvNV", 686 },
1261 #endif
1262 #if FEATURE_ARB_vertex_program
1263 { "glVertexAttrib1sARB", _gloffset_VertexAttrib1sNV },
1264 { "glVertexAttrib1fARB", _gloffset_VertexAttrib1fNV },
1265 { "glVertexAttrib1dARB", _gloffset_VertexAttrib1dNV },
1266 { "glVertexAttrib2sARB", _gloffset_VertexAttrib2sNV },
1267 { "glVertexAttrib2fARB", _gloffset_VertexAttrib2fNV },
1268 { "glVertexAttrib2dARB", _gloffset_VertexAttrib2dNV },
1269 { "glVertexAttrib3sARB", _gloffset_VertexAttrib3sNV },
1270 { "glVertexAttrib3fARB", _gloffset_VertexAttrib3fNV },
1271 { "glVertexAttrib3dARB", _gloffset_VertexAttrib3dNV },
1272 { "glVertexAttrib4sARB", _gloffset_VertexAttrib4sNV },
1273 { "glVertexAttrib4fARB", _gloffset_VertexAttrib4fNV },
1274 { "glVertexAttrib4dARB", _gloffset_VertexAttrib4dNV },
1275 { "glVertexAttrib4NubARB", _gloffset_VertexAttrib4ubNV },
1276 { "glVertexAttrib1svARB", _gloffset_VertexAttrib1svNV },
1277 { "glVertexAttrib1fvARB", _gloffset_VertexAttrib1fvNV },
1278 { "glVertexAttrib1dvARB", _gloffset_VertexAttrib1dvNV },
1279 { "glVertexAttrib2svARB", _gloffset_VertexAttrib2svNV },
1280 { "glVertexAttrib2fvARB", _gloffset_VertexAttrib2fvNV },
1281 { "glVertexAttrib2dvARB", _gloffset_VertexAttrib2dvNV },
1282 { "glVertexAttrib3svARB", _gloffset_VertexAttrib3svNV },
1283 { "glVertexAttrib3fvARB", _gloffset_VertexAttrib3fvNV },
1284 { "glVertexAttrib3dvARB", _gloffset_VertexAttrib3dvNV },
1285 { "glVertexAttrib4bvARB", _gloffset_VertexAttrib4bvARB },
1286 { "glVertexAttrib4svARB", _gloffset_VertexAttrib4svNV },
1287 { "glVertexAttrib4ivARB", _gloffset_VertexAttrib4ivARB },
1288 { "glVertexAttrib4ubvARB", _gloffset_VertexAttrib4ubvARB },
1289 { "glVertexAttrib4usvARB", _gloffset_VertexAttrib4usvARB },
1290 { "glVertexAttrib4uivARB", _gloffset_VertexAttrib4uivARB },
1291 { "glVertexAttrib4fvARB", _gloffset_VertexAttrib4fvNV },
1292 { "glVertexAttrib4dvARB", _gloffset_VertexAttrib4dvNV },
1293 { "glVertexAttrib4NbvARB", _gloffset_VertexAttrib4NbvARB },
1294 { "glVertexAttrib4NsvARB", _gloffset_VertexAttrib4NsvARB },
1295 { "glVertexAttrib4NivARB", _gloffset_VertexAttrib4NivARB },
1296 { "glVertexAttrib4NubvARB", _gloffset_VertexAttrib4ubvNV },
1297 { "glVertexAttrib4NusvARB", _gloffset_VertexAttrib4NusvARB },
1298 { "glVertexAttrib4NuivARB", _gloffset_VertexAttrib4NuivARB },
1299 { "glVertexAttribPointerARB", _gloffset_VertexAttribPointerARB },
1300 { "glEnableVertexAttribArrayARB", _gloffset_EnableVertexAttribArrayARB },
1301 { "glDisableVertexAttribArrayARB", _gloffset_DisableVertexAttribArrayARB },
1302 { "glProgramStringARB", _gloffset_ProgramStringARB },
1303 { "glBindProgramARB", _gloffset_BindProgramNV },
1304 { "glDeleteProgramsARB", _gloffset_DeleteProgramsNV },
1305 { "glGenProgramsARB", _gloffset_GenProgramsNV },
1306 { "glIsProgramARB", _gloffset_IsProgramNV },
1307 { "glProgramEnvParameter4dARB", _gloffset_ProgramEnvParameter4dARB },
1308 { "glProgramEnvParameter4dvARB", _gloffset_ProgramEnvParameter4dvARB },
1309 { "glProgramEnvParameter4fARB", _gloffset_ProgramEnvParameter4fARB },
1310 { "glProgramEnvParameter4fvARB", _gloffset_ProgramEnvParameter4fvARB },
1311 { "glProgramLocalParameter4dARB", _gloffset_ProgramLocalParameter4dARB },
1312 { "glProgramLocalParameter4dvARB", _gloffset_ProgramLocalParameter4dvARB },
1313 { "glProgramLocalParameter4fARB", _gloffset_ProgramLocalParameter4fARB },
1314 { "glProgramLocalParameter4fvARB", _gloffset_ProgramLocalParameter4fvARB },
1315 { "glGetProgramEnvParameterdvARB", _gloffset_GetProgramEnvParameterdvARB },
1316 { "glGetProgramEnvParameterfvARB", _gloffset_GetProgramEnvParameterfvARB },
1317 { "glGetProgramLocalParameterdvARB", _gloffset_GetProgramLocalParameterdvARB },
1318 { "glGetProgramLocalParameterfvARB", _gloffset_GetProgramLocalParameterfvARB },
1319 { "glGetProgramivARB", _gloffset_GetProgramivARB },
1320 { "glGetProgramStringARB", _gloffset_GetProgramStringARB },
1321 { "glGetVertexAttribdvARB", _gloffset_GetVertexAttribdvNV },
1322 { "glGetVertexAttribfvARB", _gloffset_GetVertexAttribfvNV },
1323 { "glGetVertexAttribivARB", _gloffset_GetVertexAttribivNV },
1324 { "glGetVertexAttribPointervARB", _gloffset_GetVertexAttribPointervNV },
1325 #endif
1326 { "glMultiModeDrawArraysIBM", _gloffset_MultiModeDrawArraysIBM },
1327 { "glMultiModeDrawElementsIBM", _gloffset_MultiModeDrawElementsIBM },
1328 };
1329
1330 for ( i = 0 ; i < Elements(newer_entrypoints) ; i++ ) {
1331 _glapi_add_entrypoint( newer_entrypoints[i].name,
1332 newer_entrypoints[i].offset );
1333 }
1334 }
1335
1336
1337 /**
1338 * Initialize a GLcontext struct.
1339 *
1340 * This includes allocating all the other structs and arrays which hang off of
1341 * the context by pointers.
1342 *
1343 * \sa _mesa_create_context() for the parameter description.
1344 *
1345 * Performs the imports and exports callback tables initialization, and
1346 * miscellaneous one-time initializations. If no shared context is supplied one
1347 * is allocated, and increase its reference count. Setups the GL API dispatch
1348 * tables. Initialize the TNL module. Sets the maximum Z buffer depth.
1349 * Finally queries the \c MESA_DEBUG and \c MESA_VERBOSE environment variables
1350 * for debug flags.
1351 *
1352 * \note the direct parameter is ignored (obsolete).
1353 */
1354 GLboolean
1355 _mesa_initialize_context( GLcontext *ctx,
1356 const GLvisual *visual,
1357 GLcontext *share_list,
1358 void *driver_ctx,
1359 GLboolean direct )
1360 {
1361 GLuint dispatchSize;
1362
1363 ASSERT(driver_ctx);
1364
1365 /* If the driver wants core Mesa to use special imports, it'll have to
1366 * override these defaults.
1367 */
1368 _mesa_init_default_imports( &(ctx->imports), driver_ctx );
1369
1370 /* initialize the exports (Mesa functions called by the window system) */
1371 _mesa_init_default_exports( &(ctx->exports) );
1372
1373 /* misc one-time initializations */
1374 one_time_init(ctx);
1375
1376 ctx->DriverCtx = driver_ctx;
1377 ctx->Visual = *visual;
1378 ctx->DrawBuffer = NULL;
1379 ctx->ReadBuffer = NULL;
1380
1381 /* Set these pointers to defaults now in case they're not set since
1382 * we need them while creating the default textures.
1383 */
1384 if (!ctx->Driver.NewTextureObject)
1385 ctx->Driver.NewTextureObject = _mesa_new_texture_object;
1386 if (!ctx->Driver.DeleteTexture)
1387 ctx->Driver.DeleteTexture = _mesa_delete_texture_object;
1388 if (!ctx->Driver.NewTextureImage)
1389 ctx->Driver.NewTextureImage = _mesa_new_texture_image;
1390
1391 if (share_list) {
1392 /* share state with another context */
1393 ctx->Shared = share_list->Shared;
1394 }
1395 else {
1396 /* allocate new, unshared state */
1397 if (!alloc_shared_state( ctx )) {
1398 return GL_FALSE;
1399 }
1400 }
1401 _glthread_LOCK_MUTEX(ctx->Shared->Mutex);
1402 ctx->Shared->RefCount++;
1403 _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex);
1404
1405 if (!init_attrib_groups( ctx )) {
1406 free_shared_state(ctx, ctx->Shared);
1407 return GL_FALSE;
1408 }
1409
1410 /* libGL ABI coordination */
1411 add_newer_entrypoints();
1412
1413 /* Find the larger of Mesa's dispatch table and libGL's dispatch table.
1414 * In practice, this'll be the same for stand-alone Mesa. But for DRI
1415 * Mesa we do this to accomodate different versions of libGL and various
1416 * DRI drivers.
1417 */
1418 dispatchSize = MAX2(_glapi_get_dispatch_table_size(),
1419 sizeof(struct _glapi_table) / sizeof(void *));
1420
1421 /* setup API dispatch tables */
1422 ctx->Exec = (struct _glapi_table *) CALLOC(dispatchSize * sizeof(void*));
1423 ctx->Save = (struct _glapi_table *) CALLOC(dispatchSize * sizeof(void*));
1424 if (!ctx->Exec || !ctx->Save) {
1425 free_shared_state(ctx, ctx->Shared);
1426 if (ctx->Exec)
1427 FREE( ctx->Exec );
1428 }
1429 _mesa_init_exec_table(ctx->Exec, dispatchSize);
1430 ctx->CurrentDispatch = ctx->Exec;
1431
1432 #if _HAVE_FULL_GL
1433 _mesa_init_dlist_table(ctx->Save, dispatchSize);
1434
1435 ctx->ExecPrefersFloat = GL_FALSE;
1436 ctx->SavePrefersFloat = GL_FALSE;
1437
1438 /* Neutral tnl module stuff */
1439 _mesa_init_exec_vtxfmt( ctx );
1440 ctx->TnlModule.Current = NULL;
1441 ctx->TnlModule.SwapCount = 0;
1442
1443 #endif
1444
1445 return GL_TRUE;
1446 }
1447
1448 /**
1449 * Allocate and initialize a GLcontext structure.
1450 *
1451 * \param visual a GLvisual pointer (we copy the struct contents)
1452 * \param share_list another context to share display lists with or NULL
1453 * \param driver_ctx pointer to device driver's context state struct
1454 * \param direct obsolete, ignored
1455 *
1456 * \return pointer to a new __GLcontextRec or NULL if error.
1457 */
1458 GLcontext *
1459 _mesa_create_context( const GLvisual *visual,
1460 GLcontext *share_list,
1461 void *driver_ctx,
1462 GLboolean direct )
1463
1464 {
1465 GLcontext *ctx;
1466
1467 ASSERT(visual);
1468 ASSERT(driver_ctx);
1469
1470 ctx = (GLcontext *) _mesa_calloc(sizeof(GLcontext));
1471 if (!ctx)
1472 return NULL;
1473
1474 if (_mesa_initialize_context(ctx, visual, share_list, driver_ctx, direct)) {
1475 return ctx;
1476 }
1477 else {
1478 _mesa_free(ctx);
1479 return NULL;
1480 }
1481 }
1482
1483 /**
1484 * Free the data associated with the given context.
1485 *
1486 * But doesn't free the GLcontext struct itself.
1487 *
1488 * \sa _mesa_initialize_context() and init_attrib_groups().
1489 */
1490 void
1491 _mesa_free_context_data( GLcontext *ctx )
1492 {
1493 /* if we're destroying the current context, unbind it first */
1494 if (ctx == _mesa_get_current_context()) {
1495 _mesa_make_current(NULL, NULL);
1496 }
1497
1498 _mesa_free_lighting_data( ctx );
1499 _mesa_free_eval_data( ctx );
1500 _mesa_free_texture_data( ctx );
1501 _mesa_free_matrix_data( ctx );
1502 _mesa_free_viewport_data( ctx );
1503 _mesa_free_colortables_data( ctx );
1504 #if FEATURE_NV_vertex_program
1505 if (ctx->VertexProgram.Current) {
1506 ctx->VertexProgram.Current->Base.RefCount--;
1507 if (ctx->VertexProgram.Current->Base.RefCount <= 0)
1508 _mesa_delete_program(ctx, &(ctx->VertexProgram.Current->Base));
1509 }
1510 #endif
1511 #if FEATURE_NV_fragment_program
1512 if (ctx->FragmentProgram.Current) {
1513 ctx->FragmentProgram.Current->Base.RefCount--;
1514 if (ctx->FragmentProgram.Current->Base.RefCount <= 0)
1515 _mesa_delete_program(ctx, &(ctx->FragmentProgram.Current->Base));
1516 }
1517 #endif
1518
1519 /* Shared context state (display lists, textures, etc) */
1520 _glthread_LOCK_MUTEX(ctx->Shared->Mutex);
1521 ctx->Shared->RefCount--;
1522 assert(ctx->Shared->RefCount >= 0);
1523 _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex);
1524 if (ctx->Shared->RefCount == 0) {
1525 /* free shared state */
1526 free_shared_state( ctx, ctx->Shared );
1527 }
1528
1529 if (ctx->Extensions.String)
1530 FREE((void *) ctx->Extensions.String);
1531
1532 FREE(ctx->Exec);
1533 FREE(ctx->Save);
1534 }
1535
1536 /**
1537 * Destroy a GLcontext structure.
1538 *
1539 * \param ctx GL context.
1540 *
1541 * Calls _mesa_free_context_data() and free the structure.
1542 */
1543 void
1544 _mesa_destroy_context( GLcontext *ctx )
1545 {
1546 if (ctx) {
1547 _mesa_free_context_data(ctx);
1548 FREE( (void *) ctx );
1549 }
1550 }
1551
1552 #if _HAVE_FULL_GL
1553 /**
1554 * Copy attribute groups from one context to another.
1555 *
1556 * \param src source context
1557 * \param dst destination context
1558 * \param mask bitwise OR of GL_*_BIT flags
1559 *
1560 * According to the bits specified in \p mask, copies the corresponding
1561 * attributes from \p src into \dst. For many of the attributes a simple \c
1562 * memcpy is not enough due to the existence of internal pointers in their data
1563 * structures.
1564 */
1565 void
1566 _mesa_copy_context( const GLcontext *src, GLcontext *dst, GLuint mask )
1567 {
1568 if (mask & GL_ACCUM_BUFFER_BIT) {
1569 /* OK to memcpy */
1570 dst->Accum = src->Accum;
1571 }
1572 if (mask & GL_COLOR_BUFFER_BIT) {
1573 /* OK to memcpy */
1574 dst->Color = src->Color;
1575 }
1576 if (mask & GL_CURRENT_BIT) {
1577 /* OK to memcpy */
1578 dst->Current = src->Current;
1579 }
1580 if (mask & GL_DEPTH_BUFFER_BIT) {
1581 /* OK to memcpy */
1582 dst->Depth = src->Depth;
1583 }
1584 if (mask & GL_ENABLE_BIT) {
1585 /* no op */
1586 }
1587 if (mask & GL_EVAL_BIT) {
1588 /* OK to memcpy */
1589 dst->Eval = src->Eval;
1590 }
1591 if (mask & GL_FOG_BIT) {
1592 /* OK to memcpy */
1593 dst->Fog = src->Fog;
1594 }
1595 if (mask & GL_HINT_BIT) {
1596 /* OK to memcpy */
1597 dst->Hint = src->Hint;
1598 }
1599 if (mask & GL_LIGHTING_BIT) {
1600 GLuint i;
1601 /* begin with memcpy */
1602 MEMCPY( &dst->Light, &src->Light, sizeof(struct gl_light) );
1603 /* fixup linked lists to prevent pointer insanity */
1604 make_empty_list( &(dst->Light.EnabledList) );
1605 for (i = 0; i < MAX_LIGHTS; i++) {
1606 if (dst->Light.Light[i].Enabled) {
1607 insert_at_tail(&(dst->Light.EnabledList), &(dst->Light.Light[i]));
1608 }
1609 }
1610 }
1611 if (mask & GL_LINE_BIT) {
1612 /* OK to memcpy */
1613 dst->Line = src->Line;
1614 }
1615 if (mask & GL_LIST_BIT) {
1616 /* OK to memcpy */
1617 dst->List = src->List;
1618 }
1619 if (mask & GL_PIXEL_MODE_BIT) {
1620 /* OK to memcpy */
1621 dst->Pixel = src->Pixel;
1622 }
1623 if (mask & GL_POINT_BIT) {
1624 /* OK to memcpy */
1625 dst->Point = src->Point;
1626 }
1627 if (mask & GL_POLYGON_BIT) {
1628 /* OK to memcpy */
1629 dst->Polygon = src->Polygon;
1630 }
1631 if (mask & GL_POLYGON_STIPPLE_BIT) {
1632 /* Use loop instead of MEMCPY due to problem with Portland Group's
1633 * C compiler. Reported by John Stone.
1634 */
1635 GLuint i;
1636 for (i = 0; i < 32; i++) {
1637 dst->PolygonStipple[i] = src->PolygonStipple[i];
1638 }
1639 }
1640 if (mask & GL_SCISSOR_BIT) {
1641 /* OK to memcpy */
1642 dst->Scissor = src->Scissor;
1643 }
1644 if (mask & GL_STENCIL_BUFFER_BIT) {
1645 /* OK to memcpy */
1646 dst->Stencil = src->Stencil;
1647 }
1648 if (mask & GL_TEXTURE_BIT) {
1649 /* Cannot memcpy because of pointers */
1650 _mesa_copy_texture_state(src, dst);
1651 }
1652 if (mask & GL_TRANSFORM_BIT) {
1653 /* OK to memcpy */
1654 dst->Transform = src->Transform;
1655 }
1656 if (mask & GL_VIEWPORT_BIT) {
1657 /* Cannot use memcpy, because of pointers in GLmatrix _WindowMap */
1658 dst->Viewport.X = src->Viewport.X;
1659 dst->Viewport.Y = src->Viewport.Y;
1660 dst->Viewport.Width = src->Viewport.Width;
1661 dst->Viewport.Height = src->Viewport.Height;
1662 dst->Viewport.Near = src->Viewport.Near;
1663 dst->Viewport.Far = src->Viewport.Far;
1664 _math_matrix_copy(&dst->Viewport._WindowMap, &src->Viewport._WindowMap);
1665 }
1666
1667 /* XXX FIXME: Call callbacks?
1668 */
1669 dst->NewState = _NEW_ALL;
1670 }
1671 #endif
1672
1673
1674 /**
1675 * Check if the given context can render into the given framebuffer
1676 * by checking visual attributes.
1677 * \return GL_TRUE if compatible, GL_FALSE otherwise.
1678 */
1679 static GLboolean
1680 check_compatible(const GLcontext *ctx, const GLframebuffer *buffer)
1681 {
1682 const GLvisual *ctxvis = &ctx->Visual;
1683 const GLvisual *bufvis = &buffer->Visual;
1684
1685 if (ctxvis == bufvis)
1686 return GL_TRUE;
1687
1688 if (ctxvis->rgbMode != bufvis->rgbMode)
1689 return GL_FALSE;
1690 if (ctxvis->doubleBufferMode && !bufvis->doubleBufferMode)
1691 return GL_FALSE;
1692 if (ctxvis->stereoMode && !bufvis->stereoMode)
1693 return GL_FALSE;
1694 if (ctxvis->haveAccumBuffer && !bufvis->haveAccumBuffer)
1695 return GL_FALSE;
1696 if (ctxvis->haveDepthBuffer && !bufvis->haveDepthBuffer)
1697 return GL_FALSE;
1698 if (ctxvis->haveStencilBuffer && !bufvis->haveStencilBuffer)
1699 return GL_FALSE;
1700 if (ctxvis->redMask && ctxvis->redMask != bufvis->redMask)
1701 return GL_FALSE;
1702 if (ctxvis->greenMask && ctxvis->greenMask != bufvis->greenMask)
1703 return GL_FALSE;
1704 if (ctxvis->blueMask && ctxvis->blueMask != bufvis->blueMask)
1705 return GL_FALSE;
1706 if (ctxvis->depthBits && ctxvis->depthBits != bufvis->depthBits)
1707 return GL_FALSE;
1708 if (ctxvis->stencilBits && ctxvis->stencilBits != bufvis->stencilBits)
1709 return GL_FALSE;
1710
1711 return GL_TRUE;
1712 }
1713
1714
1715 /**
1716 * Set the current context, binding the given frame buffer to the context.
1717 *
1718 * \param newCtx new GL context.
1719 * \param buffer framebuffer.
1720 *
1721 * Calls _mesa_make_current2() with \p buffer as read and write framebuffer.
1722 */
1723 void
1724 _mesa_make_current( GLcontext *newCtx, GLframebuffer *buffer )
1725 {
1726 _mesa_make_current2( newCtx, buffer, buffer );
1727 }
1728
1729 /**
1730 * Bind the given context to the given draw-buffer and read-buffer and
1731 * make it the current context for this thread.
1732 *
1733 * \param newCtx new GL context. If NULL then there will be no current GL
1734 * context.
1735 * \param drawBuffer draw framebuffer.
1736 * \param readBuffer read framebuffer.
1737 *
1738 * Check that the context's and framebuffer's visuals are compatible, returning
1739 * immediately otherwise. Sets the glapi current context via
1740 * _glapi_set_context(). If \p newCtx is not NULL, associates \p drawBuffer and
1741 * \p readBuffer with it and calls dd_function_table::ResizeBuffers if the buffers size has changed.
1742 * Calls dd_function_table::MakeCurrent callback if defined.
1743 *
1744 * When a context is bound by the first time and the \c MESA_INFO environment
1745 * variable is set it calls print_info() as an aid for remote user
1746 * troubleshooting.
1747 */
1748 void
1749 _mesa_make_current2( GLcontext *newCtx, GLframebuffer *drawBuffer,
1750 GLframebuffer *readBuffer )
1751 {
1752 if (MESA_VERBOSE)
1753 _mesa_debug(newCtx, "_mesa_make_current2()\n");
1754
1755 /* Check that the context's and framebuffer's visuals are compatible.
1756 */
1757 if (newCtx && drawBuffer && newCtx->DrawBuffer != drawBuffer) {
1758 if (!check_compatible(newCtx, drawBuffer))
1759 return;
1760 }
1761 if (newCtx && readBuffer && newCtx->ReadBuffer != readBuffer) {
1762 if (!check_compatible(newCtx, readBuffer))
1763 return;
1764 }
1765
1766 /* We call this function periodically (just here for now) in
1767 * order to detect when multithreading has begun.
1768 */
1769 _glapi_check_multithread();
1770
1771 _glapi_set_context((void *) newCtx);
1772 ASSERT(_mesa_get_current_context() == newCtx);
1773
1774
1775 if (!newCtx) {
1776 _glapi_set_dispatch(NULL); /* none current */
1777 }
1778 else {
1779 _glapi_set_dispatch(newCtx->CurrentDispatch);
1780
1781 if (drawBuffer && readBuffer) {
1782 /* TODO: check if newCtx and buffer's visual match??? */
1783 newCtx->DrawBuffer = drawBuffer;
1784 newCtx->ReadBuffer = readBuffer;
1785 newCtx->NewState |= _NEW_BUFFERS;
1786
1787 #if _HAVE_FULL_GL
1788 if (drawBuffer->Width == 0 && drawBuffer->Height == 0) {
1789 /* get initial window size */
1790 GLuint bufWidth, bufHeight;
1791
1792 /* ask device driver for size of output buffer */
1793 (*newCtx->Driver.GetBufferSize)( drawBuffer, &bufWidth, &bufHeight );
1794
1795 if (drawBuffer->Width != bufWidth ||
1796 drawBuffer->Height != bufHeight) {
1797
1798 drawBuffer->Width = bufWidth;
1799 drawBuffer->Height = bufHeight;
1800
1801 newCtx->Driver.ResizeBuffers( drawBuffer );
1802 }
1803 }
1804
1805 if (readBuffer != drawBuffer &&
1806 readBuffer->Width == 0 && readBuffer->Height == 0) {
1807 /* get initial window size */
1808 GLuint bufWidth, bufHeight;
1809
1810 /* ask device driver for size of output buffer */
1811 (*newCtx->Driver.GetBufferSize)( readBuffer, &bufWidth, &bufHeight );
1812
1813 if (readBuffer->Width != bufWidth ||
1814 readBuffer->Height != bufHeight) {
1815
1816 readBuffer->Width = bufWidth;
1817 readBuffer->Height = bufHeight;
1818
1819 newCtx->Driver.ResizeBuffers( readBuffer );
1820 }
1821 }
1822 #endif
1823 }
1824
1825 /* Alert the driver - usually passed on to the sw t&l module,
1826 * but also used to detect threaded cases in the radeon codegen
1827 * hw t&l module.
1828 */
1829 if (newCtx->Driver.MakeCurrent)
1830 newCtx->Driver.MakeCurrent( newCtx, drawBuffer, readBuffer );
1831
1832 /* We can use this to help debug user's problems. Tell them to set
1833 * the MESA_INFO env variable before running their app. Then the
1834 * first time each context is made current we'll print some useful
1835 * information.
1836 */
1837 if (newCtx->FirstTimeCurrent) {
1838 if (_mesa_getenv("MESA_INFO")) {
1839 _mesa_print_info();
1840 }
1841 newCtx->FirstTimeCurrent = GL_FALSE;
1842 }
1843 }
1844 }
1845
1846 /**
1847 * Get current context for the calling thread.
1848 *
1849 * \return pointer to the current GL context.
1850 *
1851 * Calls _glapi_get_context(). This isn't the fastest way to get the current
1852 * context. If you need speed, see the #GET_CURRENT_CONTEXT macro in context.h.
1853 */
1854 GLcontext *
1855 _mesa_get_current_context( void )
1856 {
1857 return (GLcontext *) _glapi_get_context();
1858 }
1859
1860 /**
1861 * Get context's current API dispatch table.
1862 *
1863 * It'll either be the immediate-mode execute dispatcher or the display list
1864 * compile dispatcher.
1865 *
1866 * \param ctx GL context.
1867 *
1868 * \return pointer to dispatch_table.
1869 *
1870 * Simply returns __GLcontextRec::CurrentDispatch.
1871 */
1872 struct _glapi_table *
1873 _mesa_get_dispatch(GLcontext *ctx)
1874 {
1875 return ctx->CurrentDispatch;
1876 }
1877
1878 /*@}*/
1879
1880
1881 /**********************************************************************/
1882 /** \name Miscellaneous functions */
1883 /**********************************************************************/
1884 /*@{*/
1885
1886 /**
1887 * Record an error.
1888 *
1889 * \param ctx GL context.
1890 * \param error error code.
1891 *
1892 * Records the given error code and call the driver's dd_function_table::Error
1893 * function if defined.
1894 *
1895 * \sa
1896 * This is called via _mesa_error().
1897 */
1898 void
1899 _mesa_record_error( GLcontext *ctx, GLenum error )
1900 {
1901 if (!ctx)
1902 return;
1903
1904 if (ctx->ErrorValue == GL_NO_ERROR) {
1905 ctx->ErrorValue = error;
1906 }
1907
1908 /* Call device driver's error handler, if any. This is used on the Mac. */
1909 if (ctx->Driver.Error) {
1910 (*ctx->Driver.Error)( ctx );
1911 }
1912 }
1913
1914 /**
1915 * Execute glFinish().
1916 *
1917 * Calls the #ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH macro and the
1918 * dd_function_table::Finish driver callback, if not NULL.
1919 */
1920 void GLAPIENTRY
1921 _mesa_Finish( void )
1922 {
1923 GET_CURRENT_CONTEXT(ctx);
1924 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
1925 if (ctx->Driver.Finish) {
1926 (*ctx->Driver.Finish)( ctx );
1927 }
1928 }
1929
1930 /**
1931 * Execute glFlush().
1932 *
1933 * Calls the #ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH macro and the
1934 * dd_function_table::Flush driver callback, if not NULL.
1935 */
1936 void GLAPIENTRY
1937 _mesa_Flush( void )
1938 {
1939 GET_CURRENT_CONTEXT(ctx);
1940 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
1941 if (ctx->Driver.Flush) {
1942 (*ctx->Driver.Flush)( ctx );
1943 }
1944 }
1945
1946
1947 /*@}*/