All of lore.kernel.org
 help / color / mirror / Atom feed
From: Imre Deak <imre.deak@intel.com>
To: intel-gfx@lists.freedesktop.org
Subject: [igt PATCH 4/5] lib: refactor kmstest_create_fb
Date: Fri, 31 May 2013 12:23:11 +0300	[thread overview]
Message-ID: <1369992192-957-4-git-send-email-imre.deak@intel.com> (raw)
In-Reply-To: <1369992192-957-1-git-send-email-imre.deak@intel.com>

Factor out parts that will be used by an upcoming patch adding
kmstest_create_fb2.

Also call the fb paint functions directly, there is not much
point in passing a function pointer for that.

Signed-off-by: Imre Deak <imre.deak@intel.com>
---
 lib/drmtest.c       | 176 ++++++++++++++++++++++++++++++++--------------------
 lib/drmtest.h       |  15 +++--
 tests/kms_flip.c    |  30 +++++----
 tests/testdisplay.c |  15 +++--
 4 files changed, 147 insertions(+), 89 deletions(-)

diff --git a/lib/drmtest.c b/lib/drmtest.c
index 7368077..a551e7c 100644
--- a/lib/drmtest.c
+++ b/lib/drmtest.c
@@ -39,6 +39,7 @@
 #include <getopt.h>
 #include <stdlib.h>
 #include <linux/kd.h>
+#include <drm/drm_fourcc.h>
 
 #include "drmtest.h"
 #include "i915_drm.h"
@@ -788,16 +789,14 @@ void drmtest_cleanup_aperture_trashers(void)
 }
 
 /* helpers to create nice-looking framebuffers */
-static cairo_surface_t *
-paint_allocate_surface(int fd, int width, int height, int depth, int bpp,
-		       bool tiled,
-		       struct kmstest_fb *fb_info)
+static int create_bo_for_fb(int fd, int width, int height, int bpp,
+			    bool tiled, uint32_t *gem_handle_ret,
+			    unsigned *size_ret, unsigned *stride_ret)
 {
-	cairo_format_t format;
 	struct drm_i915_gem_set_tiling set_tiling;
+	uint32_t gem_handle;
 	int size;
 	unsigned stride;
-	uint32_t *fb_ptr;
 
 	if (tiled) {
 		int v;
@@ -823,49 +822,24 @@ paint_allocate_surface(int fd, int width, int height, int depth, int bpp,
 		size = stride * height;
 	}
 
-	switch (depth) {
-	case 16:
-		format = CAIRO_FORMAT_RGB16_565;
-		break;
-	case 24:
-		format = CAIRO_FORMAT_RGB24;
-		break;
-#if 0
-	case 30:
-		format = CAIRO_FORMAT_RGB30;
-		break;
-#endif
-	case 32:
-		format = CAIRO_FORMAT_ARGB32;
-		break;
-	default:
-		fprintf(stderr, "bad depth %d\n", depth);
-		return NULL;
-	}
-
-	assert (bpp >= depth);
-
-	fb_info->gem_handle = gem_create(fd, size);
+	gem_handle = gem_create(fd, size);
 
 	if (tiled) {
-		set_tiling.handle = fb_info->gem_handle;
+		set_tiling.handle = gem_handle;
 		set_tiling.tiling_mode = I915_TILING_X;
 		set_tiling.stride = stride;
 		if (ioctl(fd, DRM_IOCTL_I915_GEM_SET_TILING, &set_tiling)) {
 			fprintf(stderr, "set tiling failed: %s (stride=%d, size=%d)\n",
 				strerror(errno), stride, size);
-			return NULL;
+			return -1;
 		}
 	}
 
-	fb_ptr = gem_mmap(fd, fb_info->gem_handle, size, PROT_READ | PROT_WRITE);
-
-	fb_info->stride = stride;
-	fb_info->size = size;
+	*stride_ret = stride;
+	*size_ret = size;
+	*gem_handle_ret = gem_handle;
 
-	return cairo_image_surface_create_for_data((unsigned char *)fb_ptr,
-						   format, width, height,
-						   stride);
+	return 0;
 }
 
 static void
@@ -981,23 +955,8 @@ paint_marker(cairo_t *cr, int x, int y)
 	kmstest_cairo_printf_line(cr, align, 0, "(%d, %d)", x, y);
 }
 
-unsigned int kmstest_create_fb(int fd, int width, int height, int bpp,
-			       int depth, bool tiled,
-			       struct kmstest_fb *fb_info,
-			       kmstest_paint_func paint_func,
-			       void *func_arg)
+void kmstest_paint_test_pattern(cairo_t *cr, int width, int height)
 {
-	cairo_surface_t *surface;
-	cairo_status_t status;
-	cairo_t *cr;
-	unsigned int fb_id;
-
-	surface = paint_allocate_surface(fd, width, height, depth, bpp,
-					 tiled, fb_info);
-	assert(surface);
-
-	cr = cairo_create(surface);
-
 	paint_test_patterns(cr, width, height);
 
 	cairo_set_line_cap(cr, CAIRO_LINE_CAP_SQUARE);
@@ -1008,27 +967,112 @@ unsigned int kmstest_create_fb(int fd, int width, int height, int bpp,
 	paint_marker(cr, 0, height);
 	paint_marker(cr, width, height);
 
-	if (paint_func)
-		paint_func(cr, width, height, func_arg);
+	assert(!cairo_status(cr));
+}
+
+#define DF(did, cid, _bpp, _depth)	\
+	{ DRM_FORMAT_##did, CAIRO_FORMAT_##cid, # did, _bpp, _depth }
+static struct format_desc_struct {
+	uint32_t drm_id;
+	cairo_format_t cairo_id;
+	const char *name;
+	int bpp;
+	int depth;
+} format_desc[] = {
+	DF(RGB565,	RGB16_565,	16, 16),
+	DF(RGB888,	INVALID,	24, 24),
+	DF(XRGB8888,	RGB24,		32, 24),
+	DF(XRGB2101010,	RGB30,		32, 30),
+	DF(ARGB8888,	ARGB32,		32, 32),
+};
+#undef DF
+
+#define for_each_format(f)	\
+	for (f = format_desc; f - format_desc < ARRAY_SIZE(format_desc); f++)
+
+static uint32_t bpp_depth_to_drm_format(int bpp, int depth)
+{
+	struct format_desc_struct *f;
+
+	for_each_format(f)
+		if (f->bpp == bpp && f->depth == depth)
+			return f->drm_id;
+
+	abort();
+}
+
+/* Return fb_id on success, 0 on error */
+unsigned int kmstest_create_fb(int fd, int width, int height, int bpp,
+			       int depth, bool tiled, struct kmstest_fb *fb)
+{
+	memset(fb, 0, sizeof(*fb));
 
-	status = cairo_status(cr);
-	assert(!status);
-	cairo_destroy(cr);
+	if (create_bo_for_fb(fd, width, height, bpp, tiled, &fb->gem_handle,
+			       &fb->size, &fb->stride) < 0)
+		return 0;
+
+	if (drmModeAddFB(fd, width, height, depth, bpp, fb->stride,
+			       fb->gem_handle, &fb->fb_id) < 0) {
+		gem_close(fd, fb->gem_handle);
+
+		return 0;
+	}
+
+	fb->width = width;
+	fb->height = height;
+	fb->drm_format = bpp_depth_to_drm_format(bpp, depth);
+
+	return fb->fb_id;
+}
+
+static cairo_format_t drm_format_to_cairo(uint32_t drm_format)
+{
+	struct format_desc_struct *f;
 
-	do_or_die(drmModeAddFB(fd, width, height, depth, bpp,
-			       fb_info->stride,
-			       fb_info->gem_handle, &fb_id));
+	for_each_format(f)
+		if (f->drm_id == drm_format)
+			return f->cairo_id;
 
+	abort();
+}
+
+static cairo_t *create_cairo_ctx(int fd, struct kmstest_fb *fb)
+{
+	cairo_t *cr;
+	cairo_surface_t *surface;
+	cairo_format_t cformat;
+	void *fb_ptr;
+
+	cformat = drm_format_to_cairo(fb->drm_format);
+	fb_ptr = gem_mmap(fd, fb->gem_handle, fb->size, PROT_READ | PROT_WRITE);
+	surface = cairo_image_surface_create_for_data((unsigned char *)fb_ptr,
+						   cformat, fb->width,
+						   fb->height, fb->stride);
+	assert(surface);
+	cr = cairo_create(surface);
 	cairo_surface_destroy(surface);
 
-	fb_info->fb_id = fb_id;
+	return cr;
+}
+
+cairo_t *kmstest_get_cairo_ctx(int fd, struct kmstest_fb *fb)
+{
+
+	if (!fb->cairo_ctx)
+		fb->cairo_ctx = create_cairo_ctx(fd, fb);
+
+	gem_set_domain(fd, fb->gem_handle, I915_GEM_DOMAIN_CPU,
+		       I915_GEM_DOMAIN_CPU);
 
-	return fb_id;
+	return fb->cairo_ctx;
 }
 
-void kmstest_remove_fb(int fd, int fb_id)
+void kmstest_remove_fb(int fd, struct kmstest_fb *fb)
 {
-	do_or_die(drmModeRmFB(fd, fb_id));
+	if (fb->cairo_ctx)
+		cairo_destroy(fb->cairo_ctx);
+	do_or_die(drmModeRmFB(fd, fb->fb_id));
+	gem_close(fd, fb->gem_handle);
 }
 
 struct type_name {
diff --git a/lib/drmtest.h b/lib/drmtest.h
index 89ded11..218914f 100644
--- a/lib/drmtest.h
+++ b/lib/drmtest.h
@@ -119,8 +119,13 @@ void kmstest_free_connector_config(struct kmstest_connector_config *config);
 struct kmstest_fb {
 	uint32_t fb_id;
 	uint32_t gem_handle;
+	uint32_t drm_format;
+	int width;
+	int height;
+	int depth;
 	unsigned stride;
 	unsigned size;
+	cairo_t *cairo_ctx;
 };
 
 enum kmstest_text_align {
@@ -136,14 +141,12 @@ int kmstest_cairo_printf_line(cairo_t *cr, enum kmstest_text_align align,
 			       double yspacing, const char *fmt, ...)
 			       __attribute__((format (printf, 4, 5)));
 
-typedef void (*kmstest_paint_func)(cairo_t *cr, int width, int height, void *priv);
-
 unsigned int kmstest_create_fb(int fd, int width, int height, int bpp,
 			       int depth, bool tiled,
-			       struct kmstest_fb *fb_info,
-			       kmstest_paint_func paint_func,
-			       void *func_arg);
-void kmstest_remove_fb(int fd, int fb_id);
+			       struct kmstest_fb *fb_info);
+void kmstest_remove_fb(int fd, struct kmstest_fb *fb_info);
+cairo_t *kmstest_get_cairo_ctx(int fd, struct kmstest_fb *fb);
+void kmstest_paint_test_pattern(cairo_t *cr, int width, int height);
 void kmstest_dump_mode(drmModeModeInfo *mode);
 int kmstest_get_pipe_from_crtc_id(int fd, int crtc_id);
 const char *kmstest_encoder_type_str(int type);
diff --git a/tests/kms_flip.c b/tests/kms_flip.c
index c9b3d8a..aeeaace 100644
--- a/tests/kms_flip.c
+++ b/tests/kms_flip.c
@@ -844,10 +844,13 @@ static void connector_find_preferred_mode(uint32_t connector_id, int crtc_idx,
 	o->mode_valid = 1;
 }
 
-static void
-paint_flip_mode(cairo_t *cr, int width, int height, void *priv)
+static void paint_flip_mode(struct kmstest_fb *fb, bool odd_frame)
 {
-	bool odd_frame = (bool) priv;
+	cairo_t *cr = kmstest_get_cairo_ctx(drm_fd, fb);
+	int width = fb->width;
+	int height = fb->height;
+
+	kmstest_paint_test_pattern(cr, width, height);
 
 	if (odd_frame)
 		cairo_rectangle(cr, width/4, height/2, width/4, height/8);
@@ -856,6 +859,8 @@ paint_flip_mode(cairo_t *cr, int width, int height, void *priv)
 
 	cairo_set_source_rgb(cr, 1, 1, 1);
 	cairo_fill(cr);
+
+	assert(!cairo_status(cr));
 }
 
 static int
@@ -991,20 +996,21 @@ static void run_test_on_crtc(struct test_output *o, int crtc_idx, int duration)
 		o->fb_width *= 2;
 
 	o->fb_ids[0] = kmstest_create_fb(drm_fd, o->fb_width, o->fb_height,
-					 o->bpp, o->depth, false, &o->fb_info[0],
-					 paint_flip_mode, (void *)false);
+					 o->bpp, o->depth, false, &o->fb_info[0]);
 	o->fb_ids[1] = kmstest_create_fb(drm_fd, o->fb_width, o->fb_height,
-					 o->bpp, o->depth, false, &o->fb_info[1],
-					 paint_flip_mode, (void *)true);
+					 o->bpp, o->depth, false, &o->fb_info[1]);
 	o->fb_ids[2] = kmstest_create_fb(drm_fd, o->fb_width, o->fb_height,
-					 o->bpp, o->depth, true, &o->fb_info[2],
-					 paint_flip_mode, (void *)true);
+					 o->bpp, o->depth, true, &o->fb_info[2]);
 
 	if (!o->fb_ids[0] || !o->fb_ids[1] || !o->fb_ids[2]) {
 		fprintf(stderr, "failed to create fbs\n");
 		exit(3);
 	}
 
+	paint_flip_mode(&o->fb_info[0], false);
+	paint_flip_mode(&o->fb_info[1], true);
+	paint_flip_mode(&o->fb_info[2], true);
+
 	set_y_tiling(o, 2);
 
 	kmstest_dump_mode(&o->mode);
@@ -1044,9 +1050,9 @@ static void run_test_on_crtc(struct test_output *o, int crtc_idx, int duration)
 	fprintf(stdout, "\n%s on crtc %d, connector %d: PASSED\n\n",
 		o->test_name, o->crtc, o->id);
 
-	kmstest_remove_fb(drm_fd, o->fb_ids[2]);
-	kmstest_remove_fb(drm_fd, o->fb_ids[1]);
-	kmstest_remove_fb(drm_fd, o->fb_ids[0]);
+	kmstest_remove_fb(drm_fd, &o->fb_info[2]);
+	kmstest_remove_fb(drm_fd, &o->fb_info[1]);
+	kmstest_remove_fb(drm_fd, &o->fb_info[0]);
 
 	last_connector = NULL;
 
diff --git a/tests/testdisplay.c b/tests/testdisplay.c
index 4470339..5ece921 100644
--- a/tests/testdisplay.c
+++ b/tests/testdisplay.c
@@ -258,15 +258,18 @@ static void paint_image(cairo_t *cr, const char *file)
 	cairo_surface_destroy(image);
 }
 
-static void
-paint_output_info(cairo_t *cr, int l_width, int l_height, void *priv)
+static void paint_output_info(struct connector *c, struct kmstest_fb *fb)
 {
-	struct connector *c = priv;
+	cairo_t *cr = kmstest_get_cairo_ctx(drm_fd, fb);
+	int l_width = fb->width;
+	int l_height = fb->height;
 	double str_width;
 	double x, y, top_y;
 	double max_width;
 	int i;
 
+	kmstest_paint_test_pattern(cr, l_width, l_height);
+
 	cairo_select_font_face(cr, "Helvetica",
 			       CAIRO_FONT_SLANT_NORMAL,
 			       CAIRO_FONT_WEIGHT_NORMAL);
@@ -308,6 +311,8 @@ paint_output_info(cairo_t *cr, int l_width, int l_height, void *priv)
 
 	if (qr_code)
 		paint_image(cr, "./pass.png");
+
+	assert(!cairo_status(cr));
 }
 
 static void sighandler(int signo)
@@ -362,8 +367,8 @@ set_mode(struct connector *c)
 		height = c->mode.vdisplay;
 
 		fb_id = kmstest_create_fb(drm_fd, width, height, bpp, depth,
-					  enable_tiling, &fb_info,
-					  paint_output_info, c);
+					  enable_tiling, &fb_info);
+		paint_output_info(c, &fb_info);
 
 		fb_ptr = gem_mmap(drm_fd, fb_info.gem_handle,
 				  fb_info.size, PROT_READ | PROT_WRITE);
-- 
1.8.1.2

  parent reply	other threads:[~2013-05-31  9:23 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-05-31  9:23 [igt PATCH 1/5] lib: move connector_type_str and co to drmtest Imre Deak
2013-05-31  9:23 ` [igt PATCH 2/5] lib: add kmstest_cairo_printf_line Imre Deak
2013-06-05 17:44   ` Rodrigo Vivi
2013-06-05 19:01     ` Imre Deak
2013-05-31  9:23 ` [igt PATCH 3/5] lib: add kmstest_get_connector_config Imre Deak
2013-06-05 18:00   ` Rodrigo Vivi
2013-05-31  9:23 ` Imre Deak [this message]
2013-06-05 18:21   ` [igt PATCH 4/5] lib: refactor kmstest_create_fb Rodrigo Vivi
2013-05-31  9:23 ` [igt PATCH 5/5] tests: add kms_render Imre Deak
2013-06-05 18:28   ` Rodrigo Vivi
2013-06-06 10:19     ` Imre Deak
2013-06-05 19:25   ` [PATCH v2 0/6] tests: add tests for front buffer rendering Imre Deak
2013-06-05 19:25     ` [PATCH v2 1/6] lib: move connector_type_str and co to drmtest Imre Deak
2013-06-05 19:25     ` [PATCH v2 2/6] lib: add kmstest_cairo_printf_line Imre Deak
2013-06-05 19:27       ` Rodrigo Vivi
2013-06-05 20:04       ` [PATCH v3 " Imre Deak
2013-06-05 19:25     ` [PATCH v2 3/6] lib: use kmstest_cairo_printf_line in paint_marker Imre Deak
2013-06-05 19:29       ` Rodrigo Vivi
2013-06-05 19:25     ` [PATCH v2 4/6] lib: add kmstest_get_connector_config Imre Deak
2013-06-05 19:25     ` [PATCH v2 5/6] lib: refactor kmstest_create_fb Imre Deak
2013-06-05 19:25     ` [PATCH v2 6/6] tests: add kms_render Imre Deak
2013-06-05 17:40 ` [igt PATCH 1/5] lib: move connector_type_str and co to drmtest Rodrigo Vivi

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1369992192-957-4-git-send-email-imre.deak@intel.com \
    --to=imre.deak@intel.com \
    --cc=intel-gfx@lists.freedesktop.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.