context.c revision c7037ccd
17117f1b4Smrg/*
27117f1b4Smrg * Mesa 3-D graphics library
3c1f859d4Smrg * Version:  7.3
47117f1b4Smrg *
57117f1b4Smrg * Copyright (C) 1999-2007  Brian Paul   All Rights Reserved.
6c1f859d4Smrg * Copyright (C) 2008  VMware, Inc.  All Rights Reserved.
77117f1b4Smrg *
87117f1b4Smrg * Permission is hereby granted, free of charge, to any person obtaining a
97117f1b4Smrg * copy of this software and associated documentation files (the "Software"),
107117f1b4Smrg * to deal in the Software without restriction, including without limitation
117117f1b4Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
127117f1b4Smrg * and/or sell copies of the Software, and to permit persons to whom the
137117f1b4Smrg * Software is furnished to do so, subject to the following conditions:
147117f1b4Smrg *
157117f1b4Smrg * The above copyright notice and this permission notice shall be included
167117f1b4Smrg * in all copies or substantial portions of the Software.
177117f1b4Smrg *
187117f1b4Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
197117f1b4Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
207117f1b4Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
217117f1b4Smrg * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
227117f1b4Smrg * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
237117f1b4Smrg * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
247117f1b4Smrg */
257117f1b4Smrg
26c1f859d4Smrg/**
27c1f859d4Smrg * \file context.c
28c1f859d4Smrg * Mesa context/visual/framebuffer management functions.
29c1f859d4Smrg * \author Brian Paul
30c1f859d4Smrg */
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"
81c1f859d4Smrg#if FEATURE_accum
827117f1b4Smrg#include "accum.h"
83c1f859d4Smrg#endif
84c1f859d4Smrg#include "api_exec.h"
857117f1b4Smrg#include "arrayobj.h"
86c1f859d4Smrg#if FEATURE_attrib_stack
877117f1b4Smrg#include "attrib.h"
88c1f859d4Smrg#endif
897117f1b4Smrg#include "blend.h"
907117f1b4Smrg#include "buffers.h"
917117f1b4Smrg#include "bufferobj.h"
92c1f859d4Smrg#if FEATURE_colortable
937117f1b4Smrg#include "colortab.h"
94c1f859d4Smrg#endif
957117f1b4Smrg#include "context.h"
967117f1b4Smrg#include "debug.h"
977117f1b4Smrg#include "depth.h"
98c1f859d4Smrg#if FEATURE_dlist
997117f1b4Smrg#include "dlist.h"
100c1f859d4Smrg#endif
101c1f859d4Smrg#if FEATURE_evaluators
1027117f1b4Smrg#include "eval.h"
103c1f859d4Smrg#endif
1047117f1b4Smrg#include "enums.h"
1057117f1b4Smrg#include "extensions.h"
1067117f1b4Smrg#include "fbobject.h"
107c1f859d4Smrg#if FEATURE_feedback
1087117f1b4Smrg#include "feedback.h"
109c1f859d4Smrg#endif
1107117f1b4Smrg#include "fog.h"
1117117f1b4Smrg#include "framebuffer.h"
1127117f1b4Smrg#include "get.h"
113c1f859d4Smrg#if FEATURE_histogram
1147117f1b4Smrg#include "histogram.h"
115c1f859d4Smrg#endif
1167117f1b4Smrg#include "hint.h"
1177117f1b4Smrg#include "hash.h"
1187117f1b4Smrg#include "light.h"
1197117f1b4Smrg#include "lines.h"
1207117f1b4Smrg#include "macros.h"
1217117f1b4Smrg#include "matrix.h"
122c1f859d4Smrg#include "multisample.h"
1237117f1b4Smrg#include "pixel.h"
124c1f859d4Smrg#include "pixelstore.h"
1257117f1b4Smrg#include "points.h"
1267117f1b4Smrg#include "polygon.h"
127c1f859d4Smrg#if FEATURE_ARB_occlusion_query
1287117f1b4Smrg#include "queryobj.h"
129c1f859d4Smrg#endif
130c1f859d4Smrg#if FEATURE_drawpix
1317117f1b4Smrg#include "rastpos.h"
132c1f859d4Smrg#endif
133c1f859d4Smrg#include "scissor.h"
1347117f1b4Smrg#include "simple_list.h"
1357117f1b4Smrg#include "state.h"
1367117f1b4Smrg#include "stencil.h"
1377117f1b4Smrg#include "texcompress.h"
1387117f1b4Smrg#include "teximage.h"
1397117f1b4Smrg#include "texobj.h"
1407117f1b4Smrg#include "texstate.h"
1417117f1b4Smrg#include "mtypes.h"
1427117f1b4Smrg#include "varray.h"
1437117f1b4Smrg#include "version.h"
1447117f1b4Smrg#include "vtxfmt.h"
145c1f859d4Smrg#include "glapi/glthread.h"
146c1f859d4Smrg#include "glapi/glapioffsets.h"
147c1f859d4Smrg#include "glapi/glapitable.h"
148c1f859d4Smrg#if FEATURE_NV_vertex_program || FEATURE_NV_fragment_program
149c1f859d4Smrg#include "shader/program.h"
150c1f859d4Smrg#endif
151c1f859d4Smrg#include "shader/shader_api.h"
152c1f859d4Smrg#if FEATURE_ATI_fragment_shader
153c1f859d4Smrg#include "shader/atifragshader.h"
154c1f859d4Smrg#endif
1557117f1b4Smrg#if _HAVE_FULL_GL
1567117f1b4Smrg#include "math/m_translate.h"
1577117f1b4Smrg#include "math/m_matrix.h"
1587117f1b4Smrg#include "math/m_xform.h"
1597117f1b4Smrg#include "math/mathmod.h"
1607117f1b4Smrg#endif
1617117f1b4Smrg
1627117f1b4Smrg#ifdef USE_SPARC_ASM
1637117f1b4Smrg#include "sparc/sparc.h"
1647117f1b4Smrg#endif
1657117f1b4Smrg
1667117f1b4Smrg#ifndef MESA_VERBOSE
1677117f1b4Smrgint MESA_VERBOSE = 0;
1687117f1b4Smrg#endif
1697117f1b4Smrg
1707117f1b4Smrg#ifndef MESA_DEBUG_FLAGS
1717117f1b4Smrgint MESA_DEBUG_FLAGS = 0;
1727117f1b4Smrg#endif
1737117f1b4Smrg
1747117f1b4Smrg
1757117f1b4Smrg/* ubyte -> float conversion */
1767117f1b4SmrgGLfloat _mesa_ubyte_to_float_color_tab[256];
1777117f1b4Smrg
1787117f1b4Smrg
1797117f1b4Smrg
1807117f1b4Smrg/**
1817117f1b4Smrg * Swap buffers notification callback.
1827117f1b4Smrg *
1837117f1b4Smrg * \param gc GL context.
1847117f1b4Smrg *
1857117f1b4Smrg * Called by window system just before swapping buffers.
1867117f1b4Smrg * We have to finish any pending rendering.
1877117f1b4Smrg */
1887117f1b4Smrgvoid
1897117f1b4Smrg_mesa_notifySwapBuffers(__GLcontext *gc)
1907117f1b4Smrg{
1917117f1b4Smrg   FLUSH_VERTICES( gc, 0 );
1927117f1b4Smrg}
1937117f1b4Smrg
1947117f1b4Smrg
1957117f1b4Smrg/**********************************************************************/
1967117f1b4Smrg/** \name GL Visual allocation/destruction                            */
1977117f1b4Smrg/**********************************************************************/
1987117f1b4Smrg/*@{*/
1997117f1b4Smrg
2007117f1b4Smrg/**
2017117f1b4Smrg * Allocates a GLvisual structure and initializes it via
2027117f1b4Smrg * _mesa_initialize_visual().
2037117f1b4Smrg *
2047117f1b4Smrg * \param rgbFlag GL_TRUE for RGB(A) mode, GL_FALSE for Color Index mode.
2057117f1b4Smrg * \param dbFlag double buffering
2067117f1b4Smrg * \param stereoFlag stereo buffer
2077117f1b4Smrg * \param depthBits requested bits per depth buffer value. Any value in [0, 32]
2087117f1b4Smrg * is acceptable but the actual depth type will be GLushort or GLuint as
2097117f1b4Smrg * needed.
2107117f1b4Smrg * \param stencilBits requested minimum bits per stencil buffer value
2117117f1b4Smrg * \param accumRedBits, accumGreenBits, accumBlueBits, accumAlphaBits number of bits per color component in accum buffer.
2127117f1b4Smrg * \param indexBits number of bits per pixel if \p rgbFlag is GL_FALSE
2137117f1b4Smrg * \param redBits number of bits per color component in frame buffer for RGB(A)
2147117f1b4Smrg * mode.  We always use 8 in core Mesa though.
2157117f1b4Smrg * \param greenBits same as above.
2167117f1b4Smrg * \param blueBits same as above.
2177117f1b4Smrg * \param alphaBits same as above.
2187117f1b4Smrg * \param numSamples not really used.
2197117f1b4Smrg *
2207117f1b4Smrg * \return pointer to new GLvisual or NULL if requested parameters can't be
2217117f1b4Smrg * met.
2227117f1b4Smrg *
2237117f1b4Smrg * \note Need to add params for level and numAuxBuffers (at least)
2247117f1b4Smrg */
2257117f1b4SmrgGLvisual *
2267117f1b4Smrg_mesa_create_visual( GLboolean rgbFlag,
2277117f1b4Smrg                     GLboolean dbFlag,
2287117f1b4Smrg                     GLboolean stereoFlag,
2297117f1b4Smrg                     GLint redBits,
2307117f1b4Smrg                     GLint greenBits,
2317117f1b4Smrg                     GLint blueBits,
2327117f1b4Smrg                     GLint alphaBits,
2337117f1b4Smrg                     GLint indexBits,
2347117f1b4Smrg                     GLint depthBits,
2357117f1b4Smrg                     GLint stencilBits,
2367117f1b4Smrg                     GLint accumRedBits,
2377117f1b4Smrg                     GLint accumGreenBits,
2387117f1b4Smrg                     GLint accumBlueBits,
2397117f1b4Smrg                     GLint accumAlphaBits,
2407117f1b4Smrg                     GLint numSamples )
2417117f1b4Smrg{
2427117f1b4Smrg   GLvisual *vis = (GLvisual *) _mesa_calloc(sizeof(GLvisual));
2437117f1b4Smrg   if (vis) {
2447117f1b4Smrg      if (!_mesa_initialize_visual(vis, rgbFlag, dbFlag, stereoFlag,
2457117f1b4Smrg                                   redBits, greenBits, blueBits, alphaBits,
2467117f1b4Smrg                                   indexBits, depthBits, stencilBits,
2477117f1b4Smrg                                   accumRedBits, accumGreenBits,
2487117f1b4Smrg                                   accumBlueBits, accumAlphaBits,
2497117f1b4Smrg                                   numSamples)) {
2507117f1b4Smrg         _mesa_free(vis);
2517117f1b4Smrg         return NULL;
2527117f1b4Smrg      }
2537117f1b4Smrg   }
2547117f1b4Smrg   return vis;
2557117f1b4Smrg}
2567117f1b4Smrg
2577117f1b4Smrg/**
2587117f1b4Smrg * Makes some sanity checks and fills in the fields of the
2597117f1b4Smrg * GLvisual object with the given parameters.  If the caller needs
2607117f1b4Smrg * to set additional fields, he should just probably init the whole GLvisual
2617117f1b4Smrg * object himself.
2627117f1b4Smrg * \return GL_TRUE on success, or GL_FALSE on failure.
2637117f1b4Smrg *
2647117f1b4Smrg * \sa _mesa_create_visual() above for the parameter description.
2657117f1b4Smrg */
2667117f1b4SmrgGLboolean
2677117f1b4Smrg_mesa_initialize_visual( GLvisual *vis,
2687117f1b4Smrg                         GLboolean rgbFlag,
2697117f1b4Smrg                         GLboolean dbFlag,
2707117f1b4Smrg                         GLboolean stereoFlag,
2717117f1b4Smrg                         GLint redBits,
2727117f1b4Smrg                         GLint greenBits,
2737117f1b4Smrg                         GLint blueBits,
2747117f1b4Smrg                         GLint alphaBits,
2757117f1b4Smrg                         GLint indexBits,
2767117f1b4Smrg                         GLint depthBits,
2777117f1b4Smrg                         GLint stencilBits,
2787117f1b4Smrg                         GLint accumRedBits,
2797117f1b4Smrg                         GLint accumGreenBits,
2807117f1b4Smrg                         GLint accumBlueBits,
2817117f1b4Smrg                         GLint accumAlphaBits,
2827117f1b4Smrg                         GLint numSamples )
2837117f1b4Smrg{
2847117f1b4Smrg   assert(vis);
2857117f1b4Smrg
2867117f1b4Smrg   if (depthBits < 0 || depthBits > 32) {
2877117f1b4Smrg      return GL_FALSE;
2887117f1b4Smrg   }
2897117f1b4Smrg   if (stencilBits < 0 || stencilBits > STENCIL_BITS) {
2907117f1b4Smrg      return GL_FALSE;
2917117f1b4Smrg   }
2927117f1b4Smrg   assert(accumRedBits >= 0);
2937117f1b4Smrg   assert(accumGreenBits >= 0);
2947117f1b4Smrg   assert(accumBlueBits >= 0);
2957117f1b4Smrg   assert(accumAlphaBits >= 0);
2967117f1b4Smrg
2977117f1b4Smrg   vis->rgbMode          = rgbFlag;
2987117f1b4Smrg   vis->doubleBufferMode = dbFlag;
2997117f1b4Smrg   vis->stereoMode       = stereoFlag;
3007117f1b4Smrg
3017117f1b4Smrg   vis->redBits          = redBits;
3027117f1b4Smrg   vis->greenBits        = greenBits;
3037117f1b4Smrg   vis->blueBits         = blueBits;
3047117f1b4Smrg   vis->alphaBits        = alphaBits;
3057117f1b4Smrg   vis->rgbBits          = redBits + greenBits + blueBits;
3067117f1b4Smrg
3077117f1b4Smrg   vis->indexBits      = indexBits;
3087117f1b4Smrg   vis->depthBits      = depthBits;
3097117f1b4Smrg   vis->stencilBits    = stencilBits;
3107117f1b4Smrg
3117117f1b4Smrg   vis->accumRedBits   = accumRedBits;
3127117f1b4Smrg   vis->accumGreenBits = accumGreenBits;
3137117f1b4Smrg   vis->accumBlueBits  = accumBlueBits;
3147117f1b4Smrg   vis->accumAlphaBits = accumAlphaBits;
3157117f1b4Smrg
3167117f1b4Smrg   vis->haveAccumBuffer   = accumRedBits > 0;
3177117f1b4Smrg   vis->haveDepthBuffer   = depthBits > 0;
3187117f1b4Smrg   vis->haveStencilBuffer = stencilBits > 0;
3197117f1b4Smrg
3207117f1b4Smrg   vis->numAuxBuffers = 0;
3217117f1b4Smrg   vis->level = 0;
3227117f1b4Smrg   vis->pixmapMode = 0;
3237117f1b4Smrg   vis->sampleBuffers = numSamples > 0 ? 1 : 0;
3247117f1b4Smrg   vis->samples = numSamples;
3257117f1b4Smrg
3267117f1b4Smrg   return GL_TRUE;
3277117f1b4Smrg}
3287117f1b4Smrg
3297117f1b4Smrg
3307117f1b4Smrg/**
3317117f1b4Smrg * Destroy a visual and free its memory.
3327117f1b4Smrg *
3337117f1b4Smrg * \param vis visual.
3347117f1b4Smrg *
3357117f1b4Smrg * Frees the visual structure.
3367117f1b4Smrg */
3377117f1b4Smrgvoid
3387117f1b4Smrg_mesa_destroy_visual( GLvisual *vis )
3397117f1b4Smrg{
3407117f1b4Smrg   _mesa_free(vis);
3417117f1b4Smrg}
3427117f1b4Smrg
3437117f1b4Smrg/*@}*/
3447117f1b4Smrg
3457117f1b4Smrg
3467117f1b4Smrg/**********************************************************************/
3477117f1b4Smrg/** \name Context allocation, initialization, destroying
3487117f1b4Smrg *
3497117f1b4Smrg * The purpose of the most initialization functions here is to provide the
3507117f1b4Smrg * default state values according to the OpenGL specification.
3517117f1b4Smrg */
3527117f1b4Smrg/**********************************************************************/
3537117f1b4Smrg/*@{*/
3547117f1b4Smrg
3557117f1b4Smrg/**
3567117f1b4Smrg * One-time initialization mutex lock.
3577117f1b4Smrg *
3587117f1b4Smrg * \sa Used by one_time_init().
3597117f1b4Smrg */
3607117f1b4Smrg_glthread_DECLARE_STATIC_MUTEX(OneTimeLock);
3617117f1b4Smrg
3627117f1b4Smrg/**
3637117f1b4Smrg * Calls all the various one-time-init functions in Mesa.
3647117f1b4Smrg *
3657117f1b4Smrg * While holding a global mutex lock, calls several initialization functions,
3667117f1b4Smrg * and sets the glapi callbacks if the \c MESA_DEBUG environment variable is
3677117f1b4Smrg * defined.
3687117f1b4Smrg *
3697117f1b4Smrg * \sa _math_init().
3707117f1b4Smrg */
3717117f1b4Smrgstatic void
3727117f1b4Smrgone_time_init( GLcontext *ctx )
3737117f1b4Smrg{
3747117f1b4Smrg   static GLboolean alreadyCalled = GL_FALSE;
3757117f1b4Smrg   (void) ctx;
3767117f1b4Smrg   _glthread_LOCK_MUTEX(OneTimeLock);
3777117f1b4Smrg   if (!alreadyCalled) {
3787117f1b4Smrg      GLuint i;
3797117f1b4Smrg
3807117f1b4Smrg      /* do some implementation tests */
3817117f1b4Smrg      assert( sizeof(GLbyte) == 1 );
3827117f1b4Smrg      assert( sizeof(GLubyte) == 1 );
3837117f1b4Smrg      assert( sizeof(GLshort) == 2 );
3847117f1b4Smrg      assert( sizeof(GLushort) == 2 );
3857117f1b4Smrg      assert( sizeof(GLint) == 4 );
3867117f1b4Smrg      assert( sizeof(GLuint) == 4 );
3877117f1b4Smrg
3887117f1b4Smrg      _mesa_init_sqrt_table();
3897117f1b4Smrg
3907117f1b4Smrg#if _HAVE_FULL_GL
3917117f1b4Smrg      _math_init();
3927117f1b4Smrg
3937117f1b4Smrg      for (i = 0; i < 256; i++) {
3947117f1b4Smrg         _mesa_ubyte_to_float_color_tab[i] = (float) i / 255.0F;
3957117f1b4Smrg      }
3967117f1b4Smrg#endif
3977117f1b4Smrg
3987117f1b4Smrg#ifdef USE_SPARC_ASM
3997117f1b4Smrg      _mesa_init_sparc_glapi_relocs();
4007117f1b4Smrg#endif
4017117f1b4Smrg      if (_mesa_getenv("MESA_DEBUG")) {
4027117f1b4Smrg         _glapi_noop_enable_warnings(GL_TRUE);
4037117f1b4Smrg         _glapi_set_warning_func( (_glapi_warning_func) _mesa_warning );
4047117f1b4Smrg      }
4057117f1b4Smrg      else {
4067117f1b4Smrg         _glapi_noop_enable_warnings(GL_FALSE);
4077117f1b4Smrg      }
4087117f1b4Smrg
4097117f1b4Smrg#if defined(DEBUG) && defined(__DATE__) && defined(__TIME__)
4107117f1b4Smrg      _mesa_debug(ctx, "Mesa %s DEBUG build %s %s\n",
4117117f1b4Smrg                  MESA_VERSION_STRING, __DATE__, __TIME__);
4127117f1b4Smrg#endif
4137117f1b4Smrg
4147117f1b4Smrg      alreadyCalled = GL_TRUE;
4157117f1b4Smrg   }
4167117f1b4Smrg   _glthread_UNLOCK_MUTEX(OneTimeLock);
4177117f1b4Smrg}
4187117f1b4Smrg
4197117f1b4Smrg
4207117f1b4Smrg/**
4217117f1b4Smrg * Allocate and initialize a shared context state structure.
4227117f1b4Smrg * Initializes the display list, texture objects and vertex programs hash
4237117f1b4Smrg * tables, allocates the texture objects. If it runs out of memory, frees
4247117f1b4Smrg * everything already allocated before returning NULL.
4257117f1b4Smrg *
4267117f1b4Smrg * \return pointer to a gl_shared_state structure on success, or NULL on
4277117f1b4Smrg * failure.
4287117f1b4Smrg */
4297117f1b4Smrgstatic GLboolean
4307117f1b4Smrgalloc_shared_state( GLcontext *ctx )
4317117f1b4Smrg{
432c1f859d4Smrg   GLuint i;
4337117f1b4Smrg   struct gl_shared_state *ss = CALLOC_STRUCT(gl_shared_state);
4347117f1b4Smrg   if (!ss)
4357117f1b4Smrg      return GL_FALSE;
4367117f1b4Smrg
4377117f1b4Smrg   ctx->Shared = ss;
4387117f1b4Smrg
4397117f1b4Smrg   _glthread_INIT_MUTEX(ss->Mutex);
4407117f1b4Smrg
4417117f1b4Smrg   ss->DisplayList = _mesa_NewHashTable();
4427117f1b4Smrg   ss->TexObjects = _mesa_NewHashTable();
4437117f1b4Smrg   ss->Programs = _mesa_NewHashTable();
4447117f1b4Smrg
4457117f1b4Smrg#if FEATURE_ARB_vertex_program
446c1f859d4Smrg   ss->DefaultVertexProgram = (struct gl_vertex_program *)
447c1f859d4Smrg      ctx->Driver.NewProgram(ctx, GL_VERTEX_PROGRAM_ARB, 0);
4487117f1b4Smrg   if (!ss->DefaultVertexProgram)
4497117f1b4Smrg      goto cleanup;
4507117f1b4Smrg#endif
4517117f1b4Smrg#if FEATURE_ARB_fragment_program
452c1f859d4Smrg   ss->DefaultFragmentProgram = (struct gl_fragment_program *)
453c1f859d4Smrg      ctx->Driver.NewProgram(ctx, GL_FRAGMENT_PROGRAM_ARB, 0);
4547117f1b4Smrg   if (!ss->DefaultFragmentProgram)
4557117f1b4Smrg      goto cleanup;
4567117f1b4Smrg#endif
4577117f1b4Smrg#if FEATURE_ATI_fragment_shader
4587117f1b4Smrg   ss->ATIShaders = _mesa_NewHashTable();
4597117f1b4Smrg   ss->DefaultFragmentShader = _mesa_new_ati_fragment_shader(ctx, 0);
4607117f1b4Smrg   if (!ss->DefaultFragmentShader)
4617117f1b4Smrg      goto cleanup;
4627117f1b4Smrg#endif
4637117f1b4Smrg
4647117f1b4Smrg#if FEATURE_ARB_vertex_buffer_object || FEATURE_ARB_pixel_buffer_object
4657117f1b4Smrg   ss->BufferObjects = _mesa_NewHashTable();
4667117f1b4Smrg#endif
4677117f1b4Smrg
4687117f1b4Smrg   ss->ArrayObjects = _mesa_NewHashTable();
4697117f1b4Smrg
4707117f1b4Smrg#if FEATURE_ARB_shader_objects
4717117f1b4Smrg   ss->ShaderObjects = _mesa_NewHashTable();
4727117f1b4Smrg#endif
4737117f1b4Smrg
474c1f859d4Smrg   /* Create default texture objects */
475c1f859d4Smrg   for (i = 0; i < NUM_TEXTURE_TARGETS; i++) {
476c1f859d4Smrg      static const GLenum targets[NUM_TEXTURE_TARGETS] = {
477c1f859d4Smrg         GL_TEXTURE_1D,
478c1f859d4Smrg         GL_TEXTURE_2D,
479c1f859d4Smrg         GL_TEXTURE_3D,
480c1f859d4Smrg         GL_TEXTURE_CUBE_MAP,
481c1f859d4Smrg         GL_TEXTURE_RECTANGLE_NV,
482c1f859d4Smrg         GL_TEXTURE_1D_ARRAY_EXT,
483c1f859d4Smrg         GL_TEXTURE_2D_ARRAY_EXT
484c1f859d4Smrg      };
485c1f859d4Smrg      ss->DefaultTex[i] = ctx->Driver.NewTextureObject(ctx, 0, targets[i]);
486c1f859d4Smrg      if (!ss->DefaultTex[i])
487c1f859d4Smrg         goto cleanup;
488c1f859d4Smrg   }
4897117f1b4Smrg
4907117f1b4Smrg   /* sanity check */
491c1f859d4Smrg   assert(ss->DefaultTex[TEXTURE_1D_INDEX]->RefCount == 1);
4927117f1b4Smrg
4937117f1b4Smrg   _glthread_INIT_MUTEX(ss->TexMutex);
4947117f1b4Smrg   ss->TextureStateStamp = 0;
4957117f1b4Smrg
4967117f1b4Smrg#if FEATURE_EXT_framebuffer_object
4977117f1b4Smrg   ss->FrameBuffers = _mesa_NewHashTable();
4987117f1b4Smrg   if (!ss->FrameBuffers)
4997117f1b4Smrg      goto cleanup;
5007117f1b4Smrg   ss->RenderBuffers = _mesa_NewHashTable();
5017117f1b4Smrg   if (!ss->RenderBuffers)
5027117f1b4Smrg      goto cleanup;
5037117f1b4Smrg#endif
5047117f1b4Smrg
5057117f1b4Smrg   return GL_TRUE;
5067117f1b4Smrg
5077117f1b4Smrgcleanup:
5087117f1b4Smrg   /* Ran out of memory at some point.  Free everything and return NULL */
5097117f1b4Smrg   if (ss->DisplayList)
5107117f1b4Smrg      _mesa_DeleteHashTable(ss->DisplayList);
5117117f1b4Smrg   if (ss->TexObjects)
5127117f1b4Smrg      _mesa_DeleteHashTable(ss->TexObjects);
5137117f1b4Smrg   if (ss->Programs)
5147117f1b4Smrg      _mesa_DeleteHashTable(ss->Programs);
5157117f1b4Smrg#if FEATURE_ARB_vertex_program
516c1f859d4Smrg   _mesa_reference_vertprog(ctx, &ss->DefaultVertexProgram, NULL);
5177117f1b4Smrg#endif
5187117f1b4Smrg#if FEATURE_ARB_fragment_program
519c1f859d4Smrg   _mesa_reference_fragprog(ctx, &ss->DefaultFragmentProgram, NULL);
5207117f1b4Smrg#endif
5217117f1b4Smrg#if FEATURE_ATI_fragment_shader
5227117f1b4Smrg   if (ss->DefaultFragmentShader)
5237117f1b4Smrg      _mesa_delete_ati_fragment_shader(ctx, ss->DefaultFragmentShader);
5247117f1b4Smrg#endif
5257117f1b4Smrg#if FEATURE_ARB_vertex_buffer_object || FEATURE_ARB_pixel_buffer_object
5267117f1b4Smrg   if (ss->BufferObjects)
5277117f1b4Smrg      _mesa_DeleteHashTable(ss->BufferObjects);
5287117f1b4Smrg#endif
5297117f1b4Smrg
5307117f1b4Smrg   if (ss->ArrayObjects)
5317117f1b4Smrg      _mesa_DeleteHashTable (ss->ArrayObjects);
5327117f1b4Smrg
5337117f1b4Smrg#if FEATURE_ARB_shader_objects
5347117f1b4Smrg   if (ss->ShaderObjects)
5357117f1b4Smrg      _mesa_DeleteHashTable (ss->ShaderObjects);
5367117f1b4Smrg#endif
5377117f1b4Smrg
5387117f1b4Smrg#if FEATURE_EXT_framebuffer_object
5397117f1b4Smrg   if (ss->FrameBuffers)
5407117f1b4Smrg      _mesa_DeleteHashTable(ss->FrameBuffers);
5417117f1b4Smrg   if (ss->RenderBuffers)
5427117f1b4Smrg      _mesa_DeleteHashTable(ss->RenderBuffers);
5437117f1b4Smrg#endif
5447117f1b4Smrg
545c1f859d4Smrg   for (i = 0; i < NUM_TEXTURE_TARGETS; i++) {
546c1f859d4Smrg      if (ss->DefaultTex[i])
547c1f859d4Smrg         ctx->Driver.DeleteTexture(ctx, ss->DefaultTex[i]);
548c1f859d4Smrg   }
549c1f859d4Smrg
550c1f859d4Smrg   _mesa_free(ss);
551c1f859d4Smrg
5527117f1b4Smrg   return GL_FALSE;
5537117f1b4Smrg}
5547117f1b4Smrg
5557117f1b4Smrg
5567117f1b4Smrg/**
5577117f1b4Smrg * Callback for deleting a display list.  Called by _mesa_HashDeleteAll().
5587117f1b4Smrg */
5597117f1b4Smrgstatic void
5607117f1b4Smrgdelete_displaylist_cb(GLuint id, void *data, void *userData)
5617117f1b4Smrg{
562c1f859d4Smrg#if FEATURE_dlist
5637117f1b4Smrg   struct mesa_display_list *list = (struct mesa_display_list *) data;
5647117f1b4Smrg   GLcontext *ctx = (GLcontext *) userData;
5657117f1b4Smrg   _mesa_delete_list(ctx, list);
566c1f859d4Smrg#endif
5677117f1b4Smrg}
5687117f1b4Smrg
5697117f1b4Smrg/**
5707117f1b4Smrg * Callback for deleting a texture object.  Called by _mesa_HashDeleteAll().
5717117f1b4Smrg */
5727117f1b4Smrgstatic void
5737117f1b4Smrgdelete_texture_cb(GLuint id, void *data, void *userData)
5747117f1b4Smrg{
5757117f1b4Smrg   struct gl_texture_object *texObj = (struct gl_texture_object *) data;
5767117f1b4Smrg   GLcontext *ctx = (GLcontext *) userData;
5777117f1b4Smrg   ctx->Driver.DeleteTexture(ctx, texObj);
5787117f1b4Smrg}
5797117f1b4Smrg
5807117f1b4Smrg/**
5817117f1b4Smrg * Callback for deleting a program object.  Called by _mesa_HashDeleteAll().
5827117f1b4Smrg */
5837117f1b4Smrgstatic void
5847117f1b4Smrgdelete_program_cb(GLuint id, void *data, void *userData)
5857117f1b4Smrg{
5867117f1b4Smrg   struct gl_program *prog = (struct gl_program *) data;
5877117f1b4Smrg   GLcontext *ctx = (GLcontext *) userData;
588c1f859d4Smrg   ASSERT(prog->RefCount == 1); /* should only be referenced by hash table */
589c1f859d4Smrg   prog->RefCount = 0;  /* now going away */
5907117f1b4Smrg   ctx->Driver.DeleteProgram(ctx, prog);
5917117f1b4Smrg}
5927117f1b4Smrg
5937117f1b4Smrg/**
5947117f1b4Smrg * Callback for deleting an ATI fragment shader object.
5957117f1b4Smrg * Called by _mesa_HashDeleteAll().
5967117f1b4Smrg */
5977117f1b4Smrgstatic void
5987117f1b4Smrgdelete_fragshader_cb(GLuint id, void *data, void *userData)
5997117f1b4Smrg{
6007117f1b4Smrg   struct ati_fragment_shader *shader = (struct ati_fragment_shader *) data;
6017117f1b4Smrg   GLcontext *ctx = (GLcontext *) userData;
6027117f1b4Smrg   _mesa_delete_ati_fragment_shader(ctx, shader);
6037117f1b4Smrg}
6047117f1b4Smrg
6057117f1b4Smrg/**
6067117f1b4Smrg * Callback for deleting a buffer object.  Called by _mesa_HashDeleteAll().
6077117f1b4Smrg */
6087117f1b4Smrgstatic void
6097117f1b4Smrgdelete_bufferobj_cb(GLuint id, void *data, void *userData)
6107117f1b4Smrg{
6117117f1b4Smrg   struct gl_buffer_object *bufObj = (struct gl_buffer_object *) data;
6127117f1b4Smrg   GLcontext *ctx = (GLcontext *) userData;
6137117f1b4Smrg   ctx->Driver.DeleteBuffer(ctx, bufObj);
6147117f1b4Smrg}
6157117f1b4Smrg
6167117f1b4Smrg/**
6177117f1b4Smrg * Callback for deleting an array object.  Called by _mesa_HashDeleteAll().
6187117f1b4Smrg */
6197117f1b4Smrgstatic void
6207117f1b4Smrgdelete_arrayobj_cb(GLuint id, void *data, void *userData)
6217117f1b4Smrg{
6227117f1b4Smrg   struct gl_array_object *arrayObj = (struct gl_array_object *) data;
6237117f1b4Smrg   GLcontext *ctx = (GLcontext *) userData;
6247117f1b4Smrg   _mesa_delete_array_object(ctx, arrayObj);
6257117f1b4Smrg}
6267117f1b4Smrg
627c1f859d4Smrg/**
628c1f859d4Smrg * Callback for freeing shader program data. Call it before delete_shader_cb
629c1f859d4Smrg * to avoid memory access error.
630c1f859d4Smrg */
631c1f859d4Smrgstatic void
632c1f859d4Smrgfree_shader_program_data_cb(GLuint id, void *data, void *userData)
633c1f859d4Smrg{
634c1f859d4Smrg   GLcontext *ctx = (GLcontext *) userData;
635c1f859d4Smrg   struct gl_shader_program *shProg = (struct gl_shader_program *) data;
636c1f859d4Smrg
637c1f859d4Smrg   if (shProg->Type == GL_SHADER_PROGRAM_MESA) {
638c1f859d4Smrg       _mesa_free_shader_program_data(ctx, shProg);
639c1f859d4Smrg   }
640c1f859d4Smrg}
641c1f859d4Smrg
6427117f1b4Smrg/**
6437117f1b4Smrg * Callback for deleting shader and shader programs objects.
6447117f1b4Smrg * Called by _mesa_HashDeleteAll().
6457117f1b4Smrg */
6467117f1b4Smrgstatic void
6477117f1b4Smrgdelete_shader_cb(GLuint id, void *data, void *userData)
6487117f1b4Smrg{
6497117f1b4Smrg   GLcontext *ctx = (GLcontext *) userData;
6507117f1b4Smrg   struct gl_shader *sh = (struct gl_shader *) data;
6517117f1b4Smrg   if (sh->Type == GL_FRAGMENT_SHADER || sh->Type == GL_VERTEX_SHADER) {
6527117f1b4Smrg      _mesa_free_shader(ctx, sh);
6537117f1b4Smrg   }
6547117f1b4Smrg   else {
6557117f1b4Smrg      struct gl_shader_program *shProg = (struct gl_shader_program *) data;
6567117f1b4Smrg      ASSERT(shProg->Type == GL_SHADER_PROGRAM_MESA);
6577117f1b4Smrg      _mesa_free_shader_program(ctx, shProg);
6587117f1b4Smrg   }
6597117f1b4Smrg}
6607117f1b4Smrg
6617117f1b4Smrg/**
6627117f1b4Smrg * Callback for deleting a framebuffer object.  Called by _mesa_HashDeleteAll()
6637117f1b4Smrg */
6647117f1b4Smrgstatic void
6657117f1b4Smrgdelete_framebuffer_cb(GLuint id, void *data, void *userData)
6667117f1b4Smrg{
6677117f1b4Smrg   struct gl_framebuffer *fb = (struct gl_framebuffer *) data;
6687117f1b4Smrg   /* The fact that the framebuffer is in the hashtable means its refcount
6697117f1b4Smrg    * is one, but we're removing from the hashtable now.  So clear refcount.
6707117f1b4Smrg    */
6717117f1b4Smrg   /*assert(fb->RefCount == 1);*/
6727117f1b4Smrg   fb->RefCount = 0;
6737117f1b4Smrg
6747117f1b4Smrg   /* NOTE: Delete should always be defined but there are two reports
6757117f1b4Smrg    * of it being NULL (bugs 13507, 14293).  Work-around for now.
6767117f1b4Smrg    */
6777117f1b4Smrg   if (fb->Delete)
6787117f1b4Smrg      fb->Delete(fb);
6797117f1b4Smrg}
6807117f1b4Smrg
6817117f1b4Smrg/**
6827117f1b4Smrg * Callback for deleting a renderbuffer object. Called by _mesa_HashDeleteAll()
6837117f1b4Smrg */
6847117f1b4Smrgstatic void
6857117f1b4Smrgdelete_renderbuffer_cb(GLuint id, void *data, void *userData)
6867117f1b4Smrg{
6877117f1b4Smrg   struct gl_renderbuffer *rb = (struct gl_renderbuffer *) data;
6887117f1b4Smrg   rb->RefCount = 0;  /* see comment for FBOs above */
689c1f859d4Smrg   if (rb->Delete)
690c1f859d4Smrg      rb->Delete(rb);
6917117f1b4Smrg}
6927117f1b4Smrg
6937117f1b4Smrg
6947117f1b4Smrg
6957117f1b4Smrg/**
6967117f1b4Smrg * Deallocate a shared state object and all children structures.
6977117f1b4Smrg *
6987117f1b4Smrg * \param ctx GL context.
6997117f1b4Smrg * \param ss shared state pointer.
7007117f1b4Smrg *
7017117f1b4Smrg * Frees the display lists, the texture objects (calling the driver texture
7027117f1b4Smrg * deletion callback to free its private data) and the vertex programs, as well
7037117f1b4Smrg * as their hash tables.
7047117f1b4Smrg *
7057117f1b4Smrg * \sa alloc_shared_state().
7067117f1b4Smrg */
7077117f1b4Smrgstatic void
7087117f1b4Smrgfree_shared_state( GLcontext *ctx, struct gl_shared_state *ss )
7097117f1b4Smrg{
710c1f859d4Smrg   GLuint i;
711c1f859d4Smrg
7127117f1b4Smrg   /*
7137117f1b4Smrg    * Free display lists
7147117f1b4Smrg    */
7157117f1b4Smrg   _mesa_HashDeleteAll(ss->DisplayList, delete_displaylist_cb, ctx);
7167117f1b4Smrg   _mesa_DeleteHashTable(ss->DisplayList);
7177117f1b4Smrg
718c1f859d4Smrg#if FEATURE_ARB_shader_objects
719c1f859d4Smrg   _mesa_HashWalk(ss->ShaderObjects, free_shader_program_data_cb, ctx);
720c1f859d4Smrg   _mesa_HashDeleteAll(ss->ShaderObjects, delete_shader_cb, ctx);
721c1f859d4Smrg   _mesa_DeleteHashTable(ss->ShaderObjects);
722c1f859d4Smrg#endif
723c1f859d4Smrg
7247117f1b4Smrg   _mesa_HashDeleteAll(ss->Programs, delete_program_cb, ctx);
7257117f1b4Smrg   _mesa_DeleteHashTable(ss->Programs);
726c1f859d4Smrg
7277117f1b4Smrg#if FEATURE_ARB_vertex_program
728c1f859d4Smrg   _mesa_reference_vertprog(ctx, &ss->DefaultVertexProgram, NULL);
7297117f1b4Smrg#endif
7307117f1b4Smrg#if FEATURE_ARB_fragment_program
731c1f859d4Smrg   _mesa_reference_fragprog(ctx, &ss->DefaultFragmentProgram, NULL);
7327117f1b4Smrg#endif
7337117f1b4Smrg
7347117f1b4Smrg#if FEATURE_ATI_fragment_shader
7357117f1b4Smrg   _mesa_HashDeleteAll(ss->ATIShaders, delete_fragshader_cb, ctx);
7367117f1b4Smrg   _mesa_DeleteHashTable(ss->ATIShaders);
7377117f1b4Smrg   _mesa_delete_ati_fragment_shader(ctx, ss->DefaultFragmentShader);
7387117f1b4Smrg#endif
7397117f1b4Smrg
7407117f1b4Smrg#if FEATURE_ARB_vertex_buffer_object || FEATURE_ARB_pixel_buffer_object
7417117f1b4Smrg   _mesa_HashDeleteAll(ss->BufferObjects, delete_bufferobj_cb, ctx);
7427117f1b4Smrg   _mesa_DeleteHashTable(ss->BufferObjects);
7437117f1b4Smrg#endif
7447117f1b4Smrg
7457117f1b4Smrg   _mesa_HashDeleteAll(ss->ArrayObjects, delete_arrayobj_cb, ctx);
7467117f1b4Smrg   _mesa_DeleteHashTable(ss->ArrayObjects);
7477117f1b4Smrg
7487117f1b4Smrg#if FEATURE_EXT_framebuffer_object
7497117f1b4Smrg   _mesa_HashDeleteAll(ss->FrameBuffers, delete_framebuffer_cb, ctx);
7507117f1b4Smrg   _mesa_DeleteHashTable(ss->FrameBuffers);
7517117f1b4Smrg   _mesa_HashDeleteAll(ss->RenderBuffers, delete_renderbuffer_cb, ctx);
7527117f1b4Smrg   _mesa_DeleteHashTable(ss->RenderBuffers);
7537117f1b4Smrg#endif
7547117f1b4Smrg
7557117f1b4Smrg   /*
7567117f1b4Smrg    * Free texture objects (after FBOs since some textures might have
7577117f1b4Smrg    * been bound to FBOs).
7587117f1b4Smrg    */
7597117f1b4Smrg   ASSERT(ctx->Driver.DeleteTexture);
7607117f1b4Smrg   /* the default textures */
761c1f859d4Smrg   for (i = 0; i < NUM_TEXTURE_TARGETS; i++) {
762c1f859d4Smrg      ctx->Driver.DeleteTexture(ctx, ss->DefaultTex[i]);
763c1f859d4Smrg   }
7647117f1b4Smrg   /* all other textures */
7657117f1b4Smrg   _mesa_HashDeleteAll(ss->TexObjects, delete_texture_cb, ctx);
7667117f1b4Smrg   _mesa_DeleteHashTable(ss->TexObjects);
7677117f1b4Smrg
7687117f1b4Smrg   _glthread_DESTROY_MUTEX(ss->Mutex);
7697117f1b4Smrg
7707117f1b4Smrg   _mesa_free(ss);
7717117f1b4Smrg}
7727117f1b4Smrg
7737117f1b4Smrg
7747117f1b4Smrg/**
7757117f1b4Smrg * Initialize fields of gl_current_attrib (aka ctx->Current.*)
7767117f1b4Smrg */
7777117f1b4Smrgstatic void
7787117f1b4Smrg_mesa_init_current(GLcontext *ctx)
7797117f1b4Smrg{
7807117f1b4Smrg   GLuint i;
7817117f1b4Smrg
7827117f1b4Smrg   /* Init all to (0,0,0,1) */
7837117f1b4Smrg   for (i = 0; i < VERT_ATTRIB_MAX; i++) {
7847117f1b4Smrg      ASSIGN_4V( ctx->Current.Attrib[i], 0.0, 0.0, 0.0, 1.0 );
7857117f1b4Smrg   }
7867117f1b4Smrg
7877117f1b4Smrg   /* redo special cases: */
7887117f1b4Smrg   ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_WEIGHT], 1.0, 0.0, 0.0, 0.0 );
7897117f1b4Smrg   ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_NORMAL], 0.0, 0.0, 1.0, 1.0 );
7907117f1b4Smrg   ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_COLOR0], 1.0, 1.0, 1.0, 1.0 );
7917117f1b4Smrg   ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_COLOR1], 0.0, 0.0, 0.0, 1.0 );
7927117f1b4Smrg   ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_COLOR_INDEX], 1.0, 0.0, 0.0, 1.0 );
7937117f1b4Smrg   ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_EDGEFLAG], 1.0, 0.0, 0.0, 1.0 );
7947117f1b4Smrg}
7957117f1b4Smrg
7967117f1b4Smrg
7977117f1b4Smrg/**
7987117f1b4Smrg * Init vertex/fragment program native limits from logical limits.
7997117f1b4Smrg */
8007117f1b4Smrgstatic void
8017117f1b4Smrginit_natives(struct gl_program_constants *prog)
8027117f1b4Smrg{
8037117f1b4Smrg   prog->MaxNativeInstructions = prog->MaxInstructions;
8047117f1b4Smrg   prog->MaxNativeAluInstructions = prog->MaxAluInstructions;
8057117f1b4Smrg   prog->MaxNativeTexInstructions = prog->MaxTexInstructions;
8067117f1b4Smrg   prog->MaxNativeTexIndirections = prog->MaxTexIndirections;
8077117f1b4Smrg   prog->MaxNativeAttribs = prog->MaxAttribs;
8087117f1b4Smrg   prog->MaxNativeTemps = prog->MaxTemps;
8097117f1b4Smrg   prog->MaxNativeAddressRegs = prog->MaxAddressRegs;
8107117f1b4Smrg   prog->MaxNativeParameters = prog->MaxParameters;
8117117f1b4Smrg}
8127117f1b4Smrg
8137117f1b4Smrg
8147117f1b4Smrg/**
8157117f1b4Smrg * Initialize fields of gl_constants (aka ctx->Const.*).
8167117f1b4Smrg * Use defaults from config.h.  The device drivers will often override
8177117f1b4Smrg * some of these values (such as number of texture units).
8187117f1b4Smrg */
8197117f1b4Smrgstatic void
8207117f1b4Smrg_mesa_init_constants(GLcontext *ctx)
8217117f1b4Smrg{
8227117f1b4Smrg   assert(ctx);
8237117f1b4Smrg
8247117f1b4Smrg   assert(MAX_TEXTURE_LEVELS >= MAX_3D_TEXTURE_LEVELS);
8257117f1b4Smrg   assert(MAX_TEXTURE_LEVELS >= MAX_CUBE_TEXTURE_LEVELS);
8267117f1b4Smrg
8277117f1b4Smrg   /* Constants, may be overriden (usually only reduced) by device drivers */
8287117f1b4Smrg   ctx->Const.MaxTextureLevels = MAX_TEXTURE_LEVELS;
8297117f1b4Smrg   ctx->Const.Max3DTextureLevels = MAX_3D_TEXTURE_LEVELS;
8307117f1b4Smrg   ctx->Const.MaxCubeTextureLevels = MAX_CUBE_TEXTURE_LEVELS;
8317117f1b4Smrg   ctx->Const.MaxTextureRectSize = MAX_TEXTURE_RECT_SIZE;
832c1f859d4Smrg   ctx->Const.MaxArrayTextureLayers = MAX_ARRAY_TEXTURE_LAYERS;
8337117f1b4Smrg   ctx->Const.MaxTextureCoordUnits = MAX_TEXTURE_COORD_UNITS;
8347117f1b4Smrg   ctx->Const.MaxTextureImageUnits = MAX_TEXTURE_IMAGE_UNITS;
8357117f1b4Smrg   ctx->Const.MaxTextureUnits = MIN2(ctx->Const.MaxTextureCoordUnits,
8367117f1b4Smrg                                     ctx->Const.MaxTextureImageUnits);
8377117f1b4Smrg   ctx->Const.MaxTextureMaxAnisotropy = MAX_TEXTURE_MAX_ANISOTROPY;
8387117f1b4Smrg   ctx->Const.MaxTextureLodBias = MAX_TEXTURE_LOD_BIAS;
8397117f1b4Smrg   ctx->Const.MaxArrayLockSize = MAX_ARRAY_LOCK_SIZE;
8407117f1b4Smrg   ctx->Const.SubPixelBits = SUB_PIXEL_BITS;
8417117f1b4Smrg   ctx->Const.MinPointSize = MIN_POINT_SIZE;
8427117f1b4Smrg   ctx->Const.MaxPointSize = MAX_POINT_SIZE;
8437117f1b4Smrg   ctx->Const.MinPointSizeAA = MIN_POINT_SIZE;
8447117f1b4Smrg   ctx->Const.MaxPointSizeAA = MAX_POINT_SIZE;
8457117f1b4Smrg   ctx->Const.PointSizeGranularity = (GLfloat) POINT_SIZE_GRANULARITY;
8467117f1b4Smrg   ctx->Const.MinLineWidth = MIN_LINE_WIDTH;
8477117f1b4Smrg   ctx->Const.MaxLineWidth = MAX_LINE_WIDTH;
8487117f1b4Smrg   ctx->Const.MinLineWidthAA = MIN_LINE_WIDTH;
8497117f1b4Smrg   ctx->Const.MaxLineWidthAA = MAX_LINE_WIDTH;
8507117f1b4Smrg   ctx->Const.LineWidthGranularity = (GLfloat) LINE_WIDTH_GRANULARITY;
8517117f1b4Smrg   ctx->Const.MaxColorTableSize = MAX_COLOR_TABLE_SIZE;
8527117f1b4Smrg   ctx->Const.MaxConvolutionWidth = MAX_CONVOLUTION_WIDTH;
8537117f1b4Smrg   ctx->Const.MaxConvolutionHeight = MAX_CONVOLUTION_HEIGHT;
8547117f1b4Smrg   ctx->Const.MaxClipPlanes = MAX_CLIP_PLANES;
8557117f1b4Smrg   ctx->Const.MaxLights = MAX_LIGHTS;
8567117f1b4Smrg   ctx->Const.MaxShininess = 128.0;
8577117f1b4Smrg   ctx->Const.MaxSpotExponent = 128.0;
8587117f1b4Smrg   ctx->Const.MaxViewportWidth = MAX_WIDTH;
8597117f1b4Smrg   ctx->Const.MaxViewportHeight = MAX_HEIGHT;
8607117f1b4Smrg#if FEATURE_ARB_vertex_program
8617117f1b4Smrg   ctx->Const.VertexProgram.MaxInstructions = MAX_NV_VERTEX_PROGRAM_INSTRUCTIONS;
8627117f1b4Smrg   ctx->Const.VertexProgram.MaxAluInstructions = 0;
8637117f1b4Smrg   ctx->Const.VertexProgram.MaxTexInstructions = 0;
8647117f1b4Smrg   ctx->Const.VertexProgram.MaxTexIndirections = 0;
8657117f1b4Smrg   ctx->Const.VertexProgram.MaxAttribs = MAX_NV_VERTEX_PROGRAM_INPUTS;
8667117f1b4Smrg   ctx->Const.VertexProgram.MaxTemps = MAX_PROGRAM_TEMPS;
8677117f1b4Smrg   ctx->Const.VertexProgram.MaxParameters = MAX_NV_VERTEX_PROGRAM_PARAMS;
8687117f1b4Smrg   ctx->Const.VertexProgram.MaxLocalParams = MAX_PROGRAM_LOCAL_PARAMS;
8697117f1b4Smrg   ctx->Const.VertexProgram.MaxEnvParams = MAX_PROGRAM_ENV_PARAMS;
8707117f1b4Smrg   ctx->Const.VertexProgram.MaxAddressRegs = MAX_VERTEX_PROGRAM_ADDRESS_REGS;
8717117f1b4Smrg   ctx->Const.VertexProgram.MaxUniformComponents = 4 * MAX_UNIFORMS;
8727117f1b4Smrg   init_natives(&ctx->Const.VertexProgram);
8737117f1b4Smrg#endif
8747117f1b4Smrg
8757117f1b4Smrg#if FEATURE_ARB_fragment_program
8767117f1b4Smrg   ctx->Const.FragmentProgram.MaxInstructions = MAX_NV_FRAGMENT_PROGRAM_INSTRUCTIONS;
8777117f1b4Smrg   ctx->Const.FragmentProgram.MaxAluInstructions = MAX_FRAGMENT_PROGRAM_ALU_INSTRUCTIONS;
8787117f1b4Smrg   ctx->Const.FragmentProgram.MaxTexInstructions = MAX_FRAGMENT_PROGRAM_TEX_INSTRUCTIONS;
8797117f1b4Smrg   ctx->Const.FragmentProgram.MaxTexIndirections = MAX_FRAGMENT_PROGRAM_TEX_INDIRECTIONS;
8807117f1b4Smrg   ctx->Const.FragmentProgram.MaxAttribs = MAX_NV_FRAGMENT_PROGRAM_INPUTS;
8817117f1b4Smrg   ctx->Const.FragmentProgram.MaxTemps = MAX_PROGRAM_TEMPS;
8827117f1b4Smrg   ctx->Const.FragmentProgram.MaxParameters = MAX_NV_FRAGMENT_PROGRAM_PARAMS;
8837117f1b4Smrg   ctx->Const.FragmentProgram.MaxLocalParams = MAX_PROGRAM_LOCAL_PARAMS;
8847117f1b4Smrg   ctx->Const.FragmentProgram.MaxEnvParams = MAX_PROGRAM_ENV_PARAMS;
8857117f1b4Smrg   ctx->Const.FragmentProgram.MaxAddressRegs = MAX_FRAGMENT_PROGRAM_ADDRESS_REGS;
8867117f1b4Smrg   ctx->Const.FragmentProgram.MaxUniformComponents = 4 * MAX_UNIFORMS;
8877117f1b4Smrg   init_natives(&ctx->Const.FragmentProgram);
8887117f1b4Smrg#endif
8897117f1b4Smrg   ctx->Const.MaxProgramMatrices = MAX_PROGRAM_MATRICES;
8907117f1b4Smrg   ctx->Const.MaxProgramMatrixStackDepth = MAX_PROGRAM_MATRIX_STACK_DEPTH;
8917117f1b4Smrg
8927117f1b4Smrg   /* CheckArrayBounds is overriden by drivers/x11 for X server */
8937117f1b4Smrg   ctx->Const.CheckArrayBounds = GL_FALSE;
8947117f1b4Smrg
8957117f1b4Smrg   /* GL_ARB_draw_buffers */
8967117f1b4Smrg   ctx->Const.MaxDrawBuffers = MAX_DRAW_BUFFERS;
8977117f1b4Smrg
8987117f1b4Smrg   /* GL_OES_read_format */
8997117f1b4Smrg   ctx->Const.ColorReadFormat = GL_RGBA;
9007117f1b4Smrg   ctx->Const.ColorReadType = GL_UNSIGNED_BYTE;
9017117f1b4Smrg
9027117f1b4Smrg#if FEATURE_EXT_framebuffer_object
9037117f1b4Smrg   ctx->Const.MaxColorAttachments = MAX_COLOR_ATTACHMENTS;
9047117f1b4Smrg   ctx->Const.MaxRenderbufferSize = MAX_WIDTH;
9057117f1b4Smrg#endif
9067117f1b4Smrg
9077117f1b4Smrg#if FEATURE_ARB_vertex_shader
9087117f1b4Smrg   ctx->Const.MaxVertexTextureImageUnits = MAX_VERTEX_TEXTURE_IMAGE_UNITS;
9097117f1b4Smrg   ctx->Const.MaxVarying = MAX_VARYING;
9107117f1b4Smrg#endif
9117117f1b4Smrg
9127117f1b4Smrg   /* sanity checks */
9137117f1b4Smrg   ASSERT(ctx->Const.MaxTextureUnits == MIN2(ctx->Const.MaxTextureImageUnits,
9147117f1b4Smrg                                             ctx->Const.MaxTextureCoordUnits));
9157117f1b4Smrg   ASSERT(ctx->Const.FragmentProgram.MaxLocalParams <= MAX_PROGRAM_LOCAL_PARAMS);
9167117f1b4Smrg   ASSERT(ctx->Const.VertexProgram.MaxLocalParams <= MAX_PROGRAM_LOCAL_PARAMS);
9177117f1b4Smrg
9187117f1b4Smrg   ASSERT(MAX_NV_FRAGMENT_PROGRAM_TEMPS <= MAX_PROGRAM_TEMPS);
9197117f1b4Smrg   ASSERT(MAX_NV_VERTEX_PROGRAM_TEMPS <= MAX_PROGRAM_TEMPS);
9207117f1b4Smrg   ASSERT(MAX_NV_VERTEX_PROGRAM_INPUTS <= VERT_ATTRIB_MAX);
9217117f1b4Smrg   ASSERT(MAX_NV_VERTEX_PROGRAM_OUTPUTS <= VERT_RESULT_MAX);
9227117f1b4Smrg}
9237117f1b4Smrg
9247117f1b4Smrg
9257117f1b4Smrg/**
9267117f1b4Smrg * Do some sanity checks on the limits/constants for the given context.
9277117f1b4Smrg * Only called the first time a context is bound.
9287117f1b4Smrg */
9297117f1b4Smrgstatic void
9307117f1b4Smrgcheck_context_limits(GLcontext *ctx)
9317117f1b4Smrg{
9327117f1b4Smrg   /* Many context limits/constants are limited by the size of
9337117f1b4Smrg    * internal arrays.
9347117f1b4Smrg    */
9357117f1b4Smrg   assert(ctx->Const.MaxTextureImageUnits <= MAX_TEXTURE_IMAGE_UNITS);
9367117f1b4Smrg   assert(ctx->Const.MaxTextureCoordUnits <= MAX_TEXTURE_COORD_UNITS);
9377117f1b4Smrg   assert(ctx->Const.MaxTextureUnits <= MAX_TEXTURE_IMAGE_UNITS);
9387117f1b4Smrg   assert(ctx->Const.MaxTextureUnits <= MAX_TEXTURE_COORD_UNITS);
9397117f1b4Smrg
940c1f859d4Smrg   /* number of coord units cannot be greater than number of image units */
941c1f859d4Smrg   assert(ctx->Const.MaxTextureCoordUnits <= ctx->Const.MaxTextureImageUnits);
942c1f859d4Smrg
9437117f1b4Smrg   assert(ctx->Const.MaxViewportWidth <= MAX_WIDTH);
9447117f1b4Smrg   assert(ctx->Const.MaxViewportHeight <= MAX_WIDTH);
9457117f1b4Smrg
9467117f1b4Smrg   /* make sure largest texture image is <= MAX_WIDTH in size */
9477117f1b4Smrg   assert((1 << (ctx->Const.MaxTextureLevels -1 )) <= MAX_WIDTH);
9487117f1b4Smrg   assert((1 << (ctx->Const.MaxCubeTextureLevels -1 )) <= MAX_WIDTH);
9497117f1b4Smrg   assert((1 << (ctx->Const.Max3DTextureLevels -1 )) <= MAX_WIDTH);
9507117f1b4Smrg
9517117f1b4Smrg   assert(ctx->Const.MaxDrawBuffers <= MAX_DRAW_BUFFERS);
9527117f1b4Smrg
9537117f1b4Smrg   /* XXX probably add more tests */
9547117f1b4Smrg}
9557117f1b4Smrg
9567117f1b4Smrg
9577117f1b4Smrg/**
9587117f1b4Smrg * Initialize the attribute groups in a GL context.
9597117f1b4Smrg *
9607117f1b4Smrg * \param ctx GL context.
9617117f1b4Smrg *
9627117f1b4Smrg * Initializes all the attributes, calling the respective <tt>init*</tt>
9637117f1b4Smrg * functions for the more complex data structures.
9647117f1b4Smrg */
9657117f1b4Smrgstatic GLboolean
9667117f1b4Smrginit_attrib_groups(GLcontext *ctx)
9677117f1b4Smrg{
9687117f1b4Smrg   assert(ctx);
9697117f1b4Smrg
9707117f1b4Smrg   /* Constants */
9717117f1b4Smrg   _mesa_init_constants( ctx );
9727117f1b4Smrg
9737117f1b4Smrg   /* Extensions */
9747117f1b4Smrg   _mesa_init_extensions( ctx );
9757117f1b4Smrg
9767117f1b4Smrg   /* Attribute Groups */
977c1f859d4Smrg#if FEATURE_accum
9787117f1b4Smrg   _mesa_init_accum( ctx );
979c1f859d4Smrg#endif
980c1f859d4Smrg#if FEATURE_attrib_stack
9817117f1b4Smrg   _mesa_init_attrib( ctx );
982c1f859d4Smrg#endif
9837117f1b4Smrg   _mesa_init_buffer_objects( ctx );
9847117f1b4Smrg   _mesa_init_color( ctx );
985c1f859d4Smrg#if FEATURE_colortable
9867117f1b4Smrg   _mesa_init_colortables( ctx );
987c1f859d4Smrg#endif
9887117f1b4Smrg   _mesa_init_current( ctx );
9897117f1b4Smrg   _mesa_init_depth( ctx );
9907117f1b4Smrg   _mesa_init_debug( ctx );
991c1f859d4Smrg#if FEATURE_dlist
9927117f1b4Smrg   _mesa_init_display_list( ctx );
993c1f859d4Smrg#endif
994c1f859d4Smrg#if FEATURE_evaluators
9957117f1b4Smrg   _mesa_init_eval( ctx );
996c1f859d4Smrg#endif
997c1f859d4Smrg   _mesa_init_fbobjects( ctx );
998c1f859d4Smrg#if FEATURE_feedback
9997117f1b4Smrg   _mesa_init_feedback( ctx );
1000c1f859d4Smrg#else
1001c1f859d4Smrg   ctx->RenderMode = GL_RENDER;
1002c1f859d4Smrg#endif
10037117f1b4Smrg   _mesa_init_fog( ctx );
1004c1f859d4Smrg#if FEATURE_histogram
10057117f1b4Smrg   _mesa_init_histogram( ctx );
1006c1f859d4Smrg#endif
10077117f1b4Smrg   _mesa_init_hint( ctx );
10087117f1b4Smrg   _mesa_init_line( ctx );
10097117f1b4Smrg   _mesa_init_lighting( ctx );
10107117f1b4Smrg   _mesa_init_matrix( ctx );
10117117f1b4Smrg   _mesa_init_multisample( ctx );
10127117f1b4Smrg   _mesa_init_pixel( ctx );
1013c1f859d4Smrg   _mesa_init_pixelstore( ctx );
10147117f1b4Smrg   _mesa_init_point( ctx );
10157117f1b4Smrg   _mesa_init_polygon( ctx );
10167117f1b4Smrg   _mesa_init_program( ctx );
1017c1f859d4Smrg#if FEATURE_ARB_occlusion_query
10187117f1b4Smrg   _mesa_init_query( ctx );
1019c1f859d4Smrg#endif
1020c1f859d4Smrg#if FEATURE_drawpix
10217117f1b4Smrg   _mesa_init_rastpos( ctx );
1022c1f859d4Smrg#endif
10237117f1b4Smrg   _mesa_init_scissor( ctx );
10247117f1b4Smrg   _mesa_init_shader_state( ctx );
10257117f1b4Smrg   _mesa_init_stencil( ctx );
10267117f1b4Smrg   _mesa_init_transform( ctx );
10277117f1b4Smrg   _mesa_init_varray( ctx );
10287117f1b4Smrg   _mesa_init_viewport( ctx );
10297117f1b4Smrg
10307117f1b4Smrg   if (!_mesa_init_texture( ctx ))
10317117f1b4Smrg      return GL_FALSE;
10327117f1b4Smrg
1033c1f859d4Smrg#if FEATURE_texture_s3tc
10347117f1b4Smrg   _mesa_init_texture_s3tc( ctx );
1035c1f859d4Smrg#endif
1036c1f859d4Smrg#if FEATURE_texture_fxt1
10377117f1b4Smrg   _mesa_init_texture_fxt1( ctx );
1038c1f859d4Smrg#endif
10397117f1b4Smrg
10407117f1b4Smrg   /* Miscellaneous */
10417117f1b4Smrg   ctx->NewState = _NEW_ALL;
10427117f1b4Smrg   ctx->ErrorValue = (GLenum) GL_NO_ERROR;
10437117f1b4Smrg
10447117f1b4Smrg   return GL_TRUE;
10457117f1b4Smrg}
10467117f1b4Smrg
10477117f1b4Smrg
1048c1f859d4Smrg/**
1049c1f859d4Smrg * Update default objects in a GL context with respect to shared state.
1050c1f859d4Smrg *
1051c1f859d4Smrg * \param ctx GL context.
1052c1f859d4Smrg *
1053c1f859d4Smrg * Removes references to old default objects, (texture objects, program
1054c1f859d4Smrg * objects, etc.) and changes to reference those from the current shared
1055c1f859d4Smrg * state.
1056c1f859d4Smrg */
1057c1f859d4Smrgstatic GLboolean
1058c1f859d4Smrgupdate_default_objects(GLcontext *ctx)
1059c1f859d4Smrg{
1060c1f859d4Smrg   assert(ctx);
1061c1f859d4Smrg
1062c1f859d4Smrg   _mesa_update_default_objects_program(ctx);
1063c1f859d4Smrg   _mesa_update_default_objects_texture(ctx);
1064c1f859d4Smrg   _mesa_update_default_objects_buffer_objects(ctx);
1065c1f859d4Smrg
1066c1f859d4Smrg   return GL_TRUE;
1067c1f859d4Smrg}
1068c1f859d4Smrg
1069c1f859d4Smrg
10707117f1b4Smrg/**
10717117f1b4Smrg * This is the default function we plug into all dispatch table slots
10727117f1b4Smrg * This helps prevents a segfault when someone calls a GL function without
10737117f1b4Smrg * first checking if the extension's supported.
10747117f1b4Smrg */
10757117f1b4Smrgstatic int
10767117f1b4Smrggeneric_nop(void)
10777117f1b4Smrg{
1078c1f859d4Smrg   _mesa_warning(NULL, "User called no-op dispatch function (an unsupported extension function?)");
10797117f1b4Smrg   return 0;
10807117f1b4Smrg}
10817117f1b4Smrg
10827117f1b4Smrg
10837117f1b4Smrg/**
10847117f1b4Smrg * Allocate and initialize a new dispatch table.
10857117f1b4Smrg */
10867117f1b4Smrgstatic struct _glapi_table *
10877117f1b4Smrgalloc_dispatch_table(void)
10887117f1b4Smrg{
10897117f1b4Smrg   /* Find the larger of Mesa's dispatch table and libGL's dispatch table.
10907117f1b4Smrg    * In practice, this'll be the same for stand-alone Mesa.  But for DRI
10917117f1b4Smrg    * Mesa we do this to accomodate different versions of libGL and various
10927117f1b4Smrg    * DRI drivers.
10937117f1b4Smrg    */
10947117f1b4Smrg   GLint numEntries = MAX2(_glapi_get_dispatch_table_size(),
10957117f1b4Smrg                           sizeof(struct _glapi_table) / sizeof(_glapi_proc));
10967117f1b4Smrg   struct _glapi_table *table =
10977117f1b4Smrg      (struct _glapi_table *) _mesa_malloc(numEntries * sizeof(_glapi_proc));
10987117f1b4Smrg   if (table) {
10997117f1b4Smrg      _glapi_proc *entry = (_glapi_proc *) table;
11007117f1b4Smrg      GLint i;
11017117f1b4Smrg      for (i = 0; i < numEntries; i++) {
11027117f1b4Smrg         entry[i] = (_glapi_proc) generic_nop;
11037117f1b4Smrg      }
11047117f1b4Smrg   }
11057117f1b4Smrg   return table;
11067117f1b4Smrg}
11077117f1b4Smrg
11087117f1b4Smrg
11097117f1b4Smrg/**
11107117f1b4Smrg * Initialize a GLcontext struct (rendering context).
11117117f1b4Smrg *
11127117f1b4Smrg * This includes allocating all the other structs and arrays which hang off of
11137117f1b4Smrg * the context by pointers.
11147117f1b4Smrg * Note that the driver needs to pass in its dd_function_table here since
11157117f1b4Smrg * we need to at least call driverFunctions->NewTextureObject to create the
11167117f1b4Smrg * default texture objects.
11177117f1b4Smrg *
11187117f1b4Smrg * Called by _mesa_create_context().
11197117f1b4Smrg *
11207117f1b4Smrg * Performs the imports and exports callback tables initialization, and
11217117f1b4Smrg * miscellaneous one-time initializations. If no shared context is supplied one
11227117f1b4Smrg * is allocated, and increase its reference count.  Setups the GL API dispatch
11237117f1b4Smrg * tables.  Initialize the TNL module. Sets the maximum Z buffer depth.
11247117f1b4Smrg * Finally queries the \c MESA_DEBUG and \c MESA_VERBOSE environment variables
11257117f1b4Smrg * for debug flags.
11267117f1b4Smrg *
11277117f1b4Smrg * \param ctx the context to initialize
11287117f1b4Smrg * \param visual describes the visual attributes for this context
11297117f1b4Smrg * \param share_list points to context to share textures, display lists,
11307117f1b4Smrg *        etc with, or NULL
11317117f1b4Smrg * \param driverFunctions table of device driver functions for this context
11327117f1b4Smrg *        to use
11337117f1b4Smrg * \param driverContext pointer to driver-specific context data
11347117f1b4Smrg */
11357117f1b4SmrgGLboolean
11367117f1b4Smrg_mesa_initialize_context(GLcontext *ctx,
11377117f1b4Smrg                         const GLvisual *visual,
11387117f1b4Smrg                         GLcontext *share_list,
11397117f1b4Smrg                         const struct dd_function_table *driverFunctions,
11407117f1b4Smrg                         void *driverContext)
11417117f1b4Smrg{
11427117f1b4Smrg   ASSERT(driverContext);
11437117f1b4Smrg   assert(driverFunctions->NewTextureObject);
11447117f1b4Smrg   assert(driverFunctions->FreeTexImageData);
11457117f1b4Smrg
11467117f1b4Smrg   /* misc one-time initializations */
11477117f1b4Smrg   one_time_init(ctx);
11487117f1b4Smrg
11497117f1b4Smrg   ctx->Visual = *visual;
11507117f1b4Smrg   ctx->DrawBuffer = NULL;
11517117f1b4Smrg   ctx->ReadBuffer = NULL;
11527117f1b4Smrg   ctx->WinSysDrawBuffer = NULL;
11537117f1b4Smrg   ctx->WinSysReadBuffer = NULL;
11547117f1b4Smrg
11557117f1b4Smrg   /* Plug in driver functions and context pointer here.
11567117f1b4Smrg    * This is important because when we call alloc_shared_state() below
11577117f1b4Smrg    * we'll call ctx->Driver.NewTextureObject() to create the default
11587117f1b4Smrg    * textures.
11597117f1b4Smrg    */
11607117f1b4Smrg   ctx->Driver = *driverFunctions;
11617117f1b4Smrg   ctx->DriverCtx = driverContext;
11627117f1b4Smrg
11637117f1b4Smrg   if (share_list) {
11647117f1b4Smrg      /* share state with another context */
11657117f1b4Smrg      ctx->Shared = share_list->Shared;
11667117f1b4Smrg   }
11677117f1b4Smrg   else {
11687117f1b4Smrg      /* allocate new, unshared state */
11697117f1b4Smrg      if (!alloc_shared_state( ctx )) {
11707117f1b4Smrg         return GL_FALSE;
11717117f1b4Smrg      }
11727117f1b4Smrg   }
11737117f1b4Smrg   _glthread_LOCK_MUTEX(ctx->Shared->Mutex);
11747117f1b4Smrg   ctx->Shared->RefCount++;
11757117f1b4Smrg   _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex);
11767117f1b4Smrg
11777117f1b4Smrg   if (!init_attrib_groups( ctx )) {
11787117f1b4Smrg      free_shared_state(ctx, ctx->Shared);
11797117f1b4Smrg      return GL_FALSE;
11807117f1b4Smrg   }
11817117f1b4Smrg
11827117f1b4Smrg   /* setup the API dispatch tables */
11837117f1b4Smrg   ctx->Exec = alloc_dispatch_table();
11847117f1b4Smrg   ctx->Save = alloc_dispatch_table();
11857117f1b4Smrg   if (!ctx->Exec || !ctx->Save) {
11867117f1b4Smrg      free_shared_state(ctx, ctx->Shared);
11877117f1b4Smrg      if (ctx->Exec)
11887117f1b4Smrg         _mesa_free(ctx->Exec);
11897117f1b4Smrg   }
1190c1f859d4Smrg#if FEATURE_dispatch
11917117f1b4Smrg   _mesa_init_exec_table(ctx->Exec);
1192c1f859d4Smrg#endif
11937117f1b4Smrg   ctx->CurrentDispatch = ctx->Exec;
1194c1f859d4Smrg#if FEATURE_dlist
11957117f1b4Smrg   _mesa_init_dlist_table(ctx->Save);
11967117f1b4Smrg   _mesa_install_save_vtxfmt( ctx, &ctx->ListState.ListVtxfmt );
1197c1f859d4Smrg#endif
11987117f1b4Smrg   /* Neutral tnl module stuff */
11997117f1b4Smrg   _mesa_init_exec_vtxfmt( ctx );
12007117f1b4Smrg   ctx->TnlModule.Current = NULL;
12017117f1b4Smrg   ctx->TnlModule.SwapCount = 0;
12027117f1b4Smrg
12037117f1b4Smrg   ctx->FragmentProgram._MaintainTexEnvProgram
12047117f1b4Smrg      = (_mesa_getenv("MESA_TEX_PROG") != NULL);
12057117f1b4Smrg
12067117f1b4Smrg   ctx->VertexProgram._MaintainTnlProgram
12077117f1b4Smrg      = (_mesa_getenv("MESA_TNL_PROG") != NULL);
12087117f1b4Smrg   if (ctx->VertexProgram._MaintainTnlProgram) {
12097117f1b4Smrg      /* this is required... */
12107117f1b4Smrg      ctx->FragmentProgram._MaintainTexEnvProgram = GL_TRUE;
12117117f1b4Smrg   }
12127117f1b4Smrg
1213c1f859d4Smrg#ifdef FEATURE_extra_context_init
1214c1f859d4Smrg   _mesa_initialize_context_extra(ctx);
1215c1f859d4Smrg#endif
1216c1f859d4Smrg
12177117f1b4Smrg   ctx->FirstTimeCurrent = GL_TRUE;
12187117f1b4Smrg
12197117f1b4Smrg   return GL_TRUE;
12207117f1b4Smrg}
12217117f1b4Smrg
12227117f1b4Smrg
12237117f1b4Smrg/**
12247117f1b4Smrg * Allocate and initialize a GLcontext structure.
12257117f1b4Smrg * Note that the driver needs to pass in its dd_function_table here since
12267117f1b4Smrg * we need to at least call driverFunctions->NewTextureObject to initialize
12277117f1b4Smrg * the rendering context.
12287117f1b4Smrg *
12297117f1b4Smrg * \param visual a GLvisual pointer (we copy the struct contents)
12307117f1b4Smrg * \param share_list another context to share display lists with or NULL
12317117f1b4Smrg * \param driverFunctions points to the dd_function_table into which the
12327117f1b4Smrg *        driver has plugged in all its special functions.
12337117f1b4Smrg * \param driverCtx points to the device driver's private context state
12347117f1b4Smrg *
12357117f1b4Smrg * \return pointer to a new __GLcontextRec or NULL if error.
12367117f1b4Smrg */
12377117f1b4SmrgGLcontext *
12387117f1b4Smrg_mesa_create_context(const GLvisual *visual,
12397117f1b4Smrg                     GLcontext *share_list,
12407117f1b4Smrg                     const struct dd_function_table *driverFunctions,
12417117f1b4Smrg                     void *driverContext)
12427117f1b4Smrg{
12437117f1b4Smrg   GLcontext *ctx;
12447117f1b4Smrg
12457117f1b4Smrg   ASSERT(visual);
12467117f1b4Smrg   ASSERT(driverContext);
12477117f1b4Smrg
12487117f1b4Smrg   ctx = (GLcontext *) _mesa_calloc(sizeof(GLcontext));
12497117f1b4Smrg   if (!ctx)
12507117f1b4Smrg      return NULL;
12517117f1b4Smrg
12527117f1b4Smrg   if (_mesa_initialize_context(ctx, visual, share_list,
12537117f1b4Smrg                                driverFunctions, driverContext)) {
12547117f1b4Smrg      return ctx;
12557117f1b4Smrg   }
12567117f1b4Smrg   else {
12577117f1b4Smrg      _mesa_free(ctx);
12587117f1b4Smrg      return NULL;
12597117f1b4Smrg   }
12607117f1b4Smrg}
12617117f1b4Smrg
12627117f1b4Smrg
12637117f1b4Smrg/**
12647117f1b4Smrg * Free the data associated with the given context.
12657117f1b4Smrg *
12667117f1b4Smrg * But doesn't free the GLcontext struct itself.
12677117f1b4Smrg *
12687117f1b4Smrg * \sa _mesa_initialize_context() and init_attrib_groups().
12697117f1b4Smrg */
12707117f1b4Smrgvoid
12717117f1b4Smrg_mesa_free_context_data( GLcontext *ctx )
12727117f1b4Smrg{
1273c1f859d4Smrg   GLint RefCount;
1274c1f859d4Smrg
12757117f1b4Smrg   if (!_mesa_get_current_context()){
12767117f1b4Smrg      /* No current context, but we may need one in order to delete
12777117f1b4Smrg       * texture objs, etc.  So temporarily bind the context now.
12787117f1b4Smrg       */
12797117f1b4Smrg      _mesa_make_current(ctx, NULL, NULL);
12807117f1b4Smrg   }
12817117f1b4Smrg
12827117f1b4Smrg   /* unreference WinSysDraw/Read buffers */
12837117f1b4Smrg   _mesa_unreference_framebuffer(&ctx->WinSysDrawBuffer);
12847117f1b4Smrg   _mesa_unreference_framebuffer(&ctx->WinSysReadBuffer);
12857117f1b4Smrg   _mesa_unreference_framebuffer(&ctx->DrawBuffer);
12867117f1b4Smrg   _mesa_unreference_framebuffer(&ctx->ReadBuffer);
12877117f1b4Smrg
1288c1f859d4Smrg   _mesa_reference_vertprog(ctx, &ctx->VertexProgram.Current, NULL);
1289c1f859d4Smrg   _mesa_reference_vertprog(ctx, &ctx->VertexProgram._Current, NULL);
1290c1f859d4Smrg   _mesa_reference_vertprog(ctx, &ctx->VertexProgram._TnlProgram, NULL);
1291c1f859d4Smrg
1292c1f859d4Smrg   _mesa_reference_fragprog(ctx, &ctx->FragmentProgram.Current, NULL);
1293c1f859d4Smrg   _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current, NULL);
1294c1f859d4Smrg   _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._TexEnvProgram, NULL);
1295c1f859d4Smrg
12967117f1b4Smrg   _mesa_free_attrib_data(ctx);
12977117f1b4Smrg   _mesa_free_lighting_data( ctx );
1298c1f859d4Smrg#if FEATURE_evaluators
12997117f1b4Smrg   _mesa_free_eval_data( ctx );
1300c1f859d4Smrg#endif
13017117f1b4Smrg   _mesa_free_texture_data( ctx );
13027117f1b4Smrg   _mesa_free_matrix_data( ctx );
13037117f1b4Smrg   _mesa_free_viewport_data( ctx );
1304c1f859d4Smrg#if FEATURE_colortable
13057117f1b4Smrg   _mesa_free_colortables_data( ctx );
1306c1f859d4Smrg#endif
13077117f1b4Smrg   _mesa_free_program_data(ctx);
13087117f1b4Smrg   _mesa_free_shader_state(ctx);
1309c1f859d4Smrg#if FEATURE_ARB_occlusion_query
13107117f1b4Smrg   _mesa_free_query_data(ctx);
1311c1f859d4Smrg#endif
13127117f1b4Smrg
13137117f1b4Smrg#if FEATURE_ARB_vertex_buffer_object
13147117f1b4Smrg   _mesa_delete_buffer_object(ctx, ctx->Array.NullBufferObj);
13157117f1b4Smrg#endif
13167117f1b4Smrg   _mesa_delete_array_object(ctx, ctx->Array.DefaultArrayObj);
13177117f1b4Smrg
13187117f1b4Smrg   /* free dispatch tables */
13197117f1b4Smrg   _mesa_free(ctx->Exec);
13207117f1b4Smrg   _mesa_free(ctx->Save);
13217117f1b4Smrg
13227117f1b4Smrg   /* Shared context state (display lists, textures, etc) */
13237117f1b4Smrg   _glthread_LOCK_MUTEX(ctx->Shared->Mutex);
1324c1f859d4Smrg   RefCount = --ctx->Shared->RefCount;
13257117f1b4Smrg   _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex);
1326c1f859d4Smrg   assert(RefCount >= 0);
1327c1f859d4Smrg   if (RefCount == 0) {
13287117f1b4Smrg      /* free shared state */
13297117f1b4Smrg      free_shared_state( ctx, ctx->Shared );
13307117f1b4Smrg   }
13317117f1b4Smrg
13327117f1b4Smrg   if (ctx->Extensions.String)
13337117f1b4Smrg      _mesa_free((void *) ctx->Extensions.String);
13347117f1b4Smrg
13357117f1b4Smrg   /* unbind the context if it's currently bound */
13367117f1b4Smrg   if (ctx == _mesa_get_current_context()) {
13377117f1b4Smrg      _mesa_make_current(NULL, NULL, NULL);
13387117f1b4Smrg   }
13397117f1b4Smrg}
13407117f1b4Smrg
13417117f1b4Smrg
13427117f1b4Smrg/**
13437117f1b4Smrg * Destroy a GLcontext structure.
13447117f1b4Smrg *
13457117f1b4Smrg * \param ctx GL context.
13467117f1b4Smrg *
13477117f1b4Smrg * Calls _mesa_free_context_data() and frees the GLcontext structure itself.
13487117f1b4Smrg */
13497117f1b4Smrgvoid
13507117f1b4Smrg_mesa_destroy_context( GLcontext *ctx )
13517117f1b4Smrg{
13527117f1b4Smrg   if (ctx) {
13537117f1b4Smrg      _mesa_free_context_data(ctx);
13547117f1b4Smrg      _mesa_free( (void *) ctx );
13557117f1b4Smrg   }
13567117f1b4Smrg}
13577117f1b4Smrg
13587117f1b4Smrg
13597117f1b4Smrg#if _HAVE_FULL_GL
13607117f1b4Smrg/**
13617117f1b4Smrg * Copy attribute groups from one context to another.
13627117f1b4Smrg *
13637117f1b4Smrg * \param src source context
13647117f1b4Smrg * \param dst destination context
13657117f1b4Smrg * \param mask bitwise OR of GL_*_BIT flags
13667117f1b4Smrg *
13677117f1b4Smrg * According to the bits specified in \p mask, copies the corresponding
13687117f1b4Smrg * attributes from \p src into \p dst.  For many of the attributes a simple \c
13697117f1b4Smrg * memcpy is not enough due to the existence of internal pointers in their data
13707117f1b4Smrg * structures.
13717117f1b4Smrg */
13727117f1b4Smrgvoid
13737117f1b4Smrg_mesa_copy_context( const GLcontext *src, GLcontext *dst, GLuint mask )
13747117f1b4Smrg{
13757117f1b4Smrg   if (mask & GL_ACCUM_BUFFER_BIT) {
13767117f1b4Smrg      /* OK to memcpy */
13777117f1b4Smrg      dst->Accum = src->Accum;
13787117f1b4Smrg   }
13797117f1b4Smrg   if (mask & GL_COLOR_BUFFER_BIT) {
13807117f1b4Smrg      /* OK to memcpy */
13817117f1b4Smrg      dst->Color = src->Color;
13827117f1b4Smrg   }
13837117f1b4Smrg   if (mask & GL_CURRENT_BIT) {
13847117f1b4Smrg      /* OK to memcpy */
13857117f1b4Smrg      dst->Current = src->Current;
13867117f1b4Smrg   }
13877117f1b4Smrg   if (mask & GL_DEPTH_BUFFER_BIT) {
13887117f1b4Smrg      /* OK to memcpy */
13897117f1b4Smrg      dst->Depth = src->Depth;
13907117f1b4Smrg   }
13917117f1b4Smrg   if (mask & GL_ENABLE_BIT) {
13927117f1b4Smrg      /* no op */
13937117f1b4Smrg   }
13947117f1b4Smrg   if (mask & GL_EVAL_BIT) {
13957117f1b4Smrg      /* OK to memcpy */
13967117f1b4Smrg      dst->Eval = src->Eval;
13977117f1b4Smrg   }
13987117f1b4Smrg   if (mask & GL_FOG_BIT) {
13997117f1b4Smrg      /* OK to memcpy */
14007117f1b4Smrg      dst->Fog = src->Fog;
14017117f1b4Smrg   }
14027117f1b4Smrg   if (mask & GL_HINT_BIT) {
14037117f1b4Smrg      /* OK to memcpy */
14047117f1b4Smrg      dst->Hint = src->Hint;
14057117f1b4Smrg   }
14067117f1b4Smrg   if (mask & GL_LIGHTING_BIT) {
14077117f1b4Smrg      GLuint i;
14087117f1b4Smrg      /* begin with memcpy */
14097117f1b4Smrg      dst->Light = src->Light;
14107117f1b4Smrg      /* fixup linked lists to prevent pointer insanity */
14117117f1b4Smrg      make_empty_list( &(dst->Light.EnabledList) );
14127117f1b4Smrg      for (i = 0; i < MAX_LIGHTS; i++) {
14137117f1b4Smrg         if (dst->Light.Light[i].Enabled) {
14147117f1b4Smrg            insert_at_tail(&(dst->Light.EnabledList), &(dst->Light.Light[i]));
14157117f1b4Smrg         }
14167117f1b4Smrg      }
14177117f1b4Smrg   }
14187117f1b4Smrg   if (mask & GL_LINE_BIT) {
14197117f1b4Smrg      /* OK to memcpy */
14207117f1b4Smrg      dst->Line = src->Line;
14217117f1b4Smrg   }
14227117f1b4Smrg   if (mask & GL_LIST_BIT) {
14237117f1b4Smrg      /* OK to memcpy */
14247117f1b4Smrg      dst->List = src->List;
14257117f1b4Smrg   }
14267117f1b4Smrg   if (mask & GL_PIXEL_MODE_BIT) {
14277117f1b4Smrg      /* OK to memcpy */
14287117f1b4Smrg      dst->Pixel = src->Pixel;
14297117f1b4Smrg   }
14307117f1b4Smrg   if (mask & GL_POINT_BIT) {
14317117f1b4Smrg      /* OK to memcpy */
14327117f1b4Smrg      dst->Point = src->Point;
14337117f1b4Smrg   }
14347117f1b4Smrg   if (mask & GL_POLYGON_BIT) {
14357117f1b4Smrg      /* OK to memcpy */
14367117f1b4Smrg      dst->Polygon = src->Polygon;
14377117f1b4Smrg   }
14387117f1b4Smrg   if (mask & GL_POLYGON_STIPPLE_BIT) {
14397117f1b4Smrg      /* Use loop instead of MEMCPY due to problem with Portland Group's
14407117f1b4Smrg       * C compiler.  Reported by John Stone.
14417117f1b4Smrg       */
14427117f1b4Smrg      GLuint i;
14437117f1b4Smrg      for (i = 0; i < 32; i++) {
14447117f1b4Smrg         dst->PolygonStipple[i] = src->PolygonStipple[i];
14457117f1b4Smrg      }
14467117f1b4Smrg   }
14477117f1b4Smrg   if (mask & GL_SCISSOR_BIT) {
14487117f1b4Smrg      /* OK to memcpy */
14497117f1b4Smrg      dst->Scissor = src->Scissor;
14507117f1b4Smrg   }
14517117f1b4Smrg   if (mask & GL_STENCIL_BUFFER_BIT) {
14527117f1b4Smrg      /* OK to memcpy */
14537117f1b4Smrg      dst->Stencil = src->Stencil;
14547117f1b4Smrg   }
14557117f1b4Smrg   if (mask & GL_TEXTURE_BIT) {
14567117f1b4Smrg      /* Cannot memcpy because of pointers */
14577117f1b4Smrg      _mesa_copy_texture_state(src, dst);
14587117f1b4Smrg   }
14597117f1b4Smrg   if (mask & GL_TRANSFORM_BIT) {
14607117f1b4Smrg      /* OK to memcpy */
14617117f1b4Smrg      dst->Transform = src->Transform;
14627117f1b4Smrg   }
14637117f1b4Smrg   if (mask & GL_VIEWPORT_BIT) {
14647117f1b4Smrg      /* Cannot use memcpy, because of pointers in GLmatrix _WindowMap */
14657117f1b4Smrg      dst->Viewport.X = src->Viewport.X;
14667117f1b4Smrg      dst->Viewport.Y = src->Viewport.Y;
14677117f1b4Smrg      dst->Viewport.Width = src->Viewport.Width;
14687117f1b4Smrg      dst->Viewport.Height = src->Viewport.Height;
14697117f1b4Smrg      dst->Viewport.Near = src->Viewport.Near;
14707117f1b4Smrg      dst->Viewport.Far = src->Viewport.Far;
14717117f1b4Smrg      _math_matrix_copy(&dst->Viewport._WindowMap, &src->Viewport._WindowMap);
14727117f1b4Smrg   }
14737117f1b4Smrg
14747117f1b4Smrg   /* XXX FIXME:  Call callbacks?
14757117f1b4Smrg    */
14767117f1b4Smrg   dst->NewState = _NEW_ALL;
14777117f1b4Smrg}
14787117f1b4Smrg#endif
14797117f1b4Smrg
14807117f1b4Smrg
14817117f1b4Smrg/**
14827117f1b4Smrg * Check if the given context can render into the given framebuffer
14837117f1b4Smrg * by checking visual attributes.
14847117f1b4Smrg *
1485c1f859d4Smrg * Most of these tests could go away because Mesa is now pretty flexible
1486c1f859d4Smrg * in terms of mixing rendering contexts with framebuffers.  As long
1487c1f859d4Smrg * as RGB vs. CI mode agree, we're probably good.
14887117f1b4Smrg *
14897117f1b4Smrg * \return GL_TRUE if compatible, GL_FALSE otherwise.
14907117f1b4Smrg */
14917117f1b4Smrgstatic GLboolean
14927117f1b4Smrgcheck_compatible(const GLcontext *ctx, const GLframebuffer *buffer)
14937117f1b4Smrg{
14947117f1b4Smrg   const GLvisual *ctxvis = &ctx->Visual;
14957117f1b4Smrg   const GLvisual *bufvis = &buffer->Visual;
14967117f1b4Smrg
14977117f1b4Smrg   if (ctxvis == bufvis)
14987117f1b4Smrg      return GL_TRUE;
14997117f1b4Smrg
15007117f1b4Smrg   if (ctxvis->rgbMode != bufvis->rgbMode)
15017117f1b4Smrg      return GL_FALSE;
15027117f1b4Smrg#if 0
15037117f1b4Smrg   /* disabling this fixes the fgl_glxgears pbuffer demo */
15047117f1b4Smrg   if (ctxvis->doubleBufferMode && !bufvis->doubleBufferMode)
15057117f1b4Smrg      return GL_FALSE;
15067117f1b4Smrg#endif
15077117f1b4Smrg   if (ctxvis->stereoMode && !bufvis->stereoMode)
15087117f1b4Smrg      return GL_FALSE;
15097117f1b4Smrg   if (ctxvis->haveAccumBuffer && !bufvis->haveAccumBuffer)
15107117f1b4Smrg      return GL_FALSE;
15117117f1b4Smrg   if (ctxvis->haveDepthBuffer && !bufvis->haveDepthBuffer)
15127117f1b4Smrg      return GL_FALSE;
15137117f1b4Smrg   if (ctxvis->haveStencilBuffer && !bufvis->haveStencilBuffer)
15147117f1b4Smrg      return GL_FALSE;
15157117f1b4Smrg   if (ctxvis->redMask && ctxvis->redMask != bufvis->redMask)
15167117f1b4Smrg      return GL_FALSE;
15177117f1b4Smrg   if (ctxvis->greenMask && ctxvis->greenMask != bufvis->greenMask)
15187117f1b4Smrg      return GL_FALSE;
15197117f1b4Smrg   if (ctxvis->blueMask && ctxvis->blueMask != bufvis->blueMask)
15207117f1b4Smrg      return GL_FALSE;
15217117f1b4Smrg#if 0
15227117f1b4Smrg   /* disabled (see bug 11161) */
15237117f1b4Smrg   if (ctxvis->depthBits && ctxvis->depthBits != bufvis->depthBits)
15247117f1b4Smrg      return GL_FALSE;
15257117f1b4Smrg#endif
15267117f1b4Smrg   if (ctxvis->stencilBits && ctxvis->stencilBits != bufvis->stencilBits)
15277117f1b4Smrg      return GL_FALSE;
15287117f1b4Smrg
15297117f1b4Smrg   return GL_TRUE;
15307117f1b4Smrg}
15317117f1b4Smrg
15327117f1b4Smrg
15337117f1b4Smrg/**
15347117f1b4Smrg * Do one-time initialization for the given framebuffer.  Specifically,
15357117f1b4Smrg * ask the driver for the window's current size and update the framebuffer
15367117f1b4Smrg * object to match.
15377117f1b4Smrg * Really, the device driver should totally take care of this.
15387117f1b4Smrg */
15397117f1b4Smrgstatic void
15407117f1b4Smrginitialize_framebuffer_size(GLcontext *ctx, GLframebuffer *fb)
15417117f1b4Smrg{
15427117f1b4Smrg   GLuint width, height;
15437117f1b4Smrg   if (ctx->Driver.GetBufferSize) {
15447117f1b4Smrg      ctx->Driver.GetBufferSize(fb, &width, &height);
15457117f1b4Smrg      if (ctx->Driver.ResizeBuffers)
15467117f1b4Smrg         ctx->Driver.ResizeBuffers(ctx, fb, width, height);
15477117f1b4Smrg      fb->Initialized = GL_TRUE;
15487117f1b4Smrg   }
15497117f1b4Smrg}
15507117f1b4Smrg
15517117f1b4Smrg
1552c7037ccdSmrg/**
1553c7037ccdSmrg * Check if the viewport/scissor size has not yet been initialized.
1554c7037ccdSmrg * Initialize the size if the given width and height are non-zero.
1555c7037ccdSmrg */
1556c7037ccdSmrgvoid
1557c7037ccdSmrg_mesa_check_init_viewport(GLcontext *ctx, GLuint width, GLuint height)
1558c7037ccdSmrg{
1559c7037ccdSmrg   if (!ctx->ViewportInitialized && width > 0 && height > 0) {
1560c7037ccdSmrg      /* Note: set flag here, before calling _mesa_set_viewport(), to prevent
1561c7037ccdSmrg       * potential infinite recursion.
1562c7037ccdSmrg       */
1563c7037ccdSmrg      ctx->ViewportInitialized = GL_TRUE;
1564c7037ccdSmrg      _mesa_set_viewport(ctx, 0, 0, width, height);
1565c7037ccdSmrg      _mesa_set_scissor(ctx, 0, 0, width, height);
1566c7037ccdSmrg   }
1567c7037ccdSmrg}
1568c7037ccdSmrg
1569c7037ccdSmrg
15707117f1b4Smrg/**
15717117f1b4Smrg * Bind the given context to the given drawBuffer and readBuffer and
15727117f1b4Smrg * make it the current context for the calling thread.
15737117f1b4Smrg * We'll render into the drawBuffer and read pixels from the
15747117f1b4Smrg * readBuffer (i.e. glRead/CopyPixels, glCopyTexImage, etc).
15757117f1b4Smrg *
15767117f1b4Smrg * We check that the context's and framebuffer's visuals are compatible
15777117f1b4Smrg * and return immediately if they're not.
15787117f1b4Smrg *
15797117f1b4Smrg * \param newCtx  the new GL context. If NULL then there will be no current GL
15807117f1b4Smrg *                context.
15817117f1b4Smrg * \param drawBuffer  the drawing framebuffer
15827117f1b4Smrg * \param readBuffer  the reading framebuffer
15837117f1b4Smrg */
15847117f1b4Smrgvoid
15857117f1b4Smrg_mesa_make_current( GLcontext *newCtx, GLframebuffer *drawBuffer,
15867117f1b4Smrg                    GLframebuffer *readBuffer )
15877117f1b4Smrg{
15887117f1b4Smrg   if (MESA_VERBOSE & VERBOSE_API)
15897117f1b4Smrg      _mesa_debug(newCtx, "_mesa_make_current()\n");
15907117f1b4Smrg
15917117f1b4Smrg   /* Check that the context's and framebuffer's visuals are compatible.
15927117f1b4Smrg    */
15937117f1b4Smrg   if (newCtx && drawBuffer && newCtx->WinSysDrawBuffer != drawBuffer) {
15947117f1b4Smrg      if (!check_compatible(newCtx, drawBuffer)) {
15957117f1b4Smrg         _mesa_warning(newCtx,
15967117f1b4Smrg              "MakeCurrent: incompatible visuals for context and drawbuffer");
15977117f1b4Smrg         return;
15987117f1b4Smrg      }
15997117f1b4Smrg   }
16007117f1b4Smrg   if (newCtx && readBuffer && newCtx->WinSysReadBuffer != readBuffer) {
16017117f1b4Smrg      if (!check_compatible(newCtx, readBuffer)) {
16027117f1b4Smrg         _mesa_warning(newCtx,
16037117f1b4Smrg              "MakeCurrent: incompatible visuals for context and readbuffer");
16047117f1b4Smrg         return;
16057117f1b4Smrg      }
16067117f1b4Smrg   }
16077117f1b4Smrg
16087117f1b4Smrg   /* We used to call _glapi_check_multithread() here.  Now do it in drivers */
16097117f1b4Smrg   _glapi_set_context((void *) newCtx);
16107117f1b4Smrg   ASSERT(_mesa_get_current_context() == newCtx);
16117117f1b4Smrg
16127117f1b4Smrg   if (!newCtx) {
16137117f1b4Smrg      _glapi_set_dispatch(NULL);  /* none current */
16147117f1b4Smrg   }
16157117f1b4Smrg   else {
16167117f1b4Smrg      _glapi_set_dispatch(newCtx->CurrentDispatch);
16177117f1b4Smrg
16187117f1b4Smrg      if (drawBuffer && readBuffer) {
16197117f1b4Smrg	 /* TODO: check if newCtx and buffer's visual match??? */
16207117f1b4Smrg
16217117f1b4Smrg         ASSERT(drawBuffer->Name == 0);
16227117f1b4Smrg         ASSERT(readBuffer->Name == 0);
16237117f1b4Smrg         _mesa_reference_framebuffer(&newCtx->WinSysDrawBuffer, drawBuffer);
16247117f1b4Smrg         _mesa_reference_framebuffer(&newCtx->WinSysReadBuffer, readBuffer);
16257117f1b4Smrg
16267117f1b4Smrg         /*
16277117f1b4Smrg          * Only set the context's Draw/ReadBuffer fields if they're NULL
16287117f1b4Smrg          * or not bound to a user-created FBO.
16297117f1b4Smrg          */
16307117f1b4Smrg         if (!newCtx->DrawBuffer || newCtx->DrawBuffer->Name == 0) {
16317117f1b4Smrg            _mesa_reference_framebuffer(&newCtx->DrawBuffer, drawBuffer);
16327117f1b4Smrg         }
16337117f1b4Smrg         if (!newCtx->ReadBuffer || newCtx->ReadBuffer->Name == 0) {
16347117f1b4Smrg            _mesa_reference_framebuffer(&newCtx->ReadBuffer, readBuffer);
16357117f1b4Smrg         }
16367117f1b4Smrg
1637c1f859d4Smrg         /* XXX only set this flag if we're really changing the draw/read
1638c1f859d4Smrg          * framebuffer bindings.
1639c1f859d4Smrg          */
16407117f1b4Smrg	 newCtx->NewState |= _NEW_BUFFERS;
16417117f1b4Smrg
16427117f1b4Smrg#if 1
16437117f1b4Smrg         /* We want to get rid of these lines: */
16447117f1b4Smrg
16457117f1b4Smrg#if _HAVE_FULL_GL
16467117f1b4Smrg         if (!drawBuffer->Initialized) {
16477117f1b4Smrg            initialize_framebuffer_size(newCtx, drawBuffer);
16487117f1b4Smrg         }
16497117f1b4Smrg         if (readBuffer != drawBuffer && !readBuffer->Initialized) {
16507117f1b4Smrg            initialize_framebuffer_size(newCtx, readBuffer);
16517117f1b4Smrg         }
16527117f1b4Smrg
16537117f1b4Smrg	 _mesa_resizebuffers(newCtx);
16547117f1b4Smrg#endif
16557117f1b4Smrg
16567117f1b4Smrg#else
16577117f1b4Smrg         /* We want the drawBuffer and readBuffer to be initialized by
16587117f1b4Smrg          * the driver.
16597117f1b4Smrg          * This generally means the Width and Height match the actual
16607117f1b4Smrg          * window size and the renderbuffers (both hardware and software
16617117f1b4Smrg          * based) are allocated to match.  The later can generally be
16627117f1b4Smrg          * done with a call to _mesa_resize_framebuffer().
16637117f1b4Smrg          *
16647117f1b4Smrg          * It's theoretically possible for a buffer to have zero width
16657117f1b4Smrg          * or height, but for now, assert check that the driver did what's
16667117f1b4Smrg          * expected of it.
16677117f1b4Smrg          */
16687117f1b4Smrg         ASSERT(drawBuffer->Width > 0);
16697117f1b4Smrg         ASSERT(drawBuffer->Height > 0);
16707117f1b4Smrg#endif
16717117f1b4Smrg
1672c7037ccdSmrg         if (drawBuffer) {
1673c7037ccdSmrg            _mesa_check_init_viewport(newCtx,
1674c7037ccdSmrg                                      drawBuffer->Width, drawBuffer->Height);
16757117f1b4Smrg         }
16767117f1b4Smrg      }
16777117f1b4Smrg
16787117f1b4Smrg      if (newCtx->FirstTimeCurrent) {
1679c7037ccdSmrg         check_context_limits(newCtx);
1680c7037ccdSmrg
1681c7037ccdSmrg         /* We can use this to help debug user's problems.  Tell them to set
1682c7037ccdSmrg          * the MESA_INFO env variable before running their app.  Then the
1683c7037ccdSmrg          * first time each context is made current we'll print some useful
1684c7037ccdSmrg          * information.
1685c7037ccdSmrg          */
16867117f1b4Smrg	 if (_mesa_getenv("MESA_INFO")) {
16877117f1b4Smrg	    _mesa_print_info();
16887117f1b4Smrg	 }
1689c7037ccdSmrg
16907117f1b4Smrg	 newCtx->FirstTimeCurrent = GL_FALSE;
16917117f1b4Smrg      }
16927117f1b4Smrg   }
16937117f1b4Smrg}
16947117f1b4Smrg
16957117f1b4Smrg
16967117f1b4Smrg/**
16977117f1b4Smrg * Make context 'ctx' share the display lists, textures and programs
16987117f1b4Smrg * that are associated with 'ctxToShare'.
16997117f1b4Smrg * Any display lists, textures or programs associated with 'ctx' will
17007117f1b4Smrg * be deleted if nobody else is sharing them.
17017117f1b4Smrg */
17027117f1b4SmrgGLboolean
17037117f1b4Smrg_mesa_share_state(GLcontext *ctx, GLcontext *ctxToShare)
17047117f1b4Smrg{
17057117f1b4Smrg   if (ctx && ctxToShare && ctx->Shared && ctxToShare->Shared) {
1706c1f859d4Smrg      struct gl_shared_state *oldSharedState = ctx->Shared;
1707c1f859d4Smrg
17087117f1b4Smrg      ctx->Shared = ctxToShare->Shared;
17097117f1b4Smrg      ctx->Shared->RefCount++;
1710c1f859d4Smrg
1711c1f859d4Smrg      update_default_objects(ctx);
1712c1f859d4Smrg
1713c1f859d4Smrg      oldSharedState->RefCount--;
1714c1f859d4Smrg      if (oldSharedState->RefCount == 0) {
1715c1f859d4Smrg         free_shared_state(ctx, oldSharedState);
1716c1f859d4Smrg      }
1717c1f859d4Smrg
17187117f1b4Smrg      return GL_TRUE;
17197117f1b4Smrg   }
17207117f1b4Smrg   else {
17217117f1b4Smrg      return GL_FALSE;
17227117f1b4Smrg   }
17237117f1b4Smrg}
17247117f1b4Smrg
17257117f1b4Smrg
17267117f1b4Smrg
17277117f1b4Smrg/**
17287117f1b4Smrg * \return pointer to the current GL context for this thread.
17297117f1b4Smrg *
17307117f1b4Smrg * Calls _glapi_get_context(). This isn't the fastest way to get the current
17317117f1b4Smrg * context.  If you need speed, see the #GET_CURRENT_CONTEXT macro in
17327117f1b4Smrg * context.h.
17337117f1b4Smrg */
17347117f1b4SmrgGLcontext *
17357117f1b4Smrg_mesa_get_current_context( void )
17367117f1b4Smrg{
17377117f1b4Smrg   return (GLcontext *) _glapi_get_context();
17387117f1b4Smrg}
17397117f1b4Smrg
17407117f1b4Smrg
17417117f1b4Smrg/**
17427117f1b4Smrg * Get context's current API dispatch table.
17437117f1b4Smrg *
17447117f1b4Smrg * It'll either be the immediate-mode execute dispatcher or the display list
17457117f1b4Smrg * compile dispatcher.
17467117f1b4Smrg *
17477117f1b4Smrg * \param ctx GL context.
17487117f1b4Smrg *
17497117f1b4Smrg * \return pointer to dispatch_table.
17507117f1b4Smrg *
17517117f1b4Smrg * Simply returns __GLcontextRec::CurrentDispatch.
17527117f1b4Smrg */
17537117f1b4Smrgstruct _glapi_table *
17547117f1b4Smrg_mesa_get_dispatch(GLcontext *ctx)
17557117f1b4Smrg{
17567117f1b4Smrg   return ctx->CurrentDispatch;
17577117f1b4Smrg}
17587117f1b4Smrg
17597117f1b4Smrg/*@}*/
17607117f1b4Smrg
17617117f1b4Smrg
17627117f1b4Smrg/**********************************************************************/
17637117f1b4Smrg/** \name Miscellaneous functions                                     */
17647117f1b4Smrg/**********************************************************************/
17657117f1b4Smrg/*@{*/
17667117f1b4Smrg
17677117f1b4Smrg/**
17687117f1b4Smrg * Record an error.
17697117f1b4Smrg *
17707117f1b4Smrg * \param ctx GL context.
17717117f1b4Smrg * \param error error code.
17727117f1b4Smrg *
17737117f1b4Smrg * Records the given error code and call the driver's dd_function_table::Error
17747117f1b4Smrg * function if defined.
17757117f1b4Smrg *
17767117f1b4Smrg * \sa
17777117f1b4Smrg * This is called via _mesa_error().
17787117f1b4Smrg */
17797117f1b4Smrgvoid
17807117f1b4Smrg_mesa_record_error(GLcontext *ctx, GLenum error)
17817117f1b4Smrg{
17827117f1b4Smrg   if (!ctx)
17837117f1b4Smrg      return;
17847117f1b4Smrg
17857117f1b4Smrg   if (ctx->ErrorValue == GL_NO_ERROR) {
17867117f1b4Smrg      ctx->ErrorValue = error;
17877117f1b4Smrg   }
17887117f1b4Smrg
17897117f1b4Smrg   /* Call device driver's error handler, if any.  This is used on the Mac. */
17907117f1b4Smrg   if (ctx->Driver.Error) {
17917117f1b4Smrg      ctx->Driver.Error(ctx);
17927117f1b4Smrg   }
17937117f1b4Smrg}
17947117f1b4Smrg
17957117f1b4Smrg
17967117f1b4Smrg/**
17977117f1b4Smrg * Execute glFinish().
17987117f1b4Smrg *
17997117f1b4Smrg * Calls the #ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH macro and the
18007117f1b4Smrg * dd_function_table::Finish driver callback, if not NULL.
18017117f1b4Smrg */
18027117f1b4Smrgvoid GLAPIENTRY
18037117f1b4Smrg_mesa_Finish(void)
18047117f1b4Smrg{
18057117f1b4Smrg   GET_CURRENT_CONTEXT(ctx);
18067117f1b4Smrg   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
18077117f1b4Smrg   if (ctx->Driver.Finish) {
18087117f1b4Smrg      ctx->Driver.Finish(ctx);
18097117f1b4Smrg   }
18107117f1b4Smrg}
18117117f1b4Smrg
18127117f1b4Smrg
18137117f1b4Smrg/**
18147117f1b4Smrg * Execute glFlush().
18157117f1b4Smrg *
18167117f1b4Smrg * Calls the #ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH macro and the
18177117f1b4Smrg * dd_function_table::Flush driver callback, if not NULL.
18187117f1b4Smrg */
18197117f1b4Smrgvoid GLAPIENTRY
18207117f1b4Smrg_mesa_Flush(void)
18217117f1b4Smrg{
18227117f1b4Smrg   GET_CURRENT_CONTEXT(ctx);
18237117f1b4Smrg   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
18247117f1b4Smrg   if (ctx->Driver.Flush) {
18257117f1b4Smrg      ctx->Driver.Flush(ctx);
18267117f1b4Smrg   }
18277117f1b4Smrg}
18287117f1b4Smrg
18297117f1b4Smrg
18307117f1b4Smrg/*@}*/
1831