mutter/tests/conform/test-utils.c
Neil Roberts 9a8a26270c test-write-texture-formats: Add fuzziness to the pixel comparisons
The rounding used when storing 10-bit per component data into an 8-bit
per component texture seems to have changed in recent versions of Mesa
which was causing this test to fail. I've also noticed this failing on
the NVidia binary driver. This patch adds some fuzziness to the
comparison so that it will pass. There is a new test_utils function
called test_utils_compare_pixel_and_alpha which is the same as
test_utils_compare_pixel except that it also compares the alpha
component.

Reviewed-by: Robert Bragg <robert@linux.intel.com>

(cherry picked from commit ce626fb3939b0f200d85ccdf32809608b879212d)
2013-01-22 18:00:11 +00:00

293 lines
8.1 KiB
C

#define COGL_ENABLE_EXPERIMENTAL_2_0_API
#include <cogl/cogl.h>
#include <stdlib.h>
#include "test-utils.h"
#define FB_WIDTH 512
#define FB_HEIGHT 512
static CoglBool cogl_test_is_verbose;
CoglContext *test_ctx;
CoglFramebuffer *test_fb;
static CoglBool
check_flags (TestFlags flags,
CoglRenderer *renderer)
{
if (flags & TEST_REQUIREMENT_GL &&
cogl_renderer_get_driver (renderer) != COGL_DRIVER_GL &&
cogl_renderer_get_driver (renderer) != COGL_DRIVER_GL3)
{
return FALSE;
}
if (flags & TEST_REQUIREMENT_NPOT &&
!cogl_has_feature (test_ctx, COGL_FEATURE_ID_TEXTURE_NPOT))
{
return FALSE;
}
if (flags & TEST_REQUIREMENT_TEXTURE_3D &&
!cogl_has_feature (test_ctx, COGL_FEATURE_ID_TEXTURE_3D))
{
return FALSE;
}
if (flags & TEST_REQUIREMENT_TEXTURE_RECTANGLE &&
!cogl_has_feature (test_ctx, COGL_FEATURE_ID_TEXTURE_RECTANGLE))
{
return FALSE;
}
if (flags & TEST_REQUIREMENT_POINT_SPRITE &&
!cogl_has_feature (test_ctx, COGL_FEATURE_ID_POINT_SPRITE))
{
return FALSE;
}
if (flags & TEST_REQUIREMENT_GLES2_CONTEXT &&
!cogl_has_feature (test_ctx, COGL_FEATURE_ID_GLES2_CONTEXT))
{
return FALSE;
}
if (flags & TEST_REQUIREMENT_MAP_WRITE &&
!cogl_has_feature (test_ctx, COGL_FEATURE_ID_MAP_BUFFER_FOR_WRITE))
{
return FALSE;
}
if (flags & TEST_REQUIREMENT_GLSL &&
!cogl_has_feature (test_ctx, COGL_FEATURE_ID_GLSL))
{
return FALSE;
}
if (flags & TEST_REQUIREMENT_OFFSCREEN &&
!cogl_has_feature (test_ctx, COGL_FEATURE_ID_OFFSCREEN))
{
return FALSE;
}
if (flags & TEST_KNOWN_FAILURE)
{
return FALSE;
}
return TRUE;
}
void
test_utils_init (TestFlags requirement_flags,
TestFlags known_failure_flags)
{
static int counter = 0;
CoglError *error = NULL;
CoglOnscreen *onscreen = NULL;
CoglDisplay *display;
CoglRenderer *renderer;
CoglBool missing_requirement;
CoglBool known_failure;
if (counter != 0)
g_critical ("We don't support running more than one test at a time\n"
"in a single test run due to the state leakage that can\n"
"cause subsequent tests to fail.\n"
"\n"
"If you want to run all the tests you should run\n"
"$ make test-report");
counter++;
if (g_getenv ("COGL_TEST_VERBOSE") || g_getenv ("V"))
cogl_test_is_verbose = TRUE;
if (g_getenv ("G_DEBUG"))
{
char *debug = g_strconcat (g_getenv ("G_DEBUG"), ",fatal-warnings", NULL);
g_setenv ("G_DEBUG", debug, TRUE);
g_free (debug);
}
else
g_setenv ("G_DEBUG", "fatal-warnings", TRUE);
g_setenv ("COGL_X11_SYNC", "1", 0);
test_ctx = cogl_context_new (NULL, &error);
if (!test_ctx)
g_critical ("Failed to create a CoglContext: %s", error->message);
display = cogl_context_get_display (test_ctx);
renderer = cogl_display_get_renderer (display);
missing_requirement = !check_flags (requirement_flags, renderer);
known_failure = !check_flags (known_failure_flags, renderer);
if (getenv ("COGL_TEST_ONSCREEN"))
{
onscreen = cogl_onscreen_new (test_ctx, 640, 480);
test_fb = COGL_FRAMEBUFFER (onscreen);
}
else
{
CoglOffscreen *offscreen;
CoglTexture2D *tex = cogl_texture_2d_new_with_size (test_ctx,
FB_WIDTH, FB_HEIGHT,
COGL_PIXEL_FORMAT_ANY);
offscreen = cogl_offscreen_new_to_texture (COGL_TEXTURE (tex));
test_fb = COGL_FRAMEBUFFER (offscreen);
}
if (!cogl_framebuffer_allocate (test_fb, &error))
g_critical ("Failed to allocate framebuffer: %s", error->message);
if (onscreen)
cogl_onscreen_show (onscreen);
cogl_framebuffer_clear4f (test_fb,
COGL_BUFFER_BIT_COLOR |
COGL_BUFFER_BIT_DEPTH |
COGL_BUFFER_BIT_STENCIL,
0, 0, 0, 1);
if (missing_requirement)
g_print ("WARNING: Missing required feature[s] for this test\n");
else if (known_failure)
g_print ("WARNING: Test is known to fail\n");
}
void
test_utils_fini (void)
{
if (test_fb)
cogl_object_unref (test_fb);
if (test_ctx)
cogl_object_unref (test_ctx);
}
static CoglBool
compare_component (int a, int b)
{
return ABS (a - b) <= 1;
}
void
test_utils_compare_pixel_and_alpha (const uint8_t *screen_pixel,
uint32_t expected_pixel)
{
/* Compare each component with a small fuzz factor */
if (!compare_component (screen_pixel[0], expected_pixel >> 24) ||
!compare_component (screen_pixel[1], (expected_pixel >> 16) & 0xff) ||
!compare_component (screen_pixel[2], (expected_pixel >> 8) & 0xff) ||
!compare_component (screen_pixel[3], (expected_pixel >> 0) & 0xff))
{
uint32_t screen_pixel_num = GUINT32_FROM_BE (*(uint32_t *) screen_pixel);
char *screen_pixel_string =
g_strdup_printf ("#%08x", screen_pixel_num);
char *expected_pixel_string =
g_strdup_printf ("#%08x", expected_pixel);
g_assert_cmpstr (screen_pixel_string, ==, expected_pixel_string);
g_free (screen_pixel_string);
g_free (expected_pixel_string);
}
}
void
test_utils_compare_pixel (const uint8_t *screen_pixel, uint32_t expected_pixel)
{
/* Compare each component with a small fuzz factor */
if (!compare_component (screen_pixel[0], expected_pixel >> 24) ||
!compare_component (screen_pixel[1], (expected_pixel >> 16) & 0xff) ||
!compare_component (screen_pixel[2], (expected_pixel >> 8) & 0xff))
{
uint32_t screen_pixel_num = GUINT32_FROM_BE (*(uint32_t *) screen_pixel);
char *screen_pixel_string =
g_strdup_printf ("#%06x", screen_pixel_num >> 8);
char *expected_pixel_string =
g_strdup_printf ("#%06x", expected_pixel >> 8);
g_assert_cmpstr (screen_pixel_string, ==, expected_pixel_string);
g_free (screen_pixel_string);
g_free (expected_pixel_string);
}
}
void
test_utils_check_pixel (CoglFramebuffer *test_fb,
int x, int y, uint32_t expected_pixel)
{
uint8_t pixel[4];
cogl_framebuffer_read_pixels (test_fb,
x, y, 1, 1,
COGL_PIXEL_FORMAT_RGBA_8888_PRE,
pixel);
test_utils_compare_pixel (pixel, expected_pixel);
}
void
test_utils_check_pixel_rgb (CoglFramebuffer *test_fb,
int x, int y, int r, int g, int b)
{
test_utils_check_pixel (test_fb, x, y, (r << 24) | (g << 16) | (b << 8));
}
void
test_utils_check_region (CoglFramebuffer *test_fb,
int x, int y,
int width, int height,
uint32_t expected_rgba)
{
uint8_t *pixels, *p;
pixels = p = g_malloc (width * height * 4);
cogl_framebuffer_read_pixels (test_fb,
x,
y,
width,
height,
COGL_PIXEL_FORMAT_RGBA_8888,
p);
/* Check whether the center of each division is the right color */
for (y = 0; y < height; y++)
for (x = 0; x < width; x++)
{
test_utils_compare_pixel (p, expected_rgba);
p += 4;
}
g_free (pixels);
}
CoglTexture *
test_utils_create_color_texture (CoglContext *context,
uint32_t color)
{
CoglTexture2D *tex_2d;
color = GUINT32_TO_BE (color);
tex_2d = cogl_texture_2d_new_from_data (context,
1, 1, /* width/height */
COGL_PIXEL_FORMAT_RGBA_8888_PRE,
COGL_PIXEL_FORMAT_RGBA_8888_PRE,
4, /* rowstride */
(uint8_t *) &color,
NULL);
return COGL_TEXTURE (tex_2d);
}
CoglBool
cogl_test_verbose (void)
{
return cogl_test_is_verbose;
}