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; - - 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); - - return surface; + struct kmstest_fb *fb = arg; + munmap(cairo_image_surface_get_data(fb->cairo_surface), fb->size); } -static cairo_t *create_cairo_ctx(int fd, struct kmstest_fb *fb) +cairo_surface_t *kmstest_get_cairo_surface(int fd, struct kmstest_fb *fb) { - cairo_t *cr; - cairo_surface_t *surface; + 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); - surface = create_image_surface(fd, fb); + cairo_surface_set_user_data(fb->cairo_surface, + (cairo_user_data_key_t *)kmstest_get_cairo_surface, + fb, __kmstest_destroy_cairo_surface); + } + + gem_set_domain(fd, fb->gem_handle, + I915_GEM_DOMAIN_CPU, I915_GEM_DOMAIN_CPU); + + igt_assert(cairo_surface_status(fb->cairo_surface) == CAIRO_STATUS_SUCCESS); + return cairo_surface_reference(fb->cairo_surface); +} + +cairo_t *kmstest_get_cairo_ctx(int fd, struct kmstest_fb *fb) +{ + cairo_surface_t *surface; + cairo_t *cr; + + 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];