shared.c revision 4045a2c7d302352646c1ff2a01cd531aa1b55d31
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
314045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul
324045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul#include "imports.h"
334045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul#include "mtypes.h"
344045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul#include "hash.h"
354045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul#include "arrayobj.h"
364045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul#include "shared.h"
374045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul#include "shader/program.h"
384045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul#include "shader/shader_api.h"
394045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul#if FEATURE_dlist
404045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul#include "dlist.h"
414045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul#endif
424045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul#if FEATURE_ATI_fragment_shader
434045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul#include "shader/atifragshader.h"
444045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul#endif
454045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul
464045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul
474045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul/**
484045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul * Allocate and initialize a shared context state structure.
494045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul * Initializes the display list, texture objects and vertex programs hash
504045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul * tables, allocates the texture objects. If it runs out of memory, frees
514045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul * everything already allocated before returning NULL.
524045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul *
534045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul * \return pointer to a gl_shared_state structure on success, or NULL on
544045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul * failure.
554045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul */
564045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paulstruct gl_shared_state *
574045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul_mesa_alloc_shared_state(GLcontext *ctx)
584045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul{
594045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul   struct gl_shared_state *shared;
604045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul   GLuint i;
614045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul
624045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul   shared = CALLOC_STRUCT(gl_shared_state);
634045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul   if (!shared)
644045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul      return NULL;
654045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul
664045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul   _glthread_INIT_MUTEX(shared->Mutex);
674045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul
684045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul   shared->DisplayList = _mesa_NewHashTable();
694045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul   shared->TexObjects = _mesa_NewHashTable();
704045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul   shared->Programs = _mesa_NewHashTable();
714045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul
724045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul#if FEATURE_ARB_vertex_program
734045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul   shared->DefaultVertexProgram = (struct gl_vertex_program *)
744045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul      ctx->Driver.NewProgram(ctx, GL_VERTEX_PROGRAM_ARB, 0);
754045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul#endif
764045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul
774045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul#if FEATURE_ARB_fragment_program
784045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul   shared->DefaultFragmentProgram = (struct gl_fragment_program *)
794045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul      ctx->Driver.NewProgram(ctx, GL_FRAGMENT_PROGRAM_ARB, 0);
804045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul#endif
814045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul
824045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul#if FEATURE_ATI_fragment_shader
834045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul   shared->ATIShaders = _mesa_NewHashTable();
844045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul   shared->DefaultFragmentShader = _mesa_new_ati_fragment_shader(ctx, 0);
854045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul#endif
864045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul
874045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul#if FEATURE_ARB_shader_objects
884045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul   shared->ShaderObjects = _mesa_NewHashTable();
894045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul#endif
904045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul
914045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul#if FEATURE_ARB_vertex_buffer_object || FEATURE_ARB_pixel_buffer_object
924045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul   shared->BufferObjects = _mesa_NewHashTable();
934045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul#endif
944045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul
954045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul   shared->ArrayObjects = _mesa_NewHashTable();
964045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul
974045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul   /* Create default texture objects */
984045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul   for (i = 0; i < NUM_TEXTURE_TARGETS; i++) {
994045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul      /* NOTE: the order of these enums matches the TEXTURE_x_INDEX values */
1004045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul      static const GLenum targets[NUM_TEXTURE_TARGETS] = {
1014045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul         GL_TEXTURE_2D_ARRAY_EXT,
1024045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul         GL_TEXTURE_1D_ARRAY_EXT,
1034045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul         GL_TEXTURE_CUBE_MAP,
1044045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul         GL_TEXTURE_3D,
1054045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul         GL_TEXTURE_RECTANGLE_NV,
1064045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul         GL_TEXTURE_2D,
1074045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul         GL_TEXTURE_1D
1084045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul      };
1094045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul      shared->DefaultTex[i] = ctx->Driver.NewTextureObject(ctx, 0, targets[i]);
1104045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul   }
1114045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul
1124045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul   /* sanity check */
1134045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul   assert(shared->DefaultTex[TEXTURE_1D_INDEX]->RefCount == 1);
1144045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul
1154045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul   /* Mutex and timestamp for texobj state validation */
1164045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul   _glthread_INIT_MUTEX(shared->TexMutex);
1174045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul   shared->TextureStateStamp = 0;
1184045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul
1194045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul#if FEATURE_EXT_framebuffer_object
1204045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul   shared->FrameBuffers = _mesa_NewHashTable();
1214045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul   shared->RenderBuffers = _mesa_NewHashTable();
1224045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul#endif
1234045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul
1244045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul   return shared;
1254045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul}
1264045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul
1274045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul
1284045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul/**
1294045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul * Callback for deleting a display list.  Called by _mesa_HashDeleteAll().
1304045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul */
1314045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paulstatic void
1324045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Pauldelete_displaylist_cb(GLuint id, void *data, void *userData)
1334045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul{
1344045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul#if FEATURE_dlist
1354045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul   struct gl_display_list *list = (struct gl_display_list *) data;
1364045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul   GLcontext *ctx = (GLcontext *) userData;
1374045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul   _mesa_delete_list(ctx, list);
1384045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul#endif
1394045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul}
1404045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul
1414045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul
1424045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul/**
1434045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul * Callback for deleting a texture object.  Called by _mesa_HashDeleteAll().
1444045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul */
1454045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paulstatic void
1464045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Pauldelete_texture_cb(GLuint id, void *data, void *userData)
1474045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul{
1484045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul   struct gl_texture_object *texObj = (struct gl_texture_object *) data;
1494045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul   GLcontext *ctx = (GLcontext *) userData;
1504045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul   ctx->Driver.DeleteTexture(ctx, texObj);
1514045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul}
1524045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul
1534045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul
1544045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul/**
1554045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul * Callback for deleting a program object.  Called by _mesa_HashDeleteAll().
1564045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul */
1574045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paulstatic void
1584045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Pauldelete_program_cb(GLuint id, void *data, void *userData)
1594045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul{
1604045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul   struct gl_program *prog = (struct gl_program *) data;
1614045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul   GLcontext *ctx = (GLcontext *) userData;
1624045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul   ASSERT(prog->RefCount == 1); /* should only be referenced by hash table */
1634045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul   prog->RefCount = 0;  /* now going away */
1644045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul   ctx->Driver.DeleteProgram(ctx, prog);
1654045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul}
1664045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul
1674045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul
1684045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul#if FEATURE_ATI_fragment_shader
1694045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul/**
1704045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul * Callback for deleting an ATI fragment shader object.
1714045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul * Called by _mesa_HashDeleteAll().
1724045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul */
1734045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paulstatic void
1744045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Pauldelete_fragshader_cb(GLuint id, void *data, void *userData)
1754045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul{
1764045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul   struct ati_fragment_shader *shader = (struct ati_fragment_shader *) data;
1774045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul   GLcontext *ctx = (GLcontext *) userData;
1784045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul   _mesa_delete_ati_fragment_shader(ctx, shader);
1794045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul}
1804045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul#endif
1814045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul
1824045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul
1834045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul/**
1844045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul * Callback for deleting a buffer object.  Called by _mesa_HashDeleteAll().
1854045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul */
1864045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paulstatic void
1874045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Pauldelete_bufferobj_cb(GLuint id, void *data, void *userData)
1884045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul{
1894045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul   struct gl_buffer_object *bufObj = (struct gl_buffer_object *) data;
1904045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul   GLcontext *ctx = (GLcontext *) userData;
1914045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul   ctx->Driver.DeleteBuffer(ctx, bufObj);
1924045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul}
1934045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul
1944045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul
1954045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul/**
1964045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul * Callback for deleting an array object.  Called by _mesa_HashDeleteAll().
1974045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul */
1984045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paulstatic void
1994045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Pauldelete_arrayobj_cb(GLuint id, void *data, void *userData)
2004045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul{
2014045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul   struct gl_array_object *arrayObj = (struct gl_array_object *) data;
2024045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul   GLcontext *ctx = (GLcontext *) userData;
2034045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul   _mesa_delete_array_object(ctx, arrayObj);
2044045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul}
2054045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul
2064045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul
2074045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul/**
2084045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul * Callback for freeing shader program data. Call it before delete_shader_cb
2094045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul * to avoid memory access error.
2104045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul */
2114045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paulstatic void
2124045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paulfree_shader_program_data_cb(GLuint id, void *data, void *userData)
2134045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul{
2144045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul   GLcontext *ctx = (GLcontext *) userData;
2154045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul   struct gl_shader_program *shProg = (struct gl_shader_program *) data;
2164045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul
2174045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul   if (shProg->Type == GL_SHADER_PROGRAM_MESA) {
2184045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul       _mesa_free_shader_program_data(ctx, shProg);
2194045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul   }
2204045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul}
2214045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul
2224045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul
2234045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul/**
2244045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul * Callback for deleting shader and shader programs objects.
2254045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul * Called by _mesa_HashDeleteAll().
2264045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul */
2274045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paulstatic void
2284045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Pauldelete_shader_cb(GLuint id, void *data, void *userData)
2294045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul{
2304045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul   GLcontext *ctx = (GLcontext *) userData;
2314045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul   struct gl_shader *sh = (struct gl_shader *) data;
2324045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul   if (sh->Type == GL_FRAGMENT_SHADER || sh->Type == GL_VERTEX_SHADER) {
2334045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul      _mesa_free_shader(ctx, sh);
2344045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul   }
2354045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul   else {
2364045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul      struct gl_shader_program *shProg = (struct gl_shader_program *) data;
2374045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul      ASSERT(shProg->Type == GL_SHADER_PROGRAM_MESA);
2384045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul      _mesa_free_shader_program(ctx, shProg);
2394045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul   }
2404045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul}
2414045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul
2424045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul
2434045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul/**
2444045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul * Callback for deleting a framebuffer object.  Called by _mesa_HashDeleteAll()
2454045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul */
2464045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paulstatic void
2474045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Pauldelete_framebuffer_cb(GLuint id, void *data, void *userData)
2484045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul{
2494045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul   struct gl_framebuffer *fb = (struct gl_framebuffer *) data;
2504045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul   /* The fact that the framebuffer is in the hashtable means its refcount
2514045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul    * is one, but we're removing from the hashtable now.  So clear refcount.
2524045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul    */
2534045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul   /*assert(fb->RefCount == 1);*/
2544045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul   fb->RefCount = 0;
2554045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul
2564045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul   /* NOTE: Delete should always be defined but there are two reports
2574045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul    * of it being NULL (bugs 13507, 14293).  Work-around for now.
2584045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul    */
2594045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul   if (fb->Delete)
2604045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul      fb->Delete(fb);
2614045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul}
2624045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul
2634045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul
2644045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul/**
2654045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul * Callback for deleting a renderbuffer object. Called by _mesa_HashDeleteAll()
2664045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul */
2674045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paulstatic void
2684045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Pauldelete_renderbuffer_cb(GLuint id, void *data, void *userData)
2694045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul{
2704045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul   struct gl_renderbuffer *rb = (struct gl_renderbuffer *) data;
2714045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul   rb->RefCount = 0;  /* see comment for FBOs above */
2724045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul   if (rb->Delete)
2734045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul      rb->Delete(rb);
2744045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul}
2754045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul
2764045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul
2774045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul/**
2784045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul * Deallocate a shared state object and all children structures.
2794045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul *
2804045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul * \param ctx GL context.
2814045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul * \param ss shared state pointer.
2824045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul *
2834045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul * Frees the display lists, the texture objects (calling the driver texture
2844045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul * deletion callback to free its private data) and the vertex programs, as well
2854045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul * as their hash tables.
2864045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul *
2874045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul * \sa alloc_shared_state().
2884045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul */
2894045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paulvoid
2904045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul_mesa_free_shared_state(GLcontext *ctx, struct gl_shared_state *shared)
2914045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul{
2924045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul   GLuint i;
2934045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul
2944045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul   /*
2954045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul    * Free display lists
2964045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul    */
2974045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul   _mesa_HashDeleteAll(shared->DisplayList, delete_displaylist_cb, ctx);
2984045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul   _mesa_DeleteHashTable(shared->DisplayList);
2994045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul
3004045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul#if FEATURE_ARB_shader_objects
3014045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul   _mesa_HashWalk(shared->ShaderObjects, free_shader_program_data_cb, ctx);
3024045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul   _mesa_HashDeleteAll(shared->ShaderObjects, delete_shader_cb, ctx);
3034045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul   _mesa_DeleteHashTable(shared->ShaderObjects);
3044045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul#endif
3054045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul
3064045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul   _mesa_HashDeleteAll(shared->Programs, delete_program_cb, ctx);
3074045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul   _mesa_DeleteHashTable(shared->Programs);
3084045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul
3094045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul   _mesa_HashDeleteAll(shared->ArrayObjects, delete_arrayobj_cb, ctx);
3104045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul   _mesa_DeleteHashTable(shared->ArrayObjects);
3114045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul
3124045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul#if FEATURE_ARB_vertex_program
3134045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul   _mesa_reference_vertprog(ctx, &shared->DefaultVertexProgram, NULL);
3144045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul#endif
3154045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul
3164045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul#if FEATURE_ARB_fragment_program
3174045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul   _mesa_reference_fragprog(ctx, &shared->DefaultFragmentProgram, NULL);
3184045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul#endif
3194045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul
3204045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul#if FEATURE_ATI_fragment_shader
3214045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul   _mesa_HashDeleteAll(shared->ATIShaders, delete_fragshader_cb, ctx);
3224045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul   _mesa_DeleteHashTable(shared->ATIShaders);
3234045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul   _mesa_delete_ati_fragment_shader(ctx, shared->DefaultFragmentShader);
3244045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul#endif
3254045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul
3264045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul#if FEATURE_ARB_vertex_buffer_object || FEATURE_ARB_pixel_buffer_object
3274045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul   _mesa_HashDeleteAll(shared->BufferObjects, delete_bufferobj_cb, ctx);
3284045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul   _mesa_DeleteHashTable(shared->BufferObjects);
3294045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul#endif
3304045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul
3314045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul#if FEATURE_EXT_framebuffer_object
3324045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul   _mesa_HashDeleteAll(shared->FrameBuffers, delete_framebuffer_cb, ctx);
3334045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul   _mesa_DeleteHashTable(shared->FrameBuffers);
3344045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul   _mesa_HashDeleteAll(shared->RenderBuffers, delete_renderbuffer_cb, ctx);
3354045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul   _mesa_DeleteHashTable(shared->RenderBuffers);
3364045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul#endif
3374045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul
3384045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul   /*
3394045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul    * Free texture objects (after FBOs since some textures might have
3404045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul    * been bound to FBOs).
3414045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul    */
3424045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul   ASSERT(ctx->Driver.DeleteTexture);
3434045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul   /* the default textures */
3444045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul   for (i = 0; i < NUM_TEXTURE_TARGETS; i++) {
3454045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul      ctx->Driver.DeleteTexture(ctx, shared->DefaultTex[i]);
3464045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul   }
3474045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul
3484045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul   /* all other textures */
3494045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul   _mesa_HashDeleteAll(shared->TexObjects, delete_texture_cb, ctx);
3504045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul   _mesa_DeleteHashTable(shared->TexObjects);
3514045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul
3524045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul   _glthread_DESTROY_MUTEX(shared->Mutex);
3534045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul   _glthread_DESTROY_MUTEX(shared->TexMutex);
3544045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul
3554045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul   _mesa_free(shared);
3564045a2c7d302352646c1ff2a01cd531aa1b55d31Brian Paul}
357