Minor tweaks to help out at a driver level.
[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 /* XXX doesn't work at this time */
391 _mesa_initialize_context(ctx, modes, NULL, NULL, NULL);
392 ctx->imports = *imports;
393
394 return ctx;
395 }
396
397 /**
398 * Exported OpenGL SI interface.
399 */
400 void
401 __glCoreNopDispatch(void)
402 {
403 #if 0
404 /* SI */
405 __gl_dispatch = __glNopDispatchState;
406 #else
407 /* Mesa */
408 _glapi_set_dispatch(NULL);
409 #endif
410 }
411
412 /*@}*/
413
414
415 /**********************************************************************/
416 /** \name GL Visual allocation/destruction */
417 /**********************************************************************/
418 /*@{*/
419
420 /**
421 * Allocate a new GLvisual object.
422 *
423 * \param rgbFlag GL_TRUE for RGB(A) mode, GL_FALSE for Color Index mode.
424 * \param dbFlag double buffering
425 * \param stereoFlag stereo buffer
426 * \param depthBits requested bits per depth buffer value. Any value in [0, 32]
427 * is acceptable but the actual depth type will be GLushort or GLuint as
428 * needed.
429 * \param stencilBits requested minimum bits per stencil buffer value
430 * \param accumRedBits, accumGreenBits, accumBlueBits, accumAlphaBits number of bits per color component in accum buffer.
431 * \param indexBits number of bits per pixel if \p rgbFlag is GL_FALSE
432 * \param redBits number of bits per color component in frame buffer for RGB(A)
433 * mode. We always use 8 in core Mesa though.
434 * \param greenBits same as above.
435 * \param blueBits same as above.
436 * \param alphaBits same as above.
437 * \param numSamples not really used.
438 *
439 * \return pointer to new GLvisual or NULL if requested parameters can't be
440 * met.
441 *
442 * Allocates a GLvisual structure and initializes it via
443 * _mesa_initialize_visual().
444 */
445 GLvisual *
446 _mesa_create_visual( GLboolean rgbFlag,
447 GLboolean dbFlag,
448 GLboolean stereoFlag,
449 GLint redBits,
450 GLint greenBits,
451 GLint blueBits,
452 GLint alphaBits,
453 GLint indexBits,
454 GLint depthBits,
455 GLint stencilBits,
456 GLint accumRedBits,
457 GLint accumGreenBits,
458 GLint accumBlueBits,
459 GLint accumAlphaBits,
460 GLint numSamples )
461 {
462 GLvisual *vis = (GLvisual *) CALLOC( sizeof(GLvisual) );
463 if (vis) {
464 if (!_mesa_initialize_visual(vis, rgbFlag, dbFlag, stereoFlag,
465 redBits, greenBits, blueBits, alphaBits,
466 indexBits, depthBits, stencilBits,
467 accumRedBits, accumGreenBits,
468 accumBlueBits, accumAlphaBits,
469 numSamples)) {
470 FREE(vis);
471 return NULL;
472 }
473 }
474 return vis;
475 }
476
477 /**
478 * Initialize the fields of the given GLvisual.
479 *
480 * \return GL_TRUE on success, or GL_FALSE on failure.
481 *
482 * \sa _mesa_create_visual() above for the parameter description.
483 *
484 * Makes some sanity checks and fills in the fields of the
485 * GLvisual structure with the given parameters.
486 */
487 GLboolean
488 _mesa_initialize_visual( GLvisual *vis,
489 GLboolean rgbFlag,
490 GLboolean dbFlag,
491 GLboolean stereoFlag,
492 GLint redBits,
493 GLint greenBits,
494 GLint blueBits,
495 GLint alphaBits,
496 GLint indexBits,
497 GLint depthBits,
498 GLint stencilBits,
499 GLint accumRedBits,
500 GLint accumGreenBits,
501 GLint accumBlueBits,
502 GLint accumAlphaBits,
503 GLint numSamples )
504 {
505 (void) numSamples;
506
507 assert(vis);
508
509 /* This is to catch bad values from device drivers not updated for
510 * Mesa 3.3. Some device drivers just passed 1. That's a REALLY
511 * bad value now (a 1-bit depth buffer!?!).
512 */
513 assert(depthBits == 0 || depthBits > 1);
514
515 if (depthBits < 0 || depthBits > 32) {
516 return GL_FALSE;
517 }
518 if (stencilBits < 0 || stencilBits > (GLint) (8 * sizeof(GLstencil))) {
519 return GL_FALSE;
520 }
521 if (accumRedBits < 0 || accumRedBits > (GLint) (8 * sizeof(GLaccum))) {
522 return GL_FALSE;
523 }
524 if (accumGreenBits < 0 || accumGreenBits > (GLint) (8 * sizeof(GLaccum))) {
525 return GL_FALSE;
526 }
527 if (accumBlueBits < 0 || accumBlueBits > (GLint) (8 * sizeof(GLaccum))) {
528 return GL_FALSE;
529 }
530 if (accumAlphaBits < 0 || accumAlphaBits > (GLint) (8 * sizeof(GLaccum))) {
531 return GL_FALSE;
532 }
533
534 vis->rgbMode = rgbFlag;
535 vis->doubleBufferMode = dbFlag;
536 vis->stereoMode = stereoFlag;
537
538 vis->redBits = redBits;
539 vis->greenBits = greenBits;
540 vis->blueBits = blueBits;
541 vis->alphaBits = alphaBits;
542
543 vis->indexBits = indexBits;
544 vis->depthBits = depthBits;
545 vis->accumRedBits = (accumRedBits > 0) ? (8 * sizeof(GLaccum)) : 0;
546 vis->accumGreenBits = (accumGreenBits > 0) ? (8 * sizeof(GLaccum)) : 0;
547 vis->accumBlueBits = (accumBlueBits > 0) ? (8 * sizeof(GLaccum)) : 0;
548 vis->accumAlphaBits = (accumAlphaBits > 0) ? (8 * sizeof(GLaccum)) : 0;
549 vis->stencilBits = (stencilBits > 0) ? (8 * sizeof(GLstencil)) : 0;
550
551 vis->haveAccumBuffer = accumRedBits > 0;
552 vis->haveDepthBuffer = depthBits > 0;
553 vis->haveStencilBuffer = stencilBits > 0;
554
555 vis->numAuxBuffers = 0;
556 vis->level = 0;
557 vis->pixmapMode = 0;
558
559 return GL_TRUE;
560 }
561
562 /**
563 * Destroy a visual.
564 *
565 * \param vis visual.
566 *
567 * Frees the visual structure.
568 */
569 void
570 _mesa_destroy_visual( GLvisual *vis )
571 {
572 FREE(vis);
573 }
574
575 /*@}*/
576
577
578 /**********************************************************************/
579 /** \name GL Framebuffer allocation/destruction */
580 /**********************************************************************/
581 /*@{*/
582
583 /**
584 * Create a new framebuffer.
585 *
586 * A GLframebuffer is a structure which encapsulates the depth, stencil and
587 * accum buffers and related parameters.
588 *
589 * \param visual a GLvisual pointer (we copy the struct contents)
590 * \param softwareDepth create/use a software depth buffer?
591 * \param softwareStencil create/use a software stencil buffer?
592 * \param softwareAccum create/use a software accum buffer?
593 * \param softwareAlpha create/use a software alpha buffer?
594 *
595 * \return pointer to new GLframebuffer struct or NULL if error.
596 *
597 * Allocate a GLframebuffer structure and initializes it via
598 * _mesa_initialize_framebuffer().
599 */
600 GLframebuffer *
601 _mesa_create_framebuffer( const GLvisual *visual,
602 GLboolean softwareDepth,
603 GLboolean softwareStencil,
604 GLboolean softwareAccum,
605 GLboolean softwareAlpha )
606 {
607 GLframebuffer *buffer = CALLOC_STRUCT(gl_frame_buffer);
608 assert(visual);
609 if (buffer) {
610 _mesa_initialize_framebuffer(buffer, visual,
611 softwareDepth, softwareStencil,
612 softwareAccum, softwareAlpha );
613 }
614 return buffer;
615 }
616
617 /**
618 * Initialize a GLframebuffer object.
619 *
620 * \sa _mesa_create_framebuffer() above for the parameter description.
621 *
622 * Makes some sanity checks and fills in the fields of the
623 * GLframebuffer structure with the given parameters.
624 */
625 void
626 _mesa_initialize_framebuffer( GLframebuffer *buffer,
627 const GLvisual *visual,
628 GLboolean softwareDepth,
629 GLboolean softwareStencil,
630 GLboolean softwareAccum,
631 GLboolean softwareAlpha )
632 {
633 assert(buffer);
634 assert(visual);
635
636 _mesa_bzero(buffer, sizeof(GLframebuffer));
637
638 /* sanity checks */
639 if (softwareDepth ) {
640 assert(visual->depthBits > 0);
641 }
642 if (softwareStencil) {
643 assert(visual->stencilBits > 0);
644 }
645 if (softwareAccum) {
646 assert(visual->rgbMode);
647 assert(visual->accumRedBits > 0);
648 assert(visual->accumGreenBits > 0);
649 assert(visual->accumBlueBits > 0);
650 }
651 if (softwareAlpha) {
652 assert(visual->rgbMode);
653 assert(visual->alphaBits > 0);
654 }
655
656 buffer->Visual = *visual;
657 buffer->UseSoftwareDepthBuffer = softwareDepth;
658 buffer->UseSoftwareStencilBuffer = softwareStencil;
659 buffer->UseSoftwareAccumBuffer = softwareAccum;
660 buffer->UseSoftwareAlphaBuffers = softwareAlpha;
661 }
662
663 /**
664 * Free a framebuffer struct and its buffers.
665 *
666 * Calls _mesa_free_framebuffer_data() and frees the structure.
667 */
668 void
669 _mesa_destroy_framebuffer( GLframebuffer *buffer )
670 {
671 if (buffer) {
672 _mesa_free_framebuffer_data(buffer);
673 FREE(buffer);
674 }
675 }
676
677 /**
678 * Free the data hanging off of \p buffer, but not \p buffer itself.
679 *
680 * \param buffer framebuffer.
681 *
682 * Frees all the buffers associated with the structure.
683 */
684 void
685 _mesa_free_framebuffer_data( GLframebuffer *buffer )
686 {
687 if (!buffer)
688 return;
689
690 if (buffer->UseSoftwareDepthBuffer && buffer->DepthBuffer) {
691 MESA_PBUFFER_FREE( buffer->DepthBuffer );
692 buffer->DepthBuffer = NULL;
693 }
694 if (buffer->UseSoftwareAccumBuffer && buffer->Accum) {
695 MESA_PBUFFER_FREE( buffer->Accum );
696 buffer->Accum = NULL;
697 }
698 if (buffer->UseSoftwareStencilBuffer && buffer->Stencil) {
699 MESA_PBUFFER_FREE( buffer->Stencil );
700 buffer->Stencil = NULL;
701 }
702 if (buffer->UseSoftwareAlphaBuffers){
703 if (buffer->FrontLeftAlpha) {
704 MESA_PBUFFER_FREE( buffer->FrontLeftAlpha );
705 buffer->FrontLeftAlpha = NULL;
706 }
707 if (buffer->BackLeftAlpha) {
708 MESA_PBUFFER_FREE( buffer->BackLeftAlpha );
709 buffer->BackLeftAlpha = NULL;
710 }
711 if (buffer->FrontRightAlpha) {
712 MESA_PBUFFER_FREE( buffer->FrontRightAlpha );
713 buffer->FrontRightAlpha = NULL;
714 }
715 if (buffer->BackRightAlpha) {
716 MESA_PBUFFER_FREE( buffer->BackRightAlpha );
717 buffer->BackRightAlpha = NULL;
718 }
719 }
720 }
721
722 /*@}*/
723
724
725 /**********************************************************************/
726 /** \name Context allocation, initialization, destroying
727 *
728 * The purpose of the most initialization functions here is to provide the
729 * default state values according to the OpenGL specification.
730 */
731 /**********************************************************************/
732 /*@{*/
733
734 /**
735 * One-time initialization mutex lock.
736 *
737 * \sa Used by one_time_init().
738 */
739 _glthread_DECLARE_STATIC_MUTEX(OneTimeLock);
740
741 /**
742 * Calls all the various one-time-init functions in Mesa.
743 *
744 * While holding a global mutex lock, calls several initialization functions,
745 * and sets the glapi callbacks if the \c MESA_DEBUG environment variable is
746 * defined.
747 *
748 * \sa _mesa_init_lists(), _math_init().
749 */
750 static void
751 one_time_init( GLcontext *ctx )
752 {
753 static GLboolean alreadyCalled = GL_FALSE;
754 _glthread_LOCK_MUTEX(OneTimeLock);
755 if (!alreadyCalled) {
756 GLuint i;
757
758 /* do some implementation tests */
759 assert( sizeof(GLbyte) == 1 );
760 assert( sizeof(GLshort) >= 2 );
761 assert( sizeof(GLint) >= 4 );
762 assert( sizeof(GLubyte) == 1 );
763 assert( sizeof(GLushort) >= 2 );
764 assert( sizeof(GLuint) >= 4 );
765
766 _mesa_init_lists();
767
768 #if _HAVE_FULL_GL
769 _math_init();
770
771 for (i = 0; i < 256; i++) {
772 _mesa_ubyte_to_float_color_tab[i] = (float) i / 255.0F;
773 }
774 #endif
775
776 #ifdef USE_SPARC_ASM
777 _mesa_init_sparc_glapi_relocs();
778 #endif
779 if (_mesa_getenv("MESA_DEBUG")) {
780 _glapi_noop_enable_warnings(GL_TRUE);
781 #ifndef GLX_DIRECT_RENDERING
782 /* libGL from before 2002/06/28 don't have this function. Someday,
783 * when newer libGL libs are common, remove the #ifdef test. This
784 * only serves to print warnings when calling undefined GL functions.
785 */
786 _glapi_set_warning_func( (_glapi_warning_func) _mesa_warning );
787 #endif
788 }
789 else {
790 _glapi_noop_enable_warnings(GL_FALSE);
791 }
792
793 #if defined(DEBUG) && defined(__DATE__) && defined(__TIME__)
794 _mesa_debug(ctx, "Mesa DEBUG build %s %s\n", __DATE__, __TIME__);
795 #endif
796
797 alreadyCalled = GL_TRUE;
798 }
799 _glthread_UNLOCK_MUTEX(OneTimeLock);
800 }
801
802 /**
803 * Allocate and initialize a shared context state structure.
804 *
805 * \return pointer to a gl_shared_state structure on success, or NULL on
806 * failure.
807 *
808 * Initializes the display list, texture objects and vertex programs hash
809 * tables, allocates the texture objects. If it runs out of memory, frees
810 * everything already allocated before returning NULL.
811 */
812 static GLboolean
813 alloc_shared_state( GLcontext *ctx )
814 {
815 struct gl_shared_state *ss = CALLOC_STRUCT(gl_shared_state);
816 if (!ss)
817 return GL_FALSE;
818
819 ctx->Shared = ss;
820
821 _glthread_INIT_MUTEX(ss->Mutex);
822
823 ss->DisplayList = _mesa_NewHashTable();
824 ss->TexObjects = _mesa_NewHashTable();
825 #if FEATURE_NV_vertex_program || FEATURE_NV_fragment_program
826 ss->Programs = _mesa_NewHashTable();
827 #endif
828
829 #if FEATURE_ARB_vertex_program
830 ss->DefaultVertexProgram = _mesa_alloc_program(ctx, GL_VERTEX_PROGRAM_ARB, 0);
831 if (!ss->DefaultVertexProgram)
832 goto cleanup;
833 #endif
834 #if FEATURE_ARB_fragment_program
835 ss->DefaultFragmentProgram = _mesa_alloc_program(ctx, GL_FRAGMENT_PROGRAM_ARB, 0);
836 if (!ss->DefaultFragmentProgram)
837 goto cleanup;
838 #endif
839
840 ss->BufferObjects = _mesa_NewHashTable();
841
842 ss->Default1D = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_1D);
843 if (!ss->Default1D)
844 goto cleanup;
845
846 ss->Default2D = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_2D);
847 if (!ss->Default2D)
848 goto cleanup;
849
850 ss->Default3D = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_3D);
851 if (!ss->Default3D)
852 goto cleanup;
853
854 ss->DefaultCubeMap = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_CUBE_MAP_ARB);
855 if (!ss->DefaultCubeMap)
856 goto cleanup;
857
858 ss->DefaultRect = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_RECTANGLE_NV);
859 if (!ss->DefaultRect)
860 goto cleanup;
861
862 /* Effectively bind the default textures to all texture units */
863 ss->Default1D->RefCount += MAX_TEXTURE_IMAGE_UNITS;
864 ss->Default2D->RefCount += MAX_TEXTURE_IMAGE_UNITS;
865 ss->Default3D->RefCount += MAX_TEXTURE_IMAGE_UNITS;
866 ss->DefaultCubeMap->RefCount += MAX_TEXTURE_IMAGE_UNITS;
867 ss->DefaultRect->RefCount += MAX_TEXTURE_IMAGE_UNITS;
868
869 return GL_TRUE;
870
871 cleanup:
872 /* Ran out of memory at some point. Free everything and return NULL */
873 if (ss->DisplayList)
874 _mesa_DeleteHashTable(ss->DisplayList);
875 if (ss->TexObjects)
876 _mesa_DeleteHashTable(ss->TexObjects);
877 #if FEATURE_NV_vertex_program
878 if (ss->Programs)
879 _mesa_DeleteHashTable(ss->Programs);
880 #endif
881 #if FEATURE_ARB_vertex_program
882 if (ss->DefaultVertexProgram)
883 _mesa_delete_program(ctx, ss->DefaultVertexProgram);
884 #endif
885 #if FEATURE_ARB_fragment_program
886 if (ss->DefaultFragmentProgram)
887 _mesa_delete_program(ctx, ss->DefaultFragmentProgram);
888 #endif
889 if (ss->BufferObjects)
890 _mesa_DeleteHashTable(ss->BufferObjects);
891
892 if (ss->Default1D)
893 (*ctx->Driver.DeleteTexture)(ctx, ss->Default1D);
894 if (ss->Default2D)
895 (*ctx->Driver.DeleteTexture)(ctx, ss->Default2D);
896 if (ss->Default3D)
897 (*ctx->Driver.DeleteTexture)(ctx, ss->Default3D);
898 if (ss->DefaultCubeMap)
899 (*ctx->Driver.DeleteTexture)(ctx, ss->DefaultCubeMap);
900 if (ss->DefaultRect)
901 (*ctx->Driver.DeleteTexture)(ctx, ss->DefaultRect);
902 if (ss)
903 _mesa_free(ss);
904 return GL_FALSE;
905 }
906
907 /**
908 * Deallocate a shared state context and all children structures.
909 *
910 * \param ctx GL context.
911 * \param ss shared state pointer.
912 *
913 * Frees the display lists, the texture objects (calling the driver texture
914 * deletion callback to free its private data) and the vertex programs, as well
915 * as their hash tables.
916 *
917 * \sa alloc_shared_state().
918 */
919 static void
920 free_shared_state( GLcontext *ctx, struct gl_shared_state *ss )
921 {
922 /* Free display lists */
923 while (1) {
924 GLuint list = _mesa_HashFirstEntry(ss->DisplayList);
925 if (list) {
926 _mesa_destroy_list(ctx, list);
927 }
928 else {
929 break;
930 }
931 }
932 _mesa_DeleteHashTable(ss->DisplayList);
933
934 /* Free texture objects */
935 ASSERT(ctx->Driver.DeleteTexture);
936 while (1) {
937 GLuint texName = _mesa_HashFirstEntry(ss->TexObjects);
938 if (texName) {
939 struct gl_texture_object *texObj = (struct gl_texture_object *)
940 _mesa_HashLookup(ss->TexObjects, texName);
941 ASSERT(texObj);
942 (*ctx->Driver.DeleteTexture)(ctx, texObj);
943 _mesa_HashRemove(ss->TexObjects, texName);
944 }
945 else {
946 break;
947 }
948 }
949 _mesa_DeleteHashTable(ss->TexObjects);
950
951 #if FEATURE_NV_vertex_program
952 /* Free vertex programs */
953 while (1) {
954 GLuint prog = _mesa_HashFirstEntry(ss->Programs);
955 if (prog) {
956 struct program *p = (struct program *) _mesa_HashLookup(ss->Programs,
957 prog);
958 ASSERT(p);
959 _mesa_delete_program(ctx, p);
960 _mesa_HashRemove(ss->Programs, prog);
961 }
962 else {
963 break;
964 }
965 }
966 _mesa_DeleteHashTable(ss->Programs);
967 #endif
968
969 _mesa_DeleteHashTable(ss->BufferObjects);
970
971 _glthread_DESTROY_MUTEX(ss->Mutex);
972
973 FREE(ss);
974 }
975
976
977 static void _mesa_init_current( GLcontext *ctx )
978 {
979 int i;
980
981 /* Current group */
982 for (i = 0; i < VERT_ATTRIB_MAX; i++) {
983 ASSIGN_4V( ctx->Current.Attrib[i], 0.0, 0.0, 0.0, 1.0 );
984 }
985 /* special cases: */
986 ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_WEIGHT], 1.0, 0.0, 0.0, 1.0 );
987 ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_NORMAL], 0.0, 0.0, 1.0, 1.0 );
988 ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_COLOR0], 1.0, 1.0, 1.0, 1.0 );
989 ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_COLOR1], 0.0, 0.0, 0.0, 0.0 );
990 ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_FOG], 0.0, 0.0, 0.0, 0.0 );
991 for (i = 0; i < MAX_TEXTURE_UNITS; i++)
992 ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_TEX0 + i], 0.0, 0.0, 0.0, 1.0);
993 ctx->Current.Index = 1;
994 ctx->Current.EdgeFlag = GL_TRUE;
995 }
996
997
998 static void
999 _mesa_init_constants( GLcontext *ctx )
1000 {
1001 assert(ctx);
1002
1003 assert(MAX_TEXTURE_LEVELS >= MAX_3D_TEXTURE_LEVELS);
1004 assert(MAX_TEXTURE_LEVELS >= MAX_CUBE_TEXTURE_LEVELS);
1005
1006 /* Constants, may be overriden by device drivers */
1007 ctx->Const.MaxTextureLevels = MAX_TEXTURE_LEVELS;
1008 ctx->Const.Max3DTextureLevels = MAX_3D_TEXTURE_LEVELS;
1009 ctx->Const.MaxCubeTextureLevels = MAX_CUBE_TEXTURE_LEVELS;
1010 ctx->Const.MaxTextureRectSize = MAX_TEXTURE_RECT_SIZE;
1011 ctx->Const.MaxTextureUnits = MAX_TEXTURE_UNITS;
1012 ctx->Const.MaxTextureCoordUnits = MAX_TEXTURE_COORD_UNITS;
1013 ctx->Const.MaxTextureImageUnits = MAX_TEXTURE_IMAGE_UNITS;
1014 ctx->Const.MaxTextureMaxAnisotropy = MAX_TEXTURE_MAX_ANISOTROPY;
1015 ctx->Const.MaxTextureLodBias = MAX_TEXTURE_LOD_BIAS;
1016 ctx->Const.MaxArrayLockSize = MAX_ARRAY_LOCK_SIZE;
1017 ctx->Const.SubPixelBits = SUB_PIXEL_BITS;
1018 ctx->Const.MinPointSize = MIN_POINT_SIZE;
1019 ctx->Const.MaxPointSize = MAX_POINT_SIZE;
1020 ctx->Const.MinPointSizeAA = MIN_POINT_SIZE;
1021 ctx->Const.MaxPointSizeAA = MAX_POINT_SIZE;
1022 ctx->Const.PointSizeGranularity = (GLfloat) POINT_SIZE_GRANULARITY;
1023 ctx->Const.MinLineWidth = MIN_LINE_WIDTH;
1024 ctx->Const.MaxLineWidth = MAX_LINE_WIDTH;
1025 ctx->Const.MinLineWidthAA = MIN_LINE_WIDTH;
1026 ctx->Const.MaxLineWidthAA = MAX_LINE_WIDTH;
1027 ctx->Const.LineWidthGranularity = (GLfloat) LINE_WIDTH_GRANULARITY;
1028 ctx->Const.NumAuxBuffers = NUM_AUX_BUFFERS;
1029 ctx->Const.MaxColorTableSize = MAX_COLOR_TABLE_SIZE;
1030 ctx->Const.MaxConvolutionWidth = MAX_CONVOLUTION_WIDTH;
1031 ctx->Const.MaxConvolutionHeight = MAX_CONVOLUTION_HEIGHT;
1032 ctx->Const.MaxClipPlanes = MAX_CLIP_PLANES;
1033 ctx->Const.MaxLights = MAX_LIGHTS;
1034 ctx->Const.MaxSpotExponent = 128.0;
1035 ctx->Const.MaxShininess = 128.0;
1036 #if FEATURE_ARB_vertex_program
1037 ctx->Const.MaxVertexProgramInstructions = MAX_NV_VERTEX_PROGRAM_INSTRUCTIONS;
1038 ctx->Const.MaxVertexProgramAttribs = MAX_NV_VERTEX_PROGRAM_INPUTS;
1039 ctx->Const.MaxVertexProgramTemps = MAX_NV_VERTEX_PROGRAM_TEMPS;
1040 ctx->Const.MaxVertexProgramLocalParams = MAX_NV_VERTEX_PROGRAM_PARAMS;
1041 ctx->Const.MaxVertexProgramEnvParams = MAX_NV_VERTEX_PROGRAM_PARAMS;/*XXX*/
1042 ctx->Const.MaxVertexProgramAddressRegs = MAX_VERTEX_PROGRAM_ADDRESS_REGS;
1043 #endif
1044 #if FEATURE_ARB_fragment_program
1045 ctx->Const.MaxFragmentProgramInstructions = MAX_NV_FRAGMENT_PROGRAM_INSTRUCTIONS;
1046 ctx->Const.MaxFragmentProgramAttribs = MAX_NV_FRAGMENT_PROGRAM_INPUTS;
1047 ctx->Const.MaxFragmentProgramTemps = MAX_NV_FRAGMENT_PROGRAM_TEMPS;
1048 ctx->Const.MaxFragmentProgramLocalParams = MAX_NV_FRAGMENT_PROGRAM_PARAMS;
1049 ctx->Const.MaxFragmentProgramEnvParams = MAX_NV_FRAGMENT_PROGRAM_PARAMS;/*XXX*/
1050 ctx->Const.MaxFragmentProgramAddressRegs = MAX_FRAGMENT_PROGRAM_ADDRESS_REGS;
1051 ctx->Const.MaxFragmentProgramAluInstructions = MAX_FRAGMENT_PROGRAM_ALU_INSTRUCTIONS;
1052 ctx->Const.MaxFragmentProgramTexInstructions = MAX_FRAGMENT_PROGRAM_TEX_INSTRUCTIONS;
1053 ctx->Const.MaxFragmentProgramTexIndirections = MAX_FRAGMENT_PROGRAM_TEX_INDIRECTIONS;
1054 #endif
1055 ctx->Const.MaxProgramMatrices = MAX_PROGRAM_MATRICES;
1056 ctx->Const.MaxProgramMatrixStackDepth = MAX_PROGRAM_MATRIX_STACK_DEPTH;
1057
1058 /* If we're running in the X server, do bounds checking to prevent
1059 * segfaults and server crashes!
1060 */
1061 #if defined(XFree86LOADER) && defined(IN_MODULE)
1062 ctx->Const.CheckArrayBounds = GL_TRUE;
1063 #else
1064 ctx->Const.CheckArrayBounds = GL_FALSE;
1065 #endif
1066
1067 ASSERT(ctx->Const.MaxTextureUnits == MAX2(ctx->Const.MaxTextureImageUnits, ctx->Const.MaxTextureCoordUnits));
1068 }
1069
1070 /**
1071 * Initialize the attribute groups in a GL context.
1072 *
1073 * \param ctx GL context.
1074 *
1075 * Initializes all the attributes, calling the respective <tt>init*</tt>
1076 * functions for the more complex data structures.
1077 */
1078 static GLboolean
1079 init_attrib_groups( GLcontext *ctx )
1080 {
1081 assert(ctx);
1082
1083 /* Constants */
1084 _mesa_init_constants( ctx );
1085
1086 /* Extensions */
1087 _mesa_init_extensions( ctx );
1088
1089 /* Attribute Groups */
1090 _mesa_init_accum( ctx );
1091 _mesa_init_attrib( ctx );
1092 _mesa_init_buffers( ctx );
1093 _mesa_init_buffer_objects( ctx );
1094 _mesa_init_color( ctx );
1095 _mesa_init_colortables( ctx );
1096 _mesa_init_current( ctx );
1097 _mesa_init_depth( ctx );
1098 _mesa_init_debug( ctx );
1099 _mesa_init_display_list( ctx );
1100 _mesa_init_eval( ctx );
1101 _mesa_init_feedback( ctx );
1102 _mesa_init_fog( ctx );
1103 _mesa_init_histogram( ctx );
1104 _mesa_init_hint( ctx );
1105 _mesa_init_line( ctx );
1106 _mesa_init_lighting( ctx );
1107 _mesa_init_matrix( ctx );
1108 _mesa_init_occlude( ctx );
1109 _mesa_init_pixel( ctx );
1110 _mesa_init_point( ctx );
1111 _mesa_init_polygon( ctx );
1112 _mesa_init_program( ctx );
1113 _mesa_init_rastpos( ctx );
1114 _mesa_init_stencil( ctx );
1115 _mesa_init_transform( ctx );
1116 _mesa_init_varray( ctx );
1117 _mesa_init_viewport( ctx );
1118
1119 if (!_mesa_init_texture( ctx ))
1120 return GL_FALSE;
1121
1122 /* Miscellaneous */
1123 ctx->NewState = _NEW_ALL;
1124 ctx->ErrorValue = (GLenum) GL_NO_ERROR;
1125 ctx->CatchSignals = GL_TRUE;
1126 ctx->_Facing = 0;
1127
1128 return GL_TRUE;
1129 }
1130
1131
1132 /**
1133 * If the DRI libGL.so library is old, it may not have the entrypoints for
1134 * some recent OpenGL extensions. Dynamically add them now.
1135 * If we're building stand-alone Mesa where libGL.so has both the dispatcher
1136 * and driver code, this won't be an issue (and calling this function won't
1137 * do any harm).
1138 */
1139 static void
1140 add_newer_entrypoints(void)
1141 {
1142 unsigned i;
1143 static const struct {
1144 const char * const name;
1145 unsigned offset;
1146 }
1147 newer_entrypoints[] = {
1148 /* GL_ARB_window_pos aliases with GL_MESA_window_pos */
1149 { "glWindowPos2dARB", 513 },
1150 { "glWindowPos2dvARB", 514 },
1151 { "glWindowPos2fARB", 515 },
1152 { "glWindowPos2fvARB", 516 },
1153 { "glWindowPos2iARB", 517 },
1154 { "glWindowPos2ivARB", 518 },
1155 { "glWindowPos2sARB", 519 },
1156 { "glWindowPos2svARB", 520 },
1157 { "glWindowPos3dARB", 521 },
1158 { "glWindowPos3dvARB", 522 },
1159 { "glWindowPos3fARB", 523 },
1160 { "glWindowPos3fvARB", 524 },
1161 { "glWindowPos3iARB", 525 },
1162 { "glWindowPos3ivARB", 526 },
1163 { "glWindowPos3sARB", 527 },
1164 { "glWindowPos3svARB", 528 },
1165 #if FEATURE_NV_vertex_program
1166 { "glAreProgramsResidentNV", 578 },
1167 { "glBindProgramNV", 579 },
1168 { "glDeleteProgramsNV", 580 },
1169 { "glExecuteProgramNV", 581 },
1170 { "glGenProgramsNV", 582 },
1171 { "glGetProgramParameterdvNV", 583 },
1172 { "glGetProgramParameterfvNV", 584 },
1173 { "glGetProgramivNV", 585 },
1174 { "glGetProgramStringNV", 586 },
1175 { "glGetTrackMatrixivNV", 587 },
1176 { "glGetVertexAttribdvNV", 588 },
1177 { "glGetVertexAttribfvNV", 589 },
1178 { "glGetVertexAttribivNV", 590 },
1179 { "glGetVertexAttribPointervNV", 591 },
1180 { "glIsProgramNV", 592 },
1181 { "glLoadProgramNV", 593 },
1182 { "glProgramParameter4dNV", 594 },
1183 { "glProgramParameter4dvNV", 595 },
1184 { "glProgramParameter4fNV", 596 },
1185 { "glProgramParameter4fvNV", 597 },
1186 { "glProgramParameters4dvNV", 598 },
1187 { "glProgramParameters4fvNV", 599 },
1188 { "glRequestResidentProgramsNV", 600 },
1189 { "glTrackMatrixNV", 601 },
1190 { "glVertexAttribPointerNV", 602 },
1191 { "glVertexAttrib1dNV", 603 },
1192 { "glVertexAttrib1dvNV", 604 },
1193 { "glVertexAttrib1fNV", 605 },
1194 { "glVertexAttrib1fvNV", 606 },
1195 { "glVertexAttrib1sNV", 607 },
1196 { "glVertexAttrib1svNV", 608 },
1197 { "glVertexAttrib2dNV", 609 },
1198 { "glVertexAttrib2dvNV", 610 },
1199 { "glVertexAttrib2fNV", 611 },
1200 { "glVertexAttrib2fvNV", 612 },
1201 { "glVertexAttrib2sNV", 613 },
1202 { "glVertexAttrib2svNV", 614 },
1203 { "glVertexAttrib3dNV", 615 },
1204 { "glVertexAttrib3dvNV", 616 },
1205 { "glVertexAttrib3fNV", 617 },
1206 { "glVertexAttrib3fvNV", 618 },
1207 { "glVertexAttrib3sNV", 619 },
1208 { "glVertexAttrib3svNV", 620 },
1209 { "glVertexAttrib4dNV", 621 },
1210 { "glVertexAttrib4dvNV", 622 },
1211 { "glVertexAttrib4fNV", 623 },
1212 { "glVertexAttrib4fvNV", 624 },
1213 { "glVertexAttrib4sNV", 625 },
1214 { "glVertexAttrib4svNV", 626 },
1215 { "glVertexAttrib4ubNV", 627 },
1216 { "glVertexAttrib4ubvNV", 628 },
1217 { "glVertexAttribs1dvNV", 629 },
1218 { "glVertexAttribs1fvNV", 630 },
1219 { "glVertexAttribs1svNV", 631 },
1220 { "glVertexAttribs2dvNV", 632 },
1221 { "glVertexAttribs2fvNV", 633 },
1222 { "glVertexAttribs2svNV", 634 },
1223 { "glVertexAttribs3dvNV", 635 },
1224 { "glVertexAttribs3fvNV", 636 },
1225 { "glVertexAttribs3svNV", 637 },
1226 { "glVertexAttribs4dvNV", 638 },
1227 { "glVertexAttribs4fvNV", 639 },
1228 { "glVertexAttribs4svNV", 640 },
1229 { "glVertexAttribs4ubvNV", 641 },
1230 #endif
1231 { "glPointParameteriNV", 642 },
1232 { "glPointParameterivNV", 643 },
1233 { "glMultiDrawArraysEXT", 644 },
1234 { "glMultiDrawElementsEXT", 645 },
1235 { "glMultiDrawArraysSUN", _gloffset_MultiDrawArraysEXT },
1236 { "glMultiDrawElementsSUN", _gloffset_MultiDrawElementsEXT },
1237 { "glActiveStencilFaceEXT", 646 },
1238 #if FEATURE_NV_fence
1239 { "glDeleteFencesNV", 647 },
1240 { "glGenFencesNV", 648 },
1241 { "glIsFenceNV", 649 },
1242 { "glTestFenceNV", 650 },
1243 { "glGetFenceivNV", 651 },
1244 { "glFinishFenceNV", 652 },
1245 { "glSetFenceNV", 653 },
1246 #endif
1247 #if FEATURE_NV_fragment_program
1248 { "glProgramNamedParameter4fNV", 682 },
1249 { "glProgramNamedParameter4dNV", 683 },
1250 { "glProgramNamedParameter4fvNV", 683 },
1251 { "glProgramNamedParameter4dvNV", 684 },
1252 { "glGetProgramNamedParameterfvNV", 685 },
1253 { "glGetProgramNamedParameterdvNV", 686 },
1254 #endif
1255 #if FEATURE_ARB_vertex_program
1256 { "glVertexAttrib1sARB", _gloffset_VertexAttrib1sNV },
1257 { "glVertexAttrib1fARB", _gloffset_VertexAttrib1fNV },
1258 { "glVertexAttrib1dARB", _gloffset_VertexAttrib1dNV },
1259 { "glVertexAttrib2sARB", _gloffset_VertexAttrib2sNV },
1260 { "glVertexAttrib2fARB", _gloffset_VertexAttrib2fNV },
1261 { "glVertexAttrib2dARB", _gloffset_VertexAttrib2dNV },
1262 { "glVertexAttrib3sARB", _gloffset_VertexAttrib3sNV },
1263 { "glVertexAttrib3fARB", _gloffset_VertexAttrib3fNV },
1264 { "glVertexAttrib3dARB", _gloffset_VertexAttrib3dNV },
1265 { "glVertexAttrib4sARB", _gloffset_VertexAttrib4sNV },
1266 { "glVertexAttrib4fARB", _gloffset_VertexAttrib4fNV },
1267 { "glVertexAttrib4dARB", _gloffset_VertexAttrib4dNV },
1268 { "glVertexAttrib4NubARB", _gloffset_VertexAttrib4ubNV },
1269 { "glVertexAttrib1svARB", _gloffset_VertexAttrib1svNV },
1270 { "glVertexAttrib1fvARB", _gloffset_VertexAttrib1fvNV },
1271 { "glVertexAttrib1dvARB", _gloffset_VertexAttrib1dvNV },
1272 { "glVertexAttrib2svARB", _gloffset_VertexAttrib2svNV },
1273 { "glVertexAttrib2fvARB", _gloffset_VertexAttrib2fvNV },
1274 { "glVertexAttrib2dvARB", _gloffset_VertexAttrib2dvNV },
1275 { "glVertexAttrib3svARB", _gloffset_VertexAttrib3svNV },
1276 { "glVertexAttrib3fvARB", _gloffset_VertexAttrib3fvNV },
1277 { "glVertexAttrib3dvARB", _gloffset_VertexAttrib3dvNV },
1278 { "glVertexAttrib4bvARB", _gloffset_VertexAttrib4bvARB },
1279 { "glVertexAttrib4svARB", _gloffset_VertexAttrib4svNV },
1280 { "glVertexAttrib4ivARB", _gloffset_VertexAttrib4ivARB },
1281 { "glVertexAttrib4ubvARB", _gloffset_VertexAttrib4ubvARB },
1282 { "glVertexAttrib4usvARB", _gloffset_VertexAttrib4usvARB },
1283 { "glVertexAttrib4uivARB", _gloffset_VertexAttrib4uivARB },
1284 { "glVertexAttrib4fvARB", _gloffset_VertexAttrib4fvNV },
1285 { "glVertexAttrib4dvARB", _gloffset_VertexAttrib4dvNV },
1286 { "glVertexAttrib4NbvARB", _gloffset_VertexAttrib4NbvARB },
1287 { "glVertexAttrib4NsvARB", _gloffset_VertexAttrib4NsvARB },
1288 { "glVertexAttrib4NivARB", _gloffset_VertexAttrib4NivARB },
1289 { "glVertexAttrib4NubvARB", _gloffset_VertexAttrib4ubvNV },
1290 { "glVertexAttrib4NusvARB", _gloffset_VertexAttrib4NusvARB },
1291 { "glVertexAttrib4NuivARB", _gloffset_VertexAttrib4NuivARB },
1292 { "glVertexAttribPointerARB", _gloffset_VertexAttribPointerARB },
1293 { "glEnableVertexAttribArrayARB", _gloffset_EnableVertexAttribArrayARB },
1294 { "glDisableVertexAttribArrayARB", _gloffset_DisableVertexAttribArrayARB },
1295 { "glProgramStringARB", _gloffset_ProgramStringARB },
1296 { "glBindProgramARB", _gloffset_BindProgramNV },
1297 { "glDeleteProgramsARB", _gloffset_DeleteProgramsNV },
1298 { "glGenProgramsARB", _gloffset_GenProgramsNV },
1299 { "glIsProgramARB", _gloffset_IsProgramNV },
1300 { "glProgramEnvParameter4dARB", _gloffset_ProgramEnvParameter4dARB },
1301 { "glProgramEnvParameter4dvARB", _gloffset_ProgramEnvParameter4dvARB },
1302 { "glProgramEnvParameter4fARB", _gloffset_ProgramEnvParameter4fARB },
1303 { "glProgramEnvParameter4fvARB", _gloffset_ProgramEnvParameter4fvARB },
1304 { "glProgramLocalParameter4dARB", _gloffset_ProgramLocalParameter4dARB },
1305 { "glProgramLocalParameter4dvARB", _gloffset_ProgramLocalParameter4dvARB },
1306 { "glProgramLocalParameter4fARB", _gloffset_ProgramLocalParameter4fARB },
1307 { "glProgramLocalParameter4fvARB", _gloffset_ProgramLocalParameter4fvARB },
1308 { "glGetProgramEnvParameterdvARB", _gloffset_GetProgramEnvParameterdvARB },
1309 { "glGetProgramEnvParameterfvARB", _gloffset_GetProgramEnvParameterfvARB },
1310 { "glGetProgramLocalParameterdvARB", _gloffset_GetProgramLocalParameterdvARB },
1311 { "glGetProgramLocalParameterfvARB", _gloffset_GetProgramLocalParameterfvARB },
1312 { "glGetProgramivARB", _gloffset_GetProgramivARB },
1313 { "glGetProgramStringARB", _gloffset_GetProgramStringARB },
1314 { "glGetVertexAttribdvARB", _gloffset_GetVertexAttribdvNV },
1315 { "glGetVertexAttribfvARB", _gloffset_GetVertexAttribfvNV },
1316 { "glGetVertexAttribivARB", _gloffset_GetVertexAttribivNV },
1317 { "glGetVertexAttribPointervARB", _gloffset_GetVertexAttribPointervNV },
1318 #endif
1319 { "glMultiModeDrawArraysIBM", _gloffset_MultiModeDrawArraysIBM },
1320 { "glMultiModeDrawElementsIBM", _gloffset_MultiModeDrawElementsIBM },
1321 };
1322
1323 for ( i = 0 ; i < Elements(newer_entrypoints) ; i++ ) {
1324 _glapi_add_entrypoint( newer_entrypoints[i].name,
1325 newer_entrypoints[i].offset );
1326 }
1327 }
1328
1329
1330 /**
1331 * Initialize a GLcontext struct (rendering context).
1332 *
1333 * This includes allocating all the other structs and arrays which hang off of
1334 * the context by pointers.
1335 * Note that the driver needs to pass in its dd_function_table here since
1336 * we need to at least call driverFunctions->NewTextureObject to create the
1337 * default texture objects.
1338 *
1339 * Called by _mesa_create_context().
1340 *
1341 * Performs the imports and exports callback tables initialization, and
1342 * miscellaneous one-time initializations. If no shared context is supplied one
1343 * is allocated, and increase its reference count. Setups the GL API dispatch
1344 * tables. Initialize the TNL module. Sets the maximum Z buffer depth.
1345 * Finally queries the \c MESA_DEBUG and \c MESA_VERBOSE environment variables
1346 * for debug flags.
1347 *
1348 * \param ctx the context to initialize
1349 * \param visual describes the visual attributes for this context
1350 * \param share_list points to context to share textures, display lists,
1351 * etc with, or NULL
1352 * \param driverFunctions table of device driver functions for this context
1353 * to use
1354 * \param driverContext pointer to driver-specific context data
1355 */
1356 GLboolean
1357 _mesa_initialize_context( GLcontext *ctx,
1358 const GLvisual *visual,
1359 GLcontext *share_list,
1360 const struct dd_function_table *driverFunctions,
1361 void *driverContext )
1362 {
1363 GLuint dispatchSize;
1364
1365 ASSERT(driverContext);
1366 assert(driverFunctions->NewTextureObject);
1367
1368 /* If the driver wants core Mesa to use special imports, it'll have to
1369 * override these defaults.
1370 */
1371 _mesa_init_default_imports( &(ctx->imports), driverContext );
1372
1373 /* initialize the exports (Mesa functions called by the window system) */
1374 _mesa_init_default_exports( &(ctx->exports) );
1375
1376 /* misc one-time initializations */
1377 one_time_init(ctx);
1378
1379 ctx->Visual = *visual;
1380 ctx->DrawBuffer = NULL;
1381 ctx->ReadBuffer = NULL;
1382
1383 /* Plug in driver functions and context pointer here.
1384 * This is important because when we call alloc_shared_state() below
1385 * we'll call ctx->Driver.NewTextureObject() to create the default
1386 * textures.
1387 */
1388 ctx->Driver = *driverFunctions;
1389 ctx->DriverCtx = driverContext;
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 _mesa_install_save_vtxfmt( ctx, &ctx->ListState.ListVtxfmt );
1435
1436
1437 /* Neutral tnl module stuff */
1438 _mesa_init_exec_vtxfmt( ctx );
1439 ctx->TnlModule.Current = NULL;
1440 ctx->TnlModule.SwapCount = 0;
1441 #endif
1442
1443 return GL_TRUE;
1444 }
1445
1446
1447 /**
1448 * Allocate and initialize a GLcontext structure.
1449 * Note that the driver needs to pass in its dd_function_table here since
1450 * we need to at least call driverFunctions->NewTextureObject to initialize
1451 * the rendering context.
1452 *
1453 * \param visual a GLvisual pointer (we copy the struct contents)
1454 * \param share_list another context to share display lists with or NULL
1455 * \param driverFunctions points to the dd_function_table into which the
1456 * driver has plugged in all its special functions.
1457 * \param driverCtx points to the device driver's private context state
1458 *
1459 * \return pointer to a new __GLcontextRec or NULL if error.
1460 */
1461 GLcontext *
1462 _mesa_create_context( const GLvisual *visual,
1463 GLcontext *share_list,
1464 const struct dd_function_table *driverFunctions,
1465 void *driverContext )
1466
1467 {
1468 GLcontext *ctx;
1469
1470 ASSERT(visual);
1471 ASSERT(driverContext);
1472
1473 ctx = (GLcontext *) _mesa_calloc(sizeof(GLcontext));
1474 if (!ctx)
1475 return NULL;
1476
1477 if (_mesa_initialize_context(ctx, visual, share_list,
1478 driverFunctions, driverContext)) {
1479 return ctx;
1480 }
1481 else {
1482 _mesa_free(ctx);
1483 return NULL;
1484 }
1485 }
1486
1487
1488 /**
1489 * Free the data associated with the given context.
1490 *
1491 * But doesn't free the GLcontext struct itself.
1492 *
1493 * \sa _mesa_initialize_context() and init_attrib_groups().
1494 */
1495 void
1496 _mesa_free_context_data( GLcontext *ctx )
1497 {
1498 /* if we're destroying the current context, unbind it first */
1499 if (ctx == _mesa_get_current_context()) {
1500 _mesa_make_current(NULL, NULL);
1501 }
1502
1503 _mesa_free_lighting_data( ctx );
1504 _mesa_free_eval_data( ctx );
1505 _mesa_free_texture_data( ctx );
1506 _mesa_free_matrix_data( ctx );
1507 _mesa_free_viewport_data( ctx );
1508 _mesa_free_colortables_data( ctx );
1509 #if FEATURE_NV_vertex_program
1510 if (ctx->VertexProgram.Current) {
1511 ctx->VertexProgram.Current->Base.RefCount--;
1512 if (ctx->VertexProgram.Current->Base.RefCount <= 0)
1513 _mesa_delete_program(ctx, &(ctx->VertexProgram.Current->Base));
1514 }
1515 #endif
1516 #if FEATURE_NV_fragment_program
1517 if (ctx->FragmentProgram.Current) {
1518 ctx->FragmentProgram.Current->Base.RefCount--;
1519 if (ctx->FragmentProgram.Current->Base.RefCount <= 0)
1520 _mesa_delete_program(ctx, &(ctx->FragmentProgram.Current->Base));
1521 }
1522 #endif
1523
1524 /* Shared context state (display lists, textures, etc) */
1525 _glthread_LOCK_MUTEX(ctx->Shared->Mutex);
1526 ctx->Shared->RefCount--;
1527 assert(ctx->Shared->RefCount >= 0);
1528 _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex);
1529 if (ctx->Shared->RefCount == 0) {
1530 /* free shared state */
1531 free_shared_state( ctx, ctx->Shared );
1532 }
1533
1534 if (ctx->Extensions.String)
1535 FREE((void *) ctx->Extensions.String);
1536
1537 FREE(ctx->Exec);
1538 FREE(ctx->Save);
1539 }
1540
1541
1542 /**
1543 * Destroy a GLcontext structure.
1544 *
1545 * \param ctx GL context.
1546 *
1547 * Calls _mesa_free_context_data() and frees the GLcontext structure itself.
1548 */
1549 void
1550 _mesa_destroy_context( GLcontext *ctx )
1551 {
1552 if (ctx) {
1553 _mesa_free_context_data(ctx);
1554 FREE( (void *) ctx );
1555 }
1556 }
1557
1558
1559 #if _HAVE_FULL_GL
1560 /**
1561 * Copy attribute groups from one context to another.
1562 *
1563 * \param src source context
1564 * \param dst destination context
1565 * \param mask bitwise OR of GL_*_BIT flags
1566 *
1567 * According to the bits specified in \p mask, copies the corresponding
1568 * attributes from \p src into \dst. For many of the attributes a simple \c
1569 * memcpy is not enough due to the existence of internal pointers in their data
1570 * structures.
1571 */
1572 void
1573 _mesa_copy_context( const GLcontext *src, GLcontext *dst, GLuint mask )
1574 {
1575 if (mask & GL_ACCUM_BUFFER_BIT) {
1576 /* OK to memcpy */
1577 dst->Accum = src->Accum;
1578 }
1579 if (mask & GL_COLOR_BUFFER_BIT) {
1580 /* OK to memcpy */
1581 dst->Color = src->Color;
1582 }
1583 if (mask & GL_CURRENT_BIT) {
1584 /* OK to memcpy */
1585 dst->Current = src->Current;
1586 }
1587 if (mask & GL_DEPTH_BUFFER_BIT) {
1588 /* OK to memcpy */
1589 dst->Depth = src->Depth;
1590 }
1591 if (mask & GL_ENABLE_BIT) {
1592 /* no op */
1593 }
1594 if (mask & GL_EVAL_BIT) {
1595 /* OK to memcpy */
1596 dst->Eval = src->Eval;
1597 }
1598 if (mask & GL_FOG_BIT) {
1599 /* OK to memcpy */
1600 dst->Fog = src->Fog;
1601 }
1602 if (mask & GL_HINT_BIT) {
1603 /* OK to memcpy */
1604 dst->Hint = src->Hint;
1605 }
1606 if (mask & GL_LIGHTING_BIT) {
1607 GLuint i;
1608 /* begin with memcpy */
1609 MEMCPY( &dst->Light, &src->Light, sizeof(struct gl_light) );
1610 /* fixup linked lists to prevent pointer insanity */
1611 make_empty_list( &(dst->Light.EnabledList) );
1612 for (i = 0; i < MAX_LIGHTS; i++) {
1613 if (dst->Light.Light[i].Enabled) {
1614 insert_at_tail(&(dst->Light.EnabledList), &(dst->Light.Light[i]));
1615 }
1616 }
1617 }
1618 if (mask & GL_LINE_BIT) {
1619 /* OK to memcpy */
1620 dst->Line = src->Line;
1621 }
1622 if (mask & GL_LIST_BIT) {
1623 /* OK to memcpy */
1624 dst->List = src->List;
1625 }
1626 if (mask & GL_PIXEL_MODE_BIT) {
1627 /* OK to memcpy */
1628 dst->Pixel = src->Pixel;
1629 }
1630 if (mask & GL_POINT_BIT) {
1631 /* OK to memcpy */
1632 dst->Point = src->Point;
1633 }
1634 if (mask & GL_POLYGON_BIT) {
1635 /* OK to memcpy */
1636 dst->Polygon = src->Polygon;
1637 }
1638 if (mask & GL_POLYGON_STIPPLE_BIT) {
1639 /* Use loop instead of MEMCPY due to problem with Portland Group's
1640 * C compiler. Reported by John Stone.
1641 */
1642 GLuint i;
1643 for (i = 0; i < 32; i++) {
1644 dst->PolygonStipple[i] = src->PolygonStipple[i];
1645 }
1646 }
1647 if (mask & GL_SCISSOR_BIT) {
1648 /* OK to memcpy */
1649 dst->Scissor = src->Scissor;
1650 }
1651 if (mask & GL_STENCIL_BUFFER_BIT) {
1652 /* OK to memcpy */
1653 dst->Stencil = src->Stencil;
1654 }
1655 if (mask & GL_TEXTURE_BIT) {
1656 /* Cannot memcpy because of pointers */
1657 _mesa_copy_texture_state(src, dst);
1658 }
1659 if (mask & GL_TRANSFORM_BIT) {
1660 /* OK to memcpy */
1661 dst->Transform = src->Transform;
1662 }
1663 if (mask & GL_VIEWPORT_BIT) {
1664 /* Cannot use memcpy, because of pointers in GLmatrix _WindowMap */
1665 dst->Viewport.X = src->Viewport.X;
1666 dst->Viewport.Y = src->Viewport.Y;
1667 dst->Viewport.Width = src->Viewport.Width;
1668 dst->Viewport.Height = src->Viewport.Height;
1669 dst->Viewport.Near = src->Viewport.Near;
1670 dst->Viewport.Far = src->Viewport.Far;
1671 _math_matrix_copy(&dst->Viewport._WindowMap, &src->Viewport._WindowMap);
1672 }
1673
1674 /* XXX FIXME: Call callbacks?
1675 */
1676 dst->NewState = _NEW_ALL;
1677 }
1678 #endif
1679
1680
1681 /**
1682 * Check if the given context can render into the given framebuffer
1683 * by checking visual attributes.
1684 * \return GL_TRUE if compatible, GL_FALSE otherwise.
1685 */
1686 static GLboolean
1687 check_compatible(const GLcontext *ctx, const GLframebuffer *buffer)
1688 {
1689 const GLvisual *ctxvis = &ctx->Visual;
1690 const GLvisual *bufvis = &buffer->Visual;
1691
1692 if (ctxvis == bufvis)
1693 return GL_TRUE;
1694
1695 if (ctxvis->rgbMode != bufvis->rgbMode)
1696 return GL_FALSE;
1697 if (ctxvis->doubleBufferMode && !bufvis->doubleBufferMode)
1698 return GL_FALSE;
1699 if (ctxvis->stereoMode && !bufvis->stereoMode)
1700 return GL_FALSE;
1701 if (ctxvis->haveAccumBuffer && !bufvis->haveAccumBuffer)
1702 return GL_FALSE;
1703 if (ctxvis->haveDepthBuffer && !bufvis->haveDepthBuffer)
1704 return GL_FALSE;
1705 if (ctxvis->haveStencilBuffer && !bufvis->haveStencilBuffer)
1706 return GL_FALSE;
1707 if (ctxvis->redMask && ctxvis->redMask != bufvis->redMask)
1708 return GL_FALSE;
1709 if (ctxvis->greenMask && ctxvis->greenMask != bufvis->greenMask)
1710 return GL_FALSE;
1711 if (ctxvis->blueMask && ctxvis->blueMask != bufvis->blueMask)
1712 return GL_FALSE;
1713 if (ctxvis->depthBits && ctxvis->depthBits != bufvis->depthBits)
1714 return GL_FALSE;
1715 if (ctxvis->stencilBits && ctxvis->stencilBits != bufvis->stencilBits)
1716 return GL_FALSE;
1717
1718 return GL_TRUE;
1719 }
1720
1721
1722 /**
1723 * Set the current context, binding the given frame buffer to the context.
1724 *
1725 * \param newCtx new GL context.
1726 * \param buffer framebuffer.
1727 *
1728 * Calls _mesa_make_current2() with \p buffer as read and write framebuffer.
1729 */
1730 void
1731 _mesa_make_current( GLcontext *newCtx, GLframebuffer *buffer )
1732 {
1733 _mesa_make_current2( newCtx, buffer, buffer );
1734 }
1735
1736 /**
1737 * Bind the given context to the given draw-buffer and read-buffer and
1738 * make it the current context for this thread.
1739 *
1740 * \param newCtx new GL context. If NULL then there will be no current GL
1741 * context.
1742 * \param drawBuffer draw framebuffer.
1743 * \param readBuffer read framebuffer.
1744 *
1745 * Check that the context's and framebuffer's visuals are compatible, returning
1746 * immediately otherwise. Sets the glapi current context via
1747 * _glapi_set_context(). If \p newCtx is not NULL, associates \p drawBuffer and
1748 * \p readBuffer with it and calls dd_function_table::ResizeBuffers if the buffers size has changed.
1749 * Calls dd_function_table::MakeCurrent callback if defined.
1750 *
1751 * When a context is bound by the first time and the \c MESA_INFO environment
1752 * variable is set it calls print_info() as an aid for remote user
1753 * troubleshooting.
1754 */
1755 void
1756 _mesa_make_current2( GLcontext *newCtx, GLframebuffer *drawBuffer,
1757 GLframebuffer *readBuffer )
1758 {
1759 if (MESA_VERBOSE)
1760 _mesa_debug(newCtx, "_mesa_make_current2()\n");
1761
1762 /* Check that the context's and framebuffer's visuals are compatible.
1763 */
1764 if (newCtx && drawBuffer && newCtx->DrawBuffer != drawBuffer) {
1765 if (!check_compatible(newCtx, drawBuffer))
1766 return;
1767 }
1768 if (newCtx && readBuffer && newCtx->ReadBuffer != readBuffer) {
1769 if (!check_compatible(newCtx, readBuffer))
1770 return;
1771 }
1772
1773 /* We call this function periodically (just here for now) in
1774 * order to detect when multithreading has begun.
1775 */
1776 _glapi_check_multithread();
1777
1778 _glapi_set_context((void *) newCtx);
1779 ASSERT(_mesa_get_current_context() == newCtx);
1780
1781
1782 if (!newCtx) {
1783 _glapi_set_dispatch(NULL); /* none current */
1784 }
1785 else {
1786 _glapi_set_dispatch(newCtx->CurrentDispatch);
1787
1788 if (drawBuffer && readBuffer) {
1789 /* TODO: check if newCtx and buffer's visual match??? */
1790 newCtx->DrawBuffer = drawBuffer;
1791 newCtx->ReadBuffer = readBuffer;
1792 newCtx->NewState |= _NEW_BUFFERS;
1793
1794 #if _HAVE_FULL_GL
1795 if (drawBuffer->Width == 0 && drawBuffer->Height == 0) {
1796 /* get initial window size */
1797 GLuint bufWidth, bufHeight;
1798
1799 /* ask device driver for size of output buffer */
1800 (*newCtx->Driver.GetBufferSize)( drawBuffer, &bufWidth, &bufHeight );
1801
1802 if (drawBuffer->Width != bufWidth ||
1803 drawBuffer->Height != bufHeight) {
1804
1805 drawBuffer->Width = bufWidth;
1806 drawBuffer->Height = bufHeight;
1807
1808 newCtx->Driver.ResizeBuffers( drawBuffer );
1809 }
1810 }
1811
1812 if (readBuffer != drawBuffer &&
1813 readBuffer->Width == 0 && readBuffer->Height == 0) {
1814 /* get initial window size */
1815 GLuint bufWidth, bufHeight;
1816
1817 /* ask device driver for size of output buffer */
1818 (*newCtx->Driver.GetBufferSize)( readBuffer, &bufWidth, &bufHeight );
1819
1820 if (readBuffer->Width != bufWidth ||
1821 readBuffer->Height != bufHeight) {
1822
1823 readBuffer->Width = bufWidth;
1824 readBuffer->Height = bufHeight;
1825
1826 newCtx->Driver.ResizeBuffers( readBuffer );
1827 }
1828 }
1829 #endif
1830 }
1831
1832 /* Alert the driver - usually passed on to the sw t&l module,
1833 * but also used to detect threaded cases in the radeon codegen
1834 * hw t&l module.
1835 */
1836 if (newCtx->Driver.MakeCurrent)
1837 newCtx->Driver.MakeCurrent( newCtx, drawBuffer, readBuffer );
1838
1839 /* We can use this to help debug user's problems. Tell them to set
1840 * the MESA_INFO env variable before running their app. Then the
1841 * first time each context is made current we'll print some useful
1842 * information.
1843 */
1844 if (newCtx->FirstTimeCurrent) {
1845 if (_mesa_getenv("MESA_INFO")) {
1846 _mesa_print_info();
1847 }
1848 newCtx->FirstTimeCurrent = GL_FALSE;
1849 }
1850 }
1851 }
1852
1853 /**
1854 * Get current context for the calling thread.
1855 *
1856 * \return pointer to the current GL context.
1857 *
1858 * Calls _glapi_get_context(). This isn't the fastest way to get the current
1859 * context. If you need speed, see the #GET_CURRENT_CONTEXT macro in context.h.
1860 */
1861 GLcontext *
1862 _mesa_get_current_context( void )
1863 {
1864 return (GLcontext *) _glapi_get_context();
1865 }
1866
1867 /**
1868 * Get context's current API dispatch table.
1869 *
1870 * It'll either be the immediate-mode execute dispatcher or the display list
1871 * compile dispatcher.
1872 *
1873 * \param ctx GL context.
1874 *
1875 * \return pointer to dispatch_table.
1876 *
1877 * Simply returns __GLcontextRec::CurrentDispatch.
1878 */
1879 struct _glapi_table *
1880 _mesa_get_dispatch(GLcontext *ctx)
1881 {
1882 return ctx->CurrentDispatch;
1883 }
1884
1885 /*@}*/
1886
1887
1888 /**********************************************************************/
1889 /** \name Miscellaneous functions */
1890 /**********************************************************************/
1891 /*@{*/
1892
1893 /**
1894 * Record an error.
1895 *
1896 * \param ctx GL context.
1897 * \param error error code.
1898 *
1899 * Records the given error code and call the driver's dd_function_table::Error
1900 * function if defined.
1901 *
1902 * \sa
1903 * This is called via _mesa_error().
1904 */
1905 void
1906 _mesa_record_error( GLcontext *ctx, GLenum error )
1907 {
1908 if (!ctx)
1909 return;
1910
1911 if (ctx->ErrorValue == GL_NO_ERROR) {
1912 ctx->ErrorValue = error;
1913 }
1914
1915 /* Call device driver's error handler, if any. This is used on the Mac. */
1916 if (ctx->Driver.Error) {
1917 (*ctx->Driver.Error)( ctx );
1918 }
1919 }
1920
1921 /**
1922 * Execute glFinish().
1923 *
1924 * Calls the #ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH macro and the
1925 * dd_function_table::Finish driver callback, if not NULL.
1926 */
1927 void GLAPIENTRY
1928 _mesa_Finish( void )
1929 {
1930 GET_CURRENT_CONTEXT(ctx);
1931 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
1932 if (ctx->Driver.Finish) {
1933 (*ctx->Driver.Finish)( ctx );
1934 }
1935 }
1936
1937 /**
1938 * Execute glFlush().
1939 *
1940 * Calls the #ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH macro and the
1941 * dd_function_table::Flush driver callback, if not NULL.
1942 */
1943 void GLAPIENTRY
1944 _mesa_Flush( void )
1945 {
1946 GET_CURRENT_CONTEXT(ctx);
1947 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
1948 if (ctx->Driver.Flush) {
1949 (*ctx->Driver.Flush)( ctx );
1950 }
1951 }
1952
1953
1954 /*@}*/