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
This commit is contained in:
Robert Bragg 2010-06-08 23:06:50 +01:00
parent 7705469d2b
commit 650df3f2eb
4 changed files with 61 additions and 40 deletions

View File

@ -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 /* We haven't tried to get a location for any of the custom uniforms
yet */ yet */
for (i = 0; i < COGL_GLES2_NUM_CUSTOM_UNIFORMS; i++) for (i = 0; i < COGL_PROGRAM_NUM_CUSTOM_UNIFORMS; i++)
program->custom_uniforms[i] = COGL_GLES2_UNBOUND_CUSTOM_UNIFORM; program->custom_gl_uniforms[i] = COGL_PROGRAM_UNBOUND_CUSTOM_UNIFORM;
w->compiled_programs = g_slist_append (w->compiled_programs, program); w->compiled_programs = g_slist_append (w->compiled_programs, program);
@ -942,7 +942,6 @@ void
_cogl_gles2_wrapper_deinit (CoglGles2Wrapper *wrapper) _cogl_gles2_wrapper_deinit (CoglGles2Wrapper *wrapper)
{ {
GSList *node, *next; GSList *node, *next;
int i;
for (node = wrapper->compiled_programs; node; node = next) for (node = wrapper->compiled_programs; node; node = next)
{ {
@ -967,10 +966,6 @@ _cogl_gles2_wrapper_deinit (CoglGles2Wrapper *wrapper)
g_slist_free1 (node); g_slist_free1 (node);
} }
wrapper->compiled_fragment_shaders = NULL; 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 static void
@ -1180,6 +1175,7 @@ static void
_cogl_wrap_prepare_for_draw (void) _cogl_wrap_prepare_for_draw (void)
{ {
CoglGles2WrapperProgram *program; CoglGles2WrapperProgram *program;
guint32 dirty_custom_uniforms = 0;
_COGL_GET_GLES2_WRAPPER (w, NO_RETVAL); _COGL_GET_GLES2_WRAPPER (w, NO_RETVAL);
@ -1200,12 +1196,18 @@ _cogl_wrap_prepare_for_draw (void)
w->current_program = program; w->current_program = program;
/* All of the uniforms are probably now out of date */ /* All of the uniforms are probably now out of date */
w->dirty_uniforms = COGL_GLES2_DIRTY_ALL; 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; w->settings_dirty = FALSE;
} }
else 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 */ /* Make sure all of the uniforms are up to date */
if (w->dirty_uniforms) if (w->dirty_uniforms)
@ -1284,7 +1286,7 @@ _cogl_wrap_prepare_for_draw (void)
w->dirty_uniforms = 0; w->dirty_uniforms = 0;
} }
if (w->dirty_custom_uniforms) if (dirty_custom_uniforms)
{ {
int i; int i;
@ -1294,21 +1296,20 @@ _cogl_wrap_prepare_for_draw (void)
= _cogl_program_pointer_from_handle (w->settings.user_program); = _cogl_program_pointer_from_handle (w->settings.user_program);
const char *uniform_name; const char *uniform_name;
for (i = 0; i < COGL_GLES2_NUM_CUSTOM_UNIFORMS; i++) for (i = 0; i < COGL_PROGRAM_NUM_CUSTOM_UNIFORMS; i++)
if ((w->dirty_custom_uniforms & (1 << i)) if ((dirty_custom_uniforms & (1 << i))
&& (uniform_name = user_program->custom_uniform_names[i])) && (uniform_name = user_program->custom_uniform_names[i]))
{ {
if (program->custom_uniforms[i] if (program->custom_gl_uniforms[i]
== COGL_GLES2_UNBOUND_CUSTOM_UNIFORM) == COGL_PROGRAM_UNBOUND_CUSTOM_UNIFORM)
program->custom_uniforms[i] program->custom_gl_uniforms[i]
= glGetUniformLocation (program->program, uniform_name); = glGetUniformLocation (program->program, uniform_name);
if (program->custom_uniforms[i] >= 0) if (program->custom_gl_uniforms[i] >= 0)
cogl_gles2_do_set_uniform (program->custom_uniforms[i], cogl_gles2_do_set_uniform (program->custom_gl_uniforms[i],
&w->custom_uniforms[i]); &user_program->custom_uniforms[i]);
} }
user_program->dirty_custom_uniforms = 0;
} }
w->dirty_custom_uniforms = 0;
} }
if (w->dirty_attribute_pointers if (w->dirty_attribute_pointers

View File

@ -26,6 +26,7 @@
#include "cogl.h" /* needed for gl header include */ #include "cogl.h" /* needed for gl header include */
#include "cogl-internal.h" #include "cogl-internal.h"
#include "cogl-program.h"
G_BEGIN_DECLS G_BEGIN_DECLS
@ -44,9 +45,6 @@ typedef struct _CoglGles2WrapperSettings CoglGles2WrapperSettings;
typedef struct _CoglGles2WrapperProgram CoglGles2WrapperProgram; typedef struct _CoglGles2WrapperProgram CoglGles2WrapperProgram;
typedef struct _CoglGles2WrapperShader CoglGles2WrapperShader; typedef struct _CoglGles2WrapperShader CoglGles2WrapperShader;
#define COGL_GLES2_NUM_CUSTOM_UNIFORMS 16
#define COGL_GLES2_UNBOUND_CUSTOM_UNIFORM -2
/* Must be a power of two */ /* Must be a power of two */
#define COGL_GLES2_MODELVIEW_STACK_SIZE 32 #define COGL_GLES2_MODELVIEW_STACK_SIZE 32
#define COGL_GLES2_PROJECTION_STACK_SIZE 2 #define COGL_GLES2_PROJECTION_STACK_SIZE 2
@ -190,7 +188,7 @@ struct _CoglGles2Wrapper
/* Whether the settings have changed since the last draw */ /* Whether the settings have changed since the last draw */
gboolean settings_dirty; gboolean settings_dirty;
/* Uniforms that have changed since the last draw */ /* 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 */ /* Attribute pointers that have changed since the last draw */
int dirty_attribute_pointers; int dirty_attribute_pointers;
@ -214,13 +212,14 @@ struct _CoglGles2Wrapper
GLfloat fog_end; GLfloat fog_end;
GLfloat fog_color[4]; GLfloat fog_color[4];
GLfloat point_size; GLfloat point_size;
CoglBoxedValue custom_uniforms[COGL_GLES2_NUM_CUSTOM_UNIFORMS];
}; };
struct _CoglGles2WrapperProgram struct _CoglGles2WrapperProgram
{ {
GLuint program; GLuint program;
CoglProgram *user_program;
/* The settings that were used to generate this combination */ /* The settings that were used to generate this combination */
CoglGles2WrapperSettings settings; CoglGles2WrapperSettings settings;
@ -230,7 +229,7 @@ struct _CoglGles2WrapperProgram
/* The uniforms for this program */ /* The uniforms for this program */
CoglGles2WrapperUniforms uniforms; CoglGles2WrapperUniforms uniforms;
GLint custom_uniforms[COGL_GLES2_NUM_CUSTOM_UNIFORMS]; GLint custom_gl_uniforms[COGL_PROGRAM_NUM_CUSTOM_UNIFORMS];
}; };
struct _CoglGles2WrapperShader struct _CoglGles2WrapperShader

View File

@ -63,9 +63,13 @@ _cogl_program_free (CoglProgram *program)
ctx->drv.gles2.settings_dirty = TRUE; ctx->drv.gles2.settings_dirty = TRUE;
} }
for (i = 0; i < COGL_GLES2_NUM_CUSTOM_UNIFORMS; 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_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); g_slice_free (CoglProgram, program);
} }
@ -75,10 +79,7 @@ cogl_create_program (void)
{ {
CoglProgram *program; CoglProgram *program;
program = g_slice_new (CoglProgram); program = g_slice_new0 (CoglProgram);
program->attached_shaders = NULL;
memset (program->custom_uniform_names, 0,
COGL_GLES2_NUM_CUSTOM_UNIFORMS * sizeof (char *));
return _cogl_program_handle_new (program); 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 with a new fixed functionality shader. Instead we make our own
mapping of uniform numbers and cache the names */ mapping of uniform numbers and cache the names */
for (i = 0; program->custom_uniform_names[i] 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)) if (!strcmp (program->custom_uniform_names[i], uniform_name))
return i; 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); program->custom_uniform_names[i] = g_strdup (uniform_name);
return i; return i;
@ -190,12 +191,18 @@ cogl_program_uniform_x (int uniform_no,
gsize value_size, gsize value_size,
gconstpointer value) gconstpointer value)
{ {
CoglProgram *program;
_COGL_GET_CONTEXT (ctx, NO_RETVAL); _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) && 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) if (count == 1)
{ {
@ -224,7 +231,7 @@ cogl_program_uniform_x (int uniform_no,
bv->size = size; bv->size = size;
bv->count = count; 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, gboolean transpose,
const GLfloat *value) const GLfloat *value)
{ {
CoglProgram *program;
CoglBoxedValue *bv; CoglBoxedValue *bv;
_COGL_GET_CONTEXT (ctx, NO_RETVAL); _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, cogl_program_uniform_x (uniform_no, size, count, COGL_BOXED_MATRIX,
sizeof (float) * size * size, value); sizeof (float) * size * size, value);

View File

@ -27,6 +27,9 @@
#include "cogl-gles2-wrapper.h" #include "cogl-gles2-wrapper.h"
#include "cogl-handle.h" #include "cogl-handle.h"
#define COGL_PROGRAM_NUM_CUSTOM_UNIFORMS 16
#define COGL_PROGRAM_UNBOUND_CUSTOM_UNIFORM -2
typedef struct _CoglProgram CoglProgram; typedef struct _CoglProgram CoglProgram;
struct _CoglProgram struct _CoglProgram
@ -35,7 +38,13 @@ struct _CoglProgram
GSList *attached_shaders; 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); CoglProgram *_cogl_program_pointer_from_handle (CoglHandle handle);