tools:modetest代码逻辑

参考代码:https://cgit.freedesktop.org/mesa/drm/tree/tests/modetest

modetest本质上是设置property,加载图片,显示单一静态图片.

main 函数
1.解析输入参数

    parse_plane 图像格式,分辨率长宽,绑定的crtcid
        struct plane_args 里面有:                        
	        uint32_t crtc_id;& unsigned int fb_id; 印证plane是fb与crtc的桥梁。绑定crtc与framebuffer
	        bool has_position;& int32_t x, y;& uint32_t w, h; 位置大小
	        double scale; 支持缩放
	        struct bo *bo;
	        char format_str[5];& unsigned int fourcc;  图像格式
    parse_connector 图像格式,绑定的ctrcid,connectorid,刷新率
        贴一段pipe_args的注释:
            Mode setting with the kernel interfaces is a bit of a chore. First you have to find the connector in question and make sure the requested mode is available. Then you need to find the encoder attached to that connector so you can bind it with a free crtc.
            这也是为什么结构体叫做pipe_args.你需要对应crtc->encoder->connector;而这个通路,称为pipe
        struct pipe_args 里面有:
    	    const char **cons;& uint32_t *con_ids;& unsigned int num_cons; connector名字,数量,id
	        uint32_t crtc_id;& struct crtc *crtc; 真正的crtc结构体和crtc id
	        char mode_str[64];&  drmModeModeInfo *mode; &unsigned int vrefresh; 图像模式
	        char format_str[5];& unsigned int fourcc; 图像格式
	        uint32_t mode_blob_id;
	        unsigned int fb_id[2], current_fb_id; 对应两个framebuffer,pagefilp用来解决tearseffect
	        struct timeval start;& int swap_count;时间戳与fb置换次数;计算帧率
    parse_property 
        property是什么,干嘛的:https://blog.csdn.net/u012839187/article/details/89927507
        struct property_args里面有
    	    uint32_t obj_id;
	        uint32_t obj_type;
	        char name[DRM_PROP_NAME_LEN+1];
	        uint32_t prop_id;
	        uint64_t value;

2.util_open

    drmOpen 打开 DRM_DIR_NAME/DRM_DEV_NAME,返回fd,并且调用ioctl->DRM_IOCTL_VERSION,将内容传入_drmVersion结构体;
            /dev/dri/card%d 多数情况是这个

3.drmSetClientCap(dev.fd, DRM_CLIENT_CAP_ATOMIC, 1) & page_flipping_supported  & cursor_supported

    确认drm是否支持atomic
    ioctl->DRM_IOCTL_SET_CLIENT_CAP(DRM_CLIENT_CAP_ATOMIC) 设置atomic-flag 0不支持,1支持 
    
    page-flip设置
    确认page-flip是否支持,目前没有统一实现,因为各家厂商不同
    确认cursor是否支持,目前没有统一实现,因为各家厂商不同

5.get_resources 填充resources结构体
    

drmSetClientCap 设置atomic/universal_planes 为1。
    DRM_CLIENT_CAP_UNIVERSAL_PLANES
            If set to 1, the DRM core will expose all planes (overlay, primary, and cursor) to userspace.
    DRM_CLIENT_CAP_ATOMICI
            If set to 1, the DRM core will expose atomic properties to userspace
    
drmModeGetResources ioctl->DRM_IOCTL_MODE_GETRESOURCES 获取fb/crtc/connector/encoder的id与数量;
drmModeGetCrtc/Encoder/Connector/FB/Plane ioctl DRM_IOCTL_MODE_GETCRTC/ENCODER/CONNECTOR/FB/PLANE
drmModeObjectGetProperties ioctl->DRM_IOCTL_MODE_OBJ_GETPROPERTIES(CRTC/CONNECTOR/PLANE),ioctl->DRM_IOCTL_MODE_GETPROPERTY

struct resources {
	drmModeRes *res;
	drmModePlaneRes *plane_res;

	struct crtc *crtcs;
	struct encoder *encoders;
	struct connector *connectors;
	struct fb *fbs;
	struct plane *planes;
};

6.pipe_resolve_connectors pipe与connector通过id绑定。

pipe->con_ids[i] = connector->connector_id;

7.dump_resource 
    dump_encoders/connectors/crtcs/plans/framebuffers  dump日志

8.set_property 

    drmModeObjectSetProperty(CRTC/CONNECTOR/PLANE)
    drmModeAtomicAddProperty

9.drmGetCap ioctl->DRM_IOCTL_GET_CAP(DRM_CAP_DUMB_BUFFER)

判断是否支持dumb_buffer对应的操作

dumb-buffer是什么
    https://www.systutorials.com/docs/linux/man/7-drm-memory/

Almost all in-kernel DRM hardware drivers support an API called Dumb-Buffers. This API allows to create buffers of arbitrary size that can be used for scanout. These buffers can be memory mapped via mmap(2) so you can render into them on the CPU. However, GPU access to these buffers is often not possible. Therefore, they are fine for simple tasks but not suitable for complex compositions and renderings.
几乎所有的内核DRM硬件驱动程序都支持一个称为Dumb-Buffers的API。该API允许创建可用于扫描的任意大小的缓冲区。这些缓冲区可以通过mmap(2)进行内存映射,这样就可以在CPU上渲染它们。然而,GPU访问这些缓冲区通常是不可能的。因此,它们适合简单的任务,但不适合复杂的合成和渲染。
The DRM_IOCTL_MODE_CREATE_DUMB ioctl can be used to create a dumb buffer. The kernel will return a 32bit handle that can be used to manage the buffer with the DRM API. You can create framebuffers with drmModeAddFB(3) and use it for mode-setting and scanout. To access the buffer, you first need to retrieve the offset of the buffer. The DRM_IOCTL_MODE_MAP_DUMB ioctl requests the DRM subsystem to prepare the buffer for memory-mapping and returns a fake-offset that can be used with mmap(2).
DRM_IOCTL_MODE_CREATE_DUMB ioctl可以用来创建dumb缓冲区。内核将返回一个32位handle,可以使用此句柄用DRM API来管理缓冲区。您可以使用drmModeAddFB(3)创建framebuffer,并将其用于模式设置和扫描。要访问缓冲区,首先需要检索缓冲区的偏移量。DRM_IOCTL_MODE_MAP_DUMB ioctl请求DRM子系统为内存映射准备缓冲区,并返回一个可以与mmap(2)一起使用的伪偏移量。

创建dumb缓冲区,返回handle,在create_arg保存
drmIoctl(fd, DRM_IOCTL_MODE_CREATE_DUMB, &create_arg);

准备映射的缓冲区内存,返回偏移量给map_arg保存
drmIoctl(fd, DRM_IOCTL_MODE_MAP_DUMB, &map_arg);

完成最终映射,用到了dumb的handle和offset
mmap(0, create_arg.size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, map_arg.offset);

绑定在framebuffer上面
drmIoctl(fd, DRM_IOCTL_MODE_ADDFB2, &cmd2);

10.set_mode 全局

    pipe_find_crtc_and_mode 获取mode。填充_drmModeModeInfo结构体,包括clock,hdisplay, hsync_start, hsync_end, htotal, hskew,vdisplay, vsync_start, vsync_end, vtotal, vscan,vrefresh,等;设置pipe的crtc
    bo_create【全局大小】//创建buffer实例,塞入dev->mode.bo
        bo_create_dumb open"/dev/ion",ioctl->ION_IOC_ALLOC/ION_IOC_MAP/DRM_IOCTL_PRIME_FD_TO_HANDLE
        bo_map
        util_fill_pattern Fill a buffer with a test pattern
    drmModeAddFB2    //管理buffer实例,返回dev->mode.fb_id
        bo_create 是负责创建buffer的, addfb2,只是把这个buffer的handle用fb_id 表示出来,适配drm架构
    atomic_populate_pipe_modeset或者drmModeSetCrtc
        设置对应的property
    drmModeDirtyFB flush frontbuffer rendering on an FB
        查找FB并将用户空间提供的损坏区域冲洗掉,作为剪辑矩形列表。执行前缓冲区渲染的通用用户空间必须调用此ioctl来刷新手动更新显示输出上的更改,例如USB显示链接,MIPI手动更新面板或EDP面板自刷新模式。始终更新前缓冲区的模式设置驱动程序不需要实现相应的&drm_framebuffer_funcs.dirty回调。

11.set_planes

    bo_create【局部大小】
    drmModeAddFB2
        bo_create 是负责创建buffer的, addfb2,只是把这个buffer的handle用fb_id 表示出来,适配drm架构
    atomic_populate_plane或者drmModeSetPlane 设置属性,fbid,src_xywh,crtc_xywh/id
         设置对应的property

12.set_cursors 操作与set_plane基本一致。

cursor在这里大概是鼠标。

另外一种看代码像是索引,用来支持atomic property的增加

13.drmModeAtomicCommit

 ioctl->DRM_IOCTL_MODE_ATOMIC设置atomic相关;提交所有atomic的commit
        Changes are applied at next vblank, unless marked asynchronous 

 

10-14完成一次commit的提交 

14.test_page_flip&drmDropMaster

15.clear_cursors&clear_planes&clear_mode

 

ION基本概念介绍和原理分析[转]

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章