2013-03-09 14:43:46 -05:00
|
|
|
#include <cogl/cogl.h>
|
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
#include "test-utils.h"
|
|
|
|
|
|
|
|
/* Keep track of the number of textures that we've created and are
|
|
|
|
* still alive */
|
|
|
|
static int alive_texture_mask = 0;
|
|
|
|
|
|
|
|
#define N_LAYERS 3
|
|
|
|
#define N_PIPELINES 4
|
|
|
|
|
|
|
|
#define PIPELINE_LAYER_MASK(pipeline_num) \
|
|
|
|
(((1 << N_LAYERS) - 1) << (N_LAYERS * (pipeline_num) + 1))
|
|
|
|
#define LAST_PIPELINE_MASK PIPELINE_LAYER_MASK (N_PIPELINES - 1)
|
|
|
|
#define FIRST_PIPELINE_MASK PIPELINE_LAYER_MASK (0)
|
|
|
|
|
|
|
|
static void
|
|
|
|
free_texture_cb (void *user_data)
|
|
|
|
{
|
|
|
|
int texture_num = GPOINTER_TO_INT (user_data);
|
|
|
|
|
|
|
|
alive_texture_mask &= ~(1 << texture_num);
|
|
|
|
}
|
|
|
|
|
|
|
|
static CoglTexture *
|
|
|
|
create_texture (void)
|
|
|
|
{
|
|
|
|
static const guint8 data[] =
|
|
|
|
{ 0xff, 0xff, 0xff, 0xff };
|
|
|
|
static CoglUserDataKey texture_data_key;
|
|
|
|
CoglTexture2D *tex_2d;
|
|
|
|
static int texture_num = 1;
|
|
|
|
|
|
|
|
alive_texture_mask |= (1 << texture_num);
|
|
|
|
|
|
|
|
tex_2d = cogl_texture_2d_new_from_data (test_ctx,
|
|
|
|
1, 1, /* width / height */
|
|
|
|
COGL_PIXEL_FORMAT_RGBA_8888_PRE,
|
|
|
|
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 (texture_num),
|
|
|
|
free_texture_cb);
|
|
|
|
|
|
|
|
texture_num++;
|
|
|
|
|
2013-10-09 08:31:12 -04:00
|
|
|
return tex_2d;
|
2013-03-09 14:43:46 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
test_copy_replace_texture (void)
|
|
|
|
{
|
|
|
|
CoglPipeline *pipelines[N_PIPELINES];
|
|
|
|
int pipeline_num;
|
|
|
|
|
|
|
|
/* Create a set of pipeline copies each with three of their own
|
|
|
|
* replacement textures */
|
|
|
|
for (pipeline_num = 0; pipeline_num < N_PIPELINES; pipeline_num++)
|
|
|
|
{
|
|
|
|
int layer_num;
|
|
|
|
|
|
|
|
if (pipeline_num == 0)
|
|
|
|
pipelines[pipeline_num] = cogl_pipeline_new (test_ctx);
|
|
|
|
else
|
|
|
|
pipelines[pipeline_num] =
|
|
|
|
cogl_pipeline_copy (pipelines[pipeline_num - 1]);
|
|
|
|
|
|
|
|
for (layer_num = 0; layer_num < N_LAYERS; layer_num++)
|
|
|
|
{
|
|
|
|
CoglTexture *tex = create_texture ();
|
|
|
|
cogl_pipeline_set_layer_texture (pipelines[pipeline_num],
|
|
|
|
layer_num,
|
|
|
|
tex);
|
|
|
|
cogl_object_unref (tex);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Unref everything but the last pipeline */
|
|
|
|
for (pipeline_num = 0; pipeline_num < N_PIPELINES - 1; pipeline_num++)
|
|
|
|
cogl_object_unref (pipelines[pipeline_num]);
|
|
|
|
|
|
|
|
if (alive_texture_mask && cogl_test_verbose ())
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
|
|
|
g_print ("Alive textures:");
|
|
|
|
|
|
|
|
for (i = 0; i < N_PIPELINES * N_LAYERS; i++)
|
|
|
|
if ((alive_texture_mask & (1 << (i + 1))))
|
|
|
|
g_print (" %i", i);
|
|
|
|
|
|
|
|
g_print ("\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Ideally there should only be the textures from the last pipeline
|
|
|
|
* left alive. We also let Cogl keep the textures from the first
|
|
|
|
* texture alive because currently the child of the third layer in
|
|
|
|
* the first pipeline will retain its authority on the unit index
|
|
|
|
* state so that it can set it to 2. If there are more textures then
|
|
|
|
* it means the pipeline isn't correctly pruning redundant
|
|
|
|
* ancestors */
|
|
|
|
g_assert_cmpint (alive_texture_mask & ~FIRST_PIPELINE_MASK,
|
|
|
|
==,
|
|
|
|
LAST_PIPELINE_MASK);
|
|
|
|
|
|
|
|
/* Clean up the last pipeline */
|
|
|
|
cogl_object_unref (pipelines[N_PIPELINES - 1]);
|
|
|
|
|
|
|
|
/* That should get rid of the last of the textures */
|
|
|
|
g_assert_cmpint (alive_texture_mask, ==, 0);
|
|
|
|
|
|
|
|
if (cogl_test_verbose ())
|
|
|
|
g_print ("OK\n");
|
|
|
|
}
|