xref: /aosp_15_r20/external/mesa3d/src/mesa/main/shared.c (revision 6104692788411f58d303aa86923a9ff6ecaded22)
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