diff options
author | Neil Roberts <neil@linux.intel.com> | 2011-08-12 16:29:30 +0100 |
---|---|---|
committer | Robert Bragg <robert@linux.intel.com> | 2011-09-05 19:02:04 +0100 |
commit | e7f374d7995eed42df5f84a8831f820dcf8ab72b (patch) | |
tree | 63c6e6d7345b908ed544e1cd67b3e3ac3f1abad6 | |
parent | 769c8472dd36064dd39510922265a43e25276ea8 (diff) | |
download | cogl-e7f374d7995eed42df5f84a8831f820dcf8ab72b.tar.gz |
cogl-pipeline-fragend-glsl: Cache the results of texture lookups
Whenever a texture lookup is performed for a layer the result is now
stored in a variable and used repeatedly instead of generating the
code for the lookup every time it is accessed. This means for example
when using the INTERPOLATE function with a texture lookup for the
third parameter it will only generate one texture lookup instead of
two.
https://bugzilla.gnome.org/show_bug.cgi?id=656426
Reviewed-by: Robert Bragg <robert@linux.intel.com>
-rw-r--r-- | cogl/cogl-pipeline-fragend-glsl.c | 138 |
1 files changed, 78 insertions, 60 deletions
diff --git a/cogl/cogl-pipeline-fragend-glsl.c b/cogl/cogl-pipeline-fragend-glsl.c index e317852f..48e523bd 100644 --- a/cogl/cogl-pipeline-fragend-glsl.c +++ b/cogl/cogl-pipeline-fragend-glsl.c @@ -337,10 +337,9 @@ add_constant_lookup (CoglPipelineShaderState *shader_state, } static void -add_texture_lookup (CoglPipelineShaderState *shader_state, - CoglPipeline *pipeline, - CoglPipelineLayer *layer, - const char *swizzle) +ensure_texture_lookup_generated (CoglPipelineShaderState *shader_state, + CoglPipeline *pipeline, + CoglPipelineLayer *layer) { CoglHandle texture; int unit_index = _cogl_pipeline_layer_get_unit_index (layer); @@ -348,11 +347,19 @@ add_texture_lookup (CoglPipelineShaderState *shader_state, _COGL_GET_CONTEXT (ctx, NO_RETVAL); + if (shader_state->unit_state[unit_index].sampled) + return; + + shader_state->unit_state[unit_index].sampled = TRUE; + + g_string_append_printf (shader_state->source, + " vec4 texel%i = ", + unit_index); + if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_DISABLE_TEXTURING))) { g_string_append (shader_state->source, - "vec4 (1.0, 1.0, 1.0, 1.0)."); - g_string_append (shader_state->source, swizzle); + "vec4 (1.0, 1.0, 1.0, 1.0);\n"); return; } @@ -400,15 +407,11 @@ add_texture_lookup (CoglPipelineShaderState *shader_state, } } - /* Create a sampler uniform for this layer if we haven't already */ - if (!shader_state->unit_state[unit_index].sampled) - { - g_string_append_printf (shader_state->header, - "uniform sampler%s _cogl_sampler_%i;\n", - target_string, - unit_index); - shader_state->unit_state[unit_index].sampled = TRUE; - } + /* Create a sampler uniform */ + g_string_append_printf (shader_state->header, + "uniform sampler%s _cogl_sampler_%i;\n", + target_string, + unit_index); g_string_append_printf (shader_state->source, "texture%s (_cogl_sampler_%i, ", @@ -433,31 +436,7 @@ add_texture_lookup (CoglPipelineShaderState *shader_state, "cogl_tex_coord_in[%d].%s", unit_index, tex_coord_swizzle); - g_string_append_printf (shader_state->source, ").%s", swizzle); -} - -typedef struct -{ - int unit_index; - CoglPipelineLayer *layer; -} FindPipelineLayerData; - -static gboolean -find_pipeline_layer_cb (CoglPipelineLayer *layer, - void *user_data) -{ - FindPipelineLayerData *data = user_data; - int unit_index; - - unit_index = _cogl_pipeline_layer_get_unit_index (layer); - - if (unit_index == data->unit_index) - { - data->layer = layer; - return FALSE; - } - - return TRUE; + g_string_append (shader_state->source, ");\n"); } static void @@ -492,10 +471,10 @@ add_arg (CoglPipelineShaderState *shader_state, switch (src) { case COGL_PIPELINE_COMBINE_SOURCE_TEXTURE: - add_texture_lookup (shader_state, - pipeline, - layer, - swizzle); + g_string_append_printf (shader_source, + "texel%i.%s", + _cogl_pipeline_layer_get_unit_index (layer), + swizzle); break; case COGL_PIPELINE_COMBINE_SOURCE_CONSTANT: @@ -522,25 +501,39 @@ add_arg (CoglPipelineShaderState *shader_state, default: if (src >= COGL_PIPELINE_COMBINE_SOURCE_TEXTURE0 && src < COGL_PIPELINE_COMBINE_SOURCE_TEXTURE0 + 32) - { - FindPipelineLayerData data; + g_string_append_printf (shader_source, + "texel%i.%s", + src - COGL_PIPELINE_COMBINE_SOURCE_TEXTURE0, + swizzle); + break; + } - data.unit_index = src - COGL_PIPELINE_COMBINE_SOURCE_TEXTURE0; - data.layer = layer; + g_string_append_c (shader_source, ')'); +} - _cogl_pipeline_foreach_layer_internal (pipeline, - find_pipeline_layer_cb, - &data); - add_texture_lookup (shader_state, - pipeline, - data.layer, - swizzle); - } - break; +typedef struct +{ + int unit_index; + CoglPipelineLayer *layer; +} FindPipelineLayerData; + +static gboolean +find_pipeline_layer_cb (CoglPipelineLayer *layer, + void *user_data) +{ + FindPipelineLayerData *data = user_data; + int unit_index; + + unit_index = _cogl_pipeline_layer_get_unit_index (layer); + + if (unit_index == data->unit_index) + { + data->layer = layer; + return FALSE; } - g_string_append_c (shader_source, ')'); + return TRUE; } static void @@ -549,12 +542,12 @@ ensure_arg_generated (CoglPipeline *pipeline, int previous_layer_index, CoglPipelineCombineSource src) { + CoglPipelineShaderState *shader_state = get_shader_state (pipeline); + switch (src) { - case COGL_PIPELINE_COMBINE_SOURCE_TEXTURE: case COGL_PIPELINE_COMBINE_SOURCE_CONSTANT: case COGL_PIPELINE_COMBINE_SOURCE_PRIMARY_COLOR: - default: /* These don't involve any other layers */ break; @@ -562,6 +555,31 @@ ensure_arg_generated (CoglPipeline *pipeline, if (previous_layer_index >= 0) ensure_layer_generated (pipeline, previous_layer_index); break; + + case COGL_PIPELINE_COMBINE_SOURCE_TEXTURE: + ensure_texture_lookup_generated (shader_state, + pipeline, + layer); + break; + + default: + if (src >= COGL_PIPELINE_COMBINE_SOURCE_TEXTURE0 && + src < COGL_PIPELINE_COMBINE_SOURCE_TEXTURE0 + 32) + { + FindPipelineLayerData data; + + data.unit_index = src - COGL_PIPELINE_COMBINE_SOURCE_TEXTURE0; + data.layer = layer; + + _cogl_pipeline_foreach_layer_internal (pipeline, + find_pipeline_layer_cb, + &data); + + ensure_texture_lookup_generated (shader_state, + pipeline, + data.layer); + } + break; } } |