OSDN Git Service

Merge branch 'master' into r300-compiler
[android-x86/external-mesa.git] / src / mesa / main / shared.c
1 /*
2  * Mesa 3-D graphics library
3  * Version:  7.5
4  *
5  * Copyright (C) 2009  VMware, Inc.  All Rights Reserved.
6  *
7  * Permission is hereby granted, free of charge, to any person obtaining a
8  * copy of this software and associated documentation files (the "Software"),
9  * to deal in the Software without restriction, including without limitation
10  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11  * and/or sell copies of the Software, and to permit persons to whom the
12  * Software is furnished to do so, subject to the following conditions:
13  *
14  * The above copyright notice and this permission notice shall be included
15  * in all copies or substantial portions of the Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
20  * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21  * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23  */
24
25 /**
26  * \file shared.c
27  * Shared-context state
28  */
29
30
31
32 #include "imports.h"
33 #include "mtypes.h"
34 #include "hash.h"
35 #include "arrayobj.h"
36 #include "bufferobj.h"
37 #include "shared.h"
38 #include "shader/program.h"
39 #include "shader/shader_api.h"
40 #if FEATURE_dlist
41 #include "dlist.h"
42 #endif
43 #if FEATURE_ATI_fragment_shader
44 #include "shader/atifragshader.h"
45 #endif
46 #if FEATURE_ARB_sync
47 #include "syncobj.h"
48 #endif
49
50 /**
51  * Allocate and initialize a shared context state structure.
52  * Initializes the display list, texture objects and vertex programs hash
53  * tables, allocates the texture objects. If it runs out of memory, frees
54  * everything already allocated before returning NULL.
55  *
56  * \return pointer to a gl_shared_state structure on success, or NULL on
57  * failure.
58  */
59 struct gl_shared_state *
60 _mesa_alloc_shared_state(GLcontext *ctx)
61 {
62    struct gl_shared_state *shared;
63    GLuint i;
64
65    shared = CALLOC_STRUCT(gl_shared_state);
66    if (!shared)
67       return NULL;
68
69    _glthread_INIT_MUTEX(shared->Mutex);
70
71    shared->DisplayList = _mesa_NewHashTable();
72    shared->TexObjects = _mesa_NewHashTable();
73    shared->Programs = _mesa_NewHashTable();
74
75 #if FEATURE_ARB_vertex_program
76    shared->DefaultVertexProgram = (struct gl_vertex_program *)
77       ctx->Driver.NewProgram(ctx, GL_VERTEX_PROGRAM_ARB, 0);
78 #endif
79
80 #if FEATURE_ARB_fragment_program
81    shared->DefaultFragmentProgram = (struct gl_fragment_program *)
82       ctx->Driver.NewProgram(ctx, GL_FRAGMENT_PROGRAM_ARB, 0);
83 #endif
84
85 #if FEATURE_ATI_fragment_shader
86    shared->ATIShaders = _mesa_NewHashTable();
87    shared->DefaultFragmentShader = _mesa_new_ati_fragment_shader(ctx, 0);
88 #endif
89
90 #if FEATURE_ARB_shader_objects
91    shared->ShaderObjects = _mesa_NewHashTable();
92 #endif
93
94 #if FEATURE_ARB_vertex_buffer_object || FEATURE_ARB_pixel_buffer_object
95    shared->BufferObjects = _mesa_NewHashTable();
96 #endif
97
98    /* Allocate the default buffer object and set refcount so high that
99     * it never gets deleted.
100     * XXX with recent/improved refcounting this may not longer be needed.
101     */
102    shared->NullBufferObj = ctx->Driver.NewBufferObject(ctx, 0, 0);
103    shared->NullBufferObj->RefCount = 1000 * 1000 * 1000;
104
105    /* Create default texture objects */
106    for (i = 0; i < NUM_TEXTURE_TARGETS; i++) {
107       /* NOTE: the order of these enums matches the TEXTURE_x_INDEX values */
108       static const GLenum targets[NUM_TEXTURE_TARGETS] = {
109          GL_TEXTURE_2D_ARRAY_EXT,
110          GL_TEXTURE_1D_ARRAY_EXT,
111          GL_TEXTURE_CUBE_MAP,
112          GL_TEXTURE_3D,
113          GL_TEXTURE_RECTANGLE_NV,
114          GL_TEXTURE_2D,
115          GL_TEXTURE_1D
116       };
117       shared->DefaultTex[i] = ctx->Driver.NewTextureObject(ctx, 0, targets[i]);
118    }
119
120    /* sanity check */
121    assert(shared->DefaultTex[TEXTURE_1D_INDEX]->RefCount == 1);
122
123    /* Mutex and timestamp for texobj state validation */
124    _glthread_INIT_MUTEX(shared->TexMutex);
125    shared->TextureStateStamp = 0;
126
127 #if FEATURE_EXT_framebuffer_object
128    shared->FrameBuffers = _mesa_NewHashTable();
129    shared->RenderBuffers = _mesa_NewHashTable();
130 #endif
131
132 #if FEATURE_ARB_sync
133    make_empty_list(& shared->SyncObjects);
134 #endif
135
136    return shared;
137 }
138
139
140 /**
141  * Callback for deleting a display list.  Called by _mesa_HashDeleteAll().
142  */
143 static void
144 delete_displaylist_cb(GLuint id, void *data, void *userData)
145 {
146 #if FEATURE_dlist
147    struct gl_display_list *list = (struct gl_display_list *) data;
148    GLcontext *ctx = (GLcontext *) userData;
149    _mesa_delete_list(ctx, list);
150 #endif
151 }
152
153
154 /**
155  * Callback for deleting a texture object.  Called by _mesa_HashDeleteAll().
156  */
157 static void
158 delete_texture_cb(GLuint id, void *data, void *userData)
159 {
160    struct gl_texture_object *texObj = (struct gl_texture_object *) data;
161    GLcontext *ctx = (GLcontext *) userData;
162    ctx->Driver.DeleteTexture(ctx, texObj);
163 }
164
165
166 /**
167  * Callback for deleting a program object.  Called by _mesa_HashDeleteAll().
168  */
169 static void
170 delete_program_cb(GLuint id, void *data, void *userData)
171 {
172    struct gl_program *prog = (struct gl_program *) data;
173    GLcontext *ctx = (GLcontext *) userData;
174    if(prog != &_mesa_DummyProgram) {
175       ASSERT(prog->RefCount == 1); /* should only be referenced by hash table */
176       prog->RefCount = 0;  /* now going away */
177       ctx->Driver.DeleteProgram(ctx, prog);
178    }
179 }
180
181
182 #if FEATURE_ATI_fragment_shader
183 /**
184  * Callback for deleting an ATI fragment shader object.
185  * Called by _mesa_HashDeleteAll().
186  */
187 static void
188 delete_fragshader_cb(GLuint id, void *data, void *userData)
189 {
190    struct ati_fragment_shader *shader = (struct ati_fragment_shader *) data;
191    GLcontext *ctx = (GLcontext *) userData;
192    _mesa_delete_ati_fragment_shader(ctx, shader);
193 }
194 #endif
195
196
197 /**
198  * Callback for deleting a buffer object.  Called by _mesa_HashDeleteAll().
199  */
200 static void
201 delete_bufferobj_cb(GLuint id, void *data, void *userData)
202 {
203    struct gl_buffer_object *bufObj = (struct gl_buffer_object *) data;
204    GLcontext *ctx = (GLcontext *) userData;
205    if (_mesa_bufferobj_mapped(bufObj)) {
206       ctx->Driver.UnmapBuffer(ctx, 0, bufObj);
207       bufObj->Pointer = NULL;
208    }
209    ctx->Driver.DeleteBuffer(ctx, bufObj);
210 }
211
212
213 /**
214  * Callback for freeing shader program data. Call it before delete_shader_cb
215  * to avoid memory access error.
216  */
217 static void
218 free_shader_program_data_cb(GLuint id, void *data, void *userData)
219 {
220    GLcontext *ctx = (GLcontext *) userData;
221    struct gl_shader_program *shProg = (struct gl_shader_program *) data;
222
223    if (shProg->Type == GL_SHADER_PROGRAM_MESA) {
224        _mesa_free_shader_program_data(ctx, shProg);
225    }
226 }
227
228
229 /**
230  * Callback for deleting shader and shader programs objects.
231  * Called by _mesa_HashDeleteAll().
232  */
233 static void
234 delete_shader_cb(GLuint id, void *data, void *userData)
235 {
236    GLcontext *ctx = (GLcontext *) userData;
237    struct gl_shader *sh = (struct gl_shader *) data;
238    if (sh->Type == GL_FRAGMENT_SHADER || sh->Type == GL_VERTEX_SHADER) {
239       _mesa_free_shader(ctx, sh);
240    }
241    else {
242       struct gl_shader_program *shProg = (struct gl_shader_program *) data;
243       ASSERT(shProg->Type == GL_SHADER_PROGRAM_MESA);
244       _mesa_free_shader_program(ctx, shProg);
245    }
246 }
247
248
249 /**
250  * Callback for deleting a framebuffer object.  Called by _mesa_HashDeleteAll()
251  */
252 static void
253 delete_framebuffer_cb(GLuint id, void *data, void *userData)
254 {
255    struct gl_framebuffer *fb = (struct gl_framebuffer *) data;
256    /* The fact that the framebuffer is in the hashtable means its refcount
257     * is one, but we're removing from the hashtable now.  So clear refcount.
258     */
259    /*assert(fb->RefCount == 1);*/
260    fb->RefCount = 0;
261
262    /* NOTE: Delete should always be defined but there are two reports
263     * of it being NULL (bugs 13507, 14293).  Work-around for now.
264     */
265    if (fb->Delete)
266       fb->Delete(fb);
267 }
268
269
270 /**
271  * Callback for deleting a renderbuffer object. Called by _mesa_HashDeleteAll()
272  */
273 static void
274 delete_renderbuffer_cb(GLuint id, void *data, void *userData)
275 {
276    struct gl_renderbuffer *rb = (struct gl_renderbuffer *) data;
277    rb->RefCount = 0;  /* see comment for FBOs above */
278    if (rb->Delete)
279       rb->Delete(rb);
280 }
281
282
283 /**
284  * Deallocate a shared state object and all children structures.
285  *
286  * \param ctx GL context.
287  * \param shared shared state pointer.
288  * 
289  * Frees the display lists, the texture objects (calling the driver texture
290  * deletion callback to free its private data) and the vertex programs, as well
291  * as their hash tables.
292  *
293  * \sa alloc_shared_state().
294  */
295 void
296 _mesa_free_shared_state(GLcontext *ctx, struct gl_shared_state *shared)
297 {
298    GLuint i;
299
300    /*
301     * Free display lists
302     */
303    _mesa_HashDeleteAll(shared->DisplayList, delete_displaylist_cb, ctx);
304    _mesa_DeleteHashTable(shared->DisplayList);
305
306 #if FEATURE_ARB_shader_objects
307    _mesa_HashWalk(shared->ShaderObjects, free_shader_program_data_cb, ctx);
308    _mesa_HashDeleteAll(shared->ShaderObjects, delete_shader_cb, ctx);
309    _mesa_DeleteHashTable(shared->ShaderObjects);
310 #endif
311
312    _mesa_HashDeleteAll(shared->Programs, delete_program_cb, ctx);
313    _mesa_DeleteHashTable(shared->Programs);
314
315 #if FEATURE_ARB_vertex_program
316    _mesa_reference_vertprog(ctx, &shared->DefaultVertexProgram, NULL);
317 #endif
318
319 #if FEATURE_ARB_fragment_program
320    _mesa_reference_fragprog(ctx, &shared->DefaultFragmentProgram, NULL);
321 #endif
322
323 #if FEATURE_ATI_fragment_shader
324    _mesa_HashDeleteAll(shared->ATIShaders, delete_fragshader_cb, ctx);
325    _mesa_DeleteHashTable(shared->ATIShaders);
326    _mesa_delete_ati_fragment_shader(ctx, shared->DefaultFragmentShader);
327 #endif
328
329 #if FEATURE_ARB_vertex_buffer_object || FEATURE_ARB_pixel_buffer_object
330    _mesa_HashDeleteAll(shared->BufferObjects, delete_bufferobj_cb, ctx);
331    _mesa_DeleteHashTable(shared->BufferObjects);
332 #endif
333
334 #if FEATURE_EXT_framebuffer_object
335    _mesa_HashDeleteAll(shared->FrameBuffers, delete_framebuffer_cb, ctx);
336    _mesa_DeleteHashTable(shared->FrameBuffers);
337    _mesa_HashDeleteAll(shared->RenderBuffers, delete_renderbuffer_cb, ctx);
338    _mesa_DeleteHashTable(shared->RenderBuffers);
339 #endif
340
341 #if FEATURE_ARB_vertex_buffer_object
342    ctx->Driver.DeleteBuffer(ctx, shared->NullBufferObj);
343 #endif
344
345 #if FEATURE_ARB_sync
346    {
347       struct simple_node *node;
348       struct simple_node *temp;
349
350       foreach_s(node, temp, & shared->SyncObjects) {
351          _mesa_unref_sync_object(ctx, (struct gl_sync_object *) node);
352       }
353    }
354 #endif
355
356    /*
357     * Free texture objects (after FBOs since some textures might have
358     * been bound to FBOs).
359     */
360    ASSERT(ctx->Driver.DeleteTexture);
361    /* the default textures */
362    for (i = 0; i < NUM_TEXTURE_TARGETS; i++) {
363       ctx->Driver.DeleteTexture(ctx, shared->DefaultTex[i]);
364    }
365
366    /* all other textures */
367    _mesa_HashDeleteAll(shared->TexObjects, delete_texture_cb, ctx);
368    _mesa_DeleteHashTable(shared->TexObjects);
369
370    _glthread_DESTROY_MUTEX(shared->Mutex);
371    _glthread_DESTROY_MUTEX(shared->TexMutex);
372
373    _mesa_free(shared);
374 }