From 52c89b2ccb5a14b854c05bc8d008ad4470fbd377 Mon Sep 17 00:00:00 2001 From: Jeffy Chen Date: Sat, 9 Oct 2021 12:33:33 +0800 Subject: [PATCH 47/95] HACK: pixman-renderer: Support passing dma fd to pixman Usage: pixman_image_set_destroy_function(image, NULL, (void *)(ptrdiff_t)dma_fd) Signed-off-by: Jeffy Chen --- libweston/backend-drm/drm-internal.h | 1 + libweston/backend-drm/drm.c | 3 ++- libweston/backend-drm/fb.c | 15 +++++++++++++++ libweston/pixman-renderer.c | 20 ++++++++++++++++++++ libweston/pixman-renderer.h | 11 +++++++++++ 5 files changed, 49 insertions(+), 1 deletion(-) diff --git a/libweston/backend-drm/drm-internal.h b/libweston/backend-drm/drm-internal.h index c966bd3..f9ccbda 100644 --- a/libweston/backend-drm/drm-internal.h +++ b/libweston/backend-drm/drm-internal.h @@ -324,6 +324,7 @@ struct drm_fb { uint64_t modifier; int width, height; int fd; + int dma_fd; uint32_t plane_mask; diff --git a/libweston/backend-drm/drm.c b/libweston/backend-drm/drm.c index 1f077ed..4a350e7 100644 --- a/libweston/backend-drm/drm.c +++ b/libweston/backend-drm/drm.c @@ -2062,9 +2062,10 @@ drm_output_init_pixman(struct drm_output *output, struct drm_backend *b) goto err; output->renderbuffer[i] = - pixman->create_image_from_ptr(&output->base, + pixman->create_image_from_dma(&output->base, options.format, w, h, output->dumb[i]->map, + output->dumb[i]->dma_fd, output->dumb[i]->strides[0]); if (!output->renderbuffer[i]) goto err; diff --git a/libweston/backend-drm/fb.c b/libweston/backend-drm/fb.c index 769a6bb..34507cb 100644 --- a/libweston/backend-drm/fb.c +++ b/libweston/backend-drm/fb.c @@ -64,6 +64,9 @@ drm_fb_destroy_dumb(struct drm_fb *fb) assert(fb->type == BUFFER_PIXMAN_DUMB); + if (fb->dma_fd >= 0) + close(fb->dma_fd); + if (fb->map && fb->size > 0) munmap(fb->map, fb->size); @@ -263,6 +266,7 @@ drm_fb_create_dumb(struct drm_device *device, int width, int height, struct drm_mode_create_dumb create_arg; struct drm_mode_destroy_dumb destroy_arg; struct drm_mode_map_dumb map_arg; + struct drm_prime_handle prime_arg; fb = zalloc(sizeof *fb); if (!fb) @@ -319,8 +323,19 @@ drm_fb_create_dumb(struct drm_device *device, int width, int height, if (fb->map == MAP_FAILED) goto err_add_fb; + memset(&prime_arg, 0, sizeof(prime_arg)); + prime_arg.fd = -1; + prime_arg.handle = fb->handles[0]; + ret = drmIoctl(fb->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &prime_arg); + if (ret) + goto err_unmap_fb; + + fb->dma_fd = prime_arg.fd; + return fb; +err_unmap_fb: + munmap(fb->map, fb->size); err_add_fb: drmModeRmFB(device->drm.fd, fb->fb_id); err_bo: diff --git a/libweston/pixman-renderer.c b/libweston/pixman-renderer.c index e1d71d5..0998dc3 100644 --- a/libweston/pixman-renderer.c +++ b/libweston/pixman-renderer.c @@ -996,6 +996,8 @@ pixman_renderer_attach_dmabuf(struct weston_surface *es, data->ptr + attributes->offset[0], attributes->stride[0]); + pixman_image_set_dma_fd(ps->image, attributes->fd[0]); + ps->buffer_destroy_listener.notify = buffer_state_handle_buffer_destroy; wl_signal_add(&buffer->destroy_signal, @@ -1745,6 +1747,23 @@ pixman_renderer_create_image_from_ptr(struct weston_output *output, return &renderbuffer->base; } +static struct weston_renderbuffer * +pixman_renderer_create_image_from_dma(struct weston_output *output, + const struct pixel_format_info *format, + int width, int height, uint32_t *ptr, + int dma_fd, int rowstride) +{ + struct weston_renderbuffer *renderbuffer = + pixman_renderer_create_image_from_ptr(output, format, + width, height, + ptr, rowstride); + struct pixman_renderbuffer *rb = + container_of(renderbuffer, struct pixman_renderbuffer, base); + + pixman_image_set_dma_fd(rb->image, dma_fd); + return renderbuffer; +} + static struct weston_renderbuffer * pixman_renderer_create_image(struct weston_output *output, const struct pixel_format_info *format, int width, @@ -1787,6 +1806,7 @@ static struct pixman_renderer_interface pixman_renderer_interface = { .output_create = pixman_renderer_output_create, .output_destroy = pixman_renderer_output_destroy, .create_image_from_ptr = pixman_renderer_create_image_from_ptr, + .create_image_from_dma = pixman_renderer_create_image_from_dma, .create_image = pixman_renderer_create_image, .renderbuffer_get_image = pixman_renderer_renderbuffer_get_image, }; diff --git a/libweston/pixman-renderer.h b/libweston/pixman-renderer.h index e508ef8..7d4b1db 100644 --- a/libweston/pixman-renderer.h +++ b/libweston/pixman-renderer.h @@ -30,6 +30,10 @@ #include "libweston-internal.h" #include "pixman.h" +/* HACK: Pass dma fd to pixman through destroy data */ +#define pixman_image_set_dma_fd(image, fd) \ + pixman_image_set_destroy_function(image, NULL, (void *)(ptrdiff_t)fd) + int pixman_renderer_init(struct weston_compositor *ec); @@ -53,6 +57,13 @@ struct pixman_renderer_interface { int height, uint32_t *ptr, int stride); + struct weston_renderbuffer *(*create_image_from_dma)(struct weston_output *output, + const struct pixel_format_info *format, + int width, + int height, + uint32_t *ptr, + int dma_fd, + int stride); struct weston_renderbuffer *(*create_image)(struct weston_output *output, const struct pixel_format_info *format, int width, int height); -- 2.20.1