文章目录
- 前言
- 一、zwp_linux_dmabuf_v1 协议
- 二、wayland client 使用 zwp_linux_dmabuf_v1 协议传递dma-buf代码实例
- 1. wayland_dmabuf.c 代码实例
- 2. xdg-shell-protocol.c 和 xdg-shell-client-protocol.h
- 3. linux-dmabuf-unstable-v1-client-protocol.h 和 linux-dmabuf-unstable-v1-protocol.c
- 4. 编译
- 5. 运行
- 总结
- 参考资料
前言
本文主要介绍如何在wayland client import 其他模块导出dma-buf, 送给wayland server(weston) 显示
软硬件环境:
硬件:aarch64
软件: weston8.0 kernel5.10
一、zwp_linux_dmabuf_v1 协议
zwp_linux_dmabuf_v1 是 Wayland 协议中的一个扩展,用于在 Wayland 中传输 DMA-BUF 对象
zwp_linux_dmabuf_v1 协议中和 dma-buf 相关的主要函数接口如下:
zwp_linux_dmabuf_v1_create_params()
zwp_linux_buffer_params_v1_add()
zwp_linux_buffer_params_v1_create()
zwp_linux_buffer_params_v1_add_listener()
zwp_linux_buffer_params_v1_destroy()
在使用zwp_linux_dmabuf_v1 之前,需要使用 weston-info 命令查看一下,当前运行的wayland server 都支持哪些像素格式(包括modifier)的dma-buf
如下图所示,是在ubuntu22.04上执行 weston-info 命令,得到的相关打印
二、wayland client 使用 zwp_linux_dmabuf_v1 协议传递dma-buf代码实例
本实例是以 /dev/dma_heap/linux,cma 节点作为dmabuf export ,得到一个分辨率为 640x480 格式为ARGB8888 的dma-buf, 使用mmap ,对齐赋值, 实现一个纯蓝色填充;
要运行wayland client 程序,需要先运行一个wayland server(比如weston)
1. wayland_dmabuf.c 代码实例
#include <wayland-client.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include "xdg-shell-client-protocol.h"
#include "linux-dmabuf-unstable-v1-client-protocol.h"#include <linux/dma-heap.h>
#include <linux/dma-buf.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <unistd.h>#include <drm/drm_fourcc.h>#define WIDTH 1920
#define HEIGHT 720struct wl_display *display = NULL;
struct wl_compositor *compositor = NULL;
struct xdg_wm_base *wm_base = NULL;
struct wl_registry *registry = NULL;
struct zwp_linux_dmabuf_v1 *dmabuf;
struct zwp_linux_buffer_params_v1 *params;
uint32_t drm_format;
bool requested_format_found;
struct wl_buffer *buffer;struct window {struct wl_surface *surface;struct wl_callback *callback;struct xdg_surface *xdg_surface;struct xdg_toplevel *xdg_toplevel;
};static uint32_t
parse_format(const char fmt[4])
{return fourcc_code(fmt[0], fmt[1], fmt[2], fmt[3]);
}static void
dmabuf_format(void *data, struct zwp_linux_dmabuf_v1 *zwp_linux_dmabuf,uint32_t format)
{uint32_t *drm_format = data;if (format == *drm_format)requested_format_found = true;
}#if 0
static void
dmabuf_modifier(void *data, struct zwp_linux_dmabuf_v1 *zwp_linux_dmabuf,uint32_t format, uint32_t modifier_hi, uint32_t modifier_lo)
{
}
#endif
static const struct zwp_linux_dmabuf_v1_listener dmabuf_listener = {dmabuf_format//dmabuf_modifier
};static void
xdg_wm_base_ping(void *data, struct xdg_wm_base