summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2013-12-30 17:48:43 +0000
committerChris Wilson <chris@chris-wilson.co.uk>2013-12-31 12:30:30 +0000
commit164d9d26ac33029287a24fbed549e3a2858d5d51 (patch)
tree717c811f7481611406b794ad82d6a5c1446360a3
parent9d6cfa6b59d0c22cf772ca71069f9e5f3e53d055 (diff)
kmstest: Fix up lifetimes of cairo objects
cairo_t is the short lived drawing context, whereas cairo_surface_t is the heavyweight object that persists and is also tied to underlying GEM objects. So make the kmstest API reflect the different weights and fix the lifetime and underlying object reference leaks. Based on the fix by Paulo Zanoni. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-rw-r--r--lib/igt_kms.c58
-rw-r--r--lib/igt_kms.h3
-rw-r--r--tests/kms_cursor_crc.c1
-rw-r--r--tests/kms_fbc_crc.c1
-rw-r--r--tests/kms_flip.c1
-rw-r--r--tests/kms_pipe_crc_basic.c1
-rw-r--r--tests/kms_render.c4
-rw-r--r--tests/kms_setmode.c4
-rw-r--r--tests/pm_lpsp.c2
-rw-r--r--tests/pm_pc8.c2
-rw-r--r--tests/testdisplay.c2
11 files changed, 45 insertions, 34 deletions
diff --git a/lib/igt_kms.c b/lib/igt_kms.c
index 57795b16..3960d24f 100644
--- a/lib/igt_kms.c
+++ b/lib/igt_kms.c
@@ -368,31 +368,43 @@ static cairo_format_t drm_format_to_cairo(uint32_t drm_format)
abort();
}
-static cairo_surface_t *create_image_surface(int fd, struct kmstest_fb *fb)
+static void __kmstest_destroy_cairo_surface(void *arg)
{
- cairo_surface_t *surface;
- cairo_format_t cformat;
- void *fb_ptr;
+ struct kmstest_fb *fb = arg;
+ munmap(cairo_image_surface_get_data(fb->cairo_surface), fb->size);
+}
+
+cairo_surface_t *kmstest_get_cairo_surface(int fd, struct kmstest_fb *fb)
+{
+ if (fb->cairo_surface == NULL) {
+ fb->cairo_surface =
+ cairo_image_surface_create_for_data(gem_mmap(fd, fb->gem_handle, fb->size, PROT_READ | PROT_WRITE),
+ drm_format_to_cairo(fb->drm_format),
+ fb->width, fb->height, fb->stride);
+
+ cairo_surface_set_user_data(fb->cairo_surface,
+ (cairo_user_data_key_t *)kmstest_get_cairo_surface,
+ fb, __kmstest_destroy_cairo_surface);
+ }
- 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);
+ gem_set_domain(fd, fb->gem_handle,
+ I915_GEM_DOMAIN_CPU, I915_GEM_DOMAIN_CPU);
- return surface;
+ igt_assert(cairo_surface_status(fb->cairo_surface) == CAIRO_STATUS_SUCCESS);
+ return cairo_surface_reference(fb->cairo_surface);
}
-static cairo_t *create_cairo_ctx(int fd, struct kmstest_fb *fb)
+cairo_t *kmstest_get_cairo_ctx(int fd, struct kmstest_fb *fb)
{
- cairo_t *cr;
cairo_surface_t *surface;
+ cairo_t *cr;
- surface = create_image_surface(fd, fb);
+ surface = kmstest_get_cairo_surface(fd, fb);
cr = cairo_create(surface);
cairo_surface_destroy(surface);
+ igt_assert(cairo_status(cr) == CAIRO_STATUS_SUCCESS);
+
return cr;
}
@@ -401,28 +413,16 @@ void kmstest_write_fb(int fd, struct kmstest_fb *fb, const char *filename)
cairo_surface_t *surface;
cairo_status_t status;
- surface = create_image_surface(fd, fb);
+ surface = kmstest_get_cairo_surface(fd, fb);
status = cairo_surface_write_to_png(surface, filename);
- assert(status == CAIRO_STATUS_SUCCESS);
cairo_surface_destroy(surface);
-}
-
-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->cairo_ctx;
+ igt_assert(status == CAIRO_STATUS_SUCCESS);
}
void kmstest_remove_fb(int fd, struct kmstest_fb *fb)
{
- if (fb->cairo_ctx)
- cairo_destroy(fb->cairo_ctx);
+ cairo_surface_destroy(fb->cairo_surface);
do_or_die(drmModeRmFB(fd, fb->fb_id));
gem_close(fd, fb->gem_handle);
}
diff --git a/lib/igt_kms.h b/lib/igt_kms.h
index f61f8e53..6f71165a 100644
--- a/lib/igt_kms.h
+++ b/lib/igt_kms.h
@@ -54,7 +54,7 @@ struct kmstest_fb {
unsigned stride;
unsigned tiling;
unsigned size;
- cairo_t *cairo_ctx;
+ cairo_surface_t *cairo_surface;
};
enum kmstest_text_align {
@@ -77,6 +77,7 @@ unsigned int kmstest_create_fb2(int fd, int width, int height, uint32_t format,
bool tiled, struct kmstest_fb *fb);
void kmstest_remove_fb(int fd, struct kmstest_fb *fb_info);
cairo_t *kmstest_get_cairo_ctx(int fd, struct kmstest_fb *fb);
+cairo_surface_t *kmstest_get_cairo_surface(int fd, struct kmstest_fb *fb);
void kmstest_paint_color(cairo_t *cr, int x, int y, int w, int h,
double r, double g, double b);
void kmstest_paint_color_alpha(cairo_t *cr, int x, int y, int w, int h,
diff --git a/tests/kms_cursor_crc.c b/tests/kms_cursor_crc.c
index d80695f6..4bcce86f 100644
--- a/tests/kms_cursor_crc.c
+++ b/tests/kms_cursor_crc.c
@@ -87,6 +87,7 @@ connector_set_mode(data_t *data, connector_t *connector, drmModeModeInfo *mode)
kmstest_paint_color(cr, 0, 0, mode->hdisplay, mode->vdisplay,
0.0, 0.0, 0.0);
igt_assert(cairo_status(cr) == 0);
+ cairo_destroy(cr);
#if 0
fprintf(stdout, "Using pipe %c, %dx%d\n", pipe_name(config->pipe),
diff --git a/tests/kms_fbc_crc.c b/tests/kms_fbc_crc.c
index 4cddd274..f3de3103 100644
--- a/tests/kms_fbc_crc.c
+++ b/tests/kms_fbc_crc.c
@@ -105,6 +105,7 @@ static uint32_t create_fb(data_t *data,
cr = kmstest_get_cairo_ctx(data->drm_fd, fb);
kmstest_paint_color(cr, 0, 0, w, h, r, g, b);
igt_assert(cairo_status(cr) == 0);
+ cairo_destroy(cr);
return fb_id;
}
diff --git a/tests/kms_flip.c b/tests/kms_flip.c
index eaa42b5b..6a116a94 100644
--- a/tests/kms_flip.c
+++ b/tests/kms_flip.c
@@ -1003,6 +1003,7 @@ static void paint_flip_mode(struct kmstest_fb *fb, bool odd_frame)
cairo_fill(cr);
igt_assert(!cairo_status(cr));
+ cairo_destroy(cr);
}
static int
diff --git a/tests/kms_pipe_crc_basic.c b/tests/kms_pipe_crc_basic.c
index 3fc59344..f4a97ebb 100644
--- a/tests/kms_pipe_crc_basic.c
+++ b/tests/kms_pipe_crc_basic.c
@@ -100,6 +100,7 @@ connector_set_mode(data_t *data, connector_t *connector, drmModeModeInfo *mode)
kmstest_paint_color(cr, 0, 0, mode->hdisplay, mode->vdisplay,
0.0, 1.0, 0.0);
igt_assert(cairo_status(cr) == 0);
+ cairo_destroy(cr);
#if 0
fprintf(stdout, "Using pipe %c, %dx%d\n", pipe_name(config->pipe),
diff --git a/tests/kms_render.c b/tests/kms_render.c
index 055ebbb8..e661753e 100644
--- a/tests/kms_render.c
+++ b/tests/kms_render.c
@@ -55,8 +55,6 @@ static int paint_fb(struct kmstest_fb *fb, const char *test_name,
cairo_t *cr;
cr = kmstest_get_cairo_ctx(drm_fd, fb);
- if (!cr)
- return -1;
kmstest_paint_color_gradient(cr, 0, 0, fb->width, fb->height, 1, 1, 1);
kmstest_paint_test_pattern(cr, fb->width, fb->height);
@@ -69,6 +67,8 @@ static int paint_fb(struct kmstest_fb *fb, const char *test_name,
kmstest_cairo_printf_line(cr, align_hcenter, 10, "%s", mode_format_str);
kmstest_cairo_printf_line(cr, align_hcenter, 10, "%s", cconf_str);
+ cairo_destroy(cr);
+
return 0;
}
diff --git a/tests/kms_setmode.c b/tests/kms_setmode.c
index e1c9c5a6..c5e86301 100644
--- a/tests/kms_setmode.c
+++ b/tests/kms_setmode.c
@@ -151,8 +151,6 @@ static int paint_fb(struct kmstest_fb *fb, const char *test_name,
int i;
cr = kmstest_get_cairo_ctx(drm_fd, fb);
- if (!cr)
- return -1;
kmstest_paint_test_pattern(cr, fb->width, fb->height);
@@ -176,6 +174,8 @@ static int paint_fb(struct kmstest_fb *fb, const char *test_name,
crtc_str[i]);
}
+ cairo_destroy(cr);
+
return 0;
}
diff --git a/tests/pm_lpsp.c b/tests/pm_lpsp.c
index 492efe10..ede91495 100644
--- a/tests/pm_lpsp.c
+++ b/tests/pm_lpsp.c
@@ -97,6 +97,8 @@ static uint32_t create_fb(int drm_fd, int width, int height)
&fb);
cr = kmstest_get_cairo_ctx(drm_fd, &fb);
kmstest_paint_test_pattern(cr, width, height);
+ cairo_destroy(cr);
+
return buffer_id;
}
diff --git a/tests/pm_pc8.c b/tests/pm_pc8.c
index d6b68e4a..f34a1138 100644
--- a/tests/pm_pc8.c
+++ b/tests/pm_pc8.c
@@ -280,6 +280,8 @@ static struct scanout_fb *create_fb(struct mode_set_data *data, int width,
cr = kmstest_get_cairo_ctx(drm_fd, &fb);
kmstest_paint_test_pattern(cr, width, height);
+ cairo_destroy(cr);
+
return fb_info;
}
diff --git a/tests/testdisplay.c b/tests/testdisplay.c
index dd9e56dd..9109d882 100644
--- a/tests/testdisplay.c
+++ b/tests/testdisplay.c
@@ -507,6 +507,8 @@ static uint32_t create_stereo_fb(drmModeModeInfo *mode, struct kmstest_fb *fb)
layout.right.x, layout.right.y,
layout.right.width, layout.right.height);
+ cairo_destroy(cr);
+
{
char buffer[64];