From 650df3f2eb3bb187bb7313ab9d5071a00a6ce4a4 Mon Sep 17 00:00:00 2001 From: Robert Bragg Date: Tue, 8 Jun 2010 23:06:50 +0100 Subject: [PATCH] gles2: Have CoglProgram track uniforms per program Previously custom uniforms were tracked in _CoglGles2Wrapper but as part of a process to consolidate the gl/gles2 shader code it seems to make sense for this state to be tracked in the CoglProgram object instead. http://bugzilla.o-hand.com/show_bug.cgi?id=2179 --- cogl/driver/gles/cogl-gles2-wrapper.c | 41 ++++++++++++++------------- cogl/driver/gles/cogl-gles2-wrapper.h | 11 ++++--- cogl/driver/gles/cogl-program.c | 38 ++++++++++++++++--------- cogl/driver/gles/cogl-program.h | 11 ++++++- 4 files changed, 61 insertions(+), 40 deletions(-) diff --git a/cogl/driver/gles/cogl-gles2-wrapper.c b/cogl/driver/gles/cogl-gles2-wrapper.c index bc4f1187c..6245bc5a7 100644 --- a/cogl/driver/gles/cogl-gles2-wrapper.c +++ b/cogl/driver/gles/cogl-gles2-wrapper.c @@ -930,8 +930,8 @@ cogl_gles2_wrapper_get_program (const CoglGles2WrapperSettings *settings) /* We haven't tried to get a location for any of the custom uniforms yet */ - for (i = 0; i < COGL_GLES2_NUM_CUSTOM_UNIFORMS; i++) - program->custom_uniforms[i] = COGL_GLES2_UNBOUND_CUSTOM_UNIFORM; + for (i = 0; i < COGL_PROGRAM_NUM_CUSTOM_UNIFORMS; i++) + program->custom_gl_uniforms[i] = COGL_PROGRAM_UNBOUND_CUSTOM_UNIFORM; w->compiled_programs = g_slist_append (w->compiled_programs, program); @@ -942,7 +942,6 @@ void _cogl_gles2_wrapper_deinit (CoglGles2Wrapper *wrapper) { GSList *node, *next; - int i; for (node = wrapper->compiled_programs; node; node = next) { @@ -967,10 +966,6 @@ _cogl_gles2_wrapper_deinit (CoglGles2Wrapper *wrapper) g_slist_free1 (node); } wrapper->compiled_fragment_shaders = NULL; - - for (i = 0; i < COGL_GLES2_NUM_CUSTOM_UNIFORMS; i++) - if (wrapper->custom_uniforms[i].count > 1) - g_free (wrapper->custom_uniforms[i].v.array); } static void @@ -1180,6 +1175,7 @@ static void _cogl_wrap_prepare_for_draw (void) { CoglGles2WrapperProgram *program; + guint32 dirty_custom_uniforms = 0; _COGL_GET_GLES2_WRAPPER (w, NO_RETVAL); @@ -1200,12 +1196,18 @@ _cogl_wrap_prepare_for_draw (void) w->current_program = program; /* All of the uniforms are probably now out of date */ w->dirty_uniforms = COGL_GLES2_DIRTY_ALL; - w->dirty_custom_uniforms = (1 << COGL_GLES2_NUM_CUSTOM_UNIFORMS) - 1; + dirty_custom_uniforms = (1 << COGL_PROGRAM_NUM_CUSTOM_UNIFORMS) - 1; } w->settings_dirty = FALSE; } else - program = w->current_program; + { + CoglProgram *user_program = + _cogl_program_pointer_from_handle (w->settings.user_program); + if (user_program) + dirty_custom_uniforms = user_program->dirty_custom_uniforms; + program = w->current_program; + } /* Make sure all of the uniforms are up to date */ if (w->dirty_uniforms) @@ -1284,7 +1286,7 @@ _cogl_wrap_prepare_for_draw (void) w->dirty_uniforms = 0; } - if (w->dirty_custom_uniforms) + if (dirty_custom_uniforms) { int i; @@ -1294,21 +1296,20 @@ _cogl_wrap_prepare_for_draw (void) = _cogl_program_pointer_from_handle (w->settings.user_program); const char *uniform_name; - for (i = 0; i < COGL_GLES2_NUM_CUSTOM_UNIFORMS; i++) - if ((w->dirty_custom_uniforms & (1 << i)) + for (i = 0; i < COGL_PROGRAM_NUM_CUSTOM_UNIFORMS; i++) + if ((dirty_custom_uniforms & (1 << i)) && (uniform_name = user_program->custom_uniform_names[i])) { - if (program->custom_uniforms[i] - == COGL_GLES2_UNBOUND_CUSTOM_UNIFORM) - program->custom_uniforms[i] + if (program->custom_gl_uniforms[i] + == COGL_PROGRAM_UNBOUND_CUSTOM_UNIFORM) + program->custom_gl_uniforms[i] = glGetUniformLocation (program->program, uniform_name); - if (program->custom_uniforms[i] >= 0) - cogl_gles2_do_set_uniform (program->custom_uniforms[i], - &w->custom_uniforms[i]); + if (program->custom_gl_uniforms[i] >= 0) + cogl_gles2_do_set_uniform (program->custom_gl_uniforms[i], + &user_program->custom_uniforms[i]); } + user_program->dirty_custom_uniforms = 0; } - - w->dirty_custom_uniforms = 0; } if (w->dirty_attribute_pointers diff --git a/cogl/driver/gles/cogl-gles2-wrapper.h b/cogl/driver/gles/cogl-gles2-wrapper.h index eb79d6c91..9edf78de0 100644 --- a/cogl/driver/gles/cogl-gles2-wrapper.h +++ b/cogl/driver/gles/cogl-gles2-wrapper.h @@ -26,6 +26,7 @@ #include "cogl.h" /* needed for gl header include */ #include "cogl-internal.h" +#include "cogl-program.h" G_BEGIN_DECLS @@ -44,9 +45,6 @@ typedef struct _CoglGles2WrapperSettings CoglGles2WrapperSettings; typedef struct _CoglGles2WrapperProgram CoglGles2WrapperProgram; typedef struct _CoglGles2WrapperShader CoglGles2WrapperShader; -#define COGL_GLES2_NUM_CUSTOM_UNIFORMS 16 -#define COGL_GLES2_UNBOUND_CUSTOM_UNIFORM -2 - /* Must be a power of two */ #define COGL_GLES2_MODELVIEW_STACK_SIZE 32 #define COGL_GLES2_PROJECTION_STACK_SIZE 2 @@ -190,7 +188,7 @@ struct _CoglGles2Wrapper /* Whether the settings have changed since the last draw */ gboolean settings_dirty; /* Uniforms that have changed since the last draw */ - int dirty_uniforms, dirty_custom_uniforms; + int dirty_uniforms; /* Attribute pointers that have changed since the last draw */ int dirty_attribute_pointers; @@ -214,13 +212,14 @@ struct _CoglGles2Wrapper GLfloat fog_end; GLfloat fog_color[4]; GLfloat point_size; - CoglBoxedValue custom_uniforms[COGL_GLES2_NUM_CUSTOM_UNIFORMS]; }; struct _CoglGles2WrapperProgram { GLuint program; + CoglProgram *user_program; + /* The settings that were used to generate this combination */ CoglGles2WrapperSettings settings; @@ -230,7 +229,7 @@ struct _CoglGles2WrapperProgram /* The uniforms for this program */ CoglGles2WrapperUniforms uniforms; - GLint custom_uniforms[COGL_GLES2_NUM_CUSTOM_UNIFORMS]; + GLint custom_gl_uniforms[COGL_PROGRAM_NUM_CUSTOM_UNIFORMS]; }; struct _CoglGles2WrapperShader diff --git a/cogl/driver/gles/cogl-program.c b/cogl/driver/gles/cogl-program.c index 22450619b..a3c51cdcb 100644 --- a/cogl/driver/gles/cogl-program.c +++ b/cogl/driver/gles/cogl-program.c @@ -63,9 +63,13 @@ _cogl_program_free (CoglProgram *program) ctx->drv.gles2.settings_dirty = TRUE; } - for (i = 0; i < COGL_GLES2_NUM_CUSTOM_UNIFORMS; i++) - if (program->custom_uniform_names[i]) - g_free (program->custom_uniform_names[i]); + for (i = 0; i < COGL_PROGRAM_NUM_CUSTOM_UNIFORMS; i++) + { + if (program->custom_uniform_names[i]) + g_free (program->custom_uniform_names[i]); + if (program->custom_uniforms[i].count > 1) + g_free (program->custom_uniforms[i].v.array); + } g_slice_free (CoglProgram, program); } @@ -75,10 +79,7 @@ cogl_create_program (void) { CoglProgram *program; - program = g_slice_new (CoglProgram); - program->attached_shaders = NULL; - memset (program->custom_uniform_names, 0, - COGL_GLES2_NUM_CUSTOM_UNIFORMS * sizeof (char *)); + program = g_slice_new0 (CoglProgram); return _cogl_program_handle_new (program); } @@ -153,11 +154,11 @@ cogl_program_get_uniform_location (CoglHandle handle, with a new fixed functionality shader. Instead we make our own mapping of uniform numbers and cache the names */ for (i = 0; program->custom_uniform_names[i] - && i < COGL_GLES2_NUM_CUSTOM_UNIFORMS; i++) + && i < COGL_PROGRAM_NUM_CUSTOM_UNIFORMS; i++) if (!strcmp (program->custom_uniform_names[i], uniform_name)) return i; - if (i < COGL_GLES2_NUM_CUSTOM_UNIFORMS) + if (i < COGL_PROGRAM_NUM_CUSTOM_UNIFORMS) { program->custom_uniform_names[i] = g_strdup (uniform_name); return i; @@ -190,12 +191,18 @@ cogl_program_uniform_x (int uniform_no, gsize value_size, gconstpointer value) { + CoglProgram *program; + _COGL_GET_CONTEXT (ctx, NO_RETVAL); - if (uniform_no >= 0 && uniform_no < COGL_GLES2_NUM_CUSTOM_UNIFORMS + program = ctx->current_program; + + g_return_if_fail (program != NULL); + + if (uniform_no >= 0 && uniform_no < COGL_PROGRAM_NUM_CUSTOM_UNIFORMS && size >= 1 && size <= 4 && count >= 1) { - CoglBoxedValue *bv = ctx->drv.gles2.custom_uniforms + uniform_no; + CoglBoxedValue *bv = program->custom_uniforms + uniform_no; if (count == 1) { @@ -224,7 +231,7 @@ cogl_program_uniform_x (int uniform_no, bv->size = size; bv->count = count; - ctx->drv.gles2.dirty_custom_uniforms |= 1 << uniform_no; + program->dirty_custom_uniforms |= 1 << uniform_no; } } @@ -255,11 +262,16 @@ cogl_program_uniform_matrix (int uniform_no, gboolean transpose, const GLfloat *value) { + CoglProgram *program; CoglBoxedValue *bv; _COGL_GET_CONTEXT (ctx, NO_RETVAL); - bv = ctx->drv.gles2.custom_uniforms + uniform_no; + program = ctx->current_program; + + g_return_if_fail (program != NULL); + + bv = program->custom_uniforms + uniform_no; cogl_program_uniform_x (uniform_no, size, count, COGL_BOXED_MATRIX, sizeof (float) * size * size, value); diff --git a/cogl/driver/gles/cogl-program.h b/cogl/driver/gles/cogl-program.h index bd69580c8..378431950 100644 --- a/cogl/driver/gles/cogl-program.h +++ b/cogl/driver/gles/cogl-program.h @@ -27,6 +27,9 @@ #include "cogl-gles2-wrapper.h" #include "cogl-handle.h" +#define COGL_PROGRAM_NUM_CUSTOM_UNIFORMS 16 +#define COGL_PROGRAM_UNBOUND_CUSTOM_UNIFORM -2 + typedef struct _CoglProgram CoglProgram; struct _CoglProgram @@ -35,7 +38,13 @@ struct _CoglProgram GSList *attached_shaders; - char *custom_uniform_names[COGL_GLES2_NUM_CUSTOM_UNIFORMS]; + char *custom_uniform_names[COGL_PROGRAM_NUM_CUSTOM_UNIFORMS]; + + CoglBoxedValue custom_uniforms[COGL_PROGRAM_NUM_CUSTOM_UNIFORMS]; + + /* Uniforms that have changed since the last time this program was + * used. */ + guint32 dirty_custom_uniforms; }; CoglProgram *_cogl_program_pointer_from_handle (CoglHandle handle);