[Intel-gfx] [PATCH i-g-t v5 6/7] chamelium: Dump captured and reference frames to png on crc error

Paul Kocialkowski paul.kocialkowski at linux.intel.com
Wed Jul 19 13:46:09 UTC 2017


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: Paul Kocialkowski <paul.kocialkowski at linux.intel.com>
---
 lib/igt_chamelium.c | 81 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 lib/igt_chamelium.h |  4 +++
 tests/chamelium.c   | 14 ++++++---
 3 files changed, 95 insertions(+), 4 deletions(-)

diff --git a/lib/igt_chamelium.c b/lib/igt_chamelium.c
index abcdc522..348d2176 100644
--- a/lib/igt_chamelium.c
+++ b/lib/igt_chamelium.c
@@ -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
@@ -973,6 +999,61 @@ void chamelium_assert_frame_eq(const struct chamelium *chamelium,
 }
 
 /**
+ * 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
  * @port: The port to check the frame limit on
diff --git a/lib/igt_chamelium.h b/lib/igt_chamelium.h
index 2bfbfdc7..80afcafa 100644
--- a/lib/igt_chamelium.h
+++ b/lib/igt_chamelium.h
@@ -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 */
diff --git a/tests/chamelium.c b/tests/chamelium.c
index ecd0434c..1567386e 100644
--- a/tests/chamelium.c
+++ b/tests/chamelium.c
@@ -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);
-- 
2.13.2



More information about the Intel-gfx mailing list