本文参考以下博文:
Linux内核4.14版本——drm框架分析(1)——drm简介
特此致谢!
1. 简介
framebuffer是一块内存区域,可以理解为一块画布,驱动和应用层都能访问它。绘制前需要将它格式化,设定绘制的色彩模式(例如RGB24,YUV 等)和画布的大小(分辨率),不负责显存的分配释放。
framebuffer在系统中的位置和作用如下所示:
2. 核心结构
在Linux内核的DRM中,framebuffer对应的核心结构体为:struct drm_framebuffer。该结构体在include/drm/drm_framebuffer.h中定义,代码如下(Linux内核版本:6.1):
/**
* struct drm_framebuffer - frame buffer object
*
* Note that the fb is refcounted for the benefit of driver internals,
* for example some hw, disabling a CRTC/plane is asynchronous, and
* scanout does not actually complete until the next vblank. So some
* cleanup (like releasing the reference(s) on the backing GEM bo(s))
* should be deferred. In cases like this, the driver would like to
* hold a ref to the fb even though it has already been removed from
* userspace perspective. See drm_framebuffer_get() and
* drm_framebuffer_put().
*
* The refcount is stored inside the mode object @base.
*/
struct drm_framebuffer {
/**
* @dev: DRM device this framebuffer belongs to
*/
struct drm_device *dev;
/**
* @head: Place on the &drm_mode_config.fb_list, access protected by
* &drm_mode_config.fb_lock.
*/
struct list_head head;
/**
* @base: base modeset object structure, contains the reference count.
*/
struct drm_mode_object base;
/**
* @comm: Name of the process allocating the fb, used for fb dumping.
*/
char comm[TASK_COMM_LEN];
/**
* @format: framebuffer format information
*/
const struct drm_format_info *format;
/**
* @funcs: framebuffer vfunc table
*/
const struct drm_framebuffer_funcs *funcs;
/**
* @pitches: Line stride per buffer. For userspace created object this
* is copied from drm_mode_fb_cmd2.
*/
unsigned int pitches[DRM_FORMAT_MAX_PLANES];
/**
* @offsets: Offset from buffer start to the actual pixel data in bytes,
* per buffer. For userspace created object this is copied from
* drm_mode_fb_cmd2.
*
* Note that this is a linear offset and does not take into account
* tiling or buffer layout per @modifier. It is meant to be used when
* the actual pixel data for this framebuffer plane starts at an offset,
* e.g. when multiple planes are allocated within the same backing
* storage buffer object. For tiled layouts this generally means its
* @offsets must at least be tile-size aligned, but hardware often has
* stricter requirements.
*
* This should not be used to specifiy x/y pixel offsets into the buffer
* data (even for linear buffers). Specifying an x/y pixel offset is
* instead done through the source rectangle in &struct drm_plane_state.
*/
unsigned int offsets[DRM_FORMAT_MAX_PLANES];
/**
* @modifier: Data layout modifier. This is used to describe
* tiling, or also special layouts (like compression) of auxiliary
* buffers. For userspace created object this is copied from
* drm_mode_fb_cmd2.
*/
uint64_t modifier;
/**
* @width: Logical width of the visible area of the framebuffer, in
* pixels.
*/
unsigned int width;
/**
* @height: Logical height of the visible area of the framebuffer, in
* pixels.
*/
unsigned int height;
/**
* @flags: Framebuffer flags like DRM_MODE_FB_INTERLACED or
* DRM_MODE_FB_MODIFIERS.
*/
int flags;
/**
* @hot_x: X coordinate of the cursor hotspot. Used by the legacy cursor
* IOCTL when the driver supports cursor through a DRM_PLANE_TYPE_CURSOR
* universal plane.
*/
int hot_x;
/**
* @hot_y: Y coordinate of the cursor hotspot. Used by the legacy cursor
* IOCTL when the driver supports cursor through a DRM_PLANE_TYPE_CURSOR
* universal plane.
*/
int hot_y;
/**
* @filp_head: Placed on &drm_file.fbs, protected by &drm_file.fbs_lock.
*/
struct list_head filp_head;
/**
* @obj: GEM objects backing the framebuffer, one per plane (optional).
*
* This is used by the GEM framebuffer helpers, see e.g.
* drm_gem_fb_create().
*/
struct drm_gem_object *obj[DRM_FORMAT_MAX_PLANES];
};
3. drm_connector结构释义
(0)总述
/**
* struct drm_framebuffer - frame buffer object
*
* Note that the fb is refcounted for the benefit of driver internals,
* for example some hw, disabling a CRTC/plane is asynchronous, and
* scanout does not actually complete until the next vblank. So some
* cleanup (like releasing the reference(s) on the backing GEM bo(s))
* should be deferred. In cases like this, the driver would like to
* hold a ref to the fb even though it has already been removed from
* userspace perspective. See drm_framebuffer_get() and
* drm_framebuffer_put().
*
* The refcount is stored inside the mode object @base.
*/
struct drm_framebuffer —— frame buffer对象。
注意,fb是为了驱动程序内部的益处而引用计数的,例如一些硬件,禁用CRTC/plane是异步的,并且扫描输出实际上直到下一个vblank才完成。因此,一些清理工作(如释放支持GEM bo(s)的引用)应该推迟。在这种情况下,驱动程序希望保留fb的引用,即使它已经从用户空间的角度被删除了。请参见drm_framebuffer_get()和drm_frame buffer_put()。
引用计数存储在模式对象@base中。
(1)struct drm_device *dev
/**
* @dev: DRM device this framebuffer belongs to
*/
struct drm_device *dev;
此framebuffer所属的DRM设备。
(2)struct list_head head
/**
* @head: Place on the &drm_mode_config.fb_list, access protected by
* &drm_mode_config.fb_lock.
*/
struct list_head head;
放置在&drm_mode_config.fb_list上,访问受&drm_mmode_config.fb.lock保护。
(3)struct drm_mode_object base
/**
* @base: base modeset object structure, contains the reference count.
*/
struct drm_mode_object base;
基本modeset对象结构,包含引用计数。
(4)char comm[TASK_COMM_LEN]
/**
* @comm: Name of the process allocating the fb, used for fb dumping.
*/
char comm[TASK_COMM_LEN];
分配framebuffer的进程的名称,用于framebuffer dumping。
(5)const struct drm_format_info *format
/**
* @format: framebuffer format information
*/
const struct drm_format_info *format;
framebuffer格式信息。
(6)const struct drm_framebuffer_funcs *funcs
/**
* @funcs: framebuffer vfunc table
*/
const struct drm_framebuffer_funcs *funcs;
framebuffer vfunc表。
(7)unsigned int pitches[DRM_FORMAT_MAX_PLANES]
/**
* @pitches: Line stride per buffer. For userspace created object this
* is copied from drm_mode_fb_cmd2.
*/
unsigned int pitches[DRM_FORMAT_MAX_PLANES];
每个缓冲区的行步幅。对于用户空间创建的对象,这是从drm_mode_fb_cmd2拷贝的。
drm_framebuffer结构的其余成员将在下一篇文章中继续深入释义。