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