/** * Callback for deleting shader and shader programs objects. * Called by _mesa_HashDeleteAll(). */ static void delete_shader_cb(GLuint id, void *data, void *userData) { GLcontext *ctx = (GLcontext *) userData; struct gl_shader *sh = (struct gl_shader *) data; if (sh->Type == GL_FRAGMENT_SHADER || sh->Type == GL_VERTEX_SHADER) { _mesa_free_shader(ctx, sh); } else { struct gl_shader_program *shProg = (struct gl_shader_program *) data; ASSERT(shProg->Type == GL_SHADER_PROGRAM_MESA); _mesa_free_shader_program(ctx, shProg); } }
/** * Search the shader program's list of shaders to find the one that * defines main(). * This will involve shader concatenation and recompilation if needed. */ static struct gl_shader * get_main_shader(GLcontext *ctx, struct gl_shader_program *shProg, GLenum type) { struct gl_shader *shader = NULL; GLuint i; /* * Look for a shader that defines main() and has no unresolved references. */ for (i = 0; i < shProg->NumShaders; i++) { shader = shProg->Shaders[i]; if (shader->Type == type && shader->Main && !shader->UnresolvedRefs) { /* All set! */ return shader; } } /* * There must have been unresolved references during the original * compilation. Try concatenating all the shaders of the given type * and recompile that. */ shader = concat_shaders(shProg, type); if (shader) { _slang_compile(ctx, shader); /* Finally, check if recompiling failed */ if (!shader->CompileStatus || !shader->Main || shader->UnresolvedRefs) { link_error(shProg, "Unresolved symbols"); _mesa_free_shader(ctx, shader); return NULL; } } return shader; }
/* XXX this could be static */ void _mesa_reference_shader(GLcontext *ctx, struct gl_shader **ptr, struct gl_shader *sh) { assert(ptr); if (*ptr == sh) { /* no-op */ return; } if (*ptr) { /* Unreference the old shader */ GLboolean deleteFlag = GL_FALSE; struct gl_shader *old = *ptr; ASSERT(old->RefCount > 0); old->RefCount--; /*printf("SHADER DECR %p (%d) to %d\n", (void*) old, old->Name, old->RefCount);*/ deleteFlag = (old->RefCount == 0); if (deleteFlag) { _mesa_HashRemove(ctx->Shared->ShaderObjects, old->Name); _mesa_free_shader(ctx, old); } *ptr = NULL; } assert(!*ptr); if (sh) { /* reference new */ sh->RefCount++; /*printf("SHADER INCR %p (%d) to %d\n", (void*) sh, sh->Name, sh->RefCount);*/ *ptr = sh; } }