diff options
author | Keith Whitwell <[email protected]> | 2004-02-14 15:00:42 +0000 |
---|---|---|
committer | Keith Whitwell <[email protected]> | 2004-02-14 15:00:42 +0000 |
commit | 964e5325bdcca702cfb2f210e0b89809e42847ef (patch) | |
tree | 1d65322fce17d62024ad7f900c30a48e7bbb321c /src/mesa/main/program.c | |
parent | 70dacabfe503e89d8c4a8df9fa6568aa5613a25b (diff) |
Make it easier for drivers to create "subclasses" of the existing
program struct hierarchy.
Add driver callbacks to enable the above and make it possible to track
more changes to program objects.
Diffstat (limited to 'src/mesa/main/program.c')
-rw-r--r-- | src/mesa/main/program.c | 102 |
1 files changed, 62 insertions, 40 deletions
diff --git a/src/mesa/main/program.c b/src/mesa/main/program.c index e32e8a3b1ac..fe536566304 100644 --- a/src/mesa/main/program.c +++ b/src/mesa/main/program.c @@ -138,12 +138,49 @@ _mesa_find_line_column(const GLubyte *string, const GLubyte *pos, } +static struct program * _mesa_init_program_struct( GLcontext *ctx, + struct program *prog, + GLenum target, GLuint id) +{ + if (prog) { + prog->Id = id; + prog->Target = target; + prog->Resident = GL_TRUE; + prog->RefCount = 1; + } + + fprintf(stderr, "%s %x %x\n", __FUNCTION__, target, prog); + return prog; +} + +struct program * _mesa_init_fragment_program( GLcontext *ctx, + struct fragment_program *prog, + GLenum target, GLuint id) +{ + if (prog) + return _mesa_init_program_struct( ctx, &prog->Base, target, id ); + else + return NULL; +} + +struct program * _mesa_init_vertex_program( GLcontext *ctx, + struct vertex_program *prog, + GLenum target, GLuint id) +{ + if (prog) + return _mesa_init_program_struct( ctx, &prog->Base, target, id ); + else + return NULL; +} + /** - * Allocate and initialize a new fragment/vertex program object but don't - * put it into the program hash table. - * Called via ctx->Driver.NewProgram. May be wrapped (OO deriviation) - * by a device driver function. + * Allocate and initialize a new fragment/vertex program object but + * don't put it into the program hash table. Called via + * ctx->Driver.NewProgram. May be overridden (ie. replaced) by a + * device driver function to implement OO deriviation with additional + * types not understood by this function. + * * \param ctx context * \param id program id/number * \param target program target/type @@ -152,33 +189,21 @@ _mesa_find_line_column(const GLubyte *string, const GLubyte *pos, struct program * _mesa_new_program(GLcontext *ctx, GLenum target, GLuint id) { - struct program *prog; + fprintf(stderr, "%s\n", __FUNCTION__); + switch (target) { + case GL_VERTEX_PROGRAM_ARB: /* == GL_VERTEX_PROGRAM_NV */ + return _mesa_init_vertex_program( ctx, CALLOC_STRUCT(vertex_program), + target, id ); - if (target == GL_VERTEX_PROGRAM_NV - || target == GL_VERTEX_PROGRAM_ARB) { - struct vertex_program *vprog = CALLOC_STRUCT(vertex_program); - if (!vprog) { - return NULL; - } - prog = &(vprog->Base); - } - else if (target == GL_FRAGMENT_PROGRAM_NV - || target == GL_FRAGMENT_PROGRAM_ARB) { - struct fragment_program *fprog = CALLOC_STRUCT(fragment_program); - if (!fprog) { - return NULL; - } - prog = &(fprog->Base); - } - else { + case GL_FRAGMENT_PROGRAM_NV: + case GL_FRAGMENT_PROGRAM_ARB: + return _mesa_init_fragment_program( ctx, CALLOC_STRUCT(fragment_program), + target, id ); + + default: _mesa_problem(ctx, "bad target in _mesa_new_program"); return NULL; } - prog->Id = id; - prog->Target = target; - prog->Resident = GL_TRUE; - prog->RefCount = 1; - return prog; } @@ -946,6 +971,14 @@ _mesa_DeletePrograms(GLsizei n, const GLuint *ids) ctx->Driver.DeleteProgram(ctx, prog); } } + else { + /* This is necessary as we can't tell from HashLookup + * whether the entry exists with data == 0, or if it + * doesn't exist at all. As GenPrograms creates the first + * case below, need to call Remove() to avoid memory leak: + */ + _mesa_HashRemove(ctx->Shared->Programs, ids[i]); + } } } } @@ -975,16 +1008,7 @@ _mesa_GenPrograms(GLsizei n, GLuint *ids) first = _mesa_HashFindFreeKeyBlock(ctx->Shared->Programs, n); for (i = 0; i < (GLuint) n; i++) { - const int bytes = MAX2(sizeof(struct vertex_program), - sizeof(struct fragment_program)); - struct program *prog = (struct program *) _mesa_calloc(bytes); - if (!prog) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGenPrograms"); - return; - } - prog->RefCount = 1; - prog->Id = first + i; - _mesa_HashInsert(ctx->Shared->Programs, first + i, prog); + _mesa_HashInsert(ctx->Shared->Programs, first + i, 0); } /* Return the program names */ @@ -1004,15 +1028,13 @@ _mesa_GenPrograms(GLsizei n, GLuint *ids) GLboolean GLAPIENTRY _mesa_IsProgram(GLuint id) { - struct program *prog; GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE); if (id == 0) return GL_FALSE; - prog = (struct program *) _mesa_HashLookup(ctx->Shared->Programs, id); - if (prog && prog->Target) + if (_mesa_HashLookup(ctx->Shared->Programs, id)) return GL_TRUE; else return GL_FALSE; |