mirror of
https://github.com/brl/mutter.git
synced 2024-11-29 19:40:43 -05:00
a3cc62c285
When r is 128 or more, running tests compiled with the undefined behaviour sanitizer (ubsan) reports: test-utils.c:312:45: runtime error: left shift of 128 by 24 places cannot be represented in type 'int' which indeed it cannot. Force the type to be unsigned 32-bit so that we get defined behaviour. Similarly, in test-atlas-migration, the left-shifted guint8 is promoted to int, which again does not have enough non-sign bits available to left-shift a value >= 128 by 24 bits. Again, force the shift to be done in unsigned 32-bit space. This was originally cogl!22, but applies equally to mutter's fork of cogl. https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1271 Signed-off-by: Simon McVittie <smcv@debian.org>
147 lines
3.9 KiB
C
147 lines
3.9 KiB
C
#include <cogl/cogl.h>
|
|
|
|
#include "test-declarations.h"
|
|
#include "test-utils.h"
|
|
|
|
#define N_TEXTURES 128
|
|
|
|
#define OPACITY_FOR_ROW(y) \
|
|
(0xff - ((y) & 0xf) * 0x10)
|
|
|
|
#define COLOR_FOR_SIZE(size) \
|
|
(colors + (size) % 3)
|
|
|
|
typedef struct
|
|
{
|
|
uint8_t red, green, blue, alpha;
|
|
} TestColor;
|
|
|
|
static const TestColor colors[] =
|
|
{ { 0xff, 0x00, 0x00, 0xff },
|
|
{ 0x00, 0xff, 0x00, 0xff },
|
|
{ 0x00, 0x00, 0xff, 0xff } };
|
|
|
|
static CoglTexture *
|
|
create_texture (int size)
|
|
{
|
|
CoglTexture *texture;
|
|
const TestColor *color;
|
|
uint8_t *data, *p;
|
|
int x, y;
|
|
|
|
/* Create a red, green or blue texture depending on the size */
|
|
color = COLOR_FOR_SIZE (size);
|
|
|
|
p = data = g_malloc (size * size * 4);
|
|
|
|
/* Fill the data with the color but fade the opacity out with
|
|
increasing y coordinates so that we can see the blending it the
|
|
atlas migration accidentally blends with garbage in the
|
|
texture */
|
|
for (y = 0; y < size; y++)
|
|
{
|
|
int opacity = OPACITY_FOR_ROW (y);
|
|
|
|
for (x = 0; x < size; x++)
|
|
{
|
|
/* Store the colors premultiplied */
|
|
p[0] = color->red * opacity / 255;
|
|
p[1] = color->green * opacity / 255;
|
|
p[2] = color->blue * opacity / 255;
|
|
p[3] = opacity;
|
|
|
|
p += 4;
|
|
}
|
|
}
|
|
|
|
texture = test_utils_texture_new_from_data (test_ctx,
|
|
size, /* width */
|
|
size, /* height */
|
|
TEST_UTILS_TEXTURE_NONE, /* flags */
|
|
/* format */
|
|
COGL_PIXEL_FORMAT_RGBA_8888_PRE,
|
|
/* rowstride */
|
|
size * 4,
|
|
data);
|
|
|
|
g_free (data);
|
|
|
|
return texture;
|
|
}
|
|
|
|
static void
|
|
verify_texture (CoglTexture *texture, int size)
|
|
{
|
|
uint8_t *data, *p;
|
|
int x, y;
|
|
const TestColor *color;
|
|
|
|
color = COLOR_FOR_SIZE (size);
|
|
|
|
p = data = g_malloc (size * size * 4);
|
|
|
|
cogl_texture_get_data (texture,
|
|
COGL_PIXEL_FORMAT_RGBA_8888_PRE,
|
|
size * 4,
|
|
data);
|
|
|
|
for (y = 0; y < size; y++)
|
|
{
|
|
int opacity = OPACITY_FOR_ROW (y);
|
|
|
|
for (x = 0; x < size; x++)
|
|
{
|
|
TestColor real_color =
|
|
{
|
|
color->red * opacity / 255,
|
|
color->green * opacity / 255,
|
|
color->blue * opacity / 255
|
|
};
|
|
|
|
test_utils_compare_pixel (p,
|
|
(((guint32) real_color.red) << 24) |
|
|
(((guint32) real_color.green) << 16) |
|
|
(((guint32) real_color.blue) << 8) |
|
|
opacity);
|
|
g_assert_cmpint (p[3], ==, opacity);
|
|
|
|
p += 4;
|
|
}
|
|
}
|
|
|
|
g_free (data);
|
|
}
|
|
|
|
void
|
|
test_atlas_migration (void)
|
|
{
|
|
CoglTexture *textures[N_TEXTURES];
|
|
int i, tex_num;
|
|
|
|
/* Create and destroy all of the textures a few times to increase
|
|
the chances that we'll end up reusing the buffers for previously
|
|
discarded atlases */
|
|
for (i = 0; i < 5; i++)
|
|
{
|
|
for (tex_num = 0; tex_num < N_TEXTURES; tex_num++)
|
|
textures[tex_num] = create_texture (tex_num + 1);
|
|
for (tex_num = 0; tex_num < N_TEXTURES; tex_num++)
|
|
cogl_object_unref (textures[tex_num]);
|
|
}
|
|
|
|
/* Create all the textures again */
|
|
for (tex_num = 0; tex_num < N_TEXTURES; tex_num++)
|
|
textures[tex_num] = create_texture (tex_num + 1);
|
|
|
|
/* Verify that they all still have the right data */
|
|
for (tex_num = 0; tex_num < N_TEXTURES; tex_num++)
|
|
verify_texture (textures[tex_num], tex_num + 1);
|
|
|
|
/* Destroy them all */
|
|
for (tex_num = 0; tex_num < N_TEXTURES; tex_num++)
|
|
cogl_object_unref (textures[tex_num]);
|
|
|
|
if (cogl_test_verbose ())
|
|
g_print ("OK\n");
|
|
}
|