Add GLAPIENTRY function decorations for correct operation on Windows.
[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: 6.1
10 *
11 * Copyright (C) 1999-2004 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 = ctx->Driver.NewProgram(ctx, GL_VERTEX_PROGRAM_ARB, 0);
831 if (!ss->DefaultVertexProgram)
832 goto cleanup;
833 #endif
834 #if FEATURE_ARB_fragment_program
835 ss->DefaultFragmentProgram = ctx->Driver.NewProgram(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 ctx->Driver.DeleteProgram(ctx, ss->DefaultVertexProgram);
884 #endif
885 #if FEATURE_ARB_fragment_program
886 if (ss->DefaultFragmentProgram)
887 ctx->Driver.DeleteProgram(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 ctx->Driver.DeleteProgram(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 /**
978 * Initialize fields of gl_current_attrib (aka ctx->Current.*)
979 */
980 static void
981 _mesa_init_current( GLcontext *ctx )
982 {
983 int i;
984
985 /* Current group */
986 for (i = 0; i < VERT_ATTRIB_MAX; i++) {
987 ASSIGN_4V( ctx->Current.Attrib[i], 0.0, 0.0, 0.0, 1.0 );
988 }
989 /* special cases: */
990 ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_WEIGHT], 1.0, 0.0, 0.0, 1.0 );
991 ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_NORMAL], 0.0, 0.0, 1.0, 1.0 );
992 ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_COLOR0], 1.0, 1.0, 1.0, 1.0 );
993 ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_COLOR1], 0.0, 0.0, 0.0, 0.0 );
994 ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_FOG], 0.0, 0.0, 0.0, 0.0 );
995 for (i = 0; i < MAX_TEXTURE_UNITS; i++)
996 ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_TEX0 + i], 0.0, 0.0, 0.0, 1.0);
997 ctx->Current.Index = 1;
998 ctx->Current.EdgeFlag = GL_TRUE;
999 }
1000
1001
1002 /**
1003 * Initialize fields of gl_constants (aka ctx->Const.*).
1004 * Use defaults from config.h. The device drivers will often override
1005 * some of these values (such as number of texture units).
1006 */
1007 static void
1008 _mesa_init_constants( GLcontext *ctx )
1009 {
1010 assert(ctx);
1011
1012 assert(MAX_TEXTURE_LEVELS >= MAX_3D_TEXTURE_LEVELS);
1013 assert(MAX_TEXTURE_LEVELS >= MAX_CUBE_TEXTURE_LEVELS);
1014
1015 /* Constants, may be overriden by device drivers */
1016 ctx->Const.MaxTextureLevels = MAX_TEXTURE_LEVELS;
1017 ctx->Const.Max3DTextureLevels = MAX_3D_TEXTURE_LEVELS;
1018 ctx->Const.MaxCubeTextureLevels = MAX_CUBE_TEXTURE_LEVELS;
1019 ctx->Const.MaxTextureRectSize = MAX_TEXTURE_RECT_SIZE;
1020 ctx->Const.MaxTextureUnits = MAX_TEXTURE_UNITS;
1021 ctx->Const.MaxTextureCoordUnits = MAX_TEXTURE_COORD_UNITS;
1022 ctx->Const.MaxTextureImageUnits = MAX_TEXTURE_IMAGE_UNITS;
1023 ctx->Const.MaxTextureMaxAnisotropy = MAX_TEXTURE_MAX_ANISOTROPY;
1024 ctx->Const.MaxTextureLodBias = MAX_TEXTURE_LOD_BIAS;
1025 ctx->Const.MaxArrayLockSize = MAX_ARRAY_LOCK_SIZE;
1026 ctx->Const.SubPixelBits = SUB_PIXEL_BITS;
1027 ctx->Const.MinPointSize = MIN_POINT_SIZE;
1028 ctx->Const.MaxPointSize = MAX_POINT_SIZE;
1029 ctx->Const.MinPointSizeAA = MIN_POINT_SIZE;
1030 ctx->Const.MaxPointSizeAA = MAX_POINT_SIZE;
1031 ctx->Const.PointSizeGranularity = (GLfloat) POINT_SIZE_GRANULARITY;
1032 ctx->Const.MinLineWidth = MIN_LINE_WIDTH;
1033 ctx->Const.MaxLineWidth = MAX_LINE_WIDTH;
1034 ctx->Const.MinLineWidthAA = MIN_LINE_WIDTH;
1035 ctx->Const.MaxLineWidthAA = MAX_LINE_WIDTH;
1036 ctx->Const.LineWidthGranularity = (GLfloat) LINE_WIDTH_GRANULARITY;
1037 ctx->Const.NumAuxBuffers = NUM_AUX_BUFFERS;
1038 ctx->Const.MaxColorTableSize = MAX_COLOR_TABLE_SIZE;
1039 ctx->Const.MaxConvolutionWidth = MAX_CONVOLUTION_WIDTH;
1040 ctx->Const.MaxConvolutionHeight = MAX_CONVOLUTION_HEIGHT;
1041 ctx->Const.MaxClipPlanes = MAX_CLIP_PLANES;
1042 ctx->Const.MaxLights = MAX_LIGHTS;
1043 ctx->Const.MaxSpotExponent = 128.0;
1044 ctx->Const.MaxShininess = 128.0;
1045 #if FEATURE_ARB_vertex_program
1046 ctx->Const.MaxVertexProgramInstructions = MAX_NV_VERTEX_PROGRAM_INSTRUCTIONS;
1047 ctx->Const.MaxVertexProgramAttribs = MAX_NV_VERTEX_PROGRAM_INPUTS;
1048 ctx->Const.MaxVertexProgramTemps = MAX_NV_VERTEX_PROGRAM_TEMPS;
1049 ctx->Const.MaxVertexProgramLocalParams = MAX_NV_VERTEX_PROGRAM_PARAMS;
1050 ctx->Const.MaxVertexProgramEnvParams = MAX_NV_VERTEX_PROGRAM_PARAMS;/*XXX*/
1051 ctx->Const.MaxVertexProgramAddressRegs = MAX_VERTEX_PROGRAM_ADDRESS_REGS;
1052 #endif
1053 #if FEATURE_ARB_fragment_program
1054 ctx->Const.MaxFragmentProgramInstructions = MAX_NV_FRAGMENT_PROGRAM_INSTRUCTIONS;
1055 ctx->Const.MaxFragmentProgramAttribs = MAX_NV_FRAGMENT_PROGRAM_INPUTS;
1056 ctx->Const.MaxFragmentProgramTemps = MAX_NV_FRAGMENT_PROGRAM_TEMPS;
1057 ctx->Const.MaxFragmentProgramLocalParams = MAX_NV_FRAGMENT_PROGRAM_PARAMS;
1058 ctx->Const.MaxFragmentProgramEnvParams = MAX_NV_FRAGMENT_PROGRAM_PARAMS;/*XXX*/
1059 ctx->Const.MaxFragmentProgramAddressRegs = MAX_FRAGMENT_PROGRAM_ADDRESS_REGS;
1060 ctx->Const.MaxFragmentProgramAluInstructions = MAX_FRAGMENT_PROGRAM_ALU_INSTRUCTIONS;
1061 ctx->Const.MaxFragmentProgramTexInstructions = MAX_FRAGMENT_PROGRAM_TEX_INSTRUCTIONS;
1062 ctx->Const.MaxFragmentProgramTexIndirections = MAX_FRAGMENT_PROGRAM_TEX_INDIRECTIONS;
1063 #endif
1064 ctx->Const.MaxProgramMatrices = MAX_PROGRAM_MATRICES;
1065 ctx->Const.MaxProgramMatrixStackDepth = MAX_PROGRAM_MATRIX_STACK_DEPTH;
1066
1067 /* If we're running in the X server, do bounds checking to prevent
1068 * segfaults and server crashes!
1069 */
1070 #if defined(XFree86LOADER) && defined(IN_MODULE)
1071 ctx->Const.CheckArrayBounds = GL_TRUE;
1072 #else
1073 ctx->Const.CheckArrayBounds = GL_FALSE;
1074 #endif
1075
1076 ASSERT(ctx->Const.MaxTextureUnits == MAX2(ctx->Const.MaxTextureImageUnits, ctx->Const.MaxTextureCoordUnits));
1077 }
1078
1079
1080 /**
1081 * Initialize the attribute groups in a GL context.
1082 *
1083 * \param ctx GL context.
1084 *
1085 * Initializes all the attributes, calling the respective <tt>init*</tt>
1086 * functions for the more complex data structures.
1087 */
1088 static GLboolean
1089 init_attrib_groups( GLcontext *ctx )
1090 {
1091 assert(ctx);
1092
1093 /* Constants */
1094 _mesa_init_constants( ctx );
1095
1096 /* Extensions */
1097 _mesa_init_extensions( ctx );
1098
1099 /* Attribute Groups */
1100 _mesa_init_accum( ctx );
1101 _mesa_init_attrib( ctx );
1102 _mesa_init_buffers( ctx );
1103 _mesa_init_buffer_objects( ctx );
1104 _mesa_init_color( ctx );
1105 _mesa_init_colortables( ctx );
1106 _mesa_init_current( ctx );
1107 _mesa_init_depth( ctx );
1108 _mesa_init_debug( ctx );
1109 _mesa_init_display_list( ctx );
1110 _mesa_init_eval( ctx );
1111 _mesa_init_feedback( ctx );
1112 _mesa_init_fog( ctx );
1113 _mesa_init_histogram( ctx );
1114 _mesa_init_hint( ctx );
1115 _mesa_init_line( ctx );
1116 _mesa_init_lighting( ctx );
1117 _mesa_init_matrix( ctx );
1118 _mesa_init_occlude( ctx );
1119 _mesa_init_pixel( ctx );
1120 _mesa_init_point( ctx );
1121 _mesa_init_polygon( ctx );
1122 _mesa_init_program( ctx );
1123 _mesa_init_rastpos( ctx );
1124 _mesa_init_stencil( ctx );
1125 _mesa_init_transform( ctx );
1126 _mesa_init_varray( ctx );
1127 _mesa_init_viewport( ctx );
1128
1129 if (!_mesa_init_texture( ctx ))
1130 return GL_FALSE;
1131
1132 /* Miscellaneous */
1133 ctx->NewState = _NEW_ALL;
1134 ctx->ErrorValue = (GLenum) GL_NO_ERROR;
1135 ctx->CatchSignals = GL_TRUE;
1136 ctx->_Facing = 0;
1137
1138 return GL_TRUE;
1139 }
1140
1141
1142 /**
1143 * If the DRI libGL.so library is old, it may not have the entrypoints for
1144 * some recent OpenGL extensions. Dynamically add them now.
1145 * If we're building stand-alone Mesa where libGL.so has both the dispatcher
1146 * and driver code, this won't be an issue (and calling this function won't
1147 * do any harm).
1148 */
1149 static void
1150 add_newer_entrypoints(void)
1151 {
1152 unsigned i;
1153 static const struct {
1154 const char * const name;
1155 unsigned offset;
1156 }
1157 newer_entrypoints[] = {
1158 /* GL_ARB_window_pos aliases with GL_MESA_window_pos */
1159 { "glWindowPos2dARB", 513 },
1160 { "glWindowPos2dvARB", 514 },
1161 { "glWindowPos2fARB", 515 },
1162 { "glWindowPos2fvARB", 516 },
1163 { "glWindowPos2iARB", 517 },
1164 { "glWindowPos2ivARB", 518 },
1165 { "glWindowPos2sARB", 519 },
1166 { "glWindowPos2svARB", 520 },
1167 { "glWindowPos3dARB", 521 },
1168 { "glWindowPos3dvARB", 522 },
1169 { "glWindowPos3fARB", 523 },
1170 { "glWindowPos3fvARB", 524 },
1171 { "glWindowPos3iARB", 525 },
1172 { "glWindowPos3ivARB", 526 },
1173 { "glWindowPos3sARB", 527 },
1174 { "glWindowPos3svARB", 528 },
1175 #if FEATURE_NV_vertex_program
1176 { "glAreProgramsResidentNV", 578 },
1177 { "glBindProgramNV", 579 },
1178 { "glDeleteProgramsNV", 580 },
1179 { "glExecuteProgramNV", 581 },
1180 { "glGenProgramsNV", 582 },
1181 { "glGetProgramParameterdvNV", 583 },
1182 { "glGetProgramParameterfvNV", 584 },
1183 { "glGetProgramivNV", 585 },
1184 { "glGetProgramStringNV", 586 },
1185 { "glGetTrackMatrixivNV", 587 },
1186 { "glGetVertexAttribdvNV", 588 },
1187 { "glGetVertexAttribfvNV", 589 },
1188 { "glGetVertexAttribivNV", 590 },
1189 { "glGetVertexAttribPointervNV", 591 },
1190 { "glIsProgramNV", 592 },
1191 { "glLoadProgramNV", 593 },
1192 { "glProgramParameter4dNV", 594 },
1193 { "glProgramParameter4dvNV", 595 },
1194 { "glProgramParameter4fNV", 596 },
1195 { "glProgramParameter4fvNV", 597 },
1196 { "glProgramParameters4dvNV", 598 },
1197 { "glProgramParameters4fvNV", 599 },
1198 { "glRequestResidentProgramsNV", 600 },
1199 { "glTrackMatrixNV", 601 },
1200 { "glVertexAttribPointerNV", 602 },
1201 { "glVertexAttrib1dNV", 603 },
1202 { "glVertexAttrib1dvNV", 604 },
1203 { "glVertexAttrib1fNV", 605 },
1204 { "glVertexAttrib1fvNV", 606 },
1205 { "glVertexAttrib1sNV", 607 },
1206 { "glVertexAttrib1svNV", 608 },
1207 { "glVertexAttrib2dNV", 609 },
1208 { "glVertexAttrib2dvNV", 610 },
1209 { "glVertexAttrib2fNV", 611 },
1210 { "glVertexAttrib2fvNV", 612 },
1211 { "glVertexAttrib2sNV", 613 },
1212 { "glVertexAttrib2svNV", 614 },
1213 { "glVertexAttrib3dNV", 615 },
1214 { "glVertexAttrib3dvNV", 616 },
1215 { "glVertexAttrib3fNV", 617 },
1216 { "glVertexAttrib3fvNV", 618 },
1217 { "glVertexAttrib3sNV", 619 },
1218 { "glVertexAttrib3svNV", 620 },
1219 { "glVertexAttrib4dNV", 621 },
1220 { "glVertexAttrib4dvNV", 622 },
1221 { "glVertexAttrib4fNV", 623 },
1222 { "glVertexAttrib4fvNV", 624 },
1223 { "glVertexAttrib4sNV", 625 },
1224 { "glVertexAttrib4svNV", 626 },
1225 { "glVertexAttrib4ubNV", 627 },
1226 { "glVertexAttrib4ubvNV", 628 },
1227 { "glVertexAttribs1dvNV", 629 },
1228 { "glVertexAttribs1fvNV", 630 },
1229 { "glVertexAttribs1svNV", 631 },
1230 { "glVertexAttribs2dvNV", 632 },
1231 { "glVertexAttribs2fvNV", 633 },
1232 { "glVertexAttribs2svNV", 634 },
1233 { "glVertexAttribs3dvNV", 635 },
1234 { "glVertexAttribs3fvNV", 636 },
1235 { "glVertexAttribs3svNV", 637 },
1236 { "glVertexAttribs4dvNV", 638 },
1237 { "glVertexAttribs4fvNV", 639 },
1238 { "glVertexAttribs4svNV", 640 },
1239 { "glVertexAttribs4ubvNV", 641 },
1240 #endif
1241 { "glPointParameteriNV", 642 },
1242 { "glPointParameterivNV", 643 },
1243 { "glMultiDrawArraysEXT", 644 },
1244 { "glMultiDrawElementsEXT", 645 },
1245 { "glMultiDrawArraysSUN", _gloffset_MultiDrawArraysEXT },
1246 { "glMultiDrawElementsSUN", _gloffset_MultiDrawElementsEXT },
1247 { "glActiveStencilFaceEXT", 646 },
1248 #if FEATURE_NV_fence
1249 { "glDeleteFencesNV", 647 },
1250 { "glGenFencesNV", 648 },
1251 { "glIsFenceNV", 649 },
1252 { "glTestFenceNV", 650 },
1253 { "glGetFenceivNV", 651 },
1254 { "glFinishFenceNV", 652 },
1255 { "glSetFenceNV", 653 },
1256 #endif
1257 #if FEATURE_NV_fragment_program
1258 { "glProgramNamedParameter4fNV", 682 },
1259 { "glProgramNamedParameter4dNV", 683 },
1260 { "glProgramNamedParameter4fvNV", 683 },
1261 { "glProgramNamedParameter4dvNV", 684 },
1262 { "glGetProgramNamedParameterfvNV", 685 },
1263 { "glGetProgramNamedParameterdvNV", 686 },
1264 #endif
1265 #if FEATURE_ARB_vertex_program
1266 { "glVertexAttrib1sARB", _gloffset_VertexAttrib1sNV },
1267 { "glVertexAttrib1fARB", _gloffset_VertexAttrib1fNV },
1268 { "glVertexAttrib1dARB", _gloffset_VertexAttrib1dNV },
1269 { "glVertexAttrib2sARB", _gloffset_VertexAttrib2sNV },
1270 { "glVertexAttrib2fARB", _gloffset_VertexAttrib2fNV },
1271 { "glVertexAttrib2dARB", _gloffset_VertexAttrib2dNV },
1272 { "glVertexAttrib3sARB", _gloffset_VertexAttrib3sNV },
1273 { "glVertexAttrib3fARB", _gloffset_VertexAttrib3fNV },
1274 { "glVertexAttrib3dARB", _gloffset_VertexAttrib3dNV },
1275 { "glVertexAttrib4sARB", _gloffset_VertexAttrib4sNV },
1276 { "glVertexAttrib4fARB", _gloffset_VertexAttrib4fNV },
1277 { "glVertexAttrib4dARB", _gloffset_VertexAttrib4dNV },
1278 { "glVertexAttrib4NubARB", _gloffset_VertexAttrib4ubNV },
1279 { "glVertexAttrib1svARB", _gloffset_VertexAttrib1svNV },
1280 { "glVertexAttrib1fvARB", _gloffset_VertexAttrib1fvNV },
1281 { "glVertexAttrib1dvARB", _gloffset_VertexAttrib1dvNV },
1282 { "glVertexAttrib2svARB", _gloffset_VertexAttrib2svNV },
1283 { "glVertexAttrib2fvARB", _gloffset_VertexAttrib2fvNV },
1284 { "glVertexAttrib2dvARB", _gloffset_VertexAttrib2dvNV },
1285 { "glVertexAttrib3svARB", _gloffset_VertexAttrib3svNV },
1286 { "glVertexAttrib3fvARB", _gloffset_VertexAttrib3fvNV },
1287 { "glVertexAttrib3dvARB", _gloffset_VertexAttrib3dvNV },
1288 { "glVertexAttrib4bvARB", _gloffset_VertexAttrib4bvARB },
1289 { "glVertexAttrib4svARB", _gloffset_VertexAttrib4svNV },
1290 { "glVertexAttrib4ivARB", _gloffset_VertexAttrib4ivARB },
1291 { "glVertexAttrib4ubvARB", _gloffset_VertexAttrib4ubvARB },
1292 { "glVertexAttrib4usvARB", _gloffset_VertexAttrib4usvARB },
1293 { "glVertexAttrib4uivARB", _gloffset_VertexAttrib4uivARB },
1294 { "glVertexAttrib4fvARB", _gloffset_VertexAttrib4fvNV },
1295 { "glVertexAttrib4dvARB", _gloffset_VertexAttrib4dvNV },
1296 { "glVertexAttrib4NbvARB", _gloffset_VertexAttrib4NbvARB },
1297 { "glVertexAttrib4NsvARB", _gloffset_VertexAttrib4NsvARB },
1298 { "glVertexAttrib4NivARB", _gloffset_VertexAttrib4NivARB },
1299 { "glVertexAttrib4NubvARB", _gloffset_VertexAttrib4ubvNV },
1300 { "glVertexAttrib4NusvARB", _gloffset_VertexAttrib4NusvARB },
1301 { "glVertexAttrib4NuivARB", _gloffset_VertexAttrib4NuivARB },
1302 { "glVertexAttribPointerARB", _gloffset_VertexAttribPointerARB },
1303 { "glEnableVertexAttribArrayARB", _gloffset_EnableVertexAttribArrayARB },
1304 { "glDisableVertexAttribArrayARB", _gloffset_DisableVertexAttribArrayARB },
1305 { "glProgramStringARB", _gloffset_ProgramStringARB },
1306 { "glBindProgramARB", _gloffset_BindProgramNV },
1307 { "glDeleteProgramsARB", _gloffset_DeleteProgramsNV },
1308 { "glGenProgramsARB", _gloffset_GenProgramsNV },
1309 { "glIsProgramARB", _gloffset_IsProgramNV },
1310 { "glProgramEnvParameter4dARB", _gloffset_ProgramEnvParameter4dARB },
1311 { "glProgramEnvParameter4dvARB", _gloffset_ProgramEnvParameter4dvARB },
1312 { "glProgramEnvParameter4fARB", _gloffset_ProgramEnvParameter4fARB },
1313 { "glProgramEnvParameter4fvARB", _gloffset_ProgramEnvParameter4fvARB },
1314 { "glProgramLocalParameter4dARB", _gloffset_ProgramLocalParameter4dARB },
1315 { "glProgramLocalParameter4dvARB", _gloffset_ProgramLocalParameter4dvARB },
1316 { "glProgramLocalParameter4fARB", _gloffset_ProgramLocalParameter4fARB },
1317 { "glProgramLocalParameter4fvARB", _gloffset_ProgramLocalParameter4fvARB },
1318 { "glGetProgramEnvParameterdvARB", _gloffset_GetProgramEnvParameterdvARB },
1319 { "glGetProgramEnvParameterfvARB", _gloffset_GetProgramEnvParameterfvARB },
1320 { "glGetProgramLocalParameterdvARB", _gloffset_GetProgramLocalParameterdvARB },
1321 { "glGetProgramLocalParameterfvARB", _gloffset_GetProgramLocalParameterfvARB },
1322 { "glGetProgramivARB", _gloffset_GetProgramivARB },
1323 { "glGetProgramStringARB", _gloffset_GetProgramStringARB },
1324 { "glGetVertexAttribdvARB", _gloffset_GetVertexAttribdvNV },
1325 { "glGetVertexAttribfvARB", _gloffset_GetVertexAttribfvNV },
1326 { "glGetVertexAttribivARB", _gloffset_GetVertexAttribivNV },
1327 { "glGetVertexAttribPointervARB", _gloffset_GetVertexAttribPointervNV },
1328 #endif
1329 { "glMultiModeDrawArraysIBM", _gloffset_MultiModeDrawArraysIBM },
1330 { "glMultiModeDrawElementsIBM", _gloffset_MultiModeDrawElementsIBM },
1331 };
1332
1333 for ( i = 0 ; i < Elements(newer_entrypoints) ; i++ ) {
1334 _glapi_add_entrypoint( newer_entrypoints[i].name,
1335 newer_entrypoints[i].offset );
1336 }
1337 }
1338
1339
1340 /**
1341 * Initialize a GLcontext struct (rendering context).
1342 *
1343 * This includes allocating all the other structs and arrays which hang off of
1344 * the context by pointers.
1345 * Note that the driver needs to pass in its dd_function_table here since
1346 * we need to at least call driverFunctions->NewTextureObject to create the
1347 * default texture objects.
1348 *
1349 * Called by _mesa_create_context().
1350 *
1351 * Performs the imports and exports callback tables initialization, and
1352 * miscellaneous one-time initializations. If no shared context is supplied one
1353 * is allocated, and increase its reference count. Setups the GL API dispatch
1354 * tables. Initialize the TNL module. Sets the maximum Z buffer depth.
1355 * Finally queries the \c MESA_DEBUG and \c MESA_VERBOSE environment variables
1356 * for debug flags.
1357 *
1358 * \param ctx the context to initialize
1359 * \param visual describes the visual attributes for this context
1360 * \param share_list points to context to share textures, display lists,
1361 * etc with, or NULL
1362 * \param driverFunctions table of device driver functions for this context
1363 * to use
1364 * \param driverContext pointer to driver-specific context data
1365 */
1366 GLboolean
1367 _mesa_initialize_context( GLcontext *ctx,
1368 const GLvisual *visual,
1369 GLcontext *share_list,
1370 const struct dd_function_table *driverFunctions,
1371 void *driverContext )
1372 {
1373 GLuint dispatchSize;
1374
1375 ASSERT(driverContext);
1376 assert(driverFunctions->NewTextureObject);
1377
1378 /* If the driver wants core Mesa to use special imports, it'll have to
1379 * override these defaults.
1380 */
1381 _mesa_init_default_imports( &(ctx->imports), driverContext );
1382
1383 /* initialize the exports (Mesa functions called by the window system) */
1384 _mesa_init_default_exports( &(ctx->exports) );
1385
1386 /* misc one-time initializations */
1387 one_time_init(ctx);
1388
1389 ctx->Visual = *visual;
1390 ctx->DrawBuffer = NULL;
1391 ctx->ReadBuffer = NULL;
1392
1393 /* Plug in driver functions and context pointer here.
1394 * This is important because when we call alloc_shared_state() below
1395 * we'll call ctx->Driver.NewTextureObject() to create the default
1396 * textures.
1397 */
1398 ctx->Driver = *driverFunctions;
1399 ctx->DriverCtx = driverContext;
1400
1401 if (share_list) {
1402 /* share state with another context */
1403 ctx->Shared = share_list->Shared;
1404 }
1405 else {
1406 /* allocate new, unshared state */
1407 if (!alloc_shared_state( ctx )) {
1408 return GL_FALSE;
1409 }
1410 }
1411 _glthread_LOCK_MUTEX(ctx->Shared->Mutex);
1412 ctx->Shared->RefCount++;
1413 _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex);
1414
1415 if (!init_attrib_groups( ctx )) {
1416 free_shared_state(ctx, ctx->Shared);
1417 return GL_FALSE;
1418 }
1419
1420 /* libGL ABI coordination */
1421 add_newer_entrypoints();
1422
1423 /* Find the larger of Mesa's dispatch table and libGL's dispatch table.
1424 * In practice, this'll be the same for stand-alone Mesa. But for DRI
1425 * Mesa we do this to accomodate different versions of libGL and various
1426 * DRI drivers.
1427 */
1428 dispatchSize = MAX2(_glapi_get_dispatch_table_size(),
1429 sizeof(struct _glapi_table) / sizeof(void *));
1430
1431 /* setup API dispatch tables */
1432 ctx->Exec = (struct _glapi_table *) CALLOC(dispatchSize * sizeof(void*));
1433 ctx->Save = (struct _glapi_table *) CALLOC(dispatchSize * sizeof(void*));
1434 if (!ctx->Exec || !ctx->Save) {
1435 free_shared_state(ctx, ctx->Shared);
1436 if (ctx->Exec)
1437 FREE( ctx->Exec );
1438 }
1439 _mesa_init_exec_table(ctx->Exec, dispatchSize);
1440 ctx->CurrentDispatch = ctx->Exec;
1441
1442 #if _HAVE_FULL_GL
1443 _mesa_init_dlist_table(ctx->Save, dispatchSize);
1444 _mesa_install_save_vtxfmt( ctx, &ctx->ListState.ListVtxfmt );
1445
1446
1447 /* Neutral tnl module stuff */
1448 _mesa_init_exec_vtxfmt( ctx );
1449 ctx->TnlModule.Current = NULL;
1450 ctx->TnlModule.SwapCount = 0;
1451 #endif
1452
1453 return GL_TRUE;
1454 }
1455
1456
1457 /**
1458 * Allocate and initialize a GLcontext structure.
1459 * Note that the driver needs to pass in its dd_function_table here since
1460 * we need to at least call driverFunctions->NewTextureObject to initialize
1461 * the rendering context.
1462 *
1463 * \param visual a GLvisual pointer (we copy the struct contents)
1464 * \param share_list another context to share display lists with or NULL
1465 * \param driverFunctions points to the dd_function_table into which the
1466 * driver has plugged in all its special functions.
1467 * \param driverCtx points to the device driver's private context state
1468 *
1469 * \return pointer to a new __GLcontextRec or NULL if error.
1470 */
1471 GLcontext *
1472 _mesa_create_context( const GLvisual *visual,
1473 GLcontext *share_list,
1474 const struct dd_function_table *driverFunctions,
1475 void *driverContext )
1476
1477 {
1478 GLcontext *ctx;
1479
1480 ASSERT(visual);
1481 ASSERT(driverContext);
1482
1483 ctx = (GLcontext *) _mesa_calloc(sizeof(GLcontext));
1484 if (!ctx)
1485 return NULL;
1486
1487 if (_mesa_initialize_context(ctx, visual, share_list,
1488 driverFunctions, driverContext)) {
1489 return ctx;
1490 }
1491 else {
1492 _mesa_free(ctx);
1493 return NULL;
1494 }
1495 }
1496
1497
1498 /**
1499 * Free the data associated with the given context.
1500 *
1501 * But doesn't free the GLcontext struct itself.
1502 *
1503 * \sa _mesa_initialize_context() and init_attrib_groups().
1504 */
1505 void
1506 _mesa_free_context_data( GLcontext *ctx )
1507 {
1508 /* if we're destroying the current context, unbind it first */
1509 if (ctx == _mesa_get_current_context()) {
1510 _mesa_make_current(NULL, NULL);
1511 }
1512
1513 _mesa_free_lighting_data( ctx );
1514 _mesa_free_eval_data( ctx );
1515 _mesa_free_texture_data( ctx );
1516 _mesa_free_matrix_data( ctx );
1517 _mesa_free_viewport_data( ctx );
1518 _mesa_free_colortables_data( ctx );
1519 #if FEATURE_NV_vertex_program
1520 if (ctx->VertexProgram.Current) {
1521 ctx->VertexProgram.Current->Base.RefCount--;
1522 if (ctx->VertexProgram.Current->Base.RefCount <= 0)
1523 ctx->Driver.DeleteProgram(ctx, &(ctx->VertexProgram.Current->Base));
1524 }
1525 #endif
1526 #if FEATURE_NV_fragment_program
1527 if (ctx->FragmentProgram.Current) {
1528 ctx->FragmentProgram.Current->Base.RefCount--;
1529 if (ctx->FragmentProgram.Current->Base.RefCount <= 0)
1530 ctx->Driver.DeleteProgram(ctx, &(ctx->FragmentProgram.Current->Base));
1531 }
1532 #endif
1533
1534 /* Shared context state (display lists, textures, etc) */
1535 _glthread_LOCK_MUTEX(ctx->Shared->Mutex);
1536 ctx->Shared->RefCount--;
1537 assert(ctx->Shared->RefCount >= 0);
1538 _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex);
1539 if (ctx->Shared->RefCount == 0) {
1540 /* free shared state */
1541 free_shared_state( ctx, ctx->Shared );
1542 }
1543
1544 if (ctx->Extensions.String)
1545 FREE((void *) ctx->Extensions.String);
1546
1547 FREE(ctx->Exec);
1548 FREE(ctx->Save);
1549 }
1550
1551
1552 /**
1553 * Destroy a GLcontext structure.
1554 *
1555 * \param ctx GL context.
1556 *
1557 * Calls _mesa_free_context_data() and frees the GLcontext structure itself.
1558 */
1559 void
1560 _mesa_destroy_context( GLcontext *ctx )
1561 {
1562 if (ctx) {
1563 _mesa_free_context_data(ctx);
1564 FREE( (void *) ctx );
1565 }
1566 }
1567
1568
1569 #if _HAVE_FULL_GL
1570 /**
1571 * Copy attribute groups from one context to another.
1572 *
1573 * \param src source context
1574 * \param dst destination context
1575 * \param mask bitwise OR of GL_*_BIT flags
1576 *
1577 * According to the bits specified in \p mask, copies the corresponding
1578 * attributes from \p src into \dst. For many of the attributes a simple \c
1579 * memcpy is not enough due to the existence of internal pointers in their data
1580 * structures.
1581 */
1582 void
1583 _mesa_copy_context( const GLcontext *src, GLcontext *dst, GLuint mask )
1584 {
1585 if (mask & GL_ACCUM_BUFFER_BIT) {
1586 /* OK to memcpy */
1587 dst->Accum = src->Accum;
1588 }
1589 if (mask & GL_COLOR_BUFFER_BIT) {
1590 /* OK to memcpy */
1591 dst->Color = src->Color;
1592 }
1593 if (mask & GL_CURRENT_BIT) {
1594 /* OK to memcpy */
1595 dst->Current = src->Current;
1596 }
1597 if (mask & GL_DEPTH_BUFFER_BIT) {
1598 /* OK to memcpy */
1599 dst->Depth = src->Depth;
1600 }
1601 if (mask & GL_ENABLE_BIT) {
1602 /* no op */
1603 }
1604 if (mask & GL_EVAL_BIT) {
1605 /* OK to memcpy */
1606 dst->Eval = src->Eval;
1607 }
1608 if (mask & GL_FOG_BIT) {
1609 /* OK to memcpy */
1610 dst->Fog = src->Fog;
1611 }
1612 if (mask & GL_HINT_BIT) {
1613 /* OK to memcpy */
1614 dst->Hint = src->Hint;
1615 }
1616 if (mask & GL_LIGHTING_BIT) {
1617 GLuint i;
1618 /* begin with memcpy */
1619 MEMCPY( &dst->Light, &src->Light, sizeof(struct gl_light) );
1620 /* fixup linked lists to prevent pointer insanity */
1621 make_empty_list( &(dst->Light.EnabledList) );
1622 for (i = 0; i < MAX_LIGHTS; i++) {
1623 if (dst->Light.Light[i].Enabled) {
1624 insert_at_tail(&(dst->Light.EnabledList), &(dst->Light.Light[i]));
1625 }
1626 }
1627 }
1628 if (mask & GL_LINE_BIT) {
1629 /* OK to memcpy */
1630 dst->Line = src->Line;
1631 }
1632 if (mask & GL_LIST_BIT) {
1633 /* OK to memcpy */
1634 dst->List = src->List;
1635 }
1636 if (mask & GL_PIXEL_MODE_BIT) {
1637 /* OK to memcpy */
1638 dst->Pixel = src->Pixel;
1639 }
1640 if (mask & GL_POINT_BIT) {
1641 /* OK to memcpy */
1642 dst->Point = src->Point;
1643 }
1644 if (mask & GL_POLYGON_BIT) {
1645 /* OK to memcpy */
1646 dst->Polygon = src->Polygon;
1647 }
1648 if (mask & GL_POLYGON_STIPPLE_BIT) {
1649 /* Use loop instead of MEMCPY due to problem with Portland Group's
1650 * C compiler. Reported by John Stone.
1651 */
1652 GLuint i;
1653 for (i = 0; i < 32; i++) {
1654 dst->PolygonStipple[i] = src->PolygonStipple[i];
1655 }
1656 }
1657 if (mask & GL_SCISSOR_BIT) {
1658 /* OK to memcpy */
1659 dst->Scissor = src->Scissor;
1660 }
1661 if (mask & GL_STENCIL_BUFFER_BIT) {
1662 /* OK to memcpy */
1663 dst->Stencil = src->Stencil;
1664 }
1665 if (mask & GL_TEXTURE_BIT) {
1666 /* Cannot memcpy because of pointers */
1667 _mesa_copy_texture_state(src, dst);
1668 }
1669 if (mask & GL_TRANSFORM_BIT) {
1670 /* OK to memcpy */
1671 dst->Transform = src->Transform;
1672 }
1673 if (mask & GL_VIEWPORT_BIT) {
1674 /* Cannot use memcpy, because of pointers in GLmatrix _WindowMap */
1675 dst->Viewport.X = src->Viewport.X;
1676 dst->Viewport.Y = src->Viewport.Y;
1677 dst->Viewport.Width = src->Viewport.Width;
1678 dst->Viewport.Height = src->Viewport.Height;
1679 dst->Viewport.Near = src->Viewport.Near;
1680 dst->Viewport.Far = src->Viewport.Far;
1681 _math_matrix_copy(&dst->Viewport._WindowMap, &src->Viewport._WindowMap);
1682 }
1683
1684 /* XXX FIXME: Call callbacks?
1685 */
1686 dst->NewState = _NEW_ALL;
1687 }
1688 #endif
1689
1690
1691 /**
1692 * Check if the given context can render into the given framebuffer
1693 * by checking visual attributes.
1694 * \return GL_TRUE if compatible, GL_FALSE otherwise.
1695 */
1696 static GLboolean
1697 check_compatible(const GLcontext *ctx, const GLframebuffer *buffer)
1698 {
1699 const GLvisual *ctxvis = &ctx->Visual;
1700 const GLvisual *bufvis = &buffer->Visual;
1701
1702 if (ctxvis == bufvis)
1703 return GL_TRUE;
1704
1705 if (ctxvis->rgbMode != bufvis->rgbMode)
1706 return GL_FALSE;
1707 if (ctxvis->doubleBufferMode && !bufvis->doubleBufferMode)
1708 return GL_FALSE;
1709 if (ctxvis->stereoMode && !bufvis->stereoMode)
1710 return GL_FALSE;
1711 if (ctxvis->haveAccumBuffer && !bufvis->haveAccumBuffer)
1712 return GL_FALSE;
1713 if (ctxvis->haveDepthBuffer && !bufvis->haveDepthBuffer)
1714 return GL_FALSE;
1715 if (ctxvis->haveStencilBuffer && !bufvis->haveStencilBuffer)
1716 return GL_FALSE;
1717 if (ctxvis->redMask && ctxvis->redMask != bufvis->redMask)
1718 return GL_FALSE;
1719 if (ctxvis->greenMask && ctxvis->greenMask != bufvis->greenMask)
1720 return GL_FALSE;
1721 if (ctxvis->blueMask && ctxvis->blueMask != bufvis->blueMask)
1722 return GL_FALSE;
1723 if (ctxvis->depthBits && ctxvis->depthBits != bufvis->depthBits)
1724 return GL_FALSE;
1725 if (ctxvis->stencilBits && ctxvis->stencilBits != bufvis->stencilBits)
1726 return GL_FALSE;
1727
1728 return GL_TRUE;
1729 }
1730
1731
1732 /**
1733 * Set the current context, binding the given frame buffer to the context.
1734 *
1735 * \param newCtx new GL context.
1736 * \param buffer framebuffer.
1737 *
1738 * Calls _mesa_make_current2() with \p buffer as read and write framebuffer.
1739 */
1740 void
1741 _mesa_make_current( GLcontext *newCtx, GLframebuffer *buffer )
1742 {
1743 _mesa_make_current2( newCtx, buffer, buffer );
1744 }
1745
1746 /**
1747 * Bind the given context to the given draw-buffer and read-buffer and
1748 * make it the current context for this thread.
1749 *
1750 * \param newCtx new GL context. If NULL then there will be no current GL
1751 * context.
1752 * \param drawBuffer draw framebuffer.
1753 * \param readBuffer read framebuffer.
1754 *
1755 * Check that the context's and framebuffer's visuals are compatible, returning
1756 * immediately otherwise. Sets the glapi current context via
1757 * _glapi_set_context(). If \p newCtx is not NULL, associates \p drawBuffer and
1758 * \p readBuffer with it and calls dd_function_table::ResizeBuffers if the buffers size has changed.
1759 * Calls dd_function_table::MakeCurrent callback if defined.
1760 *
1761 * When a context is bound by the first time and the \c MESA_INFO environment
1762 * variable is set it calls print_info() as an aid for remote user
1763 * troubleshooting.
1764 */
1765 void
1766 _mesa_make_current2( GLcontext *newCtx, GLframebuffer *drawBuffer,
1767 GLframebuffer *readBuffer )
1768 {
1769 if (MESA_VERBOSE)
1770 _mesa_debug(newCtx, "_mesa_make_current2()\n");
1771
1772 /* Check that the context's and framebuffer's visuals are compatible.
1773 */
1774 if (newCtx && drawBuffer && newCtx->DrawBuffer != drawBuffer) {
1775 if (!check_compatible(newCtx, drawBuffer))
1776 return;
1777 }
1778 if (newCtx && readBuffer && newCtx->ReadBuffer != readBuffer) {
1779 if (!check_compatible(newCtx, readBuffer))
1780 return;
1781 }
1782
1783 /* We call this function periodically (just here for now) in
1784 * order to detect when multithreading has begun.
1785 */
1786 _glapi_check_multithread();
1787
1788 _glapi_set_context((void *) newCtx);
1789 ASSERT(_mesa_get_current_context() == newCtx);
1790
1791
1792 if (!newCtx) {
1793 _glapi_set_dispatch(NULL); /* none current */
1794 }
1795 else {
1796 _glapi_set_dispatch(newCtx->CurrentDispatch);
1797
1798 if (drawBuffer && readBuffer) {
1799 /* TODO: check if newCtx and buffer's visual match??? */
1800 newCtx->DrawBuffer = drawBuffer;
1801 newCtx->ReadBuffer = readBuffer;
1802 newCtx->NewState |= _NEW_BUFFERS;
1803
1804 #if _HAVE_FULL_GL
1805 if (drawBuffer->Width == 0 && drawBuffer->Height == 0) {
1806 /* get initial window size */
1807 GLuint bufWidth, bufHeight;
1808
1809 /* ask device driver for size of output buffer */
1810 (*newCtx->Driver.GetBufferSize)( drawBuffer, &bufWidth, &bufHeight );
1811
1812 if (drawBuffer->Width != bufWidth ||
1813 drawBuffer->Height != bufHeight) {
1814
1815 drawBuffer->Width = bufWidth;
1816 drawBuffer->Height = bufHeight;
1817
1818 newCtx->Driver.ResizeBuffers( drawBuffer );
1819 }
1820 }
1821
1822 if (readBuffer != drawBuffer &&
1823 readBuffer->Width == 0 && readBuffer->Height == 0) {
1824 /* get initial window size */
1825 GLuint bufWidth, bufHeight;
1826
1827 /* ask device driver for size of output buffer */
1828 (*newCtx->Driver.GetBufferSize)( readBuffer, &bufWidth, &bufHeight );
1829
1830 if (readBuffer->Width != bufWidth ||
1831 readBuffer->Height != bufHeight) {
1832
1833 readBuffer->Width = bufWidth;
1834 readBuffer->Height = bufHeight;
1835
1836 newCtx->Driver.ResizeBuffers( readBuffer );
1837 }
1838 }
1839 #endif
1840 }
1841
1842 /* Alert the driver - usually passed on to the sw t&l module,
1843 * but also used to detect threaded cases in the radeon codegen
1844 * hw t&l module.
1845 */
1846 if (newCtx->Driver.MakeCurrent)
1847 newCtx->Driver.MakeCurrent( newCtx, drawBuffer, readBuffer );
1848
1849 /* We can use this to help debug user's problems. Tell them to set
1850 * the MESA_INFO env variable before running their app. Then the
1851 * first time each context is made current we'll print some useful
1852 * information.
1853 */
1854 if (newCtx->FirstTimeCurrent) {
1855 if (_mesa_getenv("MESA_INFO")) {
1856 _mesa_print_info();
1857 }
1858 newCtx->FirstTimeCurrent = GL_FALSE;
1859 }
1860 }
1861 }
1862
1863 /**
1864 * Get current context for the calling thread.
1865 *
1866 * \return pointer to the current GL context.
1867 *
1868 * Calls _glapi_get_context(). This isn't the fastest way to get the current
1869 * context. If you need speed, see the #GET_CURRENT_CONTEXT macro in context.h.
1870 */
1871 GLcontext *
1872 _mesa_get_current_context( void )
1873 {
1874 return (GLcontext *) _glapi_get_context();
1875 }
1876
1877 /**
1878 * Get context's current API dispatch table.
1879 *
1880 * It'll either be the immediate-mode execute dispatcher or the display list
1881 * compile dispatcher.
1882 *
1883 * \param ctx GL context.
1884 *
1885 * \return pointer to dispatch_table.
1886 *
1887 * Simply returns __GLcontextRec::CurrentDispatch.
1888 */
1889 struct _glapi_table *
1890 _mesa_get_dispatch(GLcontext *ctx)
1891 {
1892 return ctx->CurrentDispatch;
1893 }
1894
1895 /*@}*/
1896
1897
1898 /**********************************************************************/
1899 /** \name Miscellaneous functions */
1900 /**********************************************************************/
1901 /*@{*/
1902
1903 /**
1904 * Record an error.
1905 *
1906 * \param ctx GL context.
1907 * \param error error code.
1908 *
1909 * Records the given error code and call the driver's dd_function_table::Error
1910 * function if defined.
1911 *
1912 * \sa
1913 * This is called via _mesa_error().
1914 */
1915 void
1916 _mesa_record_error( GLcontext *ctx, GLenum error )
1917 {
1918 if (!ctx)
1919 return;
1920
1921 if (ctx->ErrorValue == GL_NO_ERROR) {
1922 ctx->ErrorValue = error;
1923 }
1924
1925 /* Call device driver's error handler, if any. This is used on the Mac. */
1926 if (ctx->Driver.Error) {
1927 (*ctx->Driver.Error)( ctx );
1928 }
1929 }
1930
1931 /**
1932 * Execute glFinish().
1933 *
1934 * Calls the #ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH macro and the
1935 * dd_function_table::Finish driver callback, if not NULL.
1936 */
1937 void GLAPIENTRY
1938 _mesa_Finish( void )
1939 {
1940 GET_CURRENT_CONTEXT(ctx);
1941 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
1942 if (ctx->Driver.Finish) {
1943 (*ctx->Driver.Finish)( ctx );
1944 }
1945 }
1946
1947 /**
1948 * Execute glFlush().
1949 *
1950 * Calls the #ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH macro and the
1951 * dd_function_table::Flush driver callback, if not NULL.
1952 */
1953 void GLAPIENTRY
1954 _mesa_Flush( void )
1955 {
1956 GET_CURRENT_CONTEXT(ctx);
1957 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
1958 if (ctx->Driver.Flush) {
1959 (*ctx->Driver.Flush)( ctx );
1960 }
1961 }
1962
1963
1964 /*@}*/