• 常见Soc平台图形内存管理学习笔记


    硬件编解码、硬件图像scale等过程,是在专有的硬件单元里进行,其使用的内存也是专有的内存,这种内存多是SoC中图形内存。如此方便与硬件加速图形渲染、图像显示、硬件图像加速处理等功能相交互。
    上述过程在使用图形内存时,自然需要使用对应的图形内存管理API。常见的图形内存管理API有以下几种:

    1,DRM

    主要是只其中的内存管理部分,包括dumb-buffer和GEM(Graphics Execution Manager)的两种类型接口。具体的驱动根据芯片支持情况做实现,并且为用户态提供相应的API。

    1.1 dumb-buffer

    其较为通用,分配之后可以做映射处理,获取一个用户态的指针,后续可据此在向图形内存中写入数据,但此种方式不能保证图形内存中数据缓存的一致性。其一般使用流程是
    a) open() drm 设备节点,多是 /dev/dri/card0 等,得到设备操作fd句柄
    b) ioctl(fd, DRM_IOCTL_MODE_CREATE_DUMB, )创建一个 dumb-buffer ,获取buffer句柄。需要指定 宽高/BPP 等参数
    c) ioctl(fd, DRM_IOCTL_MODE_MAP_DUMB, ) 根据该buffer对象的伪offset
    d) mmap(, offset) 将该buffer对象映射到用户态,获得一个指针,后续就可以向其中写入数据了
    e) ioctl(fd, DRM_IOCTL_MODE_DESTROY_DUMB, ) 销毁 dumb-buffer 对象

    1.2 GEM buffer

    除了dumb-buffer所提供的功能外,对于创建和读写操作,厂商多是额外提供专有的API来进行,如此完成读写的同时,可以在其中进行缓存一致性的操作;而且GEM可以为每个Buffer对象分配一个32bit的名字,用于跨进程传递。
    其使用流程一般是,以 Intel i915 系列平台威力
    a) open() drm 设备节点,多是 /dev/dri/card0 等,得到设备操作fd句柄
    b) ioctl(fd, DRM_IOCTL_I915_GEM_CREATE, struct drm_i915_gem_create) 创建一个 GEM buffer对象,获取其 handle,简单指定尺寸即可。
    c) ioctl(fd, DRM_IOCTL_I915_GEM_PREAD, struct drm_i915_gem_pread)/ioctl(fd, DRM_IOCTL_I915_GEM_PWRITE, struct drm_i915_gem_pwrite)进行读写,可以保证缓存一致性
    ioctl(fd, DRM_IOCTL_I915_GEM_MMAP, struct drm_i915_gem_mmap) 获取一个用户态的映射指针,不保证缓存一致性
    d) ioctl(fd, DRM_IOCTL_GEM_CLOSE, struct drm_gem_close) 释放刚才的 GEM buffer对象

    获取GEM Buffer对象名,以及跨进程传递流程如下
    a) ioctl(fd, DRM_IOCTL_GEM_FLINK, struct drm_gem_flink) 获取 GEM Buffer 的名字
    b) ioctl(fd, DRM_IOCTL_GEM_OPEN, struct drm_gem_open) 根据名字,获取对应 GEM Buffer对象在当前进程内的 handle

    GEM Buffer对象实现是引用计数的,当所有用户态handle全部关闭时,其才被真正释放。

    2,ION

    ION是Google提出的一套纯粹的图形内存管理API,在现在Android系统中支持的比较广泛。其使用方式和GEM有些类似,也可以跨进程传递Buffer句柄,来将不同的图形任务分散到不同的进程中进行(Android系统实际上就是这么做的)
    其基本使用流程为
    a) open() drm 设备节点,多是 /dev/ion,得到设备操作fd句柄
    b) ioctl(fd, ION_IOC_ALLOC, struct ion_allocation_data) 分配,返回 struct ion_handle,简单指定尺寸信息即可。
    b) ioctl(fd, ION_IOC_FREE, struct ion_handle_data) 释放
    c) ioctl(fd, ION_IOC_SHARE, struct ion_fd_data)/ioctl(fd, ION_IOC_MAP, struct ion_fd_data) 返回 ION Buffer对象的 fd 表示,
    后续可用此 fd 调用 mmap() 获取用户天指针,或跨进程传递
    d) ioctl(fd, ION_IOC_IMPORT, struct ion_fd_data) 根据别处提供的fd,获取本地的 struct ion_handle
    e) ioctl(fd, ION_IOC_SYNC, struct ion_fd_data) 对 ION Buffer做缓存刷新,保证一致性。

    3, 厂商私有的API

    3.1 Allwinner A20平台,其硬件编解码单元cedar,在用户态的提供的图形内存的接口就是一套私有的API,具体请见 https://github.com/allwinner-zh/media-codec/tree/master/sunxi-cedarx/SOURCE/common
    其提供的API具体访问的设备节点是 /dev/cedar_dev, 详情见 ve.h/ve_alloc.h 中的API和对应实现。

    3.2 Intel HD系列集成GPU平台,其图形内存的管理API是在libva中,具体硬件访问是在 libva 的用户态后端 vaapi-driver 中进行的。
    其中使用 VASurface 名词表示图形内存对象,其创建是需要制定 宽高/像素格式 基本参数。其使用时需要先获取一个 VADisplay 对象,而获取该对象的入口在 Android/DRM/Wayland 不同的显示后端上有不同入口。详细见libva 的API说明。

    [update 2020/3/24] libva是 VA-API的实现,背后依赖各个厂家提供的驱动。VA-API如其名(Video Acceleration),是硬件视频加速处理的一套API规范,并非Intel专有,ADM/Nvidia平台上其实也有相应的支持。libva图形内存管理的工作是用其他组来实现的,比如DRM/GLX/XWindow。

    3.3 UMP(Unified Memory Provider)
    是ARM平台下一套内存管理机制接口。

  • 相关阅读:
    bfs入门 (HDU
    Codeforces Round #570 (Div. 3)B
    nyoj 277-车牌号 (map, pair, iterator)
    nyoj 276-比较字母大小 (顺序比较, 逆序输出)
    nyoj 275-队花的烦恼一 (stack, push, pop)
    nyoj 274-正三角形的外接圆面积 (R = PI * a * a / 3)
    nyoj 273-字母小游戏 (getline(cin, string))
    nyoj 268-荷兰国旗问题 (count)
    nyoj 266-字符串逆序输出 (isdigit(), geline(cin, my_string))
    nyoj 264-国王的魔镜 (string[-1:-int(str_len/2+1):-1])
  • 原文地址:https://www.cnblogs.com/lanyuliuyun/p/8998864.html
Copyright © 2020-2023  润新知