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