Commit 5e4e8295 authored by Paul Kocialkowski's avatar Paul Kocialkowski Committed by Lyude Paul

chamelium: Dump captured and reference frames to png on crc error

This adds support for dumping both the frame capture from the chamelium
and the reference frame generated by cairo when the captured crc does
not match the crc calculated from the reference, using common helpers.

Getting a dump of the frames is quite useful in order to compare them.
Signed-off-by: default avatarPaul Kocialkowski <paul.kocialkowski@linux.intel.com>
Reviewed-by: Lyude Paul's avatarLyude <lyude@redhat.com>
parent 34a54192
......@@ -929,6 +929,32 @@ static pixman_image_t *convert_frame_format(pixman_image_t *src,
return converted;
}
static cairo_surface_t *convert_frame_dump_argb32(const struct chamelium_frame_dump *dump)
{
cairo_surface_t *dump_surface;
pixman_image_t *image_bgr;
pixman_image_t *image_argb;
int w = dump->width, h = dump->height;
uint32_t *bits_bgr = (uint32_t *) dump->bgr;
unsigned char *bits_argb;
image_bgr = pixman_image_create_bits(
PIXMAN_b8g8r8, w, h, bits_bgr,
PIXMAN_FORMAT_BPP(PIXMAN_b8g8r8) / 8 * w);
image_argb = convert_frame_format(image_bgr, PIXMAN_x8r8g8b8);
pixman_image_unref(image_bgr);
bits_argb = (unsigned char *) pixman_image_get_data(image_argb);
dump_surface = cairo_image_surface_create_for_data(
bits_argb, CAIRO_FORMAT_ARGB32, w, h,
PIXMAN_FORMAT_BPP(PIXMAN_x8r8g8b8) / 8 * w);
pixman_image_unref(image_argb);
return dump_surface;
}
/**
* chamelium_assert_frame_eq:
* @chamelium: The chamelium instance the frame dump belongs to
......@@ -972,6 +998,61 @@ void chamelium_assert_frame_eq(const struct chamelium *chamelium,
"Chamelium frame dump didn't match reference image\n");
}
/**
* chamelium_assert_crc_eq_or_dump:
* @chamelium: The chamelium instance the frame dump belongs to
* @reference_crc: The CRC for the reference frame
* @capture_crc: The CRC for the captured frame
* @fb: pointer to an #igt_fb structure
*
* Asserts that the CRC provided for both the reference and the captured frame
* are identical. If they are not, this grabs the captured frame and saves it
* along with the reference to a png file.
*/
void chamelium_assert_crc_eq_or_dump(struct chamelium *chamelium,
igt_crc_t *reference_crc,
igt_crc_t *capture_crc, struct igt_fb *fb,
int index)
{
struct chamelium_frame_dump *frame;
cairo_surface_t *reference;
cairo_surface_t *capture;
char *reference_suffix;
char *capture_suffix;
bool eq;
eq = igt_check_crc_equal(reference_crc, capture_crc);
if (!eq && igt_frame_dump_is_enabled()) {
/* Grab the reference frame from framebuffer */
reference = igt_get_cairo_surface(chamelium->drm_fd, fb);
/* Grab the captured frame from chamelium */
frame = chamelium_read_captured_frame(chamelium, index);
igt_assert(frame);
capture = convert_frame_dump_argb32(frame);
reference_suffix = igt_crc_to_string_extended(reference_crc,
'-', 2);
capture_suffix = igt_crc_to_string_extended(capture_crc, '-',
2);
/* Write reference and capture frames to png */
igt_write_compared_frames_to_png(reference, capture,
reference_suffix,
capture_suffix);
free(reference_suffix);
free(capture_suffix);
chamelium_destroy_frame_dump(frame);
cairo_surface_destroy(capture);
}
igt_assert(eq);
}
/**
* chamelium_get_frame_limit:
* @chamelium: The Chamelium instance to use
......
......@@ -105,6 +105,10 @@ int chamelium_get_frame_limit(struct chamelium *chamelium,
void chamelium_assert_frame_eq(const struct chamelium *chamelium,
const struct chamelium_frame_dump *dump,
struct igt_fb *fb);
void chamelium_assert_crc_eq_or_dump(struct chamelium *chamelium,
igt_crc_t *reference_crc,
igt_crc_t *capture_crc, struct igt_fb *fb,
int index);
void chamelium_destroy_frame_dump(struct chamelium_frame_dump *dump);
#endif /* IGT_CHAMELIUM_H */
......@@ -431,7 +431,7 @@ test_display_crc_single(data_t *data, struct chamelium_port *port)
struct igt_fb fb;
drmModeModeInfo *mode;
drmModeConnector *connector;
int fb_id, i;
int fb_id, i, captured_frame_count;
reset_state(data, port);
......@@ -456,11 +456,15 @@ test_display_crc_single(data_t *data, struct chamelium_port *port)
igt_debug("Testing single CRC fetch\n");
crc = chamelium_get_crc_for_area(data->chamelium, port,
0, 0, 0, 0);
chamelium_capture(data->chamelium, port, 0, 0, 0, 0, 1);
crc = chamelium_read_captured_crcs(data->chamelium,
&captured_frame_count);
expected_crc = chamelium_calculate_fb_crc_async_finish(fb_crc);
chamelium_assert_crc_eq_or_dump(data->chamelium, expected_crc,
crc, &fb, 0);
igt_assert_crc_equal(crc, expected_crc);
free(expected_crc);
free(crc);
......@@ -522,7 +526,9 @@ test_display_crc_multiple(data_t *data, struct chamelium_port *port)
expected_crc = chamelium_calculate_fb_crc_async_finish(fb_crc);
for (j = 0; j < captured_frame_count; j++)
igt_assert_crc_equal(&crc[j], expected_crc);
chamelium_assert_crc_eq_or_dump(data->chamelium,
expected_crc, &crc[j],
&fb, j);
free(expected_crc);
free(crc);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment