1 #include <cogl/cogl.h>
2 
3 #include "test-declarations.h"
4 #include "test-utils.h"
5 
6 #define N_TEXTURES 128
7 
8 #define OPACITY_FOR_ROW(y) \
9   (0xff - ((y) & 0xf) * 0x10)
10 
11 #define COLOR_FOR_SIZE(size) \
12   (colors + (size) % 3)
13 
14 typedef struct
15 {
16   uint8_t red, green, blue, alpha;
17 } TestColor;
18 
19 static const TestColor colors[] =
20   { { 0xff, 0x00, 0x00, 0xff },
21     { 0x00, 0xff, 0x00, 0xff },
22     { 0x00, 0x00, 0xff, 0xff } };
23 
24 static CoglTexture *
create_texture(int size)25 create_texture (int size)
26 {
27   CoglTexture *texture;
28   const TestColor *color;
29   uint8_t *data, *p;
30   int x, y;
31 
32   /* Create a red, green or blue texture depending on the size */
33   color = COLOR_FOR_SIZE (size);
34 
35   p = data = g_malloc (size * size * 4);
36 
37   /* Fill the data with the color but fade the opacity out with
38      increasing y coordinates so that we can see the blending it the
39      atlas migration accidentally blends with garbage in the
40      texture */
41   for (y = 0; y < size; y++)
42     {
43       int opacity = OPACITY_FOR_ROW (y);
44 
45       for (x = 0; x < size; x++)
46         {
47           /* Store the colors premultiplied */
48           p[0] = color->red * opacity / 255;
49           p[1] = color->green * opacity / 255;
50           p[2] = color->blue * opacity / 255;
51           p[3] = opacity;
52 
53           p += 4;
54         }
55     }
56 
57   texture = test_utils_texture_new_from_data (test_ctx,
58                                               size, /* width */
59                                               size, /* height */
60                                               TEST_UTILS_TEXTURE_NONE, /* flags */
61                                               /* format */
62                                               COGL_PIXEL_FORMAT_RGBA_8888_PRE,
63                                               /* rowstride */
64                                               size * 4,
65                                               data);
66 
67   g_free (data);
68 
69   return texture;
70 }
71 
72 static void
verify_texture(CoglTexture * texture,int size)73 verify_texture (CoglTexture *texture, int size)
74 {
75   uint8_t *data, *p;
76   int x, y;
77   const TestColor *color;
78 
79   color = COLOR_FOR_SIZE (size);
80 
81   p = data = g_malloc (size * size * 4);
82 
83   cogl_texture_get_data (texture,
84                          COGL_PIXEL_FORMAT_RGBA_8888_PRE,
85                          size * 4,
86                          data);
87 
88   for (y = 0; y < size; y++)
89     {
90       int opacity = OPACITY_FOR_ROW (y);
91 
92       for (x = 0; x < size; x++)
93         {
94           TestColor real_color =
95             {
96               color->red * opacity / 255,
97               color->green * opacity / 255,
98               color->blue * opacity / 255
99             };
100 
101           test_utils_compare_pixel (p,
102                                     (((guint32) real_color.red) << 24) |
103                                     (((guint32) real_color.green) << 16) |
104                                     (((guint32) real_color.blue) << 8) |
105                                     opacity);
106           g_assert_cmpint (p[3], ==, opacity);
107 
108           p += 4;
109         }
110     }
111 
112   g_free (data);
113 }
114 
115 void
test_atlas_migration(void)116 test_atlas_migration (void)
117 {
118   CoglTexture *textures[N_TEXTURES];
119   int i, tex_num;
120 
121   /* Create and destroy all of the textures a few times to increase
122      the chances that we'll end up reusing the buffers for previously
123      discarded atlases */
124   for (i = 0; i < 5; i++)
125     {
126       for (tex_num = 0; tex_num < N_TEXTURES; tex_num++)
127         textures[tex_num] = create_texture (tex_num + 1);
128       for (tex_num = 0; tex_num < N_TEXTURES; tex_num++)
129         cogl_object_unref (textures[tex_num]);
130     }
131 
132   /* Create all the textures again */
133   for (tex_num = 0; tex_num < N_TEXTURES; tex_num++)
134     textures[tex_num] = create_texture (tex_num + 1);
135 
136   /* Verify that they all still have the right data */
137   for (tex_num = 0; tex_num < N_TEXTURES; tex_num++)
138     verify_texture (textures[tex_num], tex_num + 1);
139 
140   /* Destroy them all */
141   for (tex_num = 0; tex_num < N_TEXTURES; tex_num++)
142     cogl_object_unref (textures[tex_num]);
143 
144   if (cogl_test_verbose ())
145     g_print ("OK\n");
146 }
147