1*61046927SAndroid Build Coastguard Worker /*
2*61046927SAndroid Build Coastguard Worker * Mesa 3-D graphics library
3*61046927SAndroid Build Coastguard Worker *
4*61046927SAndroid Build Coastguard Worker * Copyright (C) 2009 VMware, Inc. All Rights Reserved.
5*61046927SAndroid Build Coastguard Worker *
6*61046927SAndroid Build Coastguard Worker * Permission is hereby granted, free of charge, to any person obtaining a
7*61046927SAndroid Build Coastguard Worker * copy of this software and associated documentation files (the "Software"),
8*61046927SAndroid Build Coastguard Worker * to deal in the Software without restriction, including without limitation
9*61046927SAndroid Build Coastguard Worker * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10*61046927SAndroid Build Coastguard Worker * and/or sell copies of the Software, and to permit persons to whom the
11*61046927SAndroid Build Coastguard Worker * Software is furnished to do so, subject to the following conditions:
12*61046927SAndroid Build Coastguard Worker *
13*61046927SAndroid Build Coastguard Worker * The above copyright notice and this permission notice shall be included
14*61046927SAndroid Build Coastguard Worker * in all copies or substantial portions of the Software.
15*61046927SAndroid Build Coastguard Worker *
16*61046927SAndroid Build Coastguard Worker * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17*61046927SAndroid Build Coastguard Worker * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18*61046927SAndroid Build Coastguard Worker * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19*61046927SAndroid Build Coastguard Worker * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20*61046927SAndroid Build Coastguard Worker * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21*61046927SAndroid Build Coastguard Worker * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22*61046927SAndroid Build Coastguard Worker * OTHER DEALINGS IN THE SOFTWARE.
23*61046927SAndroid Build Coastguard Worker */
24*61046927SAndroid Build Coastguard Worker
25*61046927SAndroid Build Coastguard Worker /**
26*61046927SAndroid Build Coastguard Worker * \file shared.c
27*61046927SAndroid Build Coastguard Worker * Shared-context state
28*61046927SAndroid Build Coastguard Worker */
29*61046927SAndroid Build Coastguard Worker
30*61046927SAndroid Build Coastguard Worker
31*61046927SAndroid Build Coastguard Worker #include "mtypes.h"
32*61046927SAndroid Build Coastguard Worker #include "hash.h"
33*61046927SAndroid Build Coastguard Worker #include "atifragshader.h"
34*61046927SAndroid Build Coastguard Worker #include "bufferobj.h"
35*61046927SAndroid Build Coastguard Worker #include "shared.h"
36*61046927SAndroid Build Coastguard Worker #include "program/program.h"
37*61046927SAndroid Build Coastguard Worker #include "dlist.h"
38*61046927SAndroid Build Coastguard Worker #include "externalobjects.h"
39*61046927SAndroid Build Coastguard Worker #include "samplerobj.h"
40*61046927SAndroid Build Coastguard Worker #include "shaderapi.h"
41*61046927SAndroid Build Coastguard Worker #include "shaderobj.h"
42*61046927SAndroid Build Coastguard Worker #include "syncobj.h"
43*61046927SAndroid Build Coastguard Worker #include "texobj.h"
44*61046927SAndroid Build Coastguard Worker #include "texturebindless.h"
45*61046927SAndroid Build Coastguard Worker
46*61046927SAndroid Build Coastguard Worker #include "util/hash_table.h"
47*61046927SAndroid Build Coastguard Worker #include "util/set.h"
48*61046927SAndroid Build Coastguard Worker #include "util/u_memory.h"
49*61046927SAndroid Build Coastguard Worker
50*61046927SAndroid Build Coastguard Worker static void
51*61046927SAndroid Build Coastguard Worker free_shared_state(struct gl_context *ctx, struct gl_shared_state *shared);
52*61046927SAndroid Build Coastguard Worker
53*61046927SAndroid Build Coastguard Worker /**
54*61046927SAndroid Build Coastguard Worker * Allocate and initialize a shared context state structure.
55*61046927SAndroid Build Coastguard Worker * Initializes the display list, texture objects and vertex programs hash
56*61046927SAndroid Build Coastguard Worker * tables, allocates the texture objects. If it runs out of memory, frees
57*61046927SAndroid Build Coastguard Worker * everything already allocated before returning NULL.
58*61046927SAndroid Build Coastguard Worker *
59*61046927SAndroid Build Coastguard Worker * \return pointer to a gl_shared_state structure on success, or NULL on
60*61046927SAndroid Build Coastguard Worker * failure.
61*61046927SAndroid Build Coastguard Worker */
62*61046927SAndroid Build Coastguard Worker struct gl_shared_state *
_mesa_alloc_shared_state(struct gl_context * ctx)63*61046927SAndroid Build Coastguard Worker _mesa_alloc_shared_state(struct gl_context *ctx)
64*61046927SAndroid Build Coastguard Worker {
65*61046927SAndroid Build Coastguard Worker struct gl_shared_state *shared;
66*61046927SAndroid Build Coastguard Worker GLuint i;
67*61046927SAndroid Build Coastguard Worker
68*61046927SAndroid Build Coastguard Worker shared = CALLOC_STRUCT(gl_shared_state);
69*61046927SAndroid Build Coastguard Worker if (!shared)
70*61046927SAndroid Build Coastguard Worker return NULL;
71*61046927SAndroid Build Coastguard Worker
72*61046927SAndroid Build Coastguard Worker simple_mtx_init(&shared->Mutex, mtx_plain);
73*61046927SAndroid Build Coastguard Worker
74*61046927SAndroid Build Coastguard Worker _mesa_InitHashTable(&shared->DisplayList);
75*61046927SAndroid Build Coastguard Worker _mesa_InitHashTable(&shared->TexObjects);
76*61046927SAndroid Build Coastguard Worker _mesa_InitHashTable(&shared->Programs);
77*61046927SAndroid Build Coastguard Worker
78*61046927SAndroid Build Coastguard Worker shared->DefaultVertexProgram =
79*61046927SAndroid Build Coastguard Worker ctx->Driver.NewProgram(ctx, MESA_SHADER_VERTEX, 0, true);
80*61046927SAndroid Build Coastguard Worker shared->DefaultFragmentProgram =
81*61046927SAndroid Build Coastguard Worker ctx->Driver.NewProgram(ctx, MESA_SHADER_FRAGMENT, 0, true);
82*61046927SAndroid Build Coastguard Worker
83*61046927SAndroid Build Coastguard Worker _mesa_InitHashTable(&shared->ATIShaders);
84*61046927SAndroid Build Coastguard Worker shared->DefaultFragmentShader = _mesa_new_ati_fragment_shader(ctx, 0);
85*61046927SAndroid Build Coastguard Worker
86*61046927SAndroid Build Coastguard Worker _mesa_InitHashTable(&shared->ShaderObjects);
87*61046927SAndroid Build Coastguard Worker
88*61046927SAndroid Build Coastguard Worker _mesa_InitHashTable(&shared->BufferObjects);
89*61046927SAndroid Build Coastguard Worker shared->ZombieBufferObjects = _mesa_set_create(NULL, _mesa_hash_pointer,
90*61046927SAndroid Build Coastguard Worker _mesa_key_pointer_equal);
91*61046927SAndroid Build Coastguard Worker
92*61046927SAndroid Build Coastguard Worker /* GL_ARB_sampler_objects */
93*61046927SAndroid Build Coastguard Worker _mesa_InitHashTable(&shared->SamplerObjects);
94*61046927SAndroid Build Coastguard Worker
95*61046927SAndroid Build Coastguard Worker /* GL_ARB_bindless_texture */
96*61046927SAndroid Build Coastguard Worker _mesa_init_shared_handles(shared);
97*61046927SAndroid Build Coastguard Worker
98*61046927SAndroid Build Coastguard Worker /* ARB_shading_language_include */
99*61046927SAndroid Build Coastguard Worker _mesa_init_shader_includes(shared);
100*61046927SAndroid Build Coastguard Worker simple_mtx_init(&shared->ShaderIncludeMutex, mtx_plain);
101*61046927SAndroid Build Coastguard Worker
102*61046927SAndroid Build Coastguard Worker /* Create default texture objects */
103*61046927SAndroid Build Coastguard Worker for (i = 0; i < NUM_TEXTURE_TARGETS; i++) {
104*61046927SAndroid Build Coastguard Worker /* NOTE: the order of these enums matches the TEXTURE_x_INDEX values */
105*61046927SAndroid Build Coastguard Worker static const GLenum targets[] = {
106*61046927SAndroid Build Coastguard Worker GL_TEXTURE_2D_MULTISAMPLE,
107*61046927SAndroid Build Coastguard Worker GL_TEXTURE_2D_MULTISAMPLE_ARRAY,
108*61046927SAndroid Build Coastguard Worker GL_TEXTURE_CUBE_MAP_ARRAY,
109*61046927SAndroid Build Coastguard Worker GL_TEXTURE_BUFFER,
110*61046927SAndroid Build Coastguard Worker GL_TEXTURE_2D_ARRAY_EXT,
111*61046927SAndroid Build Coastguard Worker GL_TEXTURE_1D_ARRAY_EXT,
112*61046927SAndroid Build Coastguard Worker GL_TEXTURE_EXTERNAL_OES,
113*61046927SAndroid Build Coastguard Worker GL_TEXTURE_CUBE_MAP,
114*61046927SAndroid Build Coastguard Worker GL_TEXTURE_3D,
115*61046927SAndroid Build Coastguard Worker GL_TEXTURE_RECTANGLE_NV,
116*61046927SAndroid Build Coastguard Worker GL_TEXTURE_2D,
117*61046927SAndroid Build Coastguard Worker GL_TEXTURE_1D
118*61046927SAndroid Build Coastguard Worker };
119*61046927SAndroid Build Coastguard Worker STATIC_ASSERT(ARRAY_SIZE(targets) == NUM_TEXTURE_TARGETS);
120*61046927SAndroid Build Coastguard Worker shared->DefaultTex[i] = _mesa_new_texture_object(ctx, 0, targets[i]);
121*61046927SAndroid Build Coastguard Worker /* Need to explicitly set/overwrite the TargetIndex field here since
122*61046927SAndroid Build Coastguard Worker * the call to _mesa_tex_target_to_index() in NewTextureObject() may
123*61046927SAndroid Build Coastguard Worker * fail if the texture target is not supported.
124*61046927SAndroid Build Coastguard Worker */
125*61046927SAndroid Build Coastguard Worker shared->DefaultTex[i]->TargetIndex = i;
126*61046927SAndroid Build Coastguard Worker }
127*61046927SAndroid Build Coastguard Worker
128*61046927SAndroid Build Coastguard Worker /* sanity check */
129*61046927SAndroid Build Coastguard Worker assert(shared->DefaultTex[TEXTURE_1D_INDEX]->RefCount == 1);
130*61046927SAndroid Build Coastguard Worker
131*61046927SAndroid Build Coastguard Worker /* Mutex and timestamp for texobj state validation */
132*61046927SAndroid Build Coastguard Worker simple_mtx_init(&shared->TexMutex, mtx_plain);
133*61046927SAndroid Build Coastguard Worker shared->TextureStateStamp = 0;
134*61046927SAndroid Build Coastguard Worker
135*61046927SAndroid Build Coastguard Worker _mesa_InitHashTable(&shared->FrameBuffers);
136*61046927SAndroid Build Coastguard Worker _mesa_InitHashTable(&shared->RenderBuffers);
137*61046927SAndroid Build Coastguard Worker
138*61046927SAndroid Build Coastguard Worker shared->SyncObjects = _mesa_set_create(NULL, _mesa_hash_pointer,
139*61046927SAndroid Build Coastguard Worker _mesa_key_pointer_equal);
140*61046927SAndroid Build Coastguard Worker
141*61046927SAndroid Build Coastguard Worker _mesa_InitHashTable(&shared->MemoryObjects);
142*61046927SAndroid Build Coastguard Worker _mesa_InitHashTable(&shared->SemaphoreObjects);
143*61046927SAndroid Build Coastguard Worker
144*61046927SAndroid Build Coastguard Worker shared->GLThread.NoLockDuration = ONE_SECOND_IN_NS;
145*61046927SAndroid Build Coastguard Worker
146*61046927SAndroid Build Coastguard Worker return shared;
147*61046927SAndroid Build Coastguard Worker }
148*61046927SAndroid Build Coastguard Worker
149*61046927SAndroid Build Coastguard Worker
150*61046927SAndroid Build Coastguard Worker /**
151*61046927SAndroid Build Coastguard Worker * Callback for deleting a display list. Called by _mesa_DeleteHashTable().
152*61046927SAndroid Build Coastguard Worker */
153*61046927SAndroid Build Coastguard Worker static void
delete_displaylist_cb(void * data,void * userData)154*61046927SAndroid Build Coastguard Worker delete_displaylist_cb(void *data, void *userData)
155*61046927SAndroid Build Coastguard Worker {
156*61046927SAndroid Build Coastguard Worker struct gl_display_list *list = (struct gl_display_list *) data;
157*61046927SAndroid Build Coastguard Worker struct gl_context *ctx = (struct gl_context *) userData;
158*61046927SAndroid Build Coastguard Worker _mesa_delete_list(ctx, list);
159*61046927SAndroid Build Coastguard Worker }
160*61046927SAndroid Build Coastguard Worker
161*61046927SAndroid Build Coastguard Worker
162*61046927SAndroid Build Coastguard Worker /**
163*61046927SAndroid Build Coastguard Worker * Callback for deleting a texture object. Called by _mesa_DeleteHashTable().
164*61046927SAndroid Build Coastguard Worker */
165*61046927SAndroid Build Coastguard Worker static void
delete_texture_cb(void * data,void * userData)166*61046927SAndroid Build Coastguard Worker delete_texture_cb(void *data, void *userData)
167*61046927SAndroid Build Coastguard Worker {
168*61046927SAndroid Build Coastguard Worker struct gl_texture_object *texObj = (struct gl_texture_object *) data;
169*61046927SAndroid Build Coastguard Worker struct gl_context *ctx = (struct gl_context *) userData;
170*61046927SAndroid Build Coastguard Worker _mesa_delete_texture_object(ctx, texObj);
171*61046927SAndroid Build Coastguard Worker }
172*61046927SAndroid Build Coastguard Worker
173*61046927SAndroid Build Coastguard Worker
174*61046927SAndroid Build Coastguard Worker /**
175*61046927SAndroid Build Coastguard Worker * Callback for deleting a program object. Called by _mesa_DeleteHashTable().
176*61046927SAndroid Build Coastguard Worker */
177*61046927SAndroid Build Coastguard Worker static void
delete_program_cb(void * data,void * userData)178*61046927SAndroid Build Coastguard Worker delete_program_cb(void *data, void *userData)
179*61046927SAndroid Build Coastguard Worker {
180*61046927SAndroid Build Coastguard Worker struct gl_program *prog = (struct gl_program *) data;
181*61046927SAndroid Build Coastguard Worker struct gl_context *ctx = (struct gl_context *) userData;
182*61046927SAndroid Build Coastguard Worker if(prog != &_mesa_DummyProgram) {
183*61046927SAndroid Build Coastguard Worker assert(prog->RefCount == 1); /* should only be referenced by hash table */
184*61046927SAndroid Build Coastguard Worker prog->RefCount = 0; /* now going away */
185*61046927SAndroid Build Coastguard Worker _mesa_delete_program(ctx, prog);
186*61046927SAndroid Build Coastguard Worker }
187*61046927SAndroid Build Coastguard Worker }
188*61046927SAndroid Build Coastguard Worker
189*61046927SAndroid Build Coastguard Worker
190*61046927SAndroid Build Coastguard Worker /**
191*61046927SAndroid Build Coastguard Worker * Callback for deleting an ATI fragment shader object.
192*61046927SAndroid Build Coastguard Worker * Called by _mesa_DeleteHashTable().
193*61046927SAndroid Build Coastguard Worker */
194*61046927SAndroid Build Coastguard Worker static void
delete_fragshader_cb(void * data,void * userData)195*61046927SAndroid Build Coastguard Worker delete_fragshader_cb(void *data, void *userData)
196*61046927SAndroid Build Coastguard Worker {
197*61046927SAndroid Build Coastguard Worker struct ati_fragment_shader *shader = (struct ati_fragment_shader *) data;
198*61046927SAndroid Build Coastguard Worker struct gl_context *ctx = (struct gl_context *) userData;
199*61046927SAndroid Build Coastguard Worker _mesa_delete_ati_fragment_shader(ctx, shader);
200*61046927SAndroid Build Coastguard Worker }
201*61046927SAndroid Build Coastguard Worker
202*61046927SAndroid Build Coastguard Worker
203*61046927SAndroid Build Coastguard Worker /**
204*61046927SAndroid Build Coastguard Worker * Callback for deleting a buffer object. Called by _mesa_DeleteHashTable().
205*61046927SAndroid Build Coastguard Worker */
206*61046927SAndroid Build Coastguard Worker static void
delete_bufferobj_cb(void * data,void * userData)207*61046927SAndroid Build Coastguard Worker delete_bufferobj_cb(void *data, void *userData)
208*61046927SAndroid Build Coastguard Worker {
209*61046927SAndroid Build Coastguard Worker struct gl_buffer_object *bufObj = (struct gl_buffer_object *) data;
210*61046927SAndroid Build Coastguard Worker struct gl_context *ctx = (struct gl_context *) userData;
211*61046927SAndroid Build Coastguard Worker
212*61046927SAndroid Build Coastguard Worker _mesa_buffer_unmap_all_mappings(ctx, bufObj);
213*61046927SAndroid Build Coastguard Worker _mesa_reference_buffer_object(ctx, &bufObj, NULL);
214*61046927SAndroid Build Coastguard Worker }
215*61046927SAndroid Build Coastguard Worker
216*61046927SAndroid Build Coastguard Worker
217*61046927SAndroid Build Coastguard Worker /**
218*61046927SAndroid Build Coastguard Worker * Callback for freeing shader program data. Call it before delete_shader_cb
219*61046927SAndroid Build Coastguard Worker * to avoid memory access error.
220*61046927SAndroid Build Coastguard Worker */
221*61046927SAndroid Build Coastguard Worker static void
free_shader_program_data_cb(void * data,void * userData)222*61046927SAndroid Build Coastguard Worker free_shader_program_data_cb(void *data, void *userData)
223*61046927SAndroid Build Coastguard Worker {
224*61046927SAndroid Build Coastguard Worker struct gl_context *ctx = (struct gl_context *) userData;
225*61046927SAndroid Build Coastguard Worker struct gl_shader_program *shProg = (struct gl_shader_program *) data;
226*61046927SAndroid Build Coastguard Worker
227*61046927SAndroid Build Coastguard Worker if (shProg->Type == GL_SHADER_PROGRAM_MESA) {
228*61046927SAndroid Build Coastguard Worker _mesa_free_shader_program_data(ctx, shProg);
229*61046927SAndroid Build Coastguard Worker }
230*61046927SAndroid Build Coastguard Worker }
231*61046927SAndroid Build Coastguard Worker
232*61046927SAndroid Build Coastguard Worker
233*61046927SAndroid Build Coastguard Worker /**
234*61046927SAndroid Build Coastguard Worker * Callback for deleting shader and shader programs objects.
235*61046927SAndroid Build Coastguard Worker * Called by _mesa_DeleteHashTable().
236*61046927SAndroid Build Coastguard Worker */
237*61046927SAndroid Build Coastguard Worker static void
delete_shader_cb(void * data,void * userData)238*61046927SAndroid Build Coastguard Worker delete_shader_cb(void *data, void *userData)
239*61046927SAndroid Build Coastguard Worker {
240*61046927SAndroid Build Coastguard Worker struct gl_context *ctx = (struct gl_context *) userData;
241*61046927SAndroid Build Coastguard Worker struct gl_shader *sh = (struct gl_shader *) data;
242*61046927SAndroid Build Coastguard Worker if (_mesa_validate_shader_target(ctx, sh->Type)) {
243*61046927SAndroid Build Coastguard Worker _mesa_delete_shader(ctx, sh);
244*61046927SAndroid Build Coastguard Worker }
245*61046927SAndroid Build Coastguard Worker else {
246*61046927SAndroid Build Coastguard Worker struct gl_shader_program *shProg = (struct gl_shader_program *) data;
247*61046927SAndroid Build Coastguard Worker assert(shProg->Type == GL_SHADER_PROGRAM_MESA);
248*61046927SAndroid Build Coastguard Worker _mesa_delete_shader_program(ctx, shProg);
249*61046927SAndroid Build Coastguard Worker }
250*61046927SAndroid Build Coastguard Worker }
251*61046927SAndroid Build Coastguard Worker
252*61046927SAndroid Build Coastguard Worker
253*61046927SAndroid Build Coastguard Worker /**
254*61046927SAndroid Build Coastguard Worker * Callback for deleting a framebuffer object. Called by _mesa_DeleteHashTable()
255*61046927SAndroid Build Coastguard Worker */
256*61046927SAndroid Build Coastguard Worker static void
delete_framebuffer_cb(void * data,UNUSED void * userData)257*61046927SAndroid Build Coastguard Worker delete_framebuffer_cb(void *data, UNUSED void *userData)
258*61046927SAndroid Build Coastguard Worker {
259*61046927SAndroid Build Coastguard Worker struct gl_framebuffer *fb = (struct gl_framebuffer *) data;
260*61046927SAndroid Build Coastguard Worker /* The fact that the framebuffer is in the hashtable means its refcount
261*61046927SAndroid Build Coastguard Worker * is one, but we're removing from the hashtable now. So clear refcount.
262*61046927SAndroid Build Coastguard Worker */
263*61046927SAndroid Build Coastguard Worker /*assert(fb->RefCount == 1);*/
264*61046927SAndroid Build Coastguard Worker fb->RefCount = 0;
265*61046927SAndroid Build Coastguard Worker
266*61046927SAndroid Build Coastguard Worker /* NOTE: Delete should always be defined but there are two reports
267*61046927SAndroid Build Coastguard Worker * of it being NULL (bugs 13507, 14293). Work-around for now.
268*61046927SAndroid Build Coastguard Worker */
269*61046927SAndroid Build Coastguard Worker if (fb->Delete)
270*61046927SAndroid Build Coastguard Worker fb->Delete(fb);
271*61046927SAndroid Build Coastguard Worker }
272*61046927SAndroid Build Coastguard Worker
273*61046927SAndroid Build Coastguard Worker
274*61046927SAndroid Build Coastguard Worker /**
275*61046927SAndroid Build Coastguard Worker * Callback for deleting a renderbuffer object. Called by _mesa_DeleteHashTable()
276*61046927SAndroid Build Coastguard Worker */
277*61046927SAndroid Build Coastguard Worker static void
delete_renderbuffer_cb(void * data,void * userData)278*61046927SAndroid Build Coastguard Worker delete_renderbuffer_cb(void *data, void *userData)
279*61046927SAndroid Build Coastguard Worker {
280*61046927SAndroid Build Coastguard Worker struct gl_context *ctx = (struct gl_context *) userData;
281*61046927SAndroid Build Coastguard Worker struct gl_renderbuffer *rb = (struct gl_renderbuffer *) data;
282*61046927SAndroid Build Coastguard Worker rb->RefCount = 0; /* see comment for FBOs above */
283*61046927SAndroid Build Coastguard Worker if (rb->Delete)
284*61046927SAndroid Build Coastguard Worker rb->Delete(ctx, rb);
285*61046927SAndroid Build Coastguard Worker }
286*61046927SAndroid Build Coastguard Worker
287*61046927SAndroid Build Coastguard Worker
288*61046927SAndroid Build Coastguard Worker /**
289*61046927SAndroid Build Coastguard Worker * Callback for deleting a sampler object. Called by _mesa_DeleteHashTable()
290*61046927SAndroid Build Coastguard Worker */
291*61046927SAndroid Build Coastguard Worker static void
delete_sampler_object_cb(void * data,void * userData)292*61046927SAndroid Build Coastguard Worker delete_sampler_object_cb(void *data, void *userData)
293*61046927SAndroid Build Coastguard Worker {
294*61046927SAndroid Build Coastguard Worker struct gl_context *ctx = (struct gl_context *) userData;
295*61046927SAndroid Build Coastguard Worker struct gl_sampler_object *sampObj = (struct gl_sampler_object *) data;
296*61046927SAndroid Build Coastguard Worker _mesa_reference_sampler_object(ctx, &sampObj, NULL);
297*61046927SAndroid Build Coastguard Worker }
298*61046927SAndroid Build Coastguard Worker
299*61046927SAndroid Build Coastguard Worker /**
300*61046927SAndroid Build Coastguard Worker * Callback for deleting a memory object. Called by _mesa_DeleteHashTable().
301*61046927SAndroid Build Coastguard Worker */
302*61046927SAndroid Build Coastguard Worker static void
delete_memory_object_cb(void * data,void * userData)303*61046927SAndroid Build Coastguard Worker delete_memory_object_cb(void *data, void *userData)
304*61046927SAndroid Build Coastguard Worker {
305*61046927SAndroid Build Coastguard Worker struct gl_memory_object *memObj = (struct gl_memory_object *) data;
306*61046927SAndroid Build Coastguard Worker struct gl_context *ctx = (struct gl_context *) userData;
307*61046927SAndroid Build Coastguard Worker _mesa_delete_memory_object(ctx, memObj);
308*61046927SAndroid Build Coastguard Worker }
309*61046927SAndroid Build Coastguard Worker
310*61046927SAndroid Build Coastguard Worker /**
311*61046927SAndroid Build Coastguard Worker * Callback for deleting a memory object. Called by _mesa_DeleteHashTable().
312*61046927SAndroid Build Coastguard Worker */
313*61046927SAndroid Build Coastguard Worker static void
delete_semaphore_object_cb(void * data,void * userData)314*61046927SAndroid Build Coastguard Worker delete_semaphore_object_cb(void *data, void *userData)
315*61046927SAndroid Build Coastguard Worker {
316*61046927SAndroid Build Coastguard Worker struct gl_semaphore_object *semObj = (struct gl_semaphore_object *) data;
317*61046927SAndroid Build Coastguard Worker struct gl_context *ctx = (struct gl_context *) userData;
318*61046927SAndroid Build Coastguard Worker _mesa_delete_semaphore_object(ctx, semObj);
319*61046927SAndroid Build Coastguard Worker }
320*61046927SAndroid Build Coastguard Worker
321*61046927SAndroid Build Coastguard Worker /**
322*61046927SAndroid Build Coastguard Worker * Deallocate a shared state object and all children structures.
323*61046927SAndroid Build Coastguard Worker *
324*61046927SAndroid Build Coastguard Worker * \param ctx GL context.
325*61046927SAndroid Build Coastguard Worker * \param shared shared state pointer.
326*61046927SAndroid Build Coastguard Worker *
327*61046927SAndroid Build Coastguard Worker * Frees the display lists, the texture objects (calling the driver texture
328*61046927SAndroid Build Coastguard Worker * deletion callback to free its private data) and the vertex programs, as well
329*61046927SAndroid Build Coastguard Worker * as their hash tables.
330*61046927SAndroid Build Coastguard Worker *
331*61046927SAndroid Build Coastguard Worker * \sa alloc_shared_state().
332*61046927SAndroid Build Coastguard Worker */
333*61046927SAndroid Build Coastguard Worker static void
free_shared_state(struct gl_context * ctx,struct gl_shared_state * shared)334*61046927SAndroid Build Coastguard Worker free_shared_state(struct gl_context *ctx, struct gl_shared_state *shared)
335*61046927SAndroid Build Coastguard Worker {
336*61046927SAndroid Build Coastguard Worker GLuint i;
337*61046927SAndroid Build Coastguard Worker
338*61046927SAndroid Build Coastguard Worker /* Free the dummy/fallback texture objects */
339*61046927SAndroid Build Coastguard Worker for (i = 0; i < NUM_TEXTURE_TARGETS; i++) {
340*61046927SAndroid Build Coastguard Worker for (unsigned j = 0; j < ARRAY_SIZE(shared->FallbackTex[0]); j++) {
341*61046927SAndroid Build Coastguard Worker if (shared->FallbackTex[i][j])
342*61046927SAndroid Build Coastguard Worker _mesa_delete_texture_object(ctx, shared->FallbackTex[i][j]);
343*61046927SAndroid Build Coastguard Worker }
344*61046927SAndroid Build Coastguard Worker }
345*61046927SAndroid Build Coastguard Worker
346*61046927SAndroid Build Coastguard Worker /*
347*61046927SAndroid Build Coastguard Worker * Free display lists
348*61046927SAndroid Build Coastguard Worker */
349*61046927SAndroid Build Coastguard Worker _mesa_DeinitHashTable(&shared->DisplayList, delete_displaylist_cb, ctx);
350*61046927SAndroid Build Coastguard Worker free(shared->small_dlist_store.ptr);
351*61046927SAndroid Build Coastguard Worker util_idalloc_fini(&shared->small_dlist_store.free_idx);
352*61046927SAndroid Build Coastguard Worker
353*61046927SAndroid Build Coastguard Worker _mesa_HashWalk(&shared->ShaderObjects, free_shader_program_data_cb, ctx);
354*61046927SAndroid Build Coastguard Worker _mesa_DeinitHashTable(&shared->ShaderObjects, delete_shader_cb, ctx);
355*61046927SAndroid Build Coastguard Worker _mesa_DeinitHashTable(&shared->Programs, delete_program_cb, ctx);
356*61046927SAndroid Build Coastguard Worker
357*61046927SAndroid Build Coastguard Worker if (shared->DefaultVertexProgram)
358*61046927SAndroid Build Coastguard Worker _mesa_reference_program(ctx, &shared->DefaultVertexProgram, NULL);
359*61046927SAndroid Build Coastguard Worker
360*61046927SAndroid Build Coastguard Worker if (shared->DefaultFragmentProgram)
361*61046927SAndroid Build Coastguard Worker _mesa_reference_program(ctx, &shared->DefaultFragmentProgram, NULL);
362*61046927SAndroid Build Coastguard Worker
363*61046927SAndroid Build Coastguard Worker if (shared->DefaultFragmentShader)
364*61046927SAndroid Build Coastguard Worker _mesa_delete_ati_fragment_shader(ctx, shared->DefaultFragmentShader);
365*61046927SAndroid Build Coastguard Worker
366*61046927SAndroid Build Coastguard Worker _mesa_DeinitHashTable(&shared->ATIShaders, delete_fragshader_cb, ctx);
367*61046927SAndroid Build Coastguard Worker _mesa_DeinitHashTable(&shared->BufferObjects, delete_bufferobj_cb, ctx);
368*61046927SAndroid Build Coastguard Worker
369*61046927SAndroid Build Coastguard Worker if (shared->ZombieBufferObjects) {
370*61046927SAndroid Build Coastguard Worker set_foreach(shared->ZombieBufferObjects, entry) {
371*61046927SAndroid Build Coastguard Worker assert(!"ZombieBufferObjects should be empty");
372*61046927SAndroid Build Coastguard Worker }
373*61046927SAndroid Build Coastguard Worker _mesa_set_destroy(shared->ZombieBufferObjects, NULL);
374*61046927SAndroid Build Coastguard Worker }
375*61046927SAndroid Build Coastguard Worker
376*61046927SAndroid Build Coastguard Worker _mesa_DeinitHashTable(&shared->FrameBuffers, delete_framebuffer_cb, ctx);
377*61046927SAndroid Build Coastguard Worker _mesa_DeinitHashTable(&shared->RenderBuffers, delete_renderbuffer_cb, ctx);
378*61046927SAndroid Build Coastguard Worker
379*61046927SAndroid Build Coastguard Worker if (shared->SyncObjects) {
380*61046927SAndroid Build Coastguard Worker set_foreach(shared->SyncObjects, entry) {
381*61046927SAndroid Build Coastguard Worker _mesa_unref_sync_object(ctx, (struct gl_sync_object *) entry->key, 1);
382*61046927SAndroid Build Coastguard Worker }
383*61046927SAndroid Build Coastguard Worker
384*61046927SAndroid Build Coastguard Worker _mesa_set_destroy(shared->SyncObjects, NULL);
385*61046927SAndroid Build Coastguard Worker }
386*61046927SAndroid Build Coastguard Worker
387*61046927SAndroid Build Coastguard Worker _mesa_DeinitHashTable(&shared->SamplerObjects, delete_sampler_object_cb,
388*61046927SAndroid Build Coastguard Worker ctx);
389*61046927SAndroid Build Coastguard Worker
390*61046927SAndroid Build Coastguard Worker /*
391*61046927SAndroid Build Coastguard Worker * Free texture objects (after FBOs since some textures might have
392*61046927SAndroid Build Coastguard Worker * been bound to FBOs).
393*61046927SAndroid Build Coastguard Worker */
394*61046927SAndroid Build Coastguard Worker /* the default textures */
395*61046927SAndroid Build Coastguard Worker for (i = 0; i < NUM_TEXTURE_TARGETS; i++) {
396*61046927SAndroid Build Coastguard Worker if (shared->DefaultTex[i])
397*61046927SAndroid Build Coastguard Worker _mesa_delete_texture_object(ctx, shared->DefaultTex[i]);
398*61046927SAndroid Build Coastguard Worker }
399*61046927SAndroid Build Coastguard Worker
400*61046927SAndroid Build Coastguard Worker /* all other textures */
401*61046927SAndroid Build Coastguard Worker _mesa_DeinitHashTable(&shared->TexObjects, delete_texture_cb, ctx);
402*61046927SAndroid Build Coastguard Worker
403*61046927SAndroid Build Coastguard Worker _mesa_free_shared_handles(shared);
404*61046927SAndroid Build Coastguard Worker
405*61046927SAndroid Build Coastguard Worker /* ARB_shading_language_include */
406*61046927SAndroid Build Coastguard Worker _mesa_destroy_shader_includes(shared);
407*61046927SAndroid Build Coastguard Worker simple_mtx_destroy(&shared->ShaderIncludeMutex);
408*61046927SAndroid Build Coastguard Worker
409*61046927SAndroid Build Coastguard Worker _mesa_DeinitHashTable(&shared->MemoryObjects, delete_memory_object_cb,
410*61046927SAndroid Build Coastguard Worker ctx);
411*61046927SAndroid Build Coastguard Worker _mesa_DeinitHashTable(&shared->SemaphoreObjects,
412*61046927SAndroid Build Coastguard Worker delete_semaphore_object_cb, ctx);
413*61046927SAndroid Build Coastguard Worker
414*61046927SAndroid Build Coastguard Worker simple_mtx_destroy(&shared->Mutex);
415*61046927SAndroid Build Coastguard Worker simple_mtx_destroy(&shared->TexMutex);
416*61046927SAndroid Build Coastguard Worker
417*61046927SAndroid Build Coastguard Worker FREE(shared);
418*61046927SAndroid Build Coastguard Worker }
419*61046927SAndroid Build Coastguard Worker
420*61046927SAndroid Build Coastguard Worker
421*61046927SAndroid Build Coastguard Worker /**
422*61046927SAndroid Build Coastguard Worker * gl_shared_state objects are ref counted.
423*61046927SAndroid Build Coastguard Worker * If ptr's refcount goes to zero, free the shared state.
424*61046927SAndroid Build Coastguard Worker */
425*61046927SAndroid Build Coastguard Worker void
_mesa_reference_shared_state(struct gl_context * ctx,struct gl_shared_state ** ptr,struct gl_shared_state * state)426*61046927SAndroid Build Coastguard Worker _mesa_reference_shared_state(struct gl_context *ctx,
427*61046927SAndroid Build Coastguard Worker struct gl_shared_state **ptr,
428*61046927SAndroid Build Coastguard Worker struct gl_shared_state *state)
429*61046927SAndroid Build Coastguard Worker {
430*61046927SAndroid Build Coastguard Worker if (*ptr == state)
431*61046927SAndroid Build Coastguard Worker return;
432*61046927SAndroid Build Coastguard Worker
433*61046927SAndroid Build Coastguard Worker if (*ptr) {
434*61046927SAndroid Build Coastguard Worker /* unref old state */
435*61046927SAndroid Build Coastguard Worker struct gl_shared_state *old = *ptr;
436*61046927SAndroid Build Coastguard Worker GLboolean delete;
437*61046927SAndroid Build Coastguard Worker
438*61046927SAndroid Build Coastguard Worker simple_mtx_lock(&old->Mutex);
439*61046927SAndroid Build Coastguard Worker assert(old->RefCount >= 1);
440*61046927SAndroid Build Coastguard Worker old->RefCount--;
441*61046927SAndroid Build Coastguard Worker delete = (old->RefCount == 0);
442*61046927SAndroid Build Coastguard Worker simple_mtx_unlock(&old->Mutex);
443*61046927SAndroid Build Coastguard Worker
444*61046927SAndroid Build Coastguard Worker if (delete) {
445*61046927SAndroid Build Coastguard Worker free_shared_state(ctx, old);
446*61046927SAndroid Build Coastguard Worker }
447*61046927SAndroid Build Coastguard Worker
448*61046927SAndroid Build Coastguard Worker *ptr = NULL;
449*61046927SAndroid Build Coastguard Worker }
450*61046927SAndroid Build Coastguard Worker
451*61046927SAndroid Build Coastguard Worker if (state) {
452*61046927SAndroid Build Coastguard Worker /* reference new state */
453*61046927SAndroid Build Coastguard Worker simple_mtx_lock(&state->Mutex);
454*61046927SAndroid Build Coastguard Worker state->RefCount++;
455*61046927SAndroid Build Coastguard Worker *ptr = state;
456*61046927SAndroid Build Coastguard Worker simple_mtx_unlock(&state->Mutex);
457*61046927SAndroid Build Coastguard Worker }
458*61046927SAndroid Build Coastguard Worker }
459