diff --git a/cogl/cogl-pipeline-snippet.c b/cogl/cogl-pipeline-snippet.c index a5d1340b2..33bf22346 100644 --- a/cogl/cogl-pipeline-snippet.c +++ b/cogl/cogl-pipeline-snippet.c @@ -40,17 +40,66 @@ void _cogl_pipeline_snippet_generate_code (const CoglPipelineSnippetData *data) { - CoglPipelineSnippet *snippet; + CoglPipelineSnippet *first_snippet, *snippet; int snippet_num = 0; int n_snippets = 0; + first_snippet = COGL_LIST_FIRST (data->snippets); + /* First count the number of snippets so we can easily tell when we're at the last one */ COGL_LIST_FOREACH (snippet, data->snippets, list_node) if (snippet->snippet->hook == data->hook) - n_snippets++; + { + /* Don't bother processing any previous snippets if we reach + one that has a replacement */ + if (snippet->snippet->replace) + { + n_snippets = 1; + first_snippet = snippet; + } + else + n_snippets++; + } - COGL_LIST_FOREACH (snippet, data->snippets, list_node) + /* If there weren't any snippets then generate a stub function with + the final name */ + if (n_snippets == 0) + { + if (data->return_type) + g_string_append_printf (data->source_buf, + "\n" + "%s\n" + "%s (%s)\n" + "{\n" + " return %s (%s);\n" + "}\n", + data->return_type, + data->final_name, + data->argument_declarations ? + data->argument_declarations : "", + data->chain_function, + data->arguments ? data->arguments : ""); + else + g_string_append_printf (data->source_buf, + "\n" + "void\n" + "%s (%s)\n" + "{\n" + " %s (%s);\n" + "}\n", + data->final_name, + data->argument_declarations ? + data->argument_declarations : "", + data->chain_function, + data->arguments ? data->arguments : ""); + + return; + } + + for (snippet = first_snippet, snippet_num = 0; + snippet_num < n_snippets; + snippet = COGL_LIST_NEXT (snippet, list_node), snippet_num++) if (snippet->snippet->hook == data->hook) { const char *source; @@ -130,42 +179,7 @@ _cogl_pipeline_snippet_generate_code (const CoglPipelineSnippetData *data) data->return_variable); g_string_append (data->source_buf, "}\n"); - - snippet_num++; } - - /* If there weren't any snippets then generate a stub function with - the final name */ - if (snippet_num == 0) - { - if (data->return_type) - g_string_append_printf (data->source_buf, - "\n" - "%s\n" - "%s (%s)\n" - "{\n" - " return %s (%s);\n" - "}\n", - data->return_type, - data->final_name, - data->argument_declarations ? - data->argument_declarations : "", - data->chain_function, - data->arguments ? data->arguments : ""); - else - g_string_append_printf (data->source_buf, - "\n" - "void\n" - "%s (%s)\n" - "{\n" - " %s (%s);\n" - "}\n", - data->final_name, - data->argument_declarations ? - data->argument_declarations : "", - data->chain_function, - data->arguments ? data->arguments : ""); - } } static void diff --git a/tests/conform/test-snippets.c b/tests/conform/test-snippets.c index b53aeca4b..1722cb4e9 100644 --- a/tests/conform/test-snippets.c +++ b/tests/conform/test-snippets.c @@ -232,6 +232,28 @@ paint (TestState *state) cogl_object_unref (snippet); + /* Test replacing a previous snippet */ + pipeline = create_texture_pipeline (); + + snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_FRAGMENT, + NULL, + "cogl_color_out = vec4 (0.5, 0.5, 0.5, 1.0);"); + cogl_pipeline_add_snippet (pipeline, snippet); + cogl_object_unref (snippet); + + snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_FRAGMENT, NULL, NULL); + cogl_snippet_set_pre (snippet, "cogl_color_out = vec4 (1.0, 1.0, 1.0, 1.0);"); + cogl_snippet_set_replace (snippet, + "cogl_color_out *= vec4 (1.0, 0.0, 0.0, 1.0);"); + cogl_pipeline_add_snippet (pipeline, snippet); + cogl_object_unref (snippet); + + cogl_push_source (pipeline); + cogl_rectangle_with_texture_coords (100, 0, 110, 10, + 0, 0, 0, 0); + cogl_pop_source (); + cogl_object_unref (pipeline); + /* Sanity check modifying the snippet */ snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_FRAGMENT, "foo", "bar"); g_assert_cmpstr (cogl_snippet_get_declarations (snippet), ==, "foo"); @@ -280,6 +302,7 @@ validate_result (void) test_utils_check_pixel (65, 5, 0x00ff00ff); test_utils_check_pixel (75, 5, 0x808000ff); test_utils_check_pixel (85, 5, 0x00ffffff); + test_utils_check_pixel (105, 5, 0xff0000ff); } void