From: Chris Wilson Date: Mon, 30 Dec 2013 17:48:43 +0000 (+0000) Subject: kmstest: Fix up lifetimes of cairo objects X-Git-Tag: intel-gpu-tools-1.6~215 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=164d9d26ac33029287a24fbed549e3a2858d5d51;p=platform%2Fupstream%2Fintel-gpu-tools.git 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 --- diff --git a/lib/igt_kms.c b/lib/igt_kms.c index 57795b1..3960d24 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 f61f8e5..6f71165 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 d80695f..4bcce86 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 4cddd27..f3de310 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 eaa42b5..6a116a9 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 3fc5934..f4a97eb 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 055ebbb..e661753 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 e1c9c5a..c5e8630 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 492efe1..ede9149 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 d6b68e4..f34a113 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 dd9e56d..9109d88 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];