1 #include <cogl/cogl.h>
2 
3 #include "test-declarations.h"
4 #include "test-utils.h"
5 
6 /* Keep track of the number of textures that we've created and are
7  * still alive */
8 static int destroyed_texture_count = 0;
9 
10 #define N_TEXTURES 3
11 
12 static void
free_texture_cb(void * user_data)13 free_texture_cb (void *user_data)
14 {
15   destroyed_texture_count++;
16 }
17 
18 static CoglTexture *
create_texture(void)19 create_texture (void)
20 {
21   static const guint8 data[] =
22     { 0xff, 0xff, 0xff, 0xff };
23   static CoglUserDataKey texture_data_key;
24   CoglTexture2D *tex_2d;
25 
26   tex_2d = cogl_texture_2d_new_from_data (test_ctx,
27                                           1, 1, /* width / height */
28                                           COGL_PIXEL_FORMAT_RGBA_8888_PRE,
29                                           4, /* rowstride */
30                                           data,
31                                           NULL);
32 
33   /* Set some user data on the texture so we can track when it has
34    * been destroyed */
35   cogl_object_set_user_data (COGL_OBJECT (tex_2d),
36                              &texture_data_key,
37                              GINT_TO_POINTER (1),
38                              free_texture_cb);
39 
40   return tex_2d;
41 }
42 
43 void
test_pipeline_cache_unrefs_texture(void)44 test_pipeline_cache_unrefs_texture (void)
45 {
46   CoglPipeline *pipeline = cogl_pipeline_new (test_ctx);
47   CoglPipeline *simple_pipeline;
48   int i;
49 
50   /* Create a pipeline with three texture layers. That way we can be
51    * pretty sure the pipeline will cause a unique shader to be
52    * generated in the cache */
53   for (i = 0; i < N_TEXTURES; i++)
54     {
55       CoglTexture *tex = create_texture ();
56       cogl_pipeline_set_layer_texture (pipeline, i, tex);
57       cogl_object_unref (tex);
58     }
59 
60   /* Draw something with the pipeline to ensure it gets into the
61    * pipeline cache */
62   cogl_framebuffer_draw_rectangle (test_fb,
63                                    pipeline,
64                                    0, 0, 10, 10);
65   cogl_framebuffer_finish (test_fb);
66 
67   /* Draw something else so that it is no longer the current flushed
68    * pipeline, and the units have a different texture bound */
69   simple_pipeline = cogl_pipeline_new (test_ctx);
70   for (i = 0; i < N_TEXTURES; i++)
71     {
72       CoglColor combine_constant;
73       cogl_color_init_from_4ub (&combine_constant, i, 0, 0, 255);
74       cogl_pipeline_set_layer_combine_constant (simple_pipeline,
75                                                 i,
76                                                 &combine_constant);
77     }
78   cogl_framebuffer_draw_rectangle (test_fb, simple_pipeline, 0, 0, 10, 10);
79   cogl_framebuffer_finish (test_fb);
80   cogl_object_unref (simple_pipeline);
81 
82   g_assert_cmpint (destroyed_texture_count, ==, 0);
83 
84   /* Destroy the pipeline. This should immediately cause the textures
85    * to be freed */
86   cogl_object_unref (pipeline);
87 
88   g_assert_cmpint (destroyed_texture_count, ==, N_TEXTURES);
89 
90   if (cogl_test_verbose ())
91     g_print ("OK\n");
92 }
93