[Cogl] [PATCH 1/5] Conformance test to check whether the pipeline cache holds textures

Neil Roberts neil at linux.intel.com
Tue Mar 26 11:36:19 PDT 2013


Currently when a unique pipeline is created and added to the pipeline
cache that pipeline will live forever which includes keeping a
reference to any large resources that the pipeline has such as
textures. These textures don't actually need to be kept for the
pipeline to be used as a key in the hash table so ideally we wouldn't
do this. This test case tries rendering with a pipeline that has
textures and then checks whether the textures are successfully
destroyed after the pipeline is unreffed. The test is currently marked
as a known failure because the pipeline cache will prevent them from
being destroyed.
---
 tests/conform/Makefile.am                          |  1 +
 tests/conform/test-conform-main.c                  |  2 +
 tests/conform/test-pipeline-cache-unrefs-texture.c | 92 ++++++++++++++++++++++
 3 files changed, 95 insertions(+)
 create mode 100644 tests/conform/test-pipeline-cache-unrefs-texture.c

diff --git a/tests/conform/Makefile.am b/tests/conform/Makefile.am
index 6650766..e810a0c 100644
--- a/tests/conform/Makefile.am
+++ b/tests/conform/Makefile.am
@@ -64,6 +64,7 @@ test_sources = \
 	test-framebuffer-get-bits.c \
 	test-primitive-and-journal.c \
 	test-copy-replace-texture.c \
+	test-pipeline-cache-unrefs-texture.c \
 	$(NULL)
 
 test_conformance_SOURCES = $(common_sources) $(test_sources)
diff --git a/tests/conform/test-conform-main.c b/tests/conform/test-conform-main.c
index 82d631e..2dd5655 100644
--- a/tests/conform/test-conform-main.c
+++ b/tests/conform/test-conform-main.c
@@ -122,6 +122,8 @@ main (int argc, char **argv)
 
   ADD_TEST (test_copy_replace_texture, 0, 0);
 
+  ADD_TEST (test_pipeline_cache_unrefs_texture, 0, TEST_KNOWN_FAILURE);
+
   UNPORTED_TEST (test_viewport);
 
   ADD_TEST (test_gles2_context, TEST_REQUIREMENT_GLES2_CONTEXT, 0);
diff --git a/tests/conform/test-pipeline-cache-unrefs-texture.c b/tests/conform/test-pipeline-cache-unrefs-texture.c
new file mode 100644
index 0000000..ccd02e7
--- /dev/null
+++ b/tests/conform/test-pipeline-cache-unrefs-texture.c
@@ -0,0 +1,92 @@
+#include <cogl/cogl.h>
+
+#include "test-utils.h"
+
+/* Keep track of the number of textures that we've created and are
+ * still alive */
+static int destroyed_texture_count = 0;
+
+#define N_TEXTURES 3
+
+static void
+free_texture_cb (void *user_data)
+{
+  destroyed_texture_count++;
+}
+
+static CoglTexture *
+create_texture (void)
+{
+  static const guint8 data[] =
+    { 0xff, 0xff, 0xff, 0xff };
+  static CoglUserDataKey texture_data_key;
+  CoglTexture2D *tex_2d;
+
+  tex_2d = cogl_texture_2d_new_from_data (test_ctx,
+                                          1, 1, /* width / height */
+                                          COGL_PIXEL_FORMAT_RGBA_8888_PRE,
+                                          COGL_PIXEL_FORMAT_ANY,
+                                          4, /* rowstride */
+                                          data,
+                                          NULL);
+
+  /* Set some user data on the texture so we can track when it has
+   * been destroyed */
+  cogl_object_set_user_data (COGL_OBJECT (tex_2d),
+                             &texture_data_key,
+                             GINT_TO_POINTER (1),
+                             free_texture_cb);
+
+  return COGL_TEXTURE (tex_2d);
+}
+
+void
+test_pipeline_cache_unrefs_texture (void)
+{
+  CoglPipeline *pipeline = cogl_pipeline_new (test_ctx);
+  CoglPipeline *simple_pipeline;
+  int i;
+
+  /* Create a pipeline with three texture layers. That way we can be
+   * pretty sure the pipeline will cause a unique shader to be
+   * generated in the cache */
+  for (i = 0; i < N_TEXTURES; i++)
+    {
+      CoglTexture *tex = create_texture ();
+      cogl_pipeline_set_layer_texture (pipeline, i, tex);
+      cogl_object_unref (tex);
+    }
+
+  /* Draw something with the pipeline to ensure it gets into the
+   * pipeline cache */
+  cogl_framebuffer_draw_rectangle (test_fb,
+                                   pipeline,
+                                   0, 0, 10, 10);
+  cogl_framebuffer_finish (test_fb);
+
+  /* Draw something else so that it is no longer the current flushed
+   * pipeline, and the units have a different texture bound */
+  simple_pipeline = cogl_pipeline_new (test_ctx);
+  for (i = 0; i < N_TEXTURES; i++)
+    {
+      CoglColor combine_constant;
+      cogl_color_init_from_4ub (&combine_constant, i, 0, 0, 255);
+      cogl_pipeline_set_layer_combine_constant (simple_pipeline,
+                                                i,
+                                                &combine_constant);
+    }
+  cogl_framebuffer_draw_rectangle (test_fb, simple_pipeline, 0, 0, 10, 10);
+  cogl_framebuffer_finish (test_fb);
+  cogl_object_unref (simple_pipeline);
+
+  g_assert_cmpint (destroyed_texture_count, ==, 0);
+
+  /* Destroy the pipeline. This should immediately cause the textures
+   * to be freed */
+  cogl_object_unref (pipeline);
+
+  g_assert_cmpint (destroyed_texture_count, ==, N_TEXTURES);
+
+  if (cogl_test_verbose ())
+    g_print ("OK\n");
+}
-- 
1.7.11.3.g3c3efa5



More information about the Cogl mailing list