From 4905a55f64f859c56ca99c97ae50124b60989f4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Fri, 5 Aug 2022 10:55:42 +0200 Subject: [PATCH] cogl/pipeline-cache: Move unit test to its own file Part-of: --- cogl/cogl/cogl-pipeline-cache-private.h | 42 +++++++++ cogl/cogl/cogl-pipeline-cache.c | 100 ++------------------- cogl/cogl/meson.build | 1 + src/tests/cogl/unit/meson.build | 1 + src/tests/cogl/unit/test-pipeline-cache.c | 104 ++++++++++++++++++++++ 5 files changed, 155 insertions(+), 93 deletions(-) create mode 100644 cogl/cogl/cogl-pipeline-cache-private.h create mode 100644 src/tests/cogl/unit/test-pipeline-cache.c diff --git a/cogl/cogl/cogl-pipeline-cache-private.h b/cogl/cogl/cogl-pipeline-cache-private.h new file mode 100644 index 000000000..9e0f480f8 --- /dev/null +++ b/cogl/cogl/cogl-pipeline-cache-private.h @@ -0,0 +1,42 @@ +/* + * Cogl + * + * A Low Level GPU Graphics and Utilities API + * + * Copyright (C) 2022 Red Hat Inc. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef COGL_PIPELINE_CACHE_PRIVATE_H +#define COGL_PIPELINE_CACHE_PRIVATE_H + +#include "cogl/cogl-macros.h" +#include "cogl/cogl-pipeline-hash-table.h" + +COGL_EXPORT_TEST +CoglPipelineHashTable * cogl_pipeline_cache_get_fragment_hash (CoglPipelineCache *cache); + + +COGL_EXPORT_TEST +CoglPipelineHashTable * cogl_pipeline_cache_get_combined_hash (CoglPipelineCache *cache); + +#endif /* COGL_PIPELINE_CACHE_PRIVATE_H */ diff --git a/cogl/cogl/cogl-pipeline-cache.c b/cogl/cogl/cogl-pipeline-cache.c index a8e3b8a19..164c44e2c 100644 --- a/cogl/cogl/cogl-pipeline-cache.c +++ b/cogl/cogl/cogl-pipeline-cache.c @@ -33,11 +33,10 @@ #include "cogl-config.h" -#include - #include "cogl-context-private.h" #include "cogl-pipeline-private.h" #include "cogl-pipeline-cache.h" +#include "cogl-pipeline-cache-private.h" #include "cogl-pipeline-hash-table.h" struct _CoglPipelineCache @@ -116,99 +115,14 @@ _cogl_pipeline_cache_get_combined_template (CoglPipelineCache *cache, key_pipeline); } -#ifdef ENABLE_UNIT_TESTS - -static void -create_pipelines (CoglPipeline **pipelines, - int n_pipelines) +CoglPipelineHashTable * +cogl_pipeline_cache_get_fragment_hash (CoglPipelineCache *cache) { - int i; - - for (i = 0; i < n_pipelines; i++) - { - char *source = g_strdup_printf (" cogl_color_out = " - "vec4 (%f, 0.0, 0.0, 1.0);\n", - i / 255.0f); - CoglSnippet *snippet = - cogl_snippet_new (COGL_SNIPPET_HOOK_FRAGMENT, - NULL, /* declarations */ - source); - - g_free (source); - - pipelines[i] = cogl_pipeline_new (test_ctx); - cogl_pipeline_add_snippet (pipelines[i], snippet); - cogl_object_unref (snippet); - } - - /* Test that drawing with them works. This should create the entries - * in the cache */ - for (i = 0; i < n_pipelines; i++) - { - cogl_framebuffer_draw_rectangle (test_fb, - pipelines[i], - i, 0, - i + 1, 1); - test_utils_check_pixel_rgb (test_fb, i, 0, i, 0, 0); - } - + return &cache->fragment_hash; } -UNIT_TEST (check_pipeline_pruning, - 0, /* requirements */ - 0 /* no failure cases */) +CoglPipelineHashTable * +cogl_pipeline_cache_get_combined_hash (CoglPipelineCache *cache) { - CoglPipeline *pipelines[18]; - int fb_width, fb_height; - CoglPipelineHashTable *fragment_hash = - &test_ctx->pipeline_cache->fragment_hash; - CoglPipelineHashTable *combined_hash = - &test_ctx->pipeline_cache->combined_hash; - int i; - - fb_width = cogl_framebuffer_get_width (test_fb); - fb_height = cogl_framebuffer_get_height (test_fb); - - cogl_framebuffer_orthographic (test_fb, - 0, 0, - fb_width, - fb_height, - -1, - 100); - - /* Create 18 unique pipelines. This should end up being more than - * the initial expected minimum size so it will trigger the garbage - * collection. However all of the pipelines will be in use so they - * won't be collected */ - create_pipelines (pipelines, 18); - - /* These pipelines should all have unique entries in the cache. We - * should have run the garbage collection once and at that point the - * expected minimum size would have been 17 */ - g_assert_cmpint (g_hash_table_size (fragment_hash->table), ==, 18); - g_assert_cmpint (g_hash_table_size (combined_hash->table), ==, 18); - g_assert_cmpint (fragment_hash->expected_min_size, ==, 17); - g_assert_cmpint (combined_hash->expected_min_size, ==, 17); - - /* Destroy the original pipelines and create some new ones. This - * should run the garbage collector again but this time the - * pipelines won't be in use so it should free some of them */ - for (i = 0; i < 18; i++) - cogl_object_unref (pipelines[i]); - - create_pipelines (pipelines, 18); - - /* The garbage collection should have freed half of the original 18 - * pipelines which means there should now be 18*1.5 = 27 */ - g_assert_cmpint (g_hash_table_size (fragment_hash->table), ==, 27); - g_assert_cmpint (g_hash_table_size (combined_hash->table), ==, 27); - /* The 35th pipeline would have caused the garbage collection. At - * that point there would be 35-18=17 used unique pipelines. */ - g_assert_cmpint (fragment_hash->expected_min_size, ==, 17); - g_assert_cmpint (combined_hash->expected_min_size, ==, 17); - - for (i = 0; i < 18; i++) - cogl_object_unref (pipelines[i]); + return &cache->combined_hash; } - -#endif /* ENABLE_UNIT_TESTS */ diff --git a/cogl/cogl/meson.build b/cogl/cogl/meson.build index c2bb2e7d4..386f51d27 100644 --- a/cogl/cogl/meson.build +++ b/cogl/cogl/meson.build @@ -273,6 +273,7 @@ cogl_sources = [ 'cogl-glsl-shader-boilerplate.h', 'cogl-pipeline-snippet-private.h', 'cogl-pipeline-snippet.c', + 'cogl-pipeline-cache-private.h', 'cogl-pipeline-cache.h', 'cogl-pipeline-cache.c', 'cogl-pipeline-hash-table.h', diff --git a/src/tests/cogl/unit/meson.build b/src/tests/cogl/unit/meson.build index 021a5d16e..7b1046e99 100644 --- a/src/tests/cogl/unit/meson.build +++ b/src/tests/cogl/unit/meson.build @@ -1,5 +1,6 @@ cogl_unit_tests = [ 'test-bitmask', + 'test-pipeline-cache', ] test_env = environment() diff --git a/src/tests/cogl/unit/test-pipeline-cache.c b/src/tests/cogl/unit/test-pipeline-cache.c new file mode 100644 index 000000000..36b40f9ba --- /dev/null +++ b/src/tests/cogl/unit/test-pipeline-cache.c @@ -0,0 +1,104 @@ +#include "cogl-config.h" + +#include "cogl/cogl.h" +#include "cogl/cogl-pipeline-cache-private.h" +#include "cogl/cogl-pipeline-hash-table.h" +#include "tests/cogl-test-utils.h" + +static void +create_pipelines (CoglPipeline **pipelines, + int n_pipelines) +{ + int i; + + for (i = 0; i < n_pipelines; i++) + { + char fraction[G_ASCII_DTOSTR_BUF_SIZE]; + g_autofree char *source = NULL; + CoglSnippet *snippet; + + g_ascii_dtostr (fraction, sizeof (fraction), i / 255.0); + source = g_strdup_printf (" cogl_color_out = " + "vec4 (%s, 0.0, 0.0, 1.0);\n", + fraction); + snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_FRAGMENT, + NULL, /* declarations */ + source); + + pipelines[i] = cogl_pipeline_new (test_ctx); + cogl_pipeline_add_snippet (pipelines[i], snippet); + cogl_object_unref (snippet); + } + + /* Test that drawing with them works. This should create the entries + * in the cache */ + for (i = 0; i < n_pipelines; i++) + { + cogl_framebuffer_draw_rectangle (test_fb, + pipelines[i], + i, 0, + i + 1, 1); + test_utils_check_pixel_rgb (test_fb, i, 0, i, 0, 0); + } + +} + +static void +check_pipeline_pruning (void) +{ + CoglPipeline *pipelines[18]; + int fb_width, fb_height; + CoglPipelineHashTable *fragment_hash = + cogl_pipeline_cache_get_fragment_hash (test_ctx->pipeline_cache); + CoglPipelineHashTable *combined_hash = + cogl_pipeline_cache_get_combined_hash (test_ctx->pipeline_cache); + int i; + + fb_width = cogl_framebuffer_get_width (test_fb); + fb_height = cogl_framebuffer_get_height (test_fb); + + cogl_framebuffer_orthographic (test_fb, + 0, 0, + fb_width, + fb_height, + -1, + 100); + + /* Create 18 unique pipelines. This should end up being more than + * the initial expected minimum size so it will trigger the garbage + * collection. However all of the pipelines will be in use so they + * won't be collected */ + create_pipelines (pipelines, 18); + + /* These pipelines should all have unique entries in the cache. We + * should have run the garbage collection once and at that point the + * expected minimum size would have been 17 */ + g_assert_cmpint (g_hash_table_size (fragment_hash->table), ==, 18); + g_assert_cmpint (g_hash_table_size (combined_hash->table), ==, 18); + g_assert_cmpint (fragment_hash->expected_min_size, ==, 17); + g_assert_cmpint (combined_hash->expected_min_size, ==, 17); + + /* Destroy the original pipelines and create some new ones. This + * should run the garbage collector again but this time the + * pipelines won't be in use so it should free some of them */ + for (i = 0; i < 18; i++) + cogl_object_unref (pipelines[i]); + + create_pipelines (pipelines, 18); + + /* The garbage collection should have freed half of the original 18 + * pipelines which means there should now be 18*1.5 = 27 */ + g_assert_cmpint (g_hash_table_size (fragment_hash->table), ==, 27); + g_assert_cmpint (g_hash_table_size (combined_hash->table), ==, 27); + /* The 35th pipeline would have caused the garbage collection. At + * that point there would be 35-18=17 used unique pipelines. */ + g_assert_cmpint (fragment_hash->expected_min_size, ==, 17); + g_assert_cmpint (combined_hash->expected_min_size, ==, 17); + + for (i = 0; i < 18; i++) + cogl_object_unref (pipelines[i]); +} + +COGL_TEST_SUITE ( + g_test_add_func ("/pipeline-cache/pruning", check_pipeline_pruning); +)