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>
This commit is contained in:
Neil Roberts 2011-08-12 16:29:30 +01:00 committed by Robert Bragg
parent 769c8472dd
commit e7f374d799

View File

@ -337,10 +337,9 @@ add_constant_lookup (CoglPipelineShaderState *shader_state,
} }
static void static void
add_texture_lookup (CoglPipelineShaderState *shader_state, ensure_texture_lookup_generated (CoglPipelineShaderState *shader_state,
CoglPipeline *pipeline, CoglPipeline *pipeline,
CoglPipelineLayer *layer, CoglPipelineLayer *layer)
const char *swizzle)
{ {
CoglHandle texture; CoglHandle texture;
int unit_index = _cogl_pipeline_layer_get_unit_index (layer); 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); _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))) if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_DISABLE_TEXTURING)))
{ {
g_string_append (shader_state->source, g_string_append (shader_state->source,
"vec4 (1.0, 1.0, 1.0, 1.0)."); "vec4 (1.0, 1.0, 1.0, 1.0);\n");
g_string_append (shader_state->source, swizzle);
return; return;
} }
@ -400,15 +407,11 @@ add_texture_lookup (CoglPipelineShaderState *shader_state,
} }
} }
/* Create a sampler uniform for this layer if we haven't already */ /* Create a sampler uniform */
if (!shader_state->unit_state[unit_index].sampled)
{
g_string_append_printf (shader_state->header, g_string_append_printf (shader_state->header,
"uniform sampler%s _cogl_sampler_%i;\n", "uniform sampler%s _cogl_sampler_%i;\n",
target_string, target_string,
unit_index); unit_index);
shader_state->unit_state[unit_index].sampled = TRUE;
}
g_string_append_printf (shader_state->source, g_string_append_printf (shader_state->source,
"texture%s (_cogl_sampler_%i, ", "texture%s (_cogl_sampler_%i, ",
@ -433,31 +436,7 @@ add_texture_lookup (CoglPipelineShaderState *shader_state,
"cogl_tex_coord_in[%d].%s", "cogl_tex_coord_in[%d].%s",
unit_index, tex_coord_swizzle); unit_index, tex_coord_swizzle);
g_string_append_printf (shader_state->source, ").%s", swizzle); g_string_append (shader_state->source, ");\n");
}
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;
} }
static void static void
@ -492,9 +471,9 @@ add_arg (CoglPipelineShaderState *shader_state,
switch (src) switch (src)
{ {
case COGL_PIPELINE_COMBINE_SOURCE_TEXTURE: case COGL_PIPELINE_COMBINE_SOURCE_TEXTURE:
add_texture_lookup (shader_state, g_string_append_printf (shader_source,
pipeline, "texel%i.%s",
layer, _cogl_pipeline_layer_get_unit_index (layer),
swizzle); swizzle);
break; break;
@ -519,6 +498,70 @@ add_arg (CoglPipelineShaderState *shader_state,
g_string_append_printf (shader_source, "cogl_color_in.%s", swizzle); g_string_append_printf (shader_source, "cogl_color_in.%s", swizzle);
break; break;
default:
if (src >= COGL_PIPELINE_COMBINE_SOURCE_TEXTURE0 &&
src < COGL_PIPELINE_COMBINE_SOURCE_TEXTURE0 + 32)
g_string_append_printf (shader_source,
"texel%i.%s",
src - COGL_PIPELINE_COMBINE_SOURCE_TEXTURE0,
swizzle);
break;
}
g_string_append_c (shader_source, ')');
}
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;
}
static void
ensure_arg_generated (CoglPipeline *pipeline,
CoglPipelineLayer *layer,
int previous_layer_index,
CoglPipelineCombineSource src)
{
CoglPipelineShaderState *shader_state = get_shader_state (pipeline);
switch (src)
{
case COGL_PIPELINE_COMBINE_SOURCE_CONSTANT:
case COGL_PIPELINE_COMBINE_SOURCE_PRIMARY_COLOR:
/* These don't involve any other layers */
break;
case COGL_PIPELINE_COMBINE_SOURCE_PREVIOUS:
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: default:
if (src >= COGL_PIPELINE_COMBINE_SOURCE_TEXTURE0 && if (src >= COGL_PIPELINE_COMBINE_SOURCE_TEXTURE0 &&
src < COGL_PIPELINE_COMBINE_SOURCE_TEXTURE0 + 32) src < COGL_PIPELINE_COMBINE_SOURCE_TEXTURE0 + 32)
@ -532,37 +575,12 @@ add_arg (CoglPipelineShaderState *shader_state,
find_pipeline_layer_cb, find_pipeline_layer_cb,
&data); &data);
add_texture_lookup (shader_state, ensure_texture_lookup_generated (shader_state,
pipeline, pipeline,
data.layer, data.layer);
swizzle);
} }
break; break;
} }
g_string_append_c (shader_source, ')');
}
static void
ensure_arg_generated (CoglPipeline *pipeline,
CoglPipelineLayer *layer,
int previous_layer_index,
CoglPipelineCombineSource src)
{
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;
case COGL_PIPELINE_COMBINE_SOURCE_PREVIOUS:
if (previous_layer_index >= 0)
ensure_layer_generated (pipeline, previous_layer_index);
break;
}
} }
static void static void