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