display:libdrm/libgbm/ion/gem/dma_buf

  下面是一个最简单的case,使用的是dumb buffer显示

1.为什么最终是用fb_id::因为fb_id是对应drm_framebuffer管理,也就是drm机制只认fb_id

目前DRM主要推荐使用的是 Atomic(原子的) 接口;Atomic操作必须依赖的基本元素,Property(属性)。
所谓Property,其实就是把legacy接口传入的参数单独抽出来,做成一个个独立的全局属性。通过设置这些属性参数,即可完成对显示参数的设置。
Property的结构简单概括主要由3部分组成:name、id 和 value。
其中id为该property在DRM框架中全局唯一的标识符。
操作property,通过name 来获取property,通过id 来操作property,通过value 来修改property的值

Property的类型分为如下几种:
	• enum
	• bitmask
	• range
	• signed range
	• object
	• blob

From <https://blog.csdn.net/hexiaolong2009/article/details/87211230> 

drm_property的定义:
https://elixir.bootlin.com/linux/latest/source/include/drm/drm_property.h#L73
对应的详细说明:
https://www.kernel.org/doc/html/latest/gpu/drm-kms.html#c.drm_property


133 typedef struct _drmModeProperty {
134     uint32_t prop_id;
135     uint32_t flags;
136     char name[DRM_PROP_NAME_LEN];
137     int count_values;
138     uint64_t *values; /* store the blob lengths */
139     int count_enums;
140     struct drm_mode_property_enum *enums;
141     int count_blobs;
142     uint32_t *blob_ids; /* store the blob IDs */
143 } drmModePropertyRes, *drmModePropertyPtr;

2.为什么handle可以获得fb_id::是因为handle可以找到对应gem object,而drm为gem object创建drm_framebuffer,随后把这个framebuffer 的fb_id给你

3.需要讲清楚modeset_create_fb里面的过程

#include "xf86drm.h"
#include "xf86drmMode.h"
#include <stdio.h>
#include <stdint.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <sys/mman.h>

struct buffer_object {
    uint32_t width;
    uint32_t height;
    uint32_t pitch;
    uint32_t handle;
    uint32_t size;
    uint8_t *vaddr;
    uint32_t fb_id;
};
struct buffer_object buf;

static void dump_mode(drmModeModeInfo *mode)
{
    printf("  %s %d %d %d %d %d %d %d %d %d %d",
       mode->name,
       mode->vrefresh,
       mode->hdisplay,
       mode->hsync_start,
       mode->hsync_end,
       mode->htotal,
       mode->vdisplay,
       mode->vsync_start,
       mode->vsync_end,
       mode->vtotal,
       mode->clock);

    printf("\n");
}

static int modeset_create_fb(int fd, struct buffer_object *bo)
{
    struct drm_mode_create_dumb create = {};
    struct drm_mode_map_dumb map = {};
     

    create.width = bo->width;
    create.height = bo->height;
    create.bpp = 32;
    drmIoctl(fd, DRM_IOCTL_MODE_CREATE_DUMB, &create);
     
    bo->pitch = create.pitch;
    bo->size = create.size;
    bo->handle = create.handle;
    drmModeAddFB(fd, bo->width, bo->height, 24, 32, bo->pitch,
	       bo->handle, &bo->fb_id);
     
    map.handle = create.handle;
    drmIoctl(fd, DRM_IOCTL_MODE_MAP_DUMB, &map);
     
    bo->vaddr = mmap(0, create.size, PROT_READ | PROT_WRITE,
	    MAP_SHARED, fd, map.offset);
     
    memset(bo->vaddr, 0xff, bo->size/2);
    memset(bo->vaddr + bo->size/2, 0x88, bo->size/2);
     
    return 0;
}

static uint32_t get_property_id(int fd, drmModeObjectProperties *props,
			const char *name)
{
    drmModePropertyPtr property;
    uint32_t i, id = 0;
    for (i = 0; i < props->count_props; i++) {
	property = drmModeGetProperty(fd, props->props[i]);
	if (!strcmp(property->name, name))
	    id = property->prop_id;
	    drmModeFreeProperty(property);
	if (id)
	    break;
    }
    return id;
}


int main(int argc, char **argv)
{
    int drm_fd;
    drmModeRes *res;
    drmModePlaneRes *plane_res;
    drmModeConnector *conn;
    drmModeObjectProperties *props;
    int crtc_id;
    int conn_id;
    int plane_id;
    int property_temp;
    uint32_t blob_id;
    drmModeAtomicReqPtr req = NULL;

    drm_fd = open("/dev/dri/card0", O_RDWR | O_CLOEXEC);
    if (drm_fd < 0) {
	printf("open card error\n");
	return 0;
    }

    res = drmModeGetResources(drm_fd);
    if (!res) {
	printf("getresource error\n");
	return 0;
    }

    crtc_id = res->crtcs[0];
    conn_id = res->connectors[1];

    drmSetClientCap(drm_fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1);
    plane_res = drmModeGetPlaneResources(drm_fd);
    plane_id = plane_res->planes[1];
    printf("plane%d, crtc%d, conn%d\n", plane_id, crtc_id, conn_id);

    conn = drmModeGetConnector(drm_fd, conn_id);
    if (!conn) {
	printf("get conn error\n");
	return 0;
    }

    if (conn->count_modes) {
	printf("print mode counts %d\n", conn->count_modes);
	for (int i = 0; i < conn->count_modes; i++) {
	    dump_mode(&conn->modes[i]);
	    buf.width = conn->modes[i].hdisplay;
	    buf.height = conn->modes[i].vdisplay;
	}
    }

    modeset_create_fb(drm_fd, &buf);

    drmSetClientCap(drm_fd, DRM_CLIENT_CAP_ATOMIC, 1);
    req = drmModeAtomicAlloc();

    props = drmModeObjectGetProperties(drm_fd, conn_id, DRM_MODE_OBJECT_CONNECTOR);
    property_temp = get_property_id(drm_fd, props, "CRTC_ID");
    drmModeAtomicAddProperty(req, conn_id, property_temp, crtc_id);
    drmModeFreeObjectProperties(props);

    drmModeCreatePropertyBlob(drm_fd, &conn->modes[0], sizeof(conn->modes[0]), &blob_id);

    props = drmModeObjectGetProperties(drm_fd, crtc_id, DRM_MODE_OBJECT_CRTC);
    property_temp = get_property_id(drm_fd, props, "ACTIVE");
    drmModeAtomicAddProperty(req, crtc_id, property_temp, 1);
    property_temp = get_property_id(drm_fd, props, "MODE_ID");
    drmModeAtomicAddProperty(req, crtc_id, property_temp, blob_id);
    drmModeFreeObjectProperties(props);

    props = drmModeObjectGetProperties(drm_fd, plane_id, DRM_MODE_OBJECT_PLANE);
    property_temp = get_property_id(drm_fd, props, "CRTC_ID");
    drmModeAtomicAddProperty(req, plane_id, property_temp, crtc_id);
    property_temp = get_property_id(drm_fd, props, "FB_ID");
    drmModeAtomicAddProperty(req, plane_id, property_temp, buf.fb_id);
    property_temp = get_property_id(drm_fd, props, "CRTC_X");
    drmModeAtomicAddProperty(req, plane_id, property_temp, 0);
    property_temp = get_property_id(drm_fd, props, "CRTC_Y");
    drmModeAtomicAddProperty(req, plane_id, property_temp, 0);
    property_temp = get_property_id(drm_fd, props, "CRTC_W");
    drmModeAtomicAddProperty(req, plane_id, property_temp, 1920);
    property_temp = get_property_id(drm_fd, props, "CRTC_H");
    drmModeAtomicAddProperty(req, plane_id, property_temp, 1080);
    property_temp = get_property_id(drm_fd, props, "SRC_X");
    drmModeAtomicAddProperty(req, plane_id, property_temp, 0);
    property_temp = get_property_id(drm_fd, props, "SRC_Y");
    drmModeAtomicAddProperty(req, plane_id, property_temp, 0);
    property_temp = get_property_id(drm_fd, props, "SRC_W");
    drmModeAtomicAddProperty(req, plane_id, property_temp, 1920<<16);
    property_temp = get_property_id(drm_fd, props, "SRC_H");
    drmModeAtomicAddProperty(req, plane_id, property_temp, 1080<<16);
    drmModeFreeObjectProperties(props);

    drmModeAtomicCommit(drm_fd, req, DRM_MODE_ATOMIC_NONBLOCK | DRM_MODE_ATOMIC_ALLOW_MODESET , NULL);
    getchar();

    drmModeFreeConnector(conn);
    drmModeFreePlaneResources(plane_res);
    drmModeFreeResources(res);
    close(drm_fd);
    return 0;
}

 

1. 
drm_public drmModeResPtr drmModeGetResources(int fd)
        drmIoctl(fd, DRM_IOCTL_MODE_GETRESOURCES, &res) //调用ioctl,填充返回的drmModeResPtr
                DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETRESOURCES, drm_mode_getresources, 0), //kernel实现
                        
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值