material: Bail out faster if re-flushing unchanged material

This allows _cogl_material_flush_gl_state to bail out faster if
repeatedly asked to flush the same material and we can see the material
hasn't changed.

Since we can rely on the material age incrementing when any material
property changes or any associated layer property changes then we can
track the age of the material after flushing so it can be compared with
the age of the material if it is subsequently re-flushed. If the age is
the same we only have to re-assert the texture object state.
This commit is contained in:
Robert Bragg 2010-10-26 19:02:04 +01:00
parent bbf27e6b28
commit 35ddc5407e
2 changed files with 15 additions and 2 deletions

View File

@ -106,6 +106,7 @@ typedef struct
CoglMaterial *current_material; CoglMaterial *current_material;
unsigned long current_material_changes_since_flush; unsigned long current_material_changes_since_flush;
gboolean current_material_skip_gl_color; gboolean current_material_skip_gl_color;
unsigned long current_material_age;
GArray *material0_nodes; GArray *material0_nodes;
GArray *material1_nodes; GArray *material1_nodes;

View File

@ -1040,7 +1040,7 @@ _cogl_material_flush_gl_state (CoglMaterial *material,
{ {
unsigned long materials_difference; unsigned long materials_difference;
int n_layers; int n_layers;
unsigned long *layer_differences = NULL; unsigned long *layer_differences;
int i; int i;
CoglTextureUnit *unit1; CoglTextureUnit *unit1;
@ -1055,7 +1055,14 @@ _cogl_material_flush_gl_state (CoglMaterial *material,
COGL_TIMER_START (_cogl_uprof_context, material_flush_timer); COGL_TIMER_START (_cogl_uprof_context, material_flush_timer);
if (ctx->current_material == material) if (ctx->current_material == material)
materials_difference = ctx->current_material_changes_since_flush; {
/* Bail out asap if we've been asked to re-flush the already current
* material and we can see the material hasn't changed */
if (ctx->current_material_age == material->age)
goto done;
materials_difference = ctx->current_material_changes_since_flush;
}
else if (ctx->current_material) else if (ctx->current_material)
{ {
materials_difference = ctx->current_material_changes_since_flush; materials_difference = ctx->current_material_changes_since_flush;
@ -1079,6 +1086,8 @@ _cogl_material_flush_gl_state (CoglMaterial *material,
compare_layer_differences_cb, compare_layer_differences_cb,
&state); &state);
} }
else
layer_differences = NULL;
/* First flush everything that's the same regardless of which /* First flush everything that's the same regardless of which
* material backend is being used... * material backend is being used...
@ -1174,6 +1183,9 @@ _cogl_material_flush_gl_state (CoglMaterial *material,
ctx->current_material = material; ctx->current_material = material;
ctx->current_material_changes_since_flush = 0; ctx->current_material_changes_since_flush = 0;
ctx->current_material_skip_gl_color = skip_gl_color; ctx->current_material_skip_gl_color = skip_gl_color;
ctx->current_material_age = material->age;
done:
/* Handle the fact that OpenGL associates texture filter and wrap /* Handle the fact that OpenGL associates texture filter and wrap
* modes with the texture objects not the texture units... */ * modes with the texture objects not the texture units... */