美文网首页
Android 图形系统(10)---- libdrm 基本AP

Android 图形系统(10)---- libdrm 基本AP

作者: 特立独行的佩奇 | 来源:发表于2023-04-12 17:34 被阅读0次

    DRM 框架基础

    drm_object.jpg

    drm 驱动使用的基本概念:


    drm_概念.jpg

    libdrm API 调用栈

    使用 atomic 方法显示画面的调用方法如下:

    • 初始化设备,获取所有Object 的 id 和 prop id 信息
      open(/dev/dri/card0) //open drm device
      --> drmSetClientCap(DRM_CLIENT_CAP_UNIVERSAL_PLANES)
      --> drmSetClientCap(DRM_CLIENT_CAP_ATOMIC)
      --> drmModeGetResources() // connector,encoder,crtc count 和 id 信息
      --> drmModeGetConnector() // 获取 connector 的 id 和 prop 信息
      --> drmModeObjectGetProperties()
      --> drmModeGetEncoder()
      --> drmModeGetCrtc() //获取crtc id 和 fb id 信息
      --> drmGetPlaneByType(DRM_PLANE_TYPE_PRIMARY)
      --> drmModeObjectGetProperties(plane_id,DRM_MODE_OBJECT_PLANE)
      --> drmModeGetProperty() //get drm info like crtc_id,fb_id and so on,they be used for commit

    drmIoctl(DRM_IOCTL_MODE_CREATE_DUMB) //创建dumb buffer(只支持连续物理内存,基于kernel中通用CMA API实现)
    --> drmIoctl(DRM_IOCTL_MODE_MAP_DUMB) //获取dumb buffer的映射偏移值
    --> mmap() //通过mmap映射内核空间到应用层
    --> drmPrimeHandleToFD(fd,handle,0,&fd2) //handle已和fd绑定,在此将fd2与handle绑定,即fd2同fd相同
    --> drmModeAddFB2() //添加framebuffer

    drmModeAtomicAlloc //申请Atomic结构
    --> drmModeAtomicAddProperty() //将前面获取的crtc_id,fb_id等参数都传入申请的Atomic结构中
    --> drmModeAtomicCommit() //提交数据到display

    drmModeRmFB(fb_id) //删除drmModeAddFB2()添加的framebuffer,不然会造成shmem泄露
    --> munmap() //释放mmap映射的内存
    --> close() //关闭打开的drm句柄

    DRM 相关API解析

    android 下代码路径:
    external/libdrm/xf86drmMode.h
    external/libdrm/xf86drm.h
    API 和相应的 IOCTL CMD 对应关系如下


    libdrm_interface.jpg
    drmSetClientCap

    extern int drmSetClientCap(int fd, uint64_t capability, uint64_t value);
    设置 drm 的capability 属性,可以选择的属性如下:
    #define DRM_CLIENT_CAP_STEREO_3D 1
    #define DRM_CLIENT_CAP_UNIVERSAL_PLANES 2
    #define DRM_CLIENT_CAP_ATOMIC 3

    一般需要设置的属性:DRM_CLIENT_CAP_UNIVERSAL_PLANES 和 DRM_CLIENT_CAP_ATOMIC
    drmSetClientCap(dev->fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1);
    drmSetClientCap(dev->fd, DRM_CLIENT_CAP_ATOMIC, 1);

    drmGetVersion

    获取drm_driver 的major version,minor version 和name 相关信息,name是char 类型的数组,空间是 libdrm 分配的
    extern drmVersionPtr drmGetVersion(int fd);

    typedef struct _drmVersion {
        int     version_major;        /**< Major version */
        int     version_minor;        /**< Minor version */
        int     version_patchlevel;   /**< Patch level */
        int     name_len;             /**< Length of name buffer */
        char    *name;            /**< Name of driver */
        int     date_len;             /**< Length of date buffer */
        char    *date;                /**< User-space buffer to hold date */
        int     desc_len;             /**< Length of desc buffer */
        char    *desc;                /**< User-space buffer to hold desc */
    } drmVersion, *drmVersionPtr;
    
    drmModeGetResources

    drmModeResPtr drmModeGetResources(int fd)
    获取 connector,encoder,crtc 的数量和ID信息,注意不包含 plane 的相关信息

    typedef struct _drmModeRes {
        int count_fbs;
        uint32_t *fbs;
    
        int count_crtcs;
        uint32_t *crtcs;
    
        int count_connectors;
        uint32_t *connectors;
    
        int count_encoders;
        uint32_t *encoders;
    
        uint32_t min_width, max_width;
        uint32_t min_height, max_height;
    } drmModeRes, *drmModeResPtr;
    

    通过 void drmModeFreeResources(drmModeResPtr ptr) Free

    drmModeGetPlaneResources

    drmModePlaneResPtr drmModeGetPlaneResources(int fd)
    返回plane 的数量和id 信息

    typedef struct _drmModePlaneRes {
        uint32_t count_planes;
        uint32_t *planes;
    } drmModePlaneRes, *drmModePlaneResPtr;
    

    通过 void drmModeFreePlaneResources(drmModePlaneResPtr ptr) free

    drmModeGetPlane

    drmModePlanePtr drmModeGetPlane(int fd, uint32_t plane_id)
    传入 plane id 的值,获取plane 的详细信息,注意没有包含 plane 的 prop 信息

    typedef struct _drmModePlane {
        uint32_t count_formats;
        uint32_t *formats;
        uint32_t plane_id;
    
        uint32_t crtc_id;
        uint32_t fb_id;
    
        uint32_t crtc_x, crtc_y;
        uint32_t x, y;
    
        uint32_t possible_crtcs;
        uint32_t gamma_size;
    } drmModePlane, *drmModePlanePtr;
    

    通过 void drmModeFreePlane(drmModePlanePtr ptr) Free

    drmModeGetConnector

    drmModeConnectorPtr drmModeGetConnector(int fd, uint32_t connector_id)
    根据connector ID获取到 connector 的相关信息,包含 connector 的prop信息,prop 的值;encoder 的数量和 encoder 的 ID信息
    connector 相应的信息如下:

    typedef struct _drmModeConnector {
        uint32_t connector_id;
        uint32_t encoder_id; /**< Encoder currently connected to */
        uint32_t connector_type;
        uint32_t connector_type_id;
        drmModeConnection connection;
        uint32_t mmWidth, mmHeight; /**< HxW in millimeters */
        drmModeSubPixel subpixel;
    
        int count_modes;
        drmModeModeInfoPtr modes;
    
        int count_props;
        uint32_t *props; /**< List of property ids */
        uint64_t *prop_values; /**< List of property values */
    
        int count_encoders;
        uint32_t *encoders; /**< List of encoder ids */
    } drmModeConnector, *drmModeConnectorPtr;
    

    通过 void drmModeFreeConnector(drmModeConnectorPtr ptr) Free

    drmModeGetEncoder

    drmModeEncoderPtr drmModeGetEncoder(int fd, uint32_t encoder_id)
    获取encoder 的详细信息,注意没有包含prop 的 id 信息

    typedef struct _drmModeEncoder {
        uint32_t encoder_id;
        uint32_t encoder_type;
        uint32_t crtc_id;
        uint32_t possible_crtcs;
        uint32_t possible_clones;
    } drmModeEncoder, *drmModeEncoderPtr;
    

    通过void drmModeFreeEncoder(drmModeEncoderPtr ptr) Free

    drmModeGetCrtc

    drmModeCrtcPtr drmModeGetCrtc(int fd, uint32_t crtcId)
    获取Crtc 的详细信息,注意不包含 prop相关信息

    typedef struct _drmModeCrtc {
        uint32_t crtc_id;
        uint32_t buffer_id; /**< FB id to connect to 0 = disconnect */
    
        uint32_t x, y; /**< Position on the framebuffer */
        uint32_t width, height;
        int mode_valid;
        drmModeModeInfo mode;
    
        int gamma_size; /**< Number of gamma stops */
    
    } drmModeCrtc, *drmModeCrtcPtr;
    
    

    通过 void drmModeFreeCrtc(drmModeCrtcPtr ptr) free

    drmModeObjectGetProperties

    drmModeObjectPropertiesPtr drmModeObjectGetProperties(int fd, uint32_t object_id, uint32_t object_type)
    获取 crtc,plane,Encoder 和 connector 所有的prop信息

    typedef struct _drmModeObjectProperties {
        uint32_t count_props;
        uint32_t *props;
        uint64_t *prop_values;
    } drmModeObjectProperties, *drmModeObjectPropertiesPtr;
    

    其中的 uint32_t object_id, uint32_t object_typ 需要相互对应,可以选择的组合如下:

    #define DRM_MODE_OBJECT_CRTC 0xcccccccc
    #define DRM_MODE_OBJECT_CONNECTOR 0xc0c0c0c0
    #define DRM_MODE_OBJECT_ENCODER 0xe0e0e0e0
    #define DRM_MODE_OBJECT_MODE 0xdededede
    #define DRM_MODE_OBJECT_PROPERTY 0xb0b0b0b0
    #define DRM_MODE_OBJECT_FB 0xfbfbfbfb
    #define DRM_MODE_OBJECT_BLOB 0xbbbbbbbb
    #define DRM_MODE_OBJECT_PLANE 0xeeeeeeee
    #define DRM_MODE_OBJECT_ANY 0

    void drmModeFreeObjectProperties(drmModeObjectPropertiesPtr ptr)

    drmModeGetProperty

    drmModePropertyPtr drmModeGetProperty(int fd, uint32_t property_id)
    针对 drmModeObjectGetProperties 获取到的 prop id,获取到更加详细的 prop 信息,获取到每个prop 的name 和 value 信息

    typedef struct _drmModeProperty {
        uint32_t prop_id;
        uint32_t flags;
        char name[DRM_PROP_NAME_LEN];
        int count_values;
        uint64_t *values; /* store the blob lengths */
        int count_enums;
        struct drm_mode_property_enum *enums;
        int count_blobs;
        uint32_t *blob_ids; /* store the blob IDs */
    } drmModePropertyRes, *drmModePropertyPtr;
    

    通过接口 void drmModeFreeProperty(drmModePropertyPtr ptr) free

    相关文章

      网友评论

          本文标题:Android 图形系统(10)---- libdrm 基本AP

          本文链接:https://www.haomeiwen.com/subject/erqoddtx.html