context.c revision 7117f1b4
17117f1b4Smrg/**
27117f1b4Smrg * \file context.c
37117f1b4Smrg * Mesa context/visual/framebuffer management functions.
47117f1b4Smrg * \author Brian Paul
57117f1b4Smrg */
67117f1b4Smrg
77117f1b4Smrg/*
87117f1b4Smrg * Mesa 3-D graphics library
97117f1b4Smrg * Version:  7.0.2
107117f1b4Smrg *
117117f1b4Smrg * Copyright (C) 1999-2007  Brian Paul   All Rights Reserved.
127117f1b4Smrg *
137117f1b4Smrg * Permission is hereby granted, free of charge, to any person obtaining a
147117f1b4Smrg * copy of this software and associated documentation files (the "Software"),
157117f1b4Smrg * to deal in the Software without restriction, including without limitation
167117f1b4Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
177117f1b4Smrg * and/or sell copies of the Software, and to permit persons to whom the
187117f1b4Smrg * Software is furnished to do so, subject to the following conditions:
197117f1b4Smrg *
207117f1b4Smrg * The above copyright notice and this permission notice shall be included
217117f1b4Smrg * in all copies or substantial portions of the Software.
227117f1b4Smrg *
237117f1b4Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
247117f1b4Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
257117f1b4Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
267117f1b4Smrg * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
277117f1b4Smrg * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
287117f1b4Smrg * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
297117f1b4Smrg */
307117f1b4Smrg
317117f1b4Smrg
327117f1b4Smrg/**
337117f1b4Smrg * \mainpage Mesa Main Module
347117f1b4Smrg *
357117f1b4Smrg * \section MainIntroduction Introduction
367117f1b4Smrg *
377117f1b4Smrg * The Mesa Main module consists of all the files in the main/ directory.
387117f1b4Smrg * Among the features of this module are:
397117f1b4Smrg * <UL>
407117f1b4Smrg * <LI> Structures to represent most GL state </LI>
417117f1b4Smrg * <LI> State set/get functions </LI>
427117f1b4Smrg * <LI> Display lists </LI>
437117f1b4Smrg * <LI> Texture unit, object and image handling </LI>
447117f1b4Smrg * <LI> Matrix and attribute stacks </LI>
457117f1b4Smrg * </UL>
467117f1b4Smrg *
477117f1b4Smrg * Other modules are responsible for API dispatch, vertex transformation,
487117f1b4Smrg * point/line/triangle setup, rasterization, vertex array caching,
497117f1b4Smrg * vertex/fragment programs/shaders, etc.
507117f1b4Smrg *
517117f1b4Smrg *
527117f1b4Smrg * \section AboutDoxygen About Doxygen
537117f1b4Smrg *
547117f1b4Smrg * If you're viewing this information as Doxygen-generated HTML you'll
557117f1b4Smrg * see the documentation index at the top of this page.
567117f1b4Smrg *
577117f1b4Smrg * The first line lists the Mesa source code modules.
587117f1b4Smrg * The second line lists the indexes available for viewing the documentation
597117f1b4Smrg * for each module.
607117f1b4Smrg *
617117f1b4Smrg * Selecting the <b>Main page</b> link will display a summary of the module
627117f1b4Smrg * (this page).
637117f1b4Smrg *
647117f1b4Smrg * Selecting <b>Data Structures</b> will list all C structures.
657117f1b4Smrg *
667117f1b4Smrg * Selecting the <b>File List</b> link will list all the source files in
677117f1b4Smrg * the module.
687117f1b4Smrg * Selecting a filename will show a list of all functions defined in that file.
697117f1b4Smrg *
707117f1b4Smrg * Selecting the <b>Data Fields</b> link will display a list of all
717117f1b4Smrg * documented structure members.
727117f1b4Smrg *
737117f1b4Smrg * Selecting the <b>Globals</b> link will display a list
747117f1b4Smrg * of all functions, structures, global variables and macros in the module.
757117f1b4Smrg *
767117f1b4Smrg */
777117f1b4Smrg
787117f1b4Smrg
797117f1b4Smrg#include "glheader.h"
807117f1b4Smrg#include "imports.h"
817117f1b4Smrg#include "accum.h"
827117f1b4Smrg#include "arrayobj.h"
837117f1b4Smrg#include "attrib.h"
847117f1b4Smrg#include "blend.h"
857117f1b4Smrg#include "buffers.h"
867117f1b4Smrg#include "bufferobj.h"
877117f1b4Smrg#include "colortab.h"
887117f1b4Smrg#include "context.h"
897117f1b4Smrg#include "debug.h"
907117f1b4Smrg#include "depth.h"
917117f1b4Smrg#include "dlist.h"
927117f1b4Smrg#include "eval.h"
937117f1b4Smrg#include "enums.h"
947117f1b4Smrg#include "extensions.h"
957117f1b4Smrg#include "fbobject.h"
967117f1b4Smrg#include "feedback.h"
977117f1b4Smrg#include "fog.h"
987117f1b4Smrg#include "framebuffer.h"
997117f1b4Smrg#include "get.h"
1007117f1b4Smrg#include "glthread.h"
1017117f1b4Smrg#include "glapioffsets.h"
1027117f1b4Smrg#include "histogram.h"
1037117f1b4Smrg#include "hint.h"
1047117f1b4Smrg#include "hash.h"
1057117f1b4Smrg#include "atifragshader.h"
1067117f1b4Smrg#include "light.h"
1077117f1b4Smrg#include "lines.h"
1087117f1b4Smrg#include "macros.h"
1097117f1b4Smrg#include "matrix.h"
1107117f1b4Smrg#include "pixel.h"
1117117f1b4Smrg#include "points.h"
1127117f1b4Smrg#include "polygon.h"
1137117f1b4Smrg#if FEATURE_NV_vertex_program || FEATURE_NV_fragment_program
1147117f1b4Smrg#include "program.h"
1157117f1b4Smrg#endif
1167117f1b4Smrg#include "queryobj.h"
1177117f1b4Smrg#include "rastpos.h"
1187117f1b4Smrg#include "simple_list.h"
1197117f1b4Smrg#include "state.h"
1207117f1b4Smrg#include "stencil.h"
1217117f1b4Smrg#include "texcompress.h"
1227117f1b4Smrg#include "teximage.h"
1237117f1b4Smrg#include "texobj.h"
1247117f1b4Smrg#include "texstate.h"
1257117f1b4Smrg#include "mtypes.h"
1267117f1b4Smrg#include "varray.h"
1277117f1b4Smrg#include "version.h"
1287117f1b4Smrg#include "vtxfmt.h"
1297117f1b4Smrg#if _HAVE_FULL_GL
1307117f1b4Smrg#include "math/m_translate.h"
1317117f1b4Smrg#include "math/m_matrix.h"
1327117f1b4Smrg#include "math/m_xform.h"
1337117f1b4Smrg#include "math/mathmod.h"
1347117f1b4Smrg#endif
1357117f1b4Smrg#include "shader_api.h"
1367117f1b4Smrg
1377117f1b4Smrg#ifdef USE_SPARC_ASM
1387117f1b4Smrg#include "sparc/sparc.h"
1397117f1b4Smrg#endif
1407117f1b4Smrg
1417117f1b4Smrg#ifndef MESA_VERBOSE
1427117f1b4Smrgint MESA_VERBOSE = 0;
1437117f1b4Smrg#endif
1447117f1b4Smrg
1457117f1b4Smrg#ifndef MESA_DEBUG_FLAGS
1467117f1b4Smrgint MESA_DEBUG_FLAGS = 0;
1477117f1b4Smrg#endif
1487117f1b4Smrg
1497117f1b4Smrg
1507117f1b4Smrg/* ubyte -> float conversion */
1517117f1b4SmrgGLfloat _mesa_ubyte_to_float_color_tab[256];
1527117f1b4Smrg
1537117f1b4Smrgstatic void
1547117f1b4Smrgfree_shared_state( GLcontext *ctx, struct gl_shared_state *ss );
1557117f1b4Smrg
1567117f1b4Smrg
1577117f1b4Smrg/**
1587117f1b4Smrg * Swap buffers notification callback.
1597117f1b4Smrg *
1607117f1b4Smrg * \param gc GL context.
1617117f1b4Smrg *
1627117f1b4Smrg * Called by window system just before swapping buffers.
1637117f1b4Smrg * We have to finish any pending rendering.
1647117f1b4Smrg */
1657117f1b4Smrgvoid
1667117f1b4Smrg_mesa_notifySwapBuffers(__GLcontext *gc)
1677117f1b4Smrg{
1687117f1b4Smrg   FLUSH_VERTICES( gc, 0 );
1697117f1b4Smrg}
1707117f1b4Smrg
1717117f1b4Smrg
1727117f1b4Smrg/**********************************************************************/
1737117f1b4Smrg/** \name GL Visual allocation/destruction                            */
1747117f1b4Smrg/**********************************************************************/
1757117f1b4Smrg/*@{*/
1767117f1b4Smrg
1777117f1b4Smrg/**
1787117f1b4Smrg * Allocates a GLvisual structure and initializes it via
1797117f1b4Smrg * _mesa_initialize_visual().
1807117f1b4Smrg *
1817117f1b4Smrg * \param rgbFlag GL_TRUE for RGB(A) mode, GL_FALSE for Color Index mode.
1827117f1b4Smrg * \param dbFlag double buffering
1837117f1b4Smrg * \param stereoFlag stereo buffer
1847117f1b4Smrg * \param depthBits requested bits per depth buffer value. Any value in [0, 32]
1857117f1b4Smrg * is acceptable but the actual depth type will be GLushort or GLuint as
1867117f1b4Smrg * needed.
1877117f1b4Smrg * \param stencilBits requested minimum bits per stencil buffer value
1887117f1b4Smrg * \param accumRedBits, accumGreenBits, accumBlueBits, accumAlphaBits number of bits per color component in accum buffer.
1897117f1b4Smrg * \param indexBits number of bits per pixel if \p rgbFlag is GL_FALSE
1907117f1b4Smrg * \param redBits number of bits per color component in frame buffer for RGB(A)
1917117f1b4Smrg * mode.  We always use 8 in core Mesa though.
1927117f1b4Smrg * \param greenBits same as above.
1937117f1b4Smrg * \param blueBits same as above.
1947117f1b4Smrg * \param alphaBits same as above.
1957117f1b4Smrg * \param numSamples not really used.
1967117f1b4Smrg *
1977117f1b4Smrg * \return pointer to new GLvisual or NULL if requested parameters can't be
1987117f1b4Smrg * met.
1997117f1b4Smrg *
2007117f1b4Smrg * \note Need to add params for level and numAuxBuffers (at least)
2017117f1b4Smrg */
2027117f1b4SmrgGLvisual *
2037117f1b4Smrg_mesa_create_visual( GLboolean rgbFlag,
2047117f1b4Smrg                     GLboolean dbFlag,
2057117f1b4Smrg                     GLboolean stereoFlag,
2067117f1b4Smrg                     GLint redBits,
2077117f1b4Smrg                     GLint greenBits,
2087117f1b4Smrg                     GLint blueBits,
2097117f1b4Smrg                     GLint alphaBits,
2107117f1b4Smrg                     GLint indexBits,
2117117f1b4Smrg                     GLint depthBits,
2127117f1b4Smrg                     GLint stencilBits,
2137117f1b4Smrg                     GLint accumRedBits,
2147117f1b4Smrg                     GLint accumGreenBits,
2157117f1b4Smrg                     GLint accumBlueBits,
2167117f1b4Smrg                     GLint accumAlphaBits,
2177117f1b4Smrg                     GLint numSamples )
2187117f1b4Smrg{
2197117f1b4Smrg   GLvisual *vis = (GLvisual *) _mesa_calloc(sizeof(GLvisual));
2207117f1b4Smrg   if (vis) {
2217117f1b4Smrg      if (!_mesa_initialize_visual(vis, rgbFlag, dbFlag, stereoFlag,
2227117f1b4Smrg                                   redBits, greenBits, blueBits, alphaBits,
2237117f1b4Smrg                                   indexBits, depthBits, stencilBits,
2247117f1b4Smrg                                   accumRedBits, accumGreenBits,
2257117f1b4Smrg                                   accumBlueBits, accumAlphaBits,
2267117f1b4Smrg                                   numSamples)) {
2277117f1b4Smrg         _mesa_free(vis);
2287117f1b4Smrg         return NULL;
2297117f1b4Smrg      }
2307117f1b4Smrg   }
2317117f1b4Smrg   return vis;
2327117f1b4Smrg}
2337117f1b4Smrg
2347117f1b4Smrg/**
2357117f1b4Smrg * Makes some sanity checks and fills in the fields of the
2367117f1b4Smrg * GLvisual object with the given parameters.  If the caller needs
2377117f1b4Smrg * to set additional fields, he should just probably init the whole GLvisual
2387117f1b4Smrg * object himself.
2397117f1b4Smrg * \return GL_TRUE on success, or GL_FALSE on failure.
2407117f1b4Smrg *
2417117f1b4Smrg * \sa _mesa_create_visual() above for the parameter description.
2427117f1b4Smrg */
2437117f1b4SmrgGLboolean
2447117f1b4Smrg_mesa_initialize_visual( GLvisual *vis,
2457117f1b4Smrg                         GLboolean rgbFlag,
2467117f1b4Smrg                         GLboolean dbFlag,
2477117f1b4Smrg                         GLboolean stereoFlag,
2487117f1b4Smrg                         GLint redBits,
2497117f1b4Smrg                         GLint greenBits,
2507117f1b4Smrg                         GLint blueBits,
2517117f1b4Smrg                         GLint alphaBits,
2527117f1b4Smrg                         GLint indexBits,
2537117f1b4Smrg                         GLint depthBits,
2547117f1b4Smrg                         GLint stencilBits,
2557117f1b4Smrg                         GLint accumRedBits,
2567117f1b4Smrg                         GLint accumGreenBits,
2577117f1b4Smrg                         GLint accumBlueBits,
2587117f1b4Smrg                         GLint accumAlphaBits,
2597117f1b4Smrg                         GLint numSamples )
2607117f1b4Smrg{
2617117f1b4Smrg   assert(vis);
2627117f1b4Smrg
2637117f1b4Smrg   if (depthBits < 0 || depthBits > 32) {
2647117f1b4Smrg      return GL_FALSE;
2657117f1b4Smrg   }
2667117f1b4Smrg   if (stencilBits < 0 || stencilBits > STENCIL_BITS) {
2677117f1b4Smrg      return GL_FALSE;
2687117f1b4Smrg   }
2697117f1b4Smrg   assert(accumRedBits >= 0);
2707117f1b4Smrg   assert(accumGreenBits >= 0);
2717117f1b4Smrg   assert(accumBlueBits >= 0);
2727117f1b4Smrg   assert(accumAlphaBits >= 0);
2737117f1b4Smrg
2747117f1b4Smrg   vis->rgbMode          = rgbFlag;
2757117f1b4Smrg   vis->doubleBufferMode = dbFlag;
2767117f1b4Smrg   vis->stereoMode       = stereoFlag;
2777117f1b4Smrg
2787117f1b4Smrg   vis->redBits          = redBits;
2797117f1b4Smrg   vis->greenBits        = greenBits;
2807117f1b4Smrg   vis->blueBits         = blueBits;
2817117f1b4Smrg   vis->alphaBits        = alphaBits;
2827117f1b4Smrg   vis->rgbBits          = redBits + greenBits + blueBits;
2837117f1b4Smrg
2847117f1b4Smrg   vis->indexBits      = indexBits;
2857117f1b4Smrg   vis->depthBits      = depthBits;
2867117f1b4Smrg   vis->stencilBits    = stencilBits;
2877117f1b4Smrg
2887117f1b4Smrg   vis->accumRedBits   = accumRedBits;
2897117f1b4Smrg   vis->accumGreenBits = accumGreenBits;
2907117f1b4Smrg   vis->accumBlueBits  = accumBlueBits;
2917117f1b4Smrg   vis->accumAlphaBits = accumAlphaBits;
2927117f1b4Smrg
2937117f1b4Smrg   vis->haveAccumBuffer   = accumRedBits > 0;
2947117f1b4Smrg   vis->haveDepthBuffer   = depthBits > 0;
2957117f1b4Smrg   vis->haveStencilBuffer = stencilBits > 0;
2967117f1b4Smrg
2977117f1b4Smrg   vis->numAuxBuffers = 0;
2987117f1b4Smrg   vis->level = 0;
2997117f1b4Smrg   vis->pixmapMode = 0;
3007117f1b4Smrg   vis->sampleBuffers = numSamples > 0 ? 1 : 0;
3017117f1b4Smrg   vis->samples = numSamples;
3027117f1b4Smrg
3037117f1b4Smrg   return GL_TRUE;
3047117f1b4Smrg}
3057117f1b4Smrg
3067117f1b4Smrg
3077117f1b4Smrg/**
3087117f1b4Smrg * Destroy a visual and free its memory.
3097117f1b4Smrg *
3107117f1b4Smrg * \param vis visual.
3117117f1b4Smrg *
3127117f1b4Smrg * Frees the visual structure.
3137117f1b4Smrg */
3147117f1b4Smrgvoid
3157117f1b4Smrg_mesa_destroy_visual( GLvisual *vis )
3167117f1b4Smrg{
3177117f1b4Smrg   _mesa_free(vis);
3187117f1b4Smrg}
3197117f1b4Smrg
3207117f1b4Smrg/*@}*/
3217117f1b4Smrg
3227117f1b4Smrg
3237117f1b4Smrg/**********************************************************************/
3247117f1b4Smrg/** \name Context allocation, initialization, destroying
3257117f1b4Smrg *
3267117f1b4Smrg * The purpose of the most initialization functions here is to provide the
3277117f1b4Smrg * default state values according to the OpenGL specification.
3287117f1b4Smrg */
3297117f1b4Smrg/**********************************************************************/
3307117f1b4Smrg/*@{*/
3317117f1b4Smrg
3327117f1b4Smrg/**
3337117f1b4Smrg * One-time initialization mutex lock.
3347117f1b4Smrg *
3357117f1b4Smrg * \sa Used by one_time_init().
3367117f1b4Smrg */
3377117f1b4Smrg_glthread_DECLARE_STATIC_MUTEX(OneTimeLock);
3387117f1b4Smrg
3397117f1b4Smrg/**
3407117f1b4Smrg * Calls all the various one-time-init functions in Mesa.
3417117f1b4Smrg *
3427117f1b4Smrg * While holding a global mutex lock, calls several initialization functions,
3437117f1b4Smrg * and sets the glapi callbacks if the \c MESA_DEBUG environment variable is
3447117f1b4Smrg * defined.
3457117f1b4Smrg *
3467117f1b4Smrg * \sa _math_init().
3477117f1b4Smrg */
3487117f1b4Smrgstatic void
3497117f1b4Smrgone_time_init( GLcontext *ctx )
3507117f1b4Smrg{
3517117f1b4Smrg   static GLboolean alreadyCalled = GL_FALSE;
3527117f1b4Smrg   (void) ctx;
3537117f1b4Smrg   _glthread_LOCK_MUTEX(OneTimeLock);
3547117f1b4Smrg   if (!alreadyCalled) {
3557117f1b4Smrg      GLuint i;
3567117f1b4Smrg
3577117f1b4Smrg      /* do some implementation tests */
3587117f1b4Smrg      assert( sizeof(GLbyte) == 1 );
3597117f1b4Smrg      assert( sizeof(GLubyte) == 1 );
3607117f1b4Smrg      assert( sizeof(GLshort) == 2 );
3617117f1b4Smrg      assert( sizeof(GLushort) == 2 );
3627117f1b4Smrg      assert( sizeof(GLint) == 4 );
3637117f1b4Smrg      assert( sizeof(GLuint) == 4 );
3647117f1b4Smrg
3657117f1b4Smrg      _mesa_init_sqrt_table();
3667117f1b4Smrg
3677117f1b4Smrg#if _HAVE_FULL_GL
3687117f1b4Smrg      _math_init();
3697117f1b4Smrg
3707117f1b4Smrg      for (i = 0; i < 256; i++) {
3717117f1b4Smrg         _mesa_ubyte_to_float_color_tab[i] = (float) i / 255.0F;
3727117f1b4Smrg      }
3737117f1b4Smrg#endif
3747117f1b4Smrg
3757117f1b4Smrg#ifdef USE_SPARC_ASM
3767117f1b4Smrg      _mesa_init_sparc_glapi_relocs();
3777117f1b4Smrg#endif
3787117f1b4Smrg      if (_mesa_getenv("MESA_DEBUG")) {
3797117f1b4Smrg         _glapi_noop_enable_warnings(GL_TRUE);
3807117f1b4Smrg         _glapi_set_warning_func( (_glapi_warning_func) _mesa_warning );
3817117f1b4Smrg      }
3827117f1b4Smrg      else {
3837117f1b4Smrg         _glapi_noop_enable_warnings(GL_FALSE);
3847117f1b4Smrg      }
3857117f1b4Smrg
3867117f1b4Smrg#if defined(DEBUG) && defined(__DATE__) && defined(__TIME__)
3877117f1b4Smrg      _mesa_debug(ctx, "Mesa %s DEBUG build %s %s\n",
3887117f1b4Smrg                  MESA_VERSION_STRING, __DATE__, __TIME__);
3897117f1b4Smrg#endif
3907117f1b4Smrg
3917117f1b4Smrg      alreadyCalled = GL_TRUE;
3927117f1b4Smrg   }
3937117f1b4Smrg   _glthread_UNLOCK_MUTEX(OneTimeLock);
3947117f1b4Smrg}
3957117f1b4Smrg
3967117f1b4Smrg
3977117f1b4Smrg/**
3987117f1b4Smrg * Allocate and initialize a shared context state structure.
3997117f1b4Smrg * Initializes the display list, texture objects and vertex programs hash
4007117f1b4Smrg * tables, allocates the texture objects. If it runs out of memory, frees
4017117f1b4Smrg * everything already allocated before returning NULL.
4027117f1b4Smrg *
4037117f1b4Smrg * \return pointer to a gl_shared_state structure on success, or NULL on
4047117f1b4Smrg * failure.
4057117f1b4Smrg */
4067117f1b4Smrgstatic GLboolean
4077117f1b4Smrgalloc_shared_state( GLcontext *ctx )
4087117f1b4Smrg{
4097117f1b4Smrg   struct gl_shared_state *ss = CALLOC_STRUCT(gl_shared_state);
4107117f1b4Smrg   if (!ss)
4117117f1b4Smrg      return GL_FALSE;
4127117f1b4Smrg
4137117f1b4Smrg   ctx->Shared = ss;
4147117f1b4Smrg
4157117f1b4Smrg   _glthread_INIT_MUTEX(ss->Mutex);
4167117f1b4Smrg
4177117f1b4Smrg   ss->DisplayList = _mesa_NewHashTable();
4187117f1b4Smrg   ss->TexObjects = _mesa_NewHashTable();
4197117f1b4Smrg#if FEATURE_NV_vertex_program || FEATURE_NV_fragment_program
4207117f1b4Smrg   ss->Programs = _mesa_NewHashTable();
4217117f1b4Smrg#endif
4227117f1b4Smrg
4237117f1b4Smrg#if FEATURE_ARB_vertex_program
4247117f1b4Smrg   ss->DefaultVertexProgram = ctx->Driver.NewProgram(ctx, GL_VERTEX_PROGRAM_ARB, 0);
4257117f1b4Smrg   if (!ss->DefaultVertexProgram)
4267117f1b4Smrg      goto cleanup;
4277117f1b4Smrg#endif
4287117f1b4Smrg#if FEATURE_ARB_fragment_program
4297117f1b4Smrg   ss->DefaultFragmentProgram = ctx->Driver.NewProgram(ctx, GL_FRAGMENT_PROGRAM_ARB, 0);
4307117f1b4Smrg   if (!ss->DefaultFragmentProgram)
4317117f1b4Smrg      goto cleanup;
4327117f1b4Smrg#endif
4337117f1b4Smrg#if FEATURE_ATI_fragment_shader
4347117f1b4Smrg   ss->ATIShaders = _mesa_NewHashTable();
4357117f1b4Smrg   ss->DefaultFragmentShader = _mesa_new_ati_fragment_shader(ctx, 0);
4367117f1b4Smrg   if (!ss->DefaultFragmentShader)
4377117f1b4Smrg      goto cleanup;
4387117f1b4Smrg#endif
4397117f1b4Smrg
4407117f1b4Smrg#if FEATURE_ARB_vertex_buffer_object || FEATURE_ARB_pixel_buffer_object
4417117f1b4Smrg   ss->BufferObjects = _mesa_NewHashTable();
4427117f1b4Smrg#endif
4437117f1b4Smrg
4447117f1b4Smrg   ss->ArrayObjects = _mesa_NewHashTable();
4457117f1b4Smrg
4467117f1b4Smrg#if FEATURE_ARB_shader_objects
4477117f1b4Smrg   ss->ShaderObjects = _mesa_NewHashTable();
4487117f1b4Smrg#endif
4497117f1b4Smrg
4507117f1b4Smrg   ss->Default1D = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_1D);
4517117f1b4Smrg   if (!ss->Default1D)
4527117f1b4Smrg      goto cleanup;
4537117f1b4Smrg
4547117f1b4Smrg   ss->Default2D = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_2D);
4557117f1b4Smrg   if (!ss->Default2D)
4567117f1b4Smrg      goto cleanup;
4577117f1b4Smrg
4587117f1b4Smrg   ss->Default3D = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_3D);
4597117f1b4Smrg   if (!ss->Default3D)
4607117f1b4Smrg      goto cleanup;
4617117f1b4Smrg
4627117f1b4Smrg   ss->DefaultCubeMap = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_CUBE_MAP_ARB);
4637117f1b4Smrg   if (!ss->DefaultCubeMap)
4647117f1b4Smrg      goto cleanup;
4657117f1b4Smrg
4667117f1b4Smrg   ss->DefaultRect = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_RECTANGLE_NV);
4677117f1b4Smrg   if (!ss->DefaultRect)
4687117f1b4Smrg      goto cleanup;
4697117f1b4Smrg
4707117f1b4Smrg   /* sanity check */
4717117f1b4Smrg   assert(ss->Default1D->RefCount == 1);
4727117f1b4Smrg
4737117f1b4Smrg   _glthread_INIT_MUTEX(ss->TexMutex);
4747117f1b4Smrg   ss->TextureStateStamp = 0;
4757117f1b4Smrg
4767117f1b4Smrg#if FEATURE_EXT_framebuffer_object
4777117f1b4Smrg   ss->FrameBuffers = _mesa_NewHashTable();
4787117f1b4Smrg   if (!ss->FrameBuffers)
4797117f1b4Smrg      goto cleanup;
4807117f1b4Smrg   ss->RenderBuffers = _mesa_NewHashTable();
4817117f1b4Smrg   if (!ss->RenderBuffers)
4827117f1b4Smrg      goto cleanup;
4837117f1b4Smrg#endif
4847117f1b4Smrg
4857117f1b4Smrg   return GL_TRUE;
4867117f1b4Smrg
4877117f1b4Smrgcleanup:
4887117f1b4Smrg   /* Ran out of memory at some point.  Free everything and return NULL */
4897117f1b4Smrg   if (ss->DisplayList)
4907117f1b4Smrg      _mesa_DeleteHashTable(ss->DisplayList);
4917117f1b4Smrg   if (ss->TexObjects)
4927117f1b4Smrg      _mesa_DeleteHashTable(ss->TexObjects);
4937117f1b4Smrg#if FEATURE_NV_vertex_program
4947117f1b4Smrg   if (ss->Programs)
4957117f1b4Smrg      _mesa_DeleteHashTable(ss->Programs);
4967117f1b4Smrg#endif
4977117f1b4Smrg#if FEATURE_ARB_vertex_program
4987117f1b4Smrg   if (ss->DefaultVertexProgram)
4997117f1b4Smrg      ctx->Driver.DeleteProgram(ctx, ss->DefaultVertexProgram);
5007117f1b4Smrg#endif
5017117f1b4Smrg#if FEATURE_ARB_fragment_program
5027117f1b4Smrg   if (ss->DefaultFragmentProgram)
5037117f1b4Smrg      ctx->Driver.DeleteProgram(ctx, ss->DefaultFragmentProgram);
5047117f1b4Smrg#endif
5057117f1b4Smrg#if FEATURE_ATI_fragment_shader
5067117f1b4Smrg   if (ss->DefaultFragmentShader)
5077117f1b4Smrg      _mesa_delete_ati_fragment_shader(ctx, ss->DefaultFragmentShader);
5087117f1b4Smrg#endif
5097117f1b4Smrg#if FEATURE_ARB_vertex_buffer_object || FEATURE_ARB_pixel_buffer_object
5107117f1b4Smrg   if (ss->BufferObjects)
5117117f1b4Smrg      _mesa_DeleteHashTable(ss->BufferObjects);
5127117f1b4Smrg#endif
5137117f1b4Smrg
5147117f1b4Smrg   if (ss->ArrayObjects)
5157117f1b4Smrg      _mesa_DeleteHashTable (ss->ArrayObjects);
5167117f1b4Smrg
5177117f1b4Smrg#if FEATURE_ARB_shader_objects
5187117f1b4Smrg   if (ss->ShaderObjects)
5197117f1b4Smrg      _mesa_DeleteHashTable (ss->ShaderObjects);
5207117f1b4Smrg#endif
5217117f1b4Smrg
5227117f1b4Smrg#if FEATURE_EXT_framebuffer_object
5237117f1b4Smrg   if (ss->FrameBuffers)
5247117f1b4Smrg      _mesa_DeleteHashTable(ss->FrameBuffers);
5257117f1b4Smrg   if (ss->RenderBuffers)
5267117f1b4Smrg      _mesa_DeleteHashTable(ss->RenderBuffers);
5277117f1b4Smrg#endif
5287117f1b4Smrg
5297117f1b4Smrg   if (ss->Default1D)
5307117f1b4Smrg      (*ctx->Driver.DeleteTexture)(ctx, ss->Default1D);
5317117f1b4Smrg   if (ss->Default2D)
5327117f1b4Smrg      (*ctx->Driver.DeleteTexture)(ctx, ss->Default2D);
5337117f1b4Smrg   if (ss->Default3D)
5347117f1b4Smrg      (*ctx->Driver.DeleteTexture)(ctx, ss->Default3D);
5357117f1b4Smrg   if (ss->DefaultCubeMap)
5367117f1b4Smrg      (*ctx->Driver.DeleteTexture)(ctx, ss->DefaultCubeMap);
5377117f1b4Smrg   if (ss->DefaultRect)
5387117f1b4Smrg      (*ctx->Driver.DeleteTexture)(ctx, ss->DefaultRect);
5397117f1b4Smrg   if (ss)
5407117f1b4Smrg      _mesa_free(ss);
5417117f1b4Smrg   return GL_FALSE;
5427117f1b4Smrg}
5437117f1b4Smrg
5447117f1b4Smrg
5457117f1b4Smrg/**
5467117f1b4Smrg * Callback for deleting a display list.  Called by _mesa_HashDeleteAll().
5477117f1b4Smrg */
5487117f1b4Smrgstatic void
5497117f1b4Smrgdelete_displaylist_cb(GLuint id, void *data, void *userData)
5507117f1b4Smrg{
5517117f1b4Smrg   struct mesa_display_list *list = (struct mesa_display_list *) data;
5527117f1b4Smrg   GLcontext *ctx = (GLcontext *) userData;
5537117f1b4Smrg   _mesa_delete_list(ctx, list);
5547117f1b4Smrg}
5557117f1b4Smrg
5567117f1b4Smrg/**
5577117f1b4Smrg * Callback for deleting a texture object.  Called by _mesa_HashDeleteAll().
5587117f1b4Smrg */
5597117f1b4Smrgstatic void
5607117f1b4Smrgdelete_texture_cb(GLuint id, void *data, void *userData)
5617117f1b4Smrg{
5627117f1b4Smrg   struct gl_texture_object *texObj = (struct gl_texture_object *) data;
5637117f1b4Smrg   GLcontext *ctx = (GLcontext *) userData;
5647117f1b4Smrg   ctx->Driver.DeleteTexture(ctx, texObj);
5657117f1b4Smrg}
5667117f1b4Smrg
5677117f1b4Smrg/**
5687117f1b4Smrg * Callback for deleting a program object.  Called by _mesa_HashDeleteAll().
5697117f1b4Smrg */
5707117f1b4Smrgstatic void
5717117f1b4Smrgdelete_program_cb(GLuint id, void *data, void *userData)
5727117f1b4Smrg{
5737117f1b4Smrg   struct gl_program *prog = (struct gl_program *) data;
5747117f1b4Smrg   GLcontext *ctx = (GLcontext *) userData;
5757117f1b4Smrg   ctx->Driver.DeleteProgram(ctx, prog);
5767117f1b4Smrg}
5777117f1b4Smrg
5787117f1b4Smrg/**
5797117f1b4Smrg * Callback for deleting an ATI fragment shader object.
5807117f1b4Smrg * Called by _mesa_HashDeleteAll().
5817117f1b4Smrg */
5827117f1b4Smrgstatic void
5837117f1b4Smrgdelete_fragshader_cb(GLuint id, void *data, void *userData)
5847117f1b4Smrg{
5857117f1b4Smrg   struct ati_fragment_shader *shader = (struct ati_fragment_shader *) data;
5867117f1b4Smrg   GLcontext *ctx = (GLcontext *) userData;
5877117f1b4Smrg   _mesa_delete_ati_fragment_shader(ctx, shader);
5887117f1b4Smrg}
5897117f1b4Smrg
5907117f1b4Smrg/**
5917117f1b4Smrg * Callback for deleting a buffer object.  Called by _mesa_HashDeleteAll().
5927117f1b4Smrg */
5937117f1b4Smrgstatic void
5947117f1b4Smrgdelete_bufferobj_cb(GLuint id, void *data, void *userData)
5957117f1b4Smrg{
5967117f1b4Smrg   struct gl_buffer_object *bufObj = (struct gl_buffer_object *) data;
5977117f1b4Smrg   GLcontext *ctx = (GLcontext *) userData;
5987117f1b4Smrg   ctx->Driver.DeleteBuffer(ctx, bufObj);
5997117f1b4Smrg}
6007117f1b4Smrg
6017117f1b4Smrg/**
6027117f1b4Smrg * Callback for deleting an array object.  Called by _mesa_HashDeleteAll().
6037117f1b4Smrg */
6047117f1b4Smrgstatic void
6057117f1b4Smrgdelete_arrayobj_cb(GLuint id, void *data, void *userData)
6067117f1b4Smrg{
6077117f1b4Smrg   struct gl_array_object *arrayObj = (struct gl_array_object *) data;
6087117f1b4Smrg   GLcontext *ctx = (GLcontext *) userData;
6097117f1b4Smrg   _mesa_delete_array_object(ctx, arrayObj);
6107117f1b4Smrg}
6117117f1b4Smrg
6127117f1b4Smrg/**
6137117f1b4Smrg * Callback for deleting shader and shader programs objects.
6147117f1b4Smrg * Called by _mesa_HashDeleteAll().
6157117f1b4Smrg */
6167117f1b4Smrgstatic void
6177117f1b4Smrgdelete_shader_cb(GLuint id, void *data, void *userData)
6187117f1b4Smrg{
6197117f1b4Smrg   GLcontext *ctx = (GLcontext *) userData;
6207117f1b4Smrg   struct gl_shader *sh = (struct gl_shader *) data;
6217117f1b4Smrg   if (sh->Type == GL_FRAGMENT_SHADER || sh->Type == GL_VERTEX_SHADER) {
6227117f1b4Smrg      _mesa_free_shader(ctx, sh);
6237117f1b4Smrg   }
6247117f1b4Smrg   else {
6257117f1b4Smrg      struct gl_shader_program *shProg = (struct gl_shader_program *) data;
6267117f1b4Smrg      ASSERT(shProg->Type == GL_SHADER_PROGRAM_MESA);
6277117f1b4Smrg      _mesa_free_shader_program(ctx, shProg);
6287117f1b4Smrg   }
6297117f1b4Smrg}
6307117f1b4Smrg
6317117f1b4Smrg/**
6327117f1b4Smrg * Callback for deleting a framebuffer object.  Called by _mesa_HashDeleteAll()
6337117f1b4Smrg */
6347117f1b4Smrgstatic void
6357117f1b4Smrgdelete_framebuffer_cb(GLuint id, void *data, void *userData)
6367117f1b4Smrg{
6377117f1b4Smrg   struct gl_framebuffer *fb = (struct gl_framebuffer *) data;
6387117f1b4Smrg   /* The fact that the framebuffer is in the hashtable means its refcount
6397117f1b4Smrg    * is one, but we're removing from the hashtable now.  So clear refcount.
6407117f1b4Smrg    */
6417117f1b4Smrg   /*assert(fb->RefCount == 1);*/
6427117f1b4Smrg   fb->RefCount = 0;
6437117f1b4Smrg
6447117f1b4Smrg   /* NOTE: Delete should always be defined but there are two reports
6457117f1b4Smrg    * of it being NULL (bugs 13507, 14293).  Work-around for now.
6467117f1b4Smrg    */
6477117f1b4Smrg   if (fb->Delete)
6487117f1b4Smrg      fb->Delete(fb);
6497117f1b4Smrg}
6507117f1b4Smrg
6517117f1b4Smrg/**
6527117f1b4Smrg * Callback for deleting a renderbuffer object. Called by _mesa_HashDeleteAll()
6537117f1b4Smrg */
6547117f1b4Smrgstatic void
6557117f1b4Smrgdelete_renderbuffer_cb(GLuint id, void *data, void *userData)
6567117f1b4Smrg{
6577117f1b4Smrg   struct gl_renderbuffer *rb = (struct gl_renderbuffer *) data;
6587117f1b4Smrg   rb->RefCount = 0;  /* see comment for FBOs above */
6597117f1b4Smrg   rb->Delete(rb);
6607117f1b4Smrg}
6617117f1b4Smrg
6627117f1b4Smrg
6637117f1b4Smrg
6647117f1b4Smrg/**
6657117f1b4Smrg * Deallocate a shared state object and all children structures.
6667117f1b4Smrg *
6677117f1b4Smrg * \param ctx GL context.
6687117f1b4Smrg * \param ss shared state pointer.
6697117f1b4Smrg *
6707117f1b4Smrg * Frees the display lists, the texture objects (calling the driver texture
6717117f1b4Smrg * deletion callback to free its private data) and the vertex programs, as well
6727117f1b4Smrg * as their hash tables.
6737117f1b4Smrg *
6747117f1b4Smrg * \sa alloc_shared_state().
6757117f1b4Smrg */
6767117f1b4Smrgstatic void
6777117f1b4Smrgfree_shared_state( GLcontext *ctx, struct gl_shared_state *ss )
6787117f1b4Smrg{
6797117f1b4Smrg   /*
6807117f1b4Smrg    * Free display lists
6817117f1b4Smrg    */
6827117f1b4Smrg   _mesa_HashDeleteAll(ss->DisplayList, delete_displaylist_cb, ctx);
6837117f1b4Smrg   _mesa_DeleteHashTable(ss->DisplayList);
6847117f1b4Smrg
6857117f1b4Smrg#if defined(FEATURE_NV_vertex_program) || defined(FEATURE_NV_fragment_program)
6867117f1b4Smrg   _mesa_HashDeleteAll(ss->Programs, delete_program_cb, ctx);
6877117f1b4Smrg   _mesa_DeleteHashTable(ss->Programs);
6887117f1b4Smrg#endif
6897117f1b4Smrg#if FEATURE_ARB_vertex_program
6907117f1b4Smrg   ctx->Driver.DeleteProgram(ctx, ss->DefaultVertexProgram);
6917117f1b4Smrg#endif
6927117f1b4Smrg#if FEATURE_ARB_fragment_program
6937117f1b4Smrg   ctx->Driver.DeleteProgram(ctx, ss->DefaultFragmentProgram);
6947117f1b4Smrg#endif
6957117f1b4Smrg
6967117f1b4Smrg#if FEATURE_ATI_fragment_shader
6977117f1b4Smrg   _mesa_HashDeleteAll(ss->ATIShaders, delete_fragshader_cb, ctx);
6987117f1b4Smrg   _mesa_DeleteHashTable(ss->ATIShaders);
6997117f1b4Smrg   _mesa_delete_ati_fragment_shader(ctx, ss->DefaultFragmentShader);
7007117f1b4Smrg#endif
7017117f1b4Smrg
7027117f1b4Smrg#if FEATURE_ARB_vertex_buffer_object || FEATURE_ARB_pixel_buffer_object
7037117f1b4Smrg   _mesa_HashDeleteAll(ss->BufferObjects, delete_bufferobj_cb, ctx);
7047117f1b4Smrg   _mesa_DeleteHashTable(ss->BufferObjects);
7057117f1b4Smrg#endif
7067117f1b4Smrg
7077117f1b4Smrg   _mesa_HashDeleteAll(ss->ArrayObjects, delete_arrayobj_cb, ctx);
7087117f1b4Smrg   _mesa_DeleteHashTable(ss->ArrayObjects);
7097117f1b4Smrg
7107117f1b4Smrg#if FEATURE_ARB_shader_objects
7117117f1b4Smrg   _mesa_HashDeleteAll(ss->ShaderObjects, delete_shader_cb, ctx);
7127117f1b4Smrg   _mesa_DeleteHashTable(ss->ShaderObjects);
7137117f1b4Smrg#endif
7147117f1b4Smrg
7157117f1b4Smrg#if FEATURE_EXT_framebuffer_object
7167117f1b4Smrg   _mesa_HashDeleteAll(ss->FrameBuffers, delete_framebuffer_cb, ctx);
7177117f1b4Smrg   _mesa_DeleteHashTable(ss->FrameBuffers);
7187117f1b4Smrg   _mesa_HashDeleteAll(ss->RenderBuffers, delete_renderbuffer_cb, ctx);
7197117f1b4Smrg   _mesa_DeleteHashTable(ss->RenderBuffers);
7207117f1b4Smrg#endif
7217117f1b4Smrg
7227117f1b4Smrg   /*
7237117f1b4Smrg    * Free texture objects (after FBOs since some textures might have
7247117f1b4Smrg    * been bound to FBOs).
7257117f1b4Smrg    */
7267117f1b4Smrg   ASSERT(ctx->Driver.DeleteTexture);
7277117f1b4Smrg   /* the default textures */
7287117f1b4Smrg   ctx->Driver.DeleteTexture(ctx, ss->Default1D);
7297117f1b4Smrg   ctx->Driver.DeleteTexture(ctx, ss->Default2D);
7307117f1b4Smrg   ctx->Driver.DeleteTexture(ctx, ss->Default3D);
7317117f1b4Smrg   ctx->Driver.DeleteTexture(ctx, ss->DefaultCubeMap);
7327117f1b4Smrg   ctx->Driver.DeleteTexture(ctx, ss->DefaultRect);
7337117f1b4Smrg   /* all other textures */
7347117f1b4Smrg   _mesa_HashDeleteAll(ss->TexObjects, delete_texture_cb, ctx);
7357117f1b4Smrg   _mesa_DeleteHashTable(ss->TexObjects);
7367117f1b4Smrg
7377117f1b4Smrg   _glthread_DESTROY_MUTEX(ss->Mutex);
7387117f1b4Smrg
7397117f1b4Smrg   _mesa_free(ss);
7407117f1b4Smrg}
7417117f1b4Smrg
7427117f1b4Smrg
7437117f1b4Smrg/**
7447117f1b4Smrg * Initialize fields of gl_current_attrib (aka ctx->Current.*)
7457117f1b4Smrg */
7467117f1b4Smrgstatic void
7477117f1b4Smrg_mesa_init_current(GLcontext *ctx)
7487117f1b4Smrg{
7497117f1b4Smrg   GLuint i;
7507117f1b4Smrg
7517117f1b4Smrg   /* Init all to (0,0,0,1) */
7527117f1b4Smrg   for (i = 0; i < VERT_ATTRIB_MAX; i++) {
7537117f1b4Smrg      ASSIGN_4V( ctx->Current.Attrib[i], 0.0, 0.0, 0.0, 1.0 );
7547117f1b4Smrg   }
7557117f1b4Smrg
7567117f1b4Smrg   /* redo special cases: */
7577117f1b4Smrg   ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_WEIGHT], 1.0, 0.0, 0.0, 0.0 );
7587117f1b4Smrg   ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_NORMAL], 0.0, 0.0, 1.0, 1.0 );
7597117f1b4Smrg   ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_COLOR0], 1.0, 1.0, 1.0, 1.0 );
7607117f1b4Smrg   ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_COLOR1], 0.0, 0.0, 0.0, 1.0 );
7617117f1b4Smrg   ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_COLOR_INDEX], 1.0, 0.0, 0.0, 1.0 );
7627117f1b4Smrg   ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_EDGEFLAG], 1.0, 0.0, 0.0, 1.0 );
7637117f1b4Smrg}
7647117f1b4Smrg
7657117f1b4Smrg
7667117f1b4Smrg/**
7677117f1b4Smrg * Init vertex/fragment program native limits from logical limits.
7687117f1b4Smrg */
7697117f1b4Smrgstatic void
7707117f1b4Smrginit_natives(struct gl_program_constants *prog)
7717117f1b4Smrg{
7727117f1b4Smrg   prog->MaxNativeInstructions = prog->MaxInstructions;
7737117f1b4Smrg   prog->MaxNativeAluInstructions = prog->MaxAluInstructions;
7747117f1b4Smrg   prog->MaxNativeTexInstructions = prog->MaxTexInstructions;
7757117f1b4Smrg   prog->MaxNativeTexIndirections = prog->MaxTexIndirections;
7767117f1b4Smrg   prog->MaxNativeAttribs = prog->MaxAttribs;
7777117f1b4Smrg   prog->MaxNativeTemps = prog->MaxTemps;
7787117f1b4Smrg   prog->MaxNativeAddressRegs = prog->MaxAddressRegs;
7797117f1b4Smrg   prog->MaxNativeParameters = prog->MaxParameters;
7807117f1b4Smrg}
7817117f1b4Smrg
7827117f1b4Smrg
7837117f1b4Smrg/**
7847117f1b4Smrg * Initialize fields of gl_constants (aka ctx->Const.*).
7857117f1b4Smrg * Use defaults from config.h.  The device drivers will often override
7867117f1b4Smrg * some of these values (such as number of texture units).
7877117f1b4Smrg */
7887117f1b4Smrgstatic void
7897117f1b4Smrg_mesa_init_constants(GLcontext *ctx)
7907117f1b4Smrg{
7917117f1b4Smrg   assert(ctx);
7927117f1b4Smrg
7937117f1b4Smrg   assert(MAX_TEXTURE_LEVELS >= MAX_3D_TEXTURE_LEVELS);
7947117f1b4Smrg   assert(MAX_TEXTURE_LEVELS >= MAX_CUBE_TEXTURE_LEVELS);
7957117f1b4Smrg
7967117f1b4Smrg   assert(MAX_TEXTURE_UNITS >= MAX_TEXTURE_COORD_UNITS);
7977117f1b4Smrg   assert(MAX_TEXTURE_UNITS >= MAX_TEXTURE_IMAGE_UNITS);
7987117f1b4Smrg
7997117f1b4Smrg   /* Constants, may be overriden (usually only reduced) by device drivers */
8007117f1b4Smrg   ctx->Const.MaxTextureLevels = MAX_TEXTURE_LEVELS;
8017117f1b4Smrg   ctx->Const.Max3DTextureLevels = MAX_3D_TEXTURE_LEVELS;
8027117f1b4Smrg   ctx->Const.MaxCubeTextureLevels = MAX_CUBE_TEXTURE_LEVELS;
8037117f1b4Smrg   ctx->Const.MaxTextureRectSize = MAX_TEXTURE_RECT_SIZE;
8047117f1b4Smrg   ctx->Const.MaxTextureCoordUnits = MAX_TEXTURE_COORD_UNITS;
8057117f1b4Smrg   ctx->Const.MaxTextureImageUnits = MAX_TEXTURE_IMAGE_UNITS;
8067117f1b4Smrg   ctx->Const.MaxTextureUnits = MIN2(ctx->Const.MaxTextureCoordUnits,
8077117f1b4Smrg                                     ctx->Const.MaxTextureImageUnits);
8087117f1b4Smrg   ctx->Const.MaxTextureMaxAnisotropy = MAX_TEXTURE_MAX_ANISOTROPY;
8097117f1b4Smrg   ctx->Const.MaxTextureLodBias = MAX_TEXTURE_LOD_BIAS;
8107117f1b4Smrg   ctx->Const.MaxArrayLockSize = MAX_ARRAY_LOCK_SIZE;
8117117f1b4Smrg   ctx->Const.SubPixelBits = SUB_PIXEL_BITS;
8127117f1b4Smrg   ctx->Const.MinPointSize = MIN_POINT_SIZE;
8137117f1b4Smrg   ctx->Const.MaxPointSize = MAX_POINT_SIZE;
8147117f1b4Smrg   ctx->Const.MinPointSizeAA = MIN_POINT_SIZE;
8157117f1b4Smrg   ctx->Const.MaxPointSizeAA = MAX_POINT_SIZE;
8167117f1b4Smrg   ctx->Const.PointSizeGranularity = (GLfloat) POINT_SIZE_GRANULARITY;
8177117f1b4Smrg   ctx->Const.MinLineWidth = MIN_LINE_WIDTH;
8187117f1b4Smrg   ctx->Const.MaxLineWidth = MAX_LINE_WIDTH;
8197117f1b4Smrg   ctx->Const.MinLineWidthAA = MIN_LINE_WIDTH;
8207117f1b4Smrg   ctx->Const.MaxLineWidthAA = MAX_LINE_WIDTH;
8217117f1b4Smrg   ctx->Const.LineWidthGranularity = (GLfloat) LINE_WIDTH_GRANULARITY;
8227117f1b4Smrg   ctx->Const.MaxColorTableSize = MAX_COLOR_TABLE_SIZE;
8237117f1b4Smrg   ctx->Const.MaxConvolutionWidth = MAX_CONVOLUTION_WIDTH;
8247117f1b4Smrg   ctx->Const.MaxConvolutionHeight = MAX_CONVOLUTION_HEIGHT;
8257117f1b4Smrg   ctx->Const.MaxClipPlanes = MAX_CLIP_PLANES;
8267117f1b4Smrg   ctx->Const.MaxLights = MAX_LIGHTS;
8277117f1b4Smrg   ctx->Const.MaxShininess = 128.0;
8287117f1b4Smrg   ctx->Const.MaxSpotExponent = 128.0;
8297117f1b4Smrg   ctx->Const.MaxViewportWidth = MAX_WIDTH;
8307117f1b4Smrg   ctx->Const.MaxViewportHeight = MAX_HEIGHT;
8317117f1b4Smrg#if FEATURE_ARB_vertex_program
8327117f1b4Smrg   ctx->Const.VertexProgram.MaxInstructions = MAX_NV_VERTEX_PROGRAM_INSTRUCTIONS;
8337117f1b4Smrg   ctx->Const.VertexProgram.MaxAluInstructions = 0;
8347117f1b4Smrg   ctx->Const.VertexProgram.MaxTexInstructions = 0;
8357117f1b4Smrg   ctx->Const.VertexProgram.MaxTexIndirections = 0;
8367117f1b4Smrg   ctx->Const.VertexProgram.MaxAttribs = MAX_NV_VERTEX_PROGRAM_INPUTS;
8377117f1b4Smrg   ctx->Const.VertexProgram.MaxTemps = MAX_PROGRAM_TEMPS;
8387117f1b4Smrg   ctx->Const.VertexProgram.MaxParameters = MAX_NV_VERTEX_PROGRAM_PARAMS;
8397117f1b4Smrg   ctx->Const.VertexProgram.MaxLocalParams = MAX_PROGRAM_LOCAL_PARAMS;
8407117f1b4Smrg   ctx->Const.VertexProgram.MaxEnvParams = MAX_PROGRAM_ENV_PARAMS;
8417117f1b4Smrg   ctx->Const.VertexProgram.MaxAddressRegs = MAX_VERTEX_PROGRAM_ADDRESS_REGS;
8427117f1b4Smrg   ctx->Const.VertexProgram.MaxUniformComponents = 4 * MAX_UNIFORMS;
8437117f1b4Smrg   init_natives(&ctx->Const.VertexProgram);
8447117f1b4Smrg#endif
8457117f1b4Smrg
8467117f1b4Smrg#if FEATURE_ARB_fragment_program
8477117f1b4Smrg   ctx->Const.FragmentProgram.MaxInstructions = MAX_NV_FRAGMENT_PROGRAM_INSTRUCTIONS;
8487117f1b4Smrg   ctx->Const.FragmentProgram.MaxAluInstructions = MAX_FRAGMENT_PROGRAM_ALU_INSTRUCTIONS;
8497117f1b4Smrg   ctx->Const.FragmentProgram.MaxTexInstructions = MAX_FRAGMENT_PROGRAM_TEX_INSTRUCTIONS;
8507117f1b4Smrg   ctx->Const.FragmentProgram.MaxTexIndirections = MAX_FRAGMENT_PROGRAM_TEX_INDIRECTIONS;
8517117f1b4Smrg   ctx->Const.FragmentProgram.MaxAttribs = MAX_NV_FRAGMENT_PROGRAM_INPUTS;
8527117f1b4Smrg   ctx->Const.FragmentProgram.MaxTemps = MAX_PROGRAM_TEMPS;
8537117f1b4Smrg   ctx->Const.FragmentProgram.MaxParameters = MAX_NV_FRAGMENT_PROGRAM_PARAMS;
8547117f1b4Smrg   ctx->Const.FragmentProgram.MaxLocalParams = MAX_PROGRAM_LOCAL_PARAMS;
8557117f1b4Smrg   ctx->Const.FragmentProgram.MaxEnvParams = MAX_PROGRAM_ENV_PARAMS;
8567117f1b4Smrg   ctx->Const.FragmentProgram.MaxAddressRegs = MAX_FRAGMENT_PROGRAM_ADDRESS_REGS;
8577117f1b4Smrg   ctx->Const.FragmentProgram.MaxUniformComponents = 4 * MAX_UNIFORMS;
8587117f1b4Smrg   init_natives(&ctx->Const.FragmentProgram);
8597117f1b4Smrg#endif
8607117f1b4Smrg   ctx->Const.MaxProgramMatrices = MAX_PROGRAM_MATRICES;
8617117f1b4Smrg   ctx->Const.MaxProgramMatrixStackDepth = MAX_PROGRAM_MATRIX_STACK_DEPTH;
8627117f1b4Smrg
8637117f1b4Smrg   /* CheckArrayBounds is overriden by drivers/x11 for X server */
8647117f1b4Smrg   ctx->Const.CheckArrayBounds = GL_FALSE;
8657117f1b4Smrg
8667117f1b4Smrg   /* GL_ARB_draw_buffers */
8677117f1b4Smrg   ctx->Const.MaxDrawBuffers = MAX_DRAW_BUFFERS;
8687117f1b4Smrg
8697117f1b4Smrg   /* GL_OES_read_format */
8707117f1b4Smrg   ctx->Const.ColorReadFormat = GL_RGBA;
8717117f1b4Smrg   ctx->Const.ColorReadType = GL_UNSIGNED_BYTE;
8727117f1b4Smrg
8737117f1b4Smrg#if FEATURE_EXT_framebuffer_object
8747117f1b4Smrg   ctx->Const.MaxColorAttachments = MAX_COLOR_ATTACHMENTS;
8757117f1b4Smrg   ctx->Const.MaxRenderbufferSize = MAX_WIDTH;
8767117f1b4Smrg#endif
8777117f1b4Smrg
8787117f1b4Smrg#if FEATURE_ARB_vertex_shader
8797117f1b4Smrg   ctx->Const.MaxVertexTextureImageUnits = MAX_VERTEX_TEXTURE_IMAGE_UNITS;
8807117f1b4Smrg   ctx->Const.MaxVarying = MAX_VARYING;
8817117f1b4Smrg#endif
8827117f1b4Smrg
8837117f1b4Smrg   /* sanity checks */
8847117f1b4Smrg   ASSERT(ctx->Const.MaxTextureUnits == MIN2(ctx->Const.MaxTextureImageUnits,
8857117f1b4Smrg                                             ctx->Const.MaxTextureCoordUnits));
8867117f1b4Smrg   ASSERT(ctx->Const.FragmentProgram.MaxLocalParams <= MAX_PROGRAM_LOCAL_PARAMS);
8877117f1b4Smrg   ASSERT(ctx->Const.VertexProgram.MaxLocalParams <= MAX_PROGRAM_LOCAL_PARAMS);
8887117f1b4Smrg
8897117f1b4Smrg   ASSERT(MAX_NV_FRAGMENT_PROGRAM_TEMPS <= MAX_PROGRAM_TEMPS);
8907117f1b4Smrg   ASSERT(MAX_NV_VERTEX_PROGRAM_TEMPS <= MAX_PROGRAM_TEMPS);
8917117f1b4Smrg   ASSERT(MAX_NV_VERTEX_PROGRAM_INPUTS <= VERT_ATTRIB_MAX);
8927117f1b4Smrg   ASSERT(MAX_NV_VERTEX_PROGRAM_OUTPUTS <= VERT_RESULT_MAX);
8937117f1b4Smrg}
8947117f1b4Smrg
8957117f1b4Smrg
8967117f1b4Smrg/**
8977117f1b4Smrg * Do some sanity checks on the limits/constants for the given context.
8987117f1b4Smrg * Only called the first time a context is bound.
8997117f1b4Smrg */
9007117f1b4Smrgstatic void
9017117f1b4Smrgcheck_context_limits(GLcontext *ctx)
9027117f1b4Smrg{
9037117f1b4Smrg   /* Many context limits/constants are limited by the size of
9047117f1b4Smrg    * internal arrays.
9057117f1b4Smrg    */
9067117f1b4Smrg   assert(ctx->Const.MaxTextureImageUnits <= MAX_TEXTURE_IMAGE_UNITS);
9077117f1b4Smrg   assert(ctx->Const.MaxTextureCoordUnits <= MAX_TEXTURE_COORD_UNITS);
9087117f1b4Smrg   assert(ctx->Const.MaxTextureUnits <= MAX_TEXTURE_IMAGE_UNITS);
9097117f1b4Smrg   assert(ctx->Const.MaxTextureUnits <= MAX_TEXTURE_COORD_UNITS);
9107117f1b4Smrg
9117117f1b4Smrg   assert(ctx->Const.MaxViewportWidth <= MAX_WIDTH);
9127117f1b4Smrg   assert(ctx->Const.MaxViewportHeight <= MAX_WIDTH);
9137117f1b4Smrg
9147117f1b4Smrg   /* make sure largest texture image is <= MAX_WIDTH in size */
9157117f1b4Smrg   assert((1 << (ctx->Const.MaxTextureLevels -1 )) <= MAX_WIDTH);
9167117f1b4Smrg   assert((1 << (ctx->Const.MaxCubeTextureLevels -1 )) <= MAX_WIDTH);
9177117f1b4Smrg   assert((1 << (ctx->Const.Max3DTextureLevels -1 )) <= MAX_WIDTH);
9187117f1b4Smrg
9197117f1b4Smrg   assert(ctx->Const.MaxDrawBuffers <= MAX_DRAW_BUFFERS);
9207117f1b4Smrg
9217117f1b4Smrg   /* XXX probably add more tests */
9227117f1b4Smrg}
9237117f1b4Smrg
9247117f1b4Smrg
9257117f1b4Smrg/**
9267117f1b4Smrg * Initialize the attribute groups in a GL context.
9277117f1b4Smrg *
9287117f1b4Smrg * \param ctx GL context.
9297117f1b4Smrg *
9307117f1b4Smrg * Initializes all the attributes, calling the respective <tt>init*</tt>
9317117f1b4Smrg * functions for the more complex data structures.
9327117f1b4Smrg */
9337117f1b4Smrgstatic GLboolean
9347117f1b4Smrginit_attrib_groups(GLcontext *ctx)
9357117f1b4Smrg{
9367117f1b4Smrg   assert(ctx);
9377117f1b4Smrg
9387117f1b4Smrg   /* Constants */
9397117f1b4Smrg   _mesa_init_constants( ctx );
9407117f1b4Smrg
9417117f1b4Smrg   /* Extensions */
9427117f1b4Smrg   _mesa_init_extensions( ctx );
9437117f1b4Smrg
9447117f1b4Smrg   /* Attribute Groups */
9457117f1b4Smrg   _mesa_init_accum( ctx );
9467117f1b4Smrg   _mesa_init_attrib( ctx );
9477117f1b4Smrg   _mesa_init_buffer_objects( ctx );
9487117f1b4Smrg   _mesa_init_color( ctx );
9497117f1b4Smrg   _mesa_init_colortables( ctx );
9507117f1b4Smrg   _mesa_init_current( ctx );
9517117f1b4Smrg   _mesa_init_depth( ctx );
9527117f1b4Smrg   _mesa_init_debug( ctx );
9537117f1b4Smrg   _mesa_init_display_list( ctx );
9547117f1b4Smrg   _mesa_init_eval( ctx );
9557117f1b4Smrg   _mesa_init_feedback( ctx );
9567117f1b4Smrg   _mesa_init_fog( ctx );
9577117f1b4Smrg   _mesa_init_histogram( ctx );
9587117f1b4Smrg   _mesa_init_hint( ctx );
9597117f1b4Smrg   _mesa_init_line( ctx );
9607117f1b4Smrg   _mesa_init_lighting( ctx );
9617117f1b4Smrg   _mesa_init_matrix( ctx );
9627117f1b4Smrg   _mesa_init_multisample( ctx );
9637117f1b4Smrg   _mesa_init_pixel( ctx );
9647117f1b4Smrg   _mesa_init_point( ctx );
9657117f1b4Smrg   _mesa_init_polygon( ctx );
9667117f1b4Smrg   _mesa_init_program( ctx );
9677117f1b4Smrg   _mesa_init_query( ctx );
9687117f1b4Smrg   _mesa_init_rastpos( ctx );
9697117f1b4Smrg   _mesa_init_scissor( ctx );
9707117f1b4Smrg   _mesa_init_shader_state( ctx );
9717117f1b4Smrg   _mesa_init_stencil( ctx );
9727117f1b4Smrg   _mesa_init_transform( ctx );
9737117f1b4Smrg   _mesa_init_varray( ctx );
9747117f1b4Smrg   _mesa_init_viewport( ctx );
9757117f1b4Smrg
9767117f1b4Smrg   if (!_mesa_init_texture( ctx ))
9777117f1b4Smrg      return GL_FALSE;
9787117f1b4Smrg
9797117f1b4Smrg   _mesa_init_texture_s3tc( ctx );
9807117f1b4Smrg   _mesa_init_texture_fxt1( ctx );
9817117f1b4Smrg
9827117f1b4Smrg   /* Miscellaneous */
9837117f1b4Smrg   ctx->NewState = _NEW_ALL;
9847117f1b4Smrg   ctx->ErrorValue = (GLenum) GL_NO_ERROR;
9857117f1b4Smrg
9867117f1b4Smrg   return GL_TRUE;
9877117f1b4Smrg}
9887117f1b4Smrg
9897117f1b4Smrg
9907117f1b4Smrg/**
9917117f1b4Smrg * This is the default function we plug into all dispatch table slots
9927117f1b4Smrg * This helps prevents a segfault when someone calls a GL function without
9937117f1b4Smrg * first checking if the extension's supported.
9947117f1b4Smrg */
9957117f1b4Smrgstatic int
9967117f1b4Smrggeneric_nop(void)
9977117f1b4Smrg{
9987117f1b4Smrg   _mesa_problem(NULL, "User called no-op dispatch function (an unsupported extension function?)");
9997117f1b4Smrg   return 0;
10007117f1b4Smrg}
10017117f1b4Smrg
10027117f1b4Smrg
10037117f1b4Smrg/**
10047117f1b4Smrg * Allocate and initialize a new dispatch table.
10057117f1b4Smrg */
10067117f1b4Smrgstatic struct _glapi_table *
10077117f1b4Smrgalloc_dispatch_table(void)
10087117f1b4Smrg{
10097117f1b4Smrg   /* Find the larger of Mesa's dispatch table and libGL's dispatch table.
10107117f1b4Smrg    * In practice, this'll be the same for stand-alone Mesa.  But for DRI
10117117f1b4Smrg    * Mesa we do this to accomodate different versions of libGL and various
10127117f1b4Smrg    * DRI drivers.
10137117f1b4Smrg    */
10147117f1b4Smrg   GLint numEntries = MAX2(_glapi_get_dispatch_table_size(),
10157117f1b4Smrg                           sizeof(struct _glapi_table) / sizeof(_glapi_proc));
10167117f1b4Smrg   struct _glapi_table *table =
10177117f1b4Smrg      (struct _glapi_table *) _mesa_malloc(numEntries * sizeof(_glapi_proc));
10187117f1b4Smrg   if (table) {
10197117f1b4Smrg      _glapi_proc *entry = (_glapi_proc *) table;
10207117f1b4Smrg      GLint i;
10217117f1b4Smrg      for (i = 0; i < numEntries; i++) {
10227117f1b4Smrg         entry[i] = (_glapi_proc) generic_nop;
10237117f1b4Smrg      }
10247117f1b4Smrg   }
10257117f1b4Smrg   return table;
10267117f1b4Smrg}
10277117f1b4Smrg
10287117f1b4Smrg
10297117f1b4Smrg/**
10307117f1b4Smrg * Initialize a GLcontext struct (rendering context).
10317117f1b4Smrg *
10327117f1b4Smrg * This includes allocating all the other structs and arrays which hang off of
10337117f1b4Smrg * the context by pointers.
10347117f1b4Smrg * Note that the driver needs to pass in its dd_function_table here since
10357117f1b4Smrg * we need to at least call driverFunctions->NewTextureObject to create the
10367117f1b4Smrg * default texture objects.
10377117f1b4Smrg *
10387117f1b4Smrg * Called by _mesa_create_context().
10397117f1b4Smrg *
10407117f1b4Smrg * Performs the imports and exports callback tables initialization, and
10417117f1b4Smrg * miscellaneous one-time initializations. If no shared context is supplied one
10427117f1b4Smrg * is allocated, and increase its reference count.  Setups the GL API dispatch
10437117f1b4Smrg * tables.  Initialize the TNL module. Sets the maximum Z buffer depth.
10447117f1b4Smrg * Finally queries the \c MESA_DEBUG and \c MESA_VERBOSE environment variables
10457117f1b4Smrg * for debug flags.
10467117f1b4Smrg *
10477117f1b4Smrg * \param ctx the context to initialize
10487117f1b4Smrg * \param visual describes the visual attributes for this context
10497117f1b4Smrg * \param share_list points to context to share textures, display lists,
10507117f1b4Smrg *        etc with, or NULL
10517117f1b4Smrg * \param driverFunctions table of device driver functions for this context
10527117f1b4Smrg *        to use
10537117f1b4Smrg * \param driverContext pointer to driver-specific context data
10547117f1b4Smrg */
10557117f1b4SmrgGLboolean
10567117f1b4Smrg_mesa_initialize_context(GLcontext *ctx,
10577117f1b4Smrg                         const GLvisual *visual,
10587117f1b4Smrg                         GLcontext *share_list,
10597117f1b4Smrg                         const struct dd_function_table *driverFunctions,
10607117f1b4Smrg                         void *driverContext)
10617117f1b4Smrg{
10627117f1b4Smrg   ASSERT(driverContext);
10637117f1b4Smrg   assert(driverFunctions->NewTextureObject);
10647117f1b4Smrg   assert(driverFunctions->FreeTexImageData);
10657117f1b4Smrg
10667117f1b4Smrg   /* misc one-time initializations */
10677117f1b4Smrg   one_time_init(ctx);
10687117f1b4Smrg
10697117f1b4Smrg   ctx->Visual = *visual;
10707117f1b4Smrg   ctx->DrawBuffer = NULL;
10717117f1b4Smrg   ctx->ReadBuffer = NULL;
10727117f1b4Smrg   ctx->WinSysDrawBuffer = NULL;
10737117f1b4Smrg   ctx->WinSysReadBuffer = NULL;
10747117f1b4Smrg
10757117f1b4Smrg   /* Plug in driver functions and context pointer here.
10767117f1b4Smrg    * This is important because when we call alloc_shared_state() below
10777117f1b4Smrg    * we'll call ctx->Driver.NewTextureObject() to create the default
10787117f1b4Smrg    * textures.
10797117f1b4Smrg    */
10807117f1b4Smrg   ctx->Driver = *driverFunctions;
10817117f1b4Smrg   ctx->DriverCtx = driverContext;
10827117f1b4Smrg
10837117f1b4Smrg   if (share_list) {
10847117f1b4Smrg      /* share state with another context */
10857117f1b4Smrg      ctx->Shared = share_list->Shared;
10867117f1b4Smrg   }
10877117f1b4Smrg   else {
10887117f1b4Smrg      /* allocate new, unshared state */
10897117f1b4Smrg      if (!alloc_shared_state( ctx )) {
10907117f1b4Smrg         return GL_FALSE;
10917117f1b4Smrg      }
10927117f1b4Smrg   }
10937117f1b4Smrg   _glthread_LOCK_MUTEX(ctx->Shared->Mutex);
10947117f1b4Smrg   ctx->Shared->RefCount++;
10957117f1b4Smrg   _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex);
10967117f1b4Smrg
10977117f1b4Smrg   if (!init_attrib_groups( ctx )) {
10987117f1b4Smrg      free_shared_state(ctx, ctx->Shared);
10997117f1b4Smrg      return GL_FALSE;
11007117f1b4Smrg   }
11017117f1b4Smrg
11027117f1b4Smrg   /* setup the API dispatch tables */
11037117f1b4Smrg   ctx->Exec = alloc_dispatch_table();
11047117f1b4Smrg   ctx->Save = alloc_dispatch_table();
11057117f1b4Smrg   if (!ctx->Exec || !ctx->Save) {
11067117f1b4Smrg      free_shared_state(ctx, ctx->Shared);
11077117f1b4Smrg      if (ctx->Exec)
11087117f1b4Smrg         _mesa_free(ctx->Exec);
11097117f1b4Smrg   }
11107117f1b4Smrg   _mesa_init_exec_table(ctx->Exec);
11117117f1b4Smrg   ctx->CurrentDispatch = ctx->Exec;
11127117f1b4Smrg#if _HAVE_FULL_GL
11137117f1b4Smrg   _mesa_init_dlist_table(ctx->Save);
11147117f1b4Smrg   _mesa_install_save_vtxfmt( ctx, &ctx->ListState.ListVtxfmt );
11157117f1b4Smrg   /* Neutral tnl module stuff */
11167117f1b4Smrg   _mesa_init_exec_vtxfmt( ctx );
11177117f1b4Smrg   ctx->TnlModule.Current = NULL;
11187117f1b4Smrg   ctx->TnlModule.SwapCount = 0;
11197117f1b4Smrg#endif
11207117f1b4Smrg
11217117f1b4Smrg   ctx->FragmentProgram._MaintainTexEnvProgram
11227117f1b4Smrg      = (_mesa_getenv("MESA_TEX_PROG") != NULL);
11237117f1b4Smrg   ctx->FragmentProgram._UseTexEnvProgram = ctx->FragmentProgram._MaintainTexEnvProgram;
11247117f1b4Smrg
11257117f1b4Smrg   ctx->VertexProgram._MaintainTnlProgram
11267117f1b4Smrg      = (_mesa_getenv("MESA_TNL_PROG") != NULL);
11277117f1b4Smrg   if (ctx->VertexProgram._MaintainTnlProgram) {
11287117f1b4Smrg      /* this is required... */
11297117f1b4Smrg      ctx->FragmentProgram._MaintainTexEnvProgram = GL_TRUE;
11307117f1b4Smrg   }
11317117f1b4Smrg
11327117f1b4Smrg   ctx->FirstTimeCurrent = GL_TRUE;
11337117f1b4Smrg
11347117f1b4Smrg   return GL_TRUE;
11357117f1b4Smrg}
11367117f1b4Smrg
11377117f1b4Smrg
11387117f1b4Smrg/**
11397117f1b4Smrg * Allocate and initialize a GLcontext structure.
11407117f1b4Smrg * Note that the driver needs to pass in its dd_function_table here since
11417117f1b4Smrg * we need to at least call driverFunctions->NewTextureObject to initialize
11427117f1b4Smrg * the rendering context.
11437117f1b4Smrg *
11447117f1b4Smrg * \param visual a GLvisual pointer (we copy the struct contents)
11457117f1b4Smrg * \param share_list another context to share display lists with or NULL
11467117f1b4Smrg * \param driverFunctions points to the dd_function_table into which the
11477117f1b4Smrg *        driver has plugged in all its special functions.
11487117f1b4Smrg * \param driverCtx points to the device driver's private context state
11497117f1b4Smrg *
11507117f1b4Smrg * \return pointer to a new __GLcontextRec or NULL if error.
11517117f1b4Smrg */
11527117f1b4SmrgGLcontext *
11537117f1b4Smrg_mesa_create_context(const GLvisual *visual,
11547117f1b4Smrg                     GLcontext *share_list,
11557117f1b4Smrg                     const struct dd_function_table *driverFunctions,
11567117f1b4Smrg                     void *driverContext)
11577117f1b4Smrg{
11587117f1b4Smrg   GLcontext *ctx;
11597117f1b4Smrg
11607117f1b4Smrg   ASSERT(visual);
11617117f1b4Smrg   ASSERT(driverContext);
11627117f1b4Smrg
11637117f1b4Smrg   ctx = (GLcontext *) _mesa_calloc(sizeof(GLcontext));
11647117f1b4Smrg   if (!ctx)
11657117f1b4Smrg      return NULL;
11667117f1b4Smrg
11677117f1b4Smrg   if (_mesa_initialize_context(ctx, visual, share_list,
11687117f1b4Smrg                                driverFunctions, driverContext)) {
11697117f1b4Smrg      return ctx;
11707117f1b4Smrg   }
11717117f1b4Smrg   else {
11727117f1b4Smrg      _mesa_free(ctx);
11737117f1b4Smrg      return NULL;
11747117f1b4Smrg   }
11757117f1b4Smrg}
11767117f1b4Smrg
11777117f1b4Smrg
11787117f1b4Smrg/**
11797117f1b4Smrg * Free the data associated with the given context.
11807117f1b4Smrg *
11817117f1b4Smrg * But doesn't free the GLcontext struct itself.
11827117f1b4Smrg *
11837117f1b4Smrg * \sa _mesa_initialize_context() and init_attrib_groups().
11847117f1b4Smrg */
11857117f1b4Smrgvoid
11867117f1b4Smrg_mesa_free_context_data( GLcontext *ctx )
11877117f1b4Smrg{
11887117f1b4Smrg   if (!_mesa_get_current_context()){
11897117f1b4Smrg      /* No current context, but we may need one in order to delete
11907117f1b4Smrg       * texture objs, etc.  So temporarily bind the context now.
11917117f1b4Smrg       */
11927117f1b4Smrg      _mesa_make_current(ctx, NULL, NULL);
11937117f1b4Smrg   }
11947117f1b4Smrg
11957117f1b4Smrg   /* unreference WinSysDraw/Read buffers */
11967117f1b4Smrg   _mesa_unreference_framebuffer(&ctx->WinSysDrawBuffer);
11977117f1b4Smrg   _mesa_unreference_framebuffer(&ctx->WinSysReadBuffer);
11987117f1b4Smrg   _mesa_unreference_framebuffer(&ctx->DrawBuffer);
11997117f1b4Smrg   _mesa_unreference_framebuffer(&ctx->ReadBuffer);
12007117f1b4Smrg
12017117f1b4Smrg   _mesa_free_attrib_data(ctx);
12027117f1b4Smrg   _mesa_free_lighting_data( ctx );
12037117f1b4Smrg   _mesa_free_eval_data( ctx );
12047117f1b4Smrg   _mesa_free_texture_data( ctx );
12057117f1b4Smrg   _mesa_free_matrix_data( ctx );
12067117f1b4Smrg   _mesa_free_viewport_data( ctx );
12077117f1b4Smrg   _mesa_free_colortables_data( ctx );
12087117f1b4Smrg   _mesa_free_program_data(ctx);
12097117f1b4Smrg   _mesa_free_shader_state(ctx);
12107117f1b4Smrg   _mesa_free_query_data(ctx);
12117117f1b4Smrg
12127117f1b4Smrg#if FEATURE_ARB_vertex_buffer_object
12137117f1b4Smrg   _mesa_delete_buffer_object(ctx, ctx->Array.NullBufferObj);
12147117f1b4Smrg#endif
12157117f1b4Smrg   _mesa_delete_array_object(ctx, ctx->Array.DefaultArrayObj);
12167117f1b4Smrg
12177117f1b4Smrg   /* free dispatch tables */
12187117f1b4Smrg   _mesa_free(ctx->Exec);
12197117f1b4Smrg   _mesa_free(ctx->Save);
12207117f1b4Smrg
12217117f1b4Smrg   /* Shared context state (display lists, textures, etc) */
12227117f1b4Smrg   _glthread_LOCK_MUTEX(ctx->Shared->Mutex);
12237117f1b4Smrg   ctx->Shared->RefCount--;
12247117f1b4Smrg   assert(ctx->Shared->RefCount >= 0);
12257117f1b4Smrg   _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex);
12267117f1b4Smrg   if (ctx->Shared->RefCount == 0) {
12277117f1b4Smrg      /* free shared state */
12287117f1b4Smrg      free_shared_state( ctx, ctx->Shared );
12297117f1b4Smrg   }
12307117f1b4Smrg
12317117f1b4Smrg   if (ctx->Extensions.String)
12327117f1b4Smrg      _mesa_free((void *) ctx->Extensions.String);
12337117f1b4Smrg
12347117f1b4Smrg   /* unbind the context if it's currently bound */
12357117f1b4Smrg   if (ctx == _mesa_get_current_context()) {
12367117f1b4Smrg      _mesa_make_current(NULL, NULL, NULL);
12377117f1b4Smrg   }
12387117f1b4Smrg}
12397117f1b4Smrg
12407117f1b4Smrg
12417117f1b4Smrg/**
12427117f1b4Smrg * Destroy a GLcontext structure.
12437117f1b4Smrg *
12447117f1b4Smrg * \param ctx GL context.
12457117f1b4Smrg *
12467117f1b4Smrg * Calls _mesa_free_context_data() and frees the GLcontext structure itself.
12477117f1b4Smrg */
12487117f1b4Smrgvoid
12497117f1b4Smrg_mesa_destroy_context( GLcontext *ctx )
12507117f1b4Smrg{
12517117f1b4Smrg   if (ctx) {
12527117f1b4Smrg      _mesa_free_context_data(ctx);
12537117f1b4Smrg      _mesa_free( (void *) ctx );
12547117f1b4Smrg   }
12557117f1b4Smrg}
12567117f1b4Smrg
12577117f1b4Smrg
12587117f1b4Smrg#if _HAVE_FULL_GL
12597117f1b4Smrg/**
12607117f1b4Smrg * Copy attribute groups from one context to another.
12617117f1b4Smrg *
12627117f1b4Smrg * \param src source context
12637117f1b4Smrg * \param dst destination context
12647117f1b4Smrg * \param mask bitwise OR of GL_*_BIT flags
12657117f1b4Smrg *
12667117f1b4Smrg * According to the bits specified in \p mask, copies the corresponding
12677117f1b4Smrg * attributes from \p src into \p dst.  For many of the attributes a simple \c
12687117f1b4Smrg * memcpy is not enough due to the existence of internal pointers in their data
12697117f1b4Smrg * structures.
12707117f1b4Smrg */
12717117f1b4Smrgvoid
12727117f1b4Smrg_mesa_copy_context( const GLcontext *src, GLcontext *dst, GLuint mask )
12737117f1b4Smrg{
12747117f1b4Smrg   if (mask & GL_ACCUM_BUFFER_BIT) {
12757117f1b4Smrg      /* OK to memcpy */
12767117f1b4Smrg      dst->Accum = src->Accum;
12777117f1b4Smrg   }
12787117f1b4Smrg   if (mask & GL_COLOR_BUFFER_BIT) {
12797117f1b4Smrg      /* OK to memcpy */
12807117f1b4Smrg      dst->Color = src->Color;
12817117f1b4Smrg   }
12827117f1b4Smrg   if (mask & GL_CURRENT_BIT) {
12837117f1b4Smrg      /* OK to memcpy */
12847117f1b4Smrg      dst->Current = src->Current;
12857117f1b4Smrg   }
12867117f1b4Smrg   if (mask & GL_DEPTH_BUFFER_BIT) {
12877117f1b4Smrg      /* OK to memcpy */
12887117f1b4Smrg      dst->Depth = src->Depth;
12897117f1b4Smrg   }
12907117f1b4Smrg   if (mask & GL_ENABLE_BIT) {
12917117f1b4Smrg      /* no op */
12927117f1b4Smrg   }
12937117f1b4Smrg   if (mask & GL_EVAL_BIT) {
12947117f1b4Smrg      /* OK to memcpy */
12957117f1b4Smrg      dst->Eval = src->Eval;
12967117f1b4Smrg   }
12977117f1b4Smrg   if (mask & GL_FOG_BIT) {
12987117f1b4Smrg      /* OK to memcpy */
12997117f1b4Smrg      dst->Fog = src->Fog;
13007117f1b4Smrg   }
13017117f1b4Smrg   if (mask & GL_HINT_BIT) {
13027117f1b4Smrg      /* OK to memcpy */
13037117f1b4Smrg      dst->Hint = src->Hint;
13047117f1b4Smrg   }
13057117f1b4Smrg   if (mask & GL_LIGHTING_BIT) {
13067117f1b4Smrg      GLuint i;
13077117f1b4Smrg      /* begin with memcpy */
13087117f1b4Smrg      dst->Light = src->Light;
13097117f1b4Smrg      /* fixup linked lists to prevent pointer insanity */
13107117f1b4Smrg      make_empty_list( &(dst->Light.EnabledList) );
13117117f1b4Smrg      for (i = 0; i < MAX_LIGHTS; i++) {
13127117f1b4Smrg         if (dst->Light.Light[i].Enabled) {
13137117f1b4Smrg            insert_at_tail(&(dst->Light.EnabledList), &(dst->Light.Light[i]));
13147117f1b4Smrg         }
13157117f1b4Smrg      }
13167117f1b4Smrg   }
13177117f1b4Smrg   if (mask & GL_LINE_BIT) {
13187117f1b4Smrg      /* OK to memcpy */
13197117f1b4Smrg      dst->Line = src->Line;
13207117f1b4Smrg   }
13217117f1b4Smrg   if (mask & GL_LIST_BIT) {
13227117f1b4Smrg      /* OK to memcpy */
13237117f1b4Smrg      dst->List = src->List;
13247117f1b4Smrg   }
13257117f1b4Smrg   if (mask & GL_PIXEL_MODE_BIT) {
13267117f1b4Smrg      /* OK to memcpy */
13277117f1b4Smrg      dst->Pixel = src->Pixel;
13287117f1b4Smrg   }
13297117f1b4Smrg   if (mask & GL_POINT_BIT) {
13307117f1b4Smrg      /* OK to memcpy */
13317117f1b4Smrg      dst->Point = src->Point;
13327117f1b4Smrg   }
13337117f1b4Smrg   if (mask & GL_POLYGON_BIT) {
13347117f1b4Smrg      /* OK to memcpy */
13357117f1b4Smrg      dst->Polygon = src->Polygon;
13367117f1b4Smrg   }
13377117f1b4Smrg   if (mask & GL_POLYGON_STIPPLE_BIT) {
13387117f1b4Smrg      /* Use loop instead of MEMCPY due to problem with Portland Group's
13397117f1b4Smrg       * C compiler.  Reported by John Stone.
13407117f1b4Smrg       */
13417117f1b4Smrg      GLuint i;
13427117f1b4Smrg      for (i = 0; i < 32; i++) {
13437117f1b4Smrg         dst->PolygonStipple[i] = src->PolygonStipple[i];
13447117f1b4Smrg      }
13457117f1b4Smrg   }
13467117f1b4Smrg   if (mask & GL_SCISSOR_BIT) {
13477117f1b4Smrg      /* OK to memcpy */
13487117f1b4Smrg      dst->Scissor = src->Scissor;
13497117f1b4Smrg   }
13507117f1b4Smrg   if (mask & GL_STENCIL_BUFFER_BIT) {
13517117f1b4Smrg      /* OK to memcpy */
13527117f1b4Smrg      dst->Stencil = src->Stencil;
13537117f1b4Smrg   }
13547117f1b4Smrg   if (mask & GL_TEXTURE_BIT) {
13557117f1b4Smrg      /* Cannot memcpy because of pointers */
13567117f1b4Smrg      _mesa_copy_texture_state(src, dst);
13577117f1b4Smrg   }
13587117f1b4Smrg   if (mask & GL_TRANSFORM_BIT) {
13597117f1b4Smrg      /* OK to memcpy */
13607117f1b4Smrg      dst->Transform = src->Transform;
13617117f1b4Smrg   }
13627117f1b4Smrg   if (mask & GL_VIEWPORT_BIT) {
13637117f1b4Smrg      /* Cannot use memcpy, because of pointers in GLmatrix _WindowMap */
13647117f1b4Smrg      dst->Viewport.X = src->Viewport.X;
13657117f1b4Smrg      dst->Viewport.Y = src->Viewport.Y;
13667117f1b4Smrg      dst->Viewport.Width = src->Viewport.Width;
13677117f1b4Smrg      dst->Viewport.Height = src->Viewport.Height;
13687117f1b4Smrg      dst->Viewport.Near = src->Viewport.Near;
13697117f1b4Smrg      dst->Viewport.Far = src->Viewport.Far;
13707117f1b4Smrg      _math_matrix_copy(&dst->Viewport._WindowMap, &src->Viewport._WindowMap);
13717117f1b4Smrg   }
13727117f1b4Smrg
13737117f1b4Smrg   /* XXX FIXME:  Call callbacks?
13747117f1b4Smrg    */
13757117f1b4Smrg   dst->NewState = _NEW_ALL;
13767117f1b4Smrg}
13777117f1b4Smrg#endif
13787117f1b4Smrg
13797117f1b4Smrg
13807117f1b4Smrg/**
13817117f1b4Smrg * Check if the given context can render into the given framebuffer
13827117f1b4Smrg * by checking visual attributes.
13837117f1b4Smrg *
13847117f1b4Smrg * XXX this may go away someday because we're moving toward more freedom
13857117f1b4Smrg * in binding contexts to drawables with different visual attributes.
13867117f1b4Smrg * The GL_EXT_f_b_o extension is prompting some of that.
13877117f1b4Smrg *
13887117f1b4Smrg * \return GL_TRUE if compatible, GL_FALSE otherwise.
13897117f1b4Smrg */
13907117f1b4Smrgstatic GLboolean
13917117f1b4Smrgcheck_compatible(const GLcontext *ctx, const GLframebuffer *buffer)
13927117f1b4Smrg{
13937117f1b4Smrg   const GLvisual *ctxvis = &ctx->Visual;
13947117f1b4Smrg   const GLvisual *bufvis = &buffer->Visual;
13957117f1b4Smrg
13967117f1b4Smrg   if (ctxvis == bufvis)
13977117f1b4Smrg      return GL_TRUE;
13987117f1b4Smrg
13997117f1b4Smrg   if (ctxvis->rgbMode != bufvis->rgbMode)
14007117f1b4Smrg      return GL_FALSE;
14017117f1b4Smrg#if 0
14027117f1b4Smrg   /* disabling this fixes the fgl_glxgears pbuffer demo */
14037117f1b4Smrg   if (ctxvis->doubleBufferMode && !bufvis->doubleBufferMode)
14047117f1b4Smrg      return GL_FALSE;
14057117f1b4Smrg#endif
14067117f1b4Smrg   if (ctxvis->stereoMode && !bufvis->stereoMode)
14077117f1b4Smrg      return GL_FALSE;
14087117f1b4Smrg   if (ctxvis->haveAccumBuffer && !bufvis->haveAccumBuffer)
14097117f1b4Smrg      return GL_FALSE;
14107117f1b4Smrg   if (ctxvis->haveDepthBuffer && !bufvis->haveDepthBuffer)
14117117f1b4Smrg      return GL_FALSE;
14127117f1b4Smrg   if (ctxvis->haveStencilBuffer && !bufvis->haveStencilBuffer)
14137117f1b4Smrg      return GL_FALSE;
14147117f1b4Smrg   if (ctxvis->redMask && ctxvis->redMask != bufvis->redMask)
14157117f1b4Smrg      return GL_FALSE;
14167117f1b4Smrg   if (ctxvis->greenMask && ctxvis->greenMask != bufvis->greenMask)
14177117f1b4Smrg      return GL_FALSE;
14187117f1b4Smrg   if (ctxvis->blueMask && ctxvis->blueMask != bufvis->blueMask)
14197117f1b4Smrg      return GL_FALSE;
14207117f1b4Smrg#if 0
14217117f1b4Smrg   /* disabled (see bug 11161) */
14227117f1b4Smrg   if (ctxvis->depthBits && ctxvis->depthBits != bufvis->depthBits)
14237117f1b4Smrg      return GL_FALSE;
14247117f1b4Smrg#endif
14257117f1b4Smrg   if (ctxvis->stencilBits && ctxvis->stencilBits != bufvis->stencilBits)
14267117f1b4Smrg      return GL_FALSE;
14277117f1b4Smrg
14287117f1b4Smrg   return GL_TRUE;
14297117f1b4Smrg}
14307117f1b4Smrg
14317117f1b4Smrg
14327117f1b4Smrg/**
14337117f1b4Smrg * Do one-time initialization for the given framebuffer.  Specifically,
14347117f1b4Smrg * ask the driver for the window's current size and update the framebuffer
14357117f1b4Smrg * object to match.
14367117f1b4Smrg * Really, the device driver should totally take care of this.
14377117f1b4Smrg */
14387117f1b4Smrgstatic void
14397117f1b4Smrginitialize_framebuffer_size(GLcontext *ctx, GLframebuffer *fb)
14407117f1b4Smrg{
14417117f1b4Smrg   GLuint width, height;
14427117f1b4Smrg   if (ctx->Driver.GetBufferSize) {
14437117f1b4Smrg      ctx->Driver.GetBufferSize(fb, &width, &height);
14447117f1b4Smrg      if (ctx->Driver.ResizeBuffers)
14457117f1b4Smrg         ctx->Driver.ResizeBuffers(ctx, fb, width, height);
14467117f1b4Smrg      fb->Initialized = GL_TRUE;
14477117f1b4Smrg   }
14487117f1b4Smrg}
14497117f1b4Smrg
14507117f1b4Smrg
14517117f1b4Smrg/**
14527117f1b4Smrg * Bind the given context to the given drawBuffer and readBuffer and
14537117f1b4Smrg * make it the current context for the calling thread.
14547117f1b4Smrg * We'll render into the drawBuffer and read pixels from the
14557117f1b4Smrg * readBuffer (i.e. glRead/CopyPixels, glCopyTexImage, etc).
14567117f1b4Smrg *
14577117f1b4Smrg * We check that the context's and framebuffer's visuals are compatible
14587117f1b4Smrg * and return immediately if they're not.
14597117f1b4Smrg *
14607117f1b4Smrg * \param newCtx  the new GL context. If NULL then there will be no current GL
14617117f1b4Smrg *                context.
14627117f1b4Smrg * \param drawBuffer  the drawing framebuffer
14637117f1b4Smrg * \param readBuffer  the reading framebuffer
14647117f1b4Smrg */
14657117f1b4Smrgvoid
14667117f1b4Smrg_mesa_make_current( GLcontext *newCtx, GLframebuffer *drawBuffer,
14677117f1b4Smrg                    GLframebuffer *readBuffer )
14687117f1b4Smrg{
14697117f1b4Smrg   if (MESA_VERBOSE & VERBOSE_API)
14707117f1b4Smrg      _mesa_debug(newCtx, "_mesa_make_current()\n");
14717117f1b4Smrg
14727117f1b4Smrg   /* Check that the context's and framebuffer's visuals are compatible.
14737117f1b4Smrg    */
14747117f1b4Smrg   if (newCtx && drawBuffer && newCtx->WinSysDrawBuffer != drawBuffer) {
14757117f1b4Smrg      if (!check_compatible(newCtx, drawBuffer)) {
14767117f1b4Smrg         _mesa_warning(newCtx,
14777117f1b4Smrg              "MakeCurrent: incompatible visuals for context and drawbuffer");
14787117f1b4Smrg         return;
14797117f1b4Smrg      }
14807117f1b4Smrg   }
14817117f1b4Smrg   if (newCtx && readBuffer && newCtx->WinSysReadBuffer != readBuffer) {
14827117f1b4Smrg      if (!check_compatible(newCtx, readBuffer)) {
14837117f1b4Smrg         _mesa_warning(newCtx,
14847117f1b4Smrg              "MakeCurrent: incompatible visuals for context and readbuffer");
14857117f1b4Smrg         return;
14867117f1b4Smrg      }
14877117f1b4Smrg   }
14887117f1b4Smrg
14897117f1b4Smrg   /* We used to call _glapi_check_multithread() here.  Now do it in drivers */
14907117f1b4Smrg   _glapi_set_context((void *) newCtx);
14917117f1b4Smrg   ASSERT(_mesa_get_current_context() == newCtx);
14927117f1b4Smrg
14937117f1b4Smrg   if (!newCtx) {
14947117f1b4Smrg      _glapi_set_dispatch(NULL);  /* none current */
14957117f1b4Smrg   }
14967117f1b4Smrg   else {
14977117f1b4Smrg      _glapi_set_dispatch(newCtx->CurrentDispatch);
14987117f1b4Smrg
14997117f1b4Smrg      if (drawBuffer && readBuffer) {
15007117f1b4Smrg	 /* TODO: check if newCtx and buffer's visual match??? */
15017117f1b4Smrg
15027117f1b4Smrg         ASSERT(drawBuffer->Name == 0);
15037117f1b4Smrg         ASSERT(readBuffer->Name == 0);
15047117f1b4Smrg         _mesa_reference_framebuffer(&newCtx->WinSysDrawBuffer, drawBuffer);
15057117f1b4Smrg         _mesa_reference_framebuffer(&newCtx->WinSysReadBuffer, readBuffer);
15067117f1b4Smrg
15077117f1b4Smrg         /*
15087117f1b4Smrg          * Only set the context's Draw/ReadBuffer fields if they're NULL
15097117f1b4Smrg          * or not bound to a user-created FBO.
15107117f1b4Smrg          */
15117117f1b4Smrg         if (!newCtx->DrawBuffer || newCtx->DrawBuffer->Name == 0) {
15127117f1b4Smrg            _mesa_reference_framebuffer(&newCtx->DrawBuffer, drawBuffer);
15137117f1b4Smrg         }
15147117f1b4Smrg         if (!newCtx->ReadBuffer || newCtx->ReadBuffer->Name == 0) {
15157117f1b4Smrg            _mesa_reference_framebuffer(&newCtx->ReadBuffer, readBuffer);
15167117f1b4Smrg         }
15177117f1b4Smrg
15187117f1b4Smrg	 newCtx->NewState |= _NEW_BUFFERS;
15197117f1b4Smrg
15207117f1b4Smrg#if 1
15217117f1b4Smrg         /* We want to get rid of these lines: */
15227117f1b4Smrg
15237117f1b4Smrg#if _HAVE_FULL_GL
15247117f1b4Smrg         if (!drawBuffer->Initialized) {
15257117f1b4Smrg            initialize_framebuffer_size(newCtx, drawBuffer);
15267117f1b4Smrg         }
15277117f1b4Smrg         if (readBuffer != drawBuffer && !readBuffer->Initialized) {
15287117f1b4Smrg            initialize_framebuffer_size(newCtx, readBuffer);
15297117f1b4Smrg         }
15307117f1b4Smrg
15317117f1b4Smrg	 _mesa_resizebuffers(newCtx);
15327117f1b4Smrg#endif
15337117f1b4Smrg
15347117f1b4Smrg#else
15357117f1b4Smrg         /* We want the drawBuffer and readBuffer to be initialized by
15367117f1b4Smrg          * the driver.
15377117f1b4Smrg          * This generally means the Width and Height match the actual
15387117f1b4Smrg          * window size and the renderbuffers (both hardware and software
15397117f1b4Smrg          * based) are allocated to match.  The later can generally be
15407117f1b4Smrg          * done with a call to _mesa_resize_framebuffer().
15417117f1b4Smrg          *
15427117f1b4Smrg          * It's theoretically possible for a buffer to have zero width
15437117f1b4Smrg          * or height, but for now, assert check that the driver did what's
15447117f1b4Smrg          * expected of it.
15457117f1b4Smrg          */
15467117f1b4Smrg         ASSERT(drawBuffer->Width > 0);
15477117f1b4Smrg         ASSERT(drawBuffer->Height > 0);
15487117f1b4Smrg#endif
15497117f1b4Smrg
15507117f1b4Smrg         if (newCtx->FirstTimeCurrent) {
15517117f1b4Smrg            /* set initial viewport and scissor size now */
15527117f1b4Smrg            _mesa_set_viewport(newCtx, 0, 0,
15537117f1b4Smrg                               drawBuffer->Width, drawBuffer->Height);
15547117f1b4Smrg	    _mesa_set_scissor(newCtx, 0, 0,
15557117f1b4Smrg			      drawBuffer->Width, drawBuffer->Height );
15567117f1b4Smrg            check_context_limits(newCtx);
15577117f1b4Smrg         }
15587117f1b4Smrg      }
15597117f1b4Smrg
15607117f1b4Smrg      /* We can use this to help debug user's problems.  Tell them to set
15617117f1b4Smrg       * the MESA_INFO env variable before running their app.  Then the
15627117f1b4Smrg       * first time each context is made current we'll print some useful
15637117f1b4Smrg       * information.
15647117f1b4Smrg       */
15657117f1b4Smrg      if (newCtx->FirstTimeCurrent) {
15667117f1b4Smrg	 if (_mesa_getenv("MESA_INFO")) {
15677117f1b4Smrg	    _mesa_print_info();
15687117f1b4Smrg	 }
15697117f1b4Smrg	 newCtx->FirstTimeCurrent = GL_FALSE;
15707117f1b4Smrg      }
15717117f1b4Smrg   }
15727117f1b4Smrg}
15737117f1b4Smrg
15747117f1b4Smrg
15757117f1b4Smrg/**
15767117f1b4Smrg * Make context 'ctx' share the display lists, textures and programs
15777117f1b4Smrg * that are associated with 'ctxToShare'.
15787117f1b4Smrg * Any display lists, textures or programs associated with 'ctx' will
15797117f1b4Smrg * be deleted if nobody else is sharing them.
15807117f1b4Smrg */
15817117f1b4SmrgGLboolean
15827117f1b4Smrg_mesa_share_state(GLcontext *ctx, GLcontext *ctxToShare)
15837117f1b4Smrg{
15847117f1b4Smrg   if (ctx && ctxToShare && ctx->Shared && ctxToShare->Shared) {
15857117f1b4Smrg      ctx->Shared->RefCount--;
15867117f1b4Smrg      if (ctx->Shared->RefCount == 0) {
15877117f1b4Smrg         free_shared_state(ctx, ctx->Shared);
15887117f1b4Smrg      }
15897117f1b4Smrg      ctx->Shared = ctxToShare->Shared;
15907117f1b4Smrg      ctx->Shared->RefCount++;
15917117f1b4Smrg      return GL_TRUE;
15927117f1b4Smrg   }
15937117f1b4Smrg   else {
15947117f1b4Smrg      return GL_FALSE;
15957117f1b4Smrg   }
15967117f1b4Smrg}
15977117f1b4Smrg
15987117f1b4Smrg
15997117f1b4Smrg
16007117f1b4Smrg/**
16017117f1b4Smrg * \return pointer to the current GL context for this thread.
16027117f1b4Smrg *
16037117f1b4Smrg * Calls _glapi_get_context(). This isn't the fastest way to get the current
16047117f1b4Smrg * context.  If you need speed, see the #GET_CURRENT_CONTEXT macro in
16057117f1b4Smrg * context.h.
16067117f1b4Smrg */
16077117f1b4SmrgGLcontext *
16087117f1b4Smrg_mesa_get_current_context( void )
16097117f1b4Smrg{
16107117f1b4Smrg   return (GLcontext *) _glapi_get_context();
16117117f1b4Smrg}
16127117f1b4Smrg
16137117f1b4Smrg
16147117f1b4Smrg/**
16157117f1b4Smrg * Get context's current API dispatch table.
16167117f1b4Smrg *
16177117f1b4Smrg * It'll either be the immediate-mode execute dispatcher or the display list
16187117f1b4Smrg * compile dispatcher.
16197117f1b4Smrg *
16207117f1b4Smrg * \param ctx GL context.
16217117f1b4Smrg *
16227117f1b4Smrg * \return pointer to dispatch_table.
16237117f1b4Smrg *
16247117f1b4Smrg * Simply returns __GLcontextRec::CurrentDispatch.
16257117f1b4Smrg */
16267117f1b4Smrgstruct _glapi_table *
16277117f1b4Smrg_mesa_get_dispatch(GLcontext *ctx)
16287117f1b4Smrg{
16297117f1b4Smrg   return ctx->CurrentDispatch;
16307117f1b4Smrg}
16317117f1b4Smrg
16327117f1b4Smrg/*@}*/
16337117f1b4Smrg
16347117f1b4Smrg
16357117f1b4Smrg/**********************************************************************/
16367117f1b4Smrg/** \name Miscellaneous functions                                     */
16377117f1b4Smrg/**********************************************************************/
16387117f1b4Smrg/*@{*/
16397117f1b4Smrg
16407117f1b4Smrg/**
16417117f1b4Smrg * Record an error.
16427117f1b4Smrg *
16437117f1b4Smrg * \param ctx GL context.
16447117f1b4Smrg * \param error error code.
16457117f1b4Smrg *
16467117f1b4Smrg * Records the given error code and call the driver's dd_function_table::Error
16477117f1b4Smrg * function if defined.
16487117f1b4Smrg *
16497117f1b4Smrg * \sa
16507117f1b4Smrg * This is called via _mesa_error().
16517117f1b4Smrg */
16527117f1b4Smrgvoid
16537117f1b4Smrg_mesa_record_error(GLcontext *ctx, GLenum error)
16547117f1b4Smrg{
16557117f1b4Smrg   if (!ctx)
16567117f1b4Smrg      return;
16577117f1b4Smrg
16587117f1b4Smrg   if (ctx->ErrorValue == GL_NO_ERROR) {
16597117f1b4Smrg      ctx->ErrorValue = error;
16607117f1b4Smrg   }
16617117f1b4Smrg
16627117f1b4Smrg   /* Call device driver's error handler, if any.  This is used on the Mac. */
16637117f1b4Smrg   if (ctx->Driver.Error) {
16647117f1b4Smrg      ctx->Driver.Error(ctx);
16657117f1b4Smrg   }
16667117f1b4Smrg}
16677117f1b4Smrg
16687117f1b4Smrg
16697117f1b4Smrg/**
16707117f1b4Smrg * Execute glFinish().
16717117f1b4Smrg *
16727117f1b4Smrg * Calls the #ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH macro and the
16737117f1b4Smrg * dd_function_table::Finish driver callback, if not NULL.
16747117f1b4Smrg */
16757117f1b4Smrgvoid GLAPIENTRY
16767117f1b4Smrg_mesa_Finish(void)
16777117f1b4Smrg{
16787117f1b4Smrg   GET_CURRENT_CONTEXT(ctx);
16797117f1b4Smrg   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
16807117f1b4Smrg   if (ctx->Driver.Finish) {
16817117f1b4Smrg      ctx->Driver.Finish(ctx);
16827117f1b4Smrg   }
16837117f1b4Smrg}
16847117f1b4Smrg
16857117f1b4Smrg
16867117f1b4Smrg/**
16877117f1b4Smrg * Execute glFlush().
16887117f1b4Smrg *
16897117f1b4Smrg * Calls the #ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH macro and the
16907117f1b4Smrg * dd_function_table::Flush driver callback, if not NULL.
16917117f1b4Smrg */
16927117f1b4Smrgvoid GLAPIENTRY
16937117f1b4Smrg_mesa_Flush(void)
16947117f1b4Smrg{
16957117f1b4Smrg   GET_CURRENT_CONTEXT(ctx);
16967117f1b4Smrg   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
16977117f1b4Smrg   if (ctx->Driver.Flush) {
16987117f1b4Smrg      ctx->Driver.Flush(ctx);
16997117f1b4Smrg   }
17007117f1b4Smrg}
17017117f1b4Smrg
17027117f1b4Smrg
17037117f1b4Smrg/*@}*/
1704