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基本概念介紹和原理分析[轉]

 

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