14045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul/* 24045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul * Mesa 3-D graphics library 34045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul * Version: 7.5 44045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul * 54045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul * Copyright (C) 2009 VMware, Inc. All Rights Reserved. 64045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul * 74045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul * Permission is hereby granted, free of charge, to any person obtaining a 84045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul * copy of this software and associated documentation files (the "Software"), 94045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul * to deal in the Software without restriction, including without limitation 104045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul * the rights to use, copy, modify, merge, publish, distribute, sublicense, 114045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul * and/or sell copies of the Software, and to permit persons to whom the 124045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul * Software is furnished to do so, subject to the following conditions: 134045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul * 144045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul * The above copyright notice and this permission notice shall be included 154045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul * in all copies or substantial portions of the Software. 164045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul * 174045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 184045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 194045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 204045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 214045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 224045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 234045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul */ 244045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul 254045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul/** 264045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul * \file shared.c 274045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul * Shared-context state 284045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul */ 294045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul 304045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul#include "imports.h" 31db61b9ce39bccc43140357652ceb78baaf2aea44Vinson Lee#include "mfeatures.h" 324045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul#include "mtypes.h" 334045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul#include "hash.h" 3470c8d29b6bb3214966892d51e6b2befa7040622dBrian Paul#if FEATURE_ATI_fragment_shader 3570c8d29b6bb3214966892d51e6b2befa7040622dBrian Paul#include "atifragshader.h" 3670c8d29b6bb3214966892d51e6b2befa7040622dBrian Paul#endif 374f6b704f9796775d8d9937c3cf75a2901b99b896Brian Paul#include "bufferobj.h" 384045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul#include "shared.h" 39ec2b92f98c2e7f161521b447cc1d9a36bce3707cBrian Paul#include "program/program.h" 404045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul#include "dlist.h" 416bb4d807f7e80eaf899fd5c34c2c9ff0474eb80eBrian Paul#if FEATURE_ARB_sampler_objects 426bb4d807f7e80eaf899fd5c34c2c9ff0474eb80eBrian Paul#include "samplerobj.h" 436bb4d807f7e80eaf899fd5c34c2c9ff0474eb80eBrian Paul#endif 44a37b2219d6e3f299379c6434d65f300660d12c3eBrian Paul#include "shaderobj.h" 4516b393d05990b6e917e144f9de87d0103b4c3e6dIan Romanick#include "syncobj.h" 464045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul 47032a7ef0a1cb753defc11e97b11ea2e602bae5f2Brian Paul 484045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul/** 494045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul * Allocate and initialize a shared context state structure. 504045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul * Initializes the display list, texture objects and vertex programs hash 514045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul * tables, allocates the texture objects. If it runs out of memory, frees 524045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul * everything already allocated before returning NULL. 534045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul * 544045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul * \return pointer to a gl_shared_state structure on success, or NULL on 554045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul * failure. 564045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul */ 574045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paulstruct gl_shared_state * 58f9995b30756140724f41daf963fa06167912be7fKristian Høgsberg_mesa_alloc_shared_state(struct gl_context *ctx) 594045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul{ 604045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul struct gl_shared_state *shared; 614045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul GLuint i; 624045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul 634045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul shared = CALLOC_STRUCT(gl_shared_state); 644045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul if (!shared) 654045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul return NULL; 664045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul 674045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul _glthread_INIT_MUTEX(shared->Mutex); 684045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul 694045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul shared->DisplayList = _mesa_NewHashTable(); 704045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul shared->TexObjects = _mesa_NewHashTable(); 714045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul shared->Programs = _mesa_NewHashTable(); 724045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul 734045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul#if FEATURE_ARB_vertex_program 74e4f8d33aea7e0112dfbf3a38fdc36d11b2e7be10Brian Paul shared->DefaultVertexProgram = 75e4f8d33aea7e0112dfbf3a38fdc36d11b2e7be10Brian Paul gl_vertex_program(ctx->Driver.NewProgram(ctx, 76e4f8d33aea7e0112dfbf3a38fdc36d11b2e7be10Brian Paul GL_VERTEX_PROGRAM_ARB, 0)); 774045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul#endif 784045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul 794045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul#if FEATURE_ARB_fragment_program 80e4f8d33aea7e0112dfbf3a38fdc36d11b2e7be10Brian Paul shared->DefaultFragmentProgram = 81e4f8d33aea7e0112dfbf3a38fdc36d11b2e7be10Brian Paul gl_fragment_program(ctx->Driver.NewProgram(ctx, 82e4f8d33aea7e0112dfbf3a38fdc36d11b2e7be10Brian Paul GL_FRAGMENT_PROGRAM_ARB, 0)); 834045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul#endif 844045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul 854045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul#if FEATURE_ATI_fragment_shader 864045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul shared->ATIShaders = _mesa_NewHashTable(); 874045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul shared->DefaultFragmentShader = _mesa_new_ati_fragment_shader(ctx, 0); 884045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul#endif 894045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul 904045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul#if FEATURE_ARB_shader_objects 914045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul shared->ShaderObjects = _mesa_NewHashTable(); 924045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul#endif 934045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul 944045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul shared->BufferObjects = _mesa_NewHashTable(); 954045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul 966bb4d807f7e80eaf899fd5c34c2c9ff0474eb80eBrian Paul#if FEATURE_ARB_sampler_objects 976bb4d807f7e80eaf899fd5c34c2c9ff0474eb80eBrian Paul /* GL_ARB_sampler_objects */ 986bb4d807f7e80eaf899fd5c34c2c9ff0474eb80eBrian Paul shared->SamplerObjects = _mesa_NewHashTable(); 996bb4d807f7e80eaf899fd5c34c2c9ff0474eb80eBrian Paul#endif 1006bb4d807f7e80eaf899fd5c34c2c9ff0474eb80eBrian Paul 10105ac187f305bb653d569b5c07446ec0f4cd7ff08José Fonseca /* Allocate the default buffer object */ 1026629a35559ff7e3b993966f697f7c7f68e5a38d9Brian Paul shared->NullBufferObj = ctx->Driver.NewBufferObject(ctx, 0, 0); 1034f6b704f9796775d8d9937c3cf75a2901b99b896Brian Paul 1044045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul /* Create default texture objects */ 1054045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul for (i = 0; i < NUM_TEXTURE_TARGETS; i++) { 1064045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul /* NOTE: the order of these enums matches the TEXTURE_x_INDEX values */ 1074045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul static const GLenum targets[NUM_TEXTURE_TARGETS] = { 108874a2c0b7da62f4dd08dedcec221f55b22e40e95Brian Paul GL_TEXTURE_BUFFER, 1094045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul GL_TEXTURE_2D_ARRAY_EXT, 1104045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul GL_TEXTURE_1D_ARRAY_EXT, 1110c87f16817ff0bf1f05e0d634944fd47b097faeeChia-I Wu GL_TEXTURE_EXTERNAL_OES, 1124045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul GL_TEXTURE_CUBE_MAP, 1134045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul GL_TEXTURE_3D, 1144045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul GL_TEXTURE_RECTANGLE_NV, 1154045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul GL_TEXTURE_2D, 1164045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul GL_TEXTURE_1D 1174045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul }; 1186bf5daf331f13ec9503615a2578247e72b7d2cbbBrian Paul STATIC_ASSERT(Elements(targets) == NUM_TEXTURE_TARGETS); 1194045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul shared->DefaultTex[i] = ctx->Driver.NewTextureObject(ctx, 0, targets[i]); 1204045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul } 1214045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul 1224045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul /* sanity check */ 1234045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul assert(shared->DefaultTex[TEXTURE_1D_INDEX]->RefCount == 1); 1244045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul 1254045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul /* Mutex and timestamp for texobj state validation */ 1264045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul _glthread_INIT_MUTEX(shared->TexMutex); 1274045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul shared->TextureStateStamp = 0; 1284045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul 1294045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul#if FEATURE_EXT_framebuffer_object 1304045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul shared->FrameBuffers = _mesa_NewHashTable(); 1314045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul shared->RenderBuffers = _mesa_NewHashTable(); 1324045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul#endif 1334045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul 13416b393d05990b6e917e144f9de87d0103b4c3e6dIan Romanick make_empty_list(& shared->SyncObjects); 13516b393d05990b6e917e144f9de87d0103b4c3e6dIan Romanick 1364045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul return shared; 1374045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul} 1384045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul 1394045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul 1404045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul/** 1414045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul * Callback for deleting a display list. Called by _mesa_HashDeleteAll(). 1424045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul */ 1434045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paulstatic void 1444045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Pauldelete_displaylist_cb(GLuint id, void *data, void *userData) 1454045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul{ 1464045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul struct gl_display_list *list = (struct gl_display_list *) data; 147f9995b30756140724f41daf963fa06167912be7fKristian Høgsberg struct gl_context *ctx = (struct gl_context *) userData; 1484045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul _mesa_delete_list(ctx, list); 1494045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul} 1504045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul 1514045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul 1524045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul/** 1534045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul * Callback for deleting a texture object. Called by _mesa_HashDeleteAll(). 1544045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul */ 1554045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paulstatic void 1564045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Pauldelete_texture_cb(GLuint id, void *data, void *userData) 1574045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul{ 1584045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul struct gl_texture_object *texObj = (struct gl_texture_object *) data; 159f9995b30756140724f41daf963fa06167912be7fKristian Høgsberg struct gl_context *ctx = (struct gl_context *) userData; 1604045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul ctx->Driver.DeleteTexture(ctx, texObj); 1614045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul} 1624045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul 1634045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul 1644045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul/** 1654045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul * Callback for deleting a program object. Called by _mesa_HashDeleteAll(). 1664045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul */ 1674045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paulstatic void 1684045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Pauldelete_program_cb(GLuint id, void *data, void *userData) 1694045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul{ 1704045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul struct gl_program *prog = (struct gl_program *) data; 171f9995b30756140724f41daf963fa06167912be7fKristian Høgsberg struct gl_context *ctx = (struct gl_context *) userData; 172629700ed7eaaf63d2037a11b2931c91fdc22944aJosé Fonseca if(prog != &_mesa_DummyProgram) { 173629700ed7eaaf63d2037a11b2931c91fdc22944aJosé Fonseca ASSERT(prog->RefCount == 1); /* should only be referenced by hash table */ 174629700ed7eaaf63d2037a11b2931c91fdc22944aJosé Fonseca prog->RefCount = 0; /* now going away */ 175629700ed7eaaf63d2037a11b2931c91fdc22944aJosé Fonseca ctx->Driver.DeleteProgram(ctx, prog); 176629700ed7eaaf63d2037a11b2931c91fdc22944aJosé Fonseca } 1774045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul} 1784045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul 1794045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul 1804045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul#if FEATURE_ATI_fragment_shader 1814045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul/** 1824045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul * Callback for deleting an ATI fragment shader object. 1834045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul * Called by _mesa_HashDeleteAll(). 1844045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul */ 1854045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paulstatic void 1864045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Pauldelete_fragshader_cb(GLuint id, void *data, void *userData) 1874045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul{ 1884045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul struct ati_fragment_shader *shader = (struct ati_fragment_shader *) data; 189f9995b30756140724f41daf963fa06167912be7fKristian Høgsberg struct gl_context *ctx = (struct gl_context *) userData; 1904045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul _mesa_delete_ati_fragment_shader(ctx, shader); 1914045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul} 1924045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul#endif 1934045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul 1944045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul 1954045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul/** 1964045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul * Callback for deleting a buffer object. Called by _mesa_HashDeleteAll(). 1974045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul */ 1984045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paulstatic void 1994045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Pauldelete_bufferobj_cb(GLuint id, void *data, void *userData) 2004045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul{ 2014045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul struct gl_buffer_object *bufObj = (struct gl_buffer_object *) data; 202f9995b30756140724f41daf963fa06167912be7fKristian Høgsberg struct gl_context *ctx = (struct gl_context *) userData; 2034482f96c59d7d0f0b19329e997fb59dba3e84119Brian Paul if (_mesa_bufferobj_mapped(bufObj)) { 20456f0c00f125ee75caeadc1c9e8cab8a488635e5eIan Romanick ctx->Driver.UnmapBuffer(ctx, bufObj); 205cc7170464493453ec8213decd21df95121b236e2Brian Paul bufObj->Pointer = NULL; 206cc7170464493453ec8213decd21df95121b236e2Brian Paul } 20705ac187f305bb653d569b5c07446ec0f4cd7ff08José Fonseca _mesa_reference_buffer_object(ctx, &bufObj, NULL); 2084045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul} 2094045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul 2104045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul 2114045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul/** 2124045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul * Callback for freeing shader program data. Call it before delete_shader_cb 2134045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul * to avoid memory access error. 2144045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul */ 2154045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paulstatic void 2164045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paulfree_shader_program_data_cb(GLuint id, void *data, void *userData) 2174045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul{ 218f9995b30756140724f41daf963fa06167912be7fKristian Høgsberg struct gl_context *ctx = (struct gl_context *) userData; 2194045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul struct gl_shader_program *shProg = (struct gl_shader_program *) data; 2204045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul 2214045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul if (shProg->Type == GL_SHADER_PROGRAM_MESA) { 2224045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul _mesa_free_shader_program_data(ctx, shProg); 2234045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul } 2244045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul} 2254045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul 2264045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul 2274045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul/** 2284045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul * Callback for deleting shader and shader programs objects. 2294045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul * Called by _mesa_HashDeleteAll(). 2304045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul */ 2314045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paulstatic void 2324045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Pauldelete_shader_cb(GLuint id, void *data, void *userData) 2334045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul{ 234f9995b30756140724f41daf963fa06167912be7fKristian Høgsberg struct gl_context *ctx = (struct gl_context *) userData; 2354045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul struct gl_shader *sh = (struct gl_shader *) data; 2364045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul if (sh->Type == GL_FRAGMENT_SHADER || sh->Type == GL_VERTEX_SHADER) { 237a37b2219d6e3f299379c6434d65f300660d12c3eBrian Paul ctx->Driver.DeleteShader(ctx, sh); 2384045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul } 2394045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul else { 2404045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul struct gl_shader_program *shProg = (struct gl_shader_program *) data; 2414045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul ASSERT(shProg->Type == GL_SHADER_PROGRAM_MESA); 242a37b2219d6e3f299379c6434d65f300660d12c3eBrian Paul ctx->Driver.DeleteShaderProgram(ctx, shProg); 2434045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul } 2444045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul} 2454045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul 2464045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul 2474045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul/** 2484045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul * Callback for deleting a framebuffer object. Called by _mesa_HashDeleteAll() 2494045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul */ 2504045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paulstatic void 2514045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Pauldelete_framebuffer_cb(GLuint id, void *data, void *userData) 2524045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul{ 2534045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul struct gl_framebuffer *fb = (struct gl_framebuffer *) data; 2544045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul /* The fact that the framebuffer is in the hashtable means its refcount 2554045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul * is one, but we're removing from the hashtable now. So clear refcount. 2564045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul */ 2574045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul /*assert(fb->RefCount == 1);*/ 2584045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul fb->RefCount = 0; 2594045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul 2604045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul /* NOTE: Delete should always be defined but there are two reports 2614045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul * of it being NULL (bugs 13507, 14293). Work-around for now. 2624045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul */ 2634045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul if (fb->Delete) 2644045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul fb->Delete(fb); 2654045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul} 2664045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul 2674045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul 2684045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul/** 2694045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul * Callback for deleting a renderbuffer object. Called by _mesa_HashDeleteAll() 2704045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul */ 2714045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paulstatic void 2724045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Pauldelete_renderbuffer_cb(GLuint id, void *data, void *userData) 2734045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul{ 2749d4ab9a663d4088ec553edaae0eeafb746d2490dBrian Paul struct gl_context *ctx = (struct gl_context *) userData; 2754045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul struct gl_renderbuffer *rb = (struct gl_renderbuffer *) data; 2764045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul rb->RefCount = 0; /* see comment for FBOs above */ 2774045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul if (rb->Delete) 2789d4ab9a663d4088ec553edaae0eeafb746d2490dBrian Paul rb->Delete(ctx, rb); 2794045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul} 2804045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul 2814045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul 2826bb4d807f7e80eaf899fd5c34c2c9ff0474eb80eBrian Paul#if FEATURE_ARB_sampler_objects 2836bb4d807f7e80eaf899fd5c34c2c9ff0474eb80eBrian Paul/** 2846bb4d807f7e80eaf899fd5c34c2c9ff0474eb80eBrian Paul * Callback for deleting a sampler object. Called by _mesa_HashDeleteAll() 2856bb4d807f7e80eaf899fd5c34c2c9ff0474eb80eBrian Paul */ 2866bb4d807f7e80eaf899fd5c34c2c9ff0474eb80eBrian Paulstatic void 2876bb4d807f7e80eaf899fd5c34c2c9ff0474eb80eBrian Pauldelete_sampler_object_cb(GLuint id, void *data, void *userData) 2886bb4d807f7e80eaf899fd5c34c2c9ff0474eb80eBrian Paul{ 2896bb4d807f7e80eaf899fd5c34c2c9ff0474eb80eBrian Paul struct gl_context *ctx = (struct gl_context *) userData; 2906bb4d807f7e80eaf899fd5c34c2c9ff0474eb80eBrian Paul struct gl_sampler_object *sampObj = (struct gl_sampler_object *) data; 2916bb4d807f7e80eaf899fd5c34c2c9ff0474eb80eBrian Paul _mesa_reference_sampler_object(ctx, &sampObj, NULL); 2926bb4d807f7e80eaf899fd5c34c2c9ff0474eb80eBrian Paul} 2936bb4d807f7e80eaf899fd5c34c2c9ff0474eb80eBrian Paul#endif 2946bb4d807f7e80eaf899fd5c34c2c9ff0474eb80eBrian Paul 2956bb4d807f7e80eaf899fd5c34c2c9ff0474eb80eBrian Paul 2964045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul/** 2974045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul * Deallocate a shared state object and all children structures. 2984045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul * 2994045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul * \param ctx GL context. 3001eee1bac1f6d911e6124daafc9b9291666d91cefVinson Lee * \param shared shared state pointer. 3014045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul * 3024045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul * Frees the display lists, the texture objects (calling the driver texture 3034045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul * deletion callback to free its private data) and the vertex programs, as well 3044045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul * as their hash tables. 3054045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul * 3064045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul * \sa alloc_shared_state(). 3074045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul */ 3081c39dbb90cefad8a5a97e75042466d66ea4270bcJosé Fonsecastatic void 309f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergfree_shared_state(struct gl_context *ctx, struct gl_shared_state *shared) 3104045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul{ 3114045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul GLuint i; 3124045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul 313c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul /* Free the dummy/fallback texture objects */ 314c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul for (i = 0; i < NUM_TEXTURE_TARGETS; i++) { 315c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul if (shared->FallbackTex[i]) 316c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul ctx->Driver.DeleteTexture(ctx, shared->FallbackTex[i]); 317c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul } 318c8e0970667d2b4d92abe22bf099cafee4acb717bBrian Paul 3194045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul /* 3204045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul * Free display lists 3214045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul */ 3224045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul _mesa_HashDeleteAll(shared->DisplayList, delete_displaylist_cb, ctx); 3234045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul _mesa_DeleteHashTable(shared->DisplayList); 3244045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul 3254045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul#if FEATURE_ARB_shader_objects 3264045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul _mesa_HashWalk(shared->ShaderObjects, free_shader_program_data_cb, ctx); 3274045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul _mesa_HashDeleteAll(shared->ShaderObjects, delete_shader_cb, ctx); 3284045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul _mesa_DeleteHashTable(shared->ShaderObjects); 3294045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul#endif 3304045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul 3314045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul _mesa_HashDeleteAll(shared->Programs, delete_program_cb, ctx); 3324045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul _mesa_DeleteHashTable(shared->Programs); 3334045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul 3344045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul#if FEATURE_ARB_vertex_program 3354045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul _mesa_reference_vertprog(ctx, &shared->DefaultVertexProgram, NULL); 3364045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul#endif 3374045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul 3384045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul#if FEATURE_ARB_fragment_program 3394045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul _mesa_reference_fragprog(ctx, &shared->DefaultFragmentProgram, NULL); 3404045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul#endif 3414045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul 3424045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul#if FEATURE_ATI_fragment_shader 3434045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul _mesa_HashDeleteAll(shared->ATIShaders, delete_fragshader_cb, ctx); 3444045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul _mesa_DeleteHashTable(shared->ATIShaders); 3454045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul _mesa_delete_ati_fragment_shader(ctx, shared->DefaultFragmentShader); 3464045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul#endif 3474045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul 3484045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul _mesa_HashDeleteAll(shared->BufferObjects, delete_bufferobj_cb, ctx); 3494045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul _mesa_DeleteHashTable(shared->BufferObjects); 3504045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul 3514045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul#if FEATURE_EXT_framebuffer_object 3524045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul _mesa_HashDeleteAll(shared->FrameBuffers, delete_framebuffer_cb, ctx); 3534045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul _mesa_DeleteHashTable(shared->FrameBuffers); 3544045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul _mesa_HashDeleteAll(shared->RenderBuffers, delete_renderbuffer_cb, ctx); 3554045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul _mesa_DeleteHashTable(shared->RenderBuffers); 3564045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul#endif 3574045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul 35805ac187f305bb653d569b5c07446ec0f4cd7ff08José Fonseca _mesa_reference_buffer_object(ctx, &shared->NullBufferObj, NULL); 3594f6b704f9796775d8d9937c3cf75a2901b99b896Brian Paul 36016b393d05990b6e917e144f9de87d0103b4c3e6dIan Romanick { 36116b393d05990b6e917e144f9de87d0103b4c3e6dIan Romanick struct simple_node *node; 36216b393d05990b6e917e144f9de87d0103b4c3e6dIan Romanick struct simple_node *temp; 36316b393d05990b6e917e144f9de87d0103b4c3e6dIan Romanick 36416b393d05990b6e917e144f9de87d0103b4c3e6dIan Romanick foreach_s(node, temp, & shared->SyncObjects) { 36516b393d05990b6e917e144f9de87d0103b4c3e6dIan Romanick _mesa_unref_sync_object(ctx, (struct gl_sync_object *) node); 36616b393d05990b6e917e144f9de87d0103b4c3e6dIan Romanick } 36716b393d05990b6e917e144f9de87d0103b4c3e6dIan Romanick } 36816b393d05990b6e917e144f9de87d0103b4c3e6dIan Romanick 3696bb4d807f7e80eaf899fd5c34c2c9ff0474eb80eBrian Paul#if FEATURE_ARB_sampler_objects 3706bb4d807f7e80eaf899fd5c34c2c9ff0474eb80eBrian Paul _mesa_HashDeleteAll(shared->SamplerObjects, delete_sampler_object_cb, ctx); 3716bb4d807f7e80eaf899fd5c34c2c9ff0474eb80eBrian Paul _mesa_DeleteHashTable(shared->SamplerObjects); 3726bb4d807f7e80eaf899fd5c34c2c9ff0474eb80eBrian Paul#endif 3736bb4d807f7e80eaf899fd5c34c2c9ff0474eb80eBrian Paul 3744045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul /* 3754045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul * Free texture objects (after FBOs since some textures might have 3764045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul * been bound to FBOs). 3774045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul */ 3784045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul ASSERT(ctx->Driver.DeleteTexture); 3794045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul /* the default textures */ 3804045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul for (i = 0; i < NUM_TEXTURE_TARGETS; i++) { 3814045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul ctx->Driver.DeleteTexture(ctx, shared->DefaultTex[i]); 3824045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul } 3834045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul 3844045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul /* all other textures */ 3854045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul _mesa_HashDeleteAll(shared->TexObjects, delete_texture_cb, ctx); 3864045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul _mesa_DeleteHashTable(shared->TexObjects); 3874045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul 3884045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul _glthread_DESTROY_MUTEX(shared->Mutex); 3894045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul _glthread_DESTROY_MUTEX(shared->TexMutex); 3904045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul 39132f2fd1c5d6088692551c80352b7d6fa35b0cd09Kristian Høgsberg free(shared); 3924045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul} 3931c39dbb90cefad8a5a97e75042466d66ea4270bcJosé Fonseca 3941c39dbb90cefad8a5a97e75042466d66ea4270bcJosé Fonseca 3951c39dbb90cefad8a5a97e75042466d66ea4270bcJosé Fonseca/** 396361cd53a77dd48fbf2a0321446c0b7c07365bff9Brian Paul * gl_shared_state objects are ref counted. 397361cd53a77dd48fbf2a0321446c0b7c07365bff9Brian Paul * If ptr's refcount goes to zero, free the shared state. 3981c39dbb90cefad8a5a97e75042466d66ea4270bcJosé Fonseca */ 3991c39dbb90cefad8a5a97e75042466d66ea4270bcJosé Fonsecavoid 400361cd53a77dd48fbf2a0321446c0b7c07365bff9Brian Paul_mesa_reference_shared_state(struct gl_context *ctx, 401361cd53a77dd48fbf2a0321446c0b7c07365bff9Brian Paul struct gl_shared_state **ptr, 402361cd53a77dd48fbf2a0321446c0b7c07365bff9Brian Paul struct gl_shared_state *state) 4031c39dbb90cefad8a5a97e75042466d66ea4270bcJosé Fonseca{ 404361cd53a77dd48fbf2a0321446c0b7c07365bff9Brian Paul if (*ptr == state) 405361cd53a77dd48fbf2a0321446c0b7c07365bff9Brian Paul return; 406361cd53a77dd48fbf2a0321446c0b7c07365bff9Brian Paul 407361cd53a77dd48fbf2a0321446c0b7c07365bff9Brian Paul if (*ptr) { 408361cd53a77dd48fbf2a0321446c0b7c07365bff9Brian Paul /* unref old state */ 409361cd53a77dd48fbf2a0321446c0b7c07365bff9Brian Paul struct gl_shared_state *old = *ptr; 410361cd53a77dd48fbf2a0321446c0b7c07365bff9Brian Paul GLboolean delete; 411361cd53a77dd48fbf2a0321446c0b7c07365bff9Brian Paul 412361cd53a77dd48fbf2a0321446c0b7c07365bff9Brian Paul _glthread_LOCK_MUTEX(old->Mutex); 413361cd53a77dd48fbf2a0321446c0b7c07365bff9Brian Paul assert(old->RefCount >= 1); 414361cd53a77dd48fbf2a0321446c0b7c07365bff9Brian Paul old->RefCount--; 415361cd53a77dd48fbf2a0321446c0b7c07365bff9Brian Paul delete = (old->RefCount == 0); 416361cd53a77dd48fbf2a0321446c0b7c07365bff9Brian Paul _glthread_UNLOCK_MUTEX(old->Mutex); 417361cd53a77dd48fbf2a0321446c0b7c07365bff9Brian Paul 418361cd53a77dd48fbf2a0321446c0b7c07365bff9Brian Paul if (delete) { 419361cd53a77dd48fbf2a0321446c0b7c07365bff9Brian Paul free_shared_state(ctx, old); 420361cd53a77dd48fbf2a0321446c0b7c07365bff9Brian Paul } 4211c39dbb90cefad8a5a97e75042466d66ea4270bcJosé Fonseca 422361cd53a77dd48fbf2a0321446c0b7c07365bff9Brian Paul *ptr = NULL; 423361cd53a77dd48fbf2a0321446c0b7c07365bff9Brian Paul } 4241c39dbb90cefad8a5a97e75042466d66ea4270bcJosé Fonseca 425361cd53a77dd48fbf2a0321446c0b7c07365bff9Brian Paul if (state) { 426361cd53a77dd48fbf2a0321446c0b7c07365bff9Brian Paul /* reference new state */ 427361cd53a77dd48fbf2a0321446c0b7c07365bff9Brian Paul _glthread_LOCK_MUTEX(state->Mutex); 428361cd53a77dd48fbf2a0321446c0b7c07365bff9Brian Paul state->RefCount++; 429361cd53a77dd48fbf2a0321446c0b7c07365bff9Brian Paul *ptr = state; 430361cd53a77dd48fbf2a0321446c0b7c07365bff9Brian Paul _glthread_UNLOCK_MUTEX(state->Mutex); 4311c39dbb90cefad8a5a97e75042466d66ea4270bcJosé Fonseca } 4321c39dbb90cefad8a5a97e75042466d66ea4270bcJosé Fonseca} 433