文章目录
- 前言
- 一、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 720
struct 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