模仿别人的网站,公司注册资金可以随便填吗,山海关区建设局网站,佛山设计公司接前一篇文章#xff1a;DRM全解析 —— ADD_FB2#xff08;2#xff09; 本文参考以下博文#xff1a;
DRM驱动#xff08;四#xff09;之ADD_FB
特此致谢#xff01; 上一回围绕libdrm与DRM在Linux内核中的接口#xff1a;
DRM_IOCTL_DEF(DRM_IOCTL_MODE_ADDFB2,…接前一篇文章DRM全解析 —— ADD_FB22 本文参考以下博文
DRM驱动四之ADD_FB
特此致谢 上一回围绕libdrm与DRM在Linux内核中的接口
DRM_IOCTL_DEF(DRM_IOCTL_MODE_ADDFB2, drm_mode_addfb2_ioctl, 0),
进行了相关宏的展开。本文开始对于drm_mode_addfb2_ioctl函数进行详解。drm_mode_addfb2_ioctl函数在drivers/gpu/drm/drm_framebuffer.c中代码如下
int drm_mode_addfb2_ioctl(struct drm_device *dev,void *data, struct drm_file *file_priv)
{
#ifdef __BIG_ENDIANif (!dev-mode_config.quirk_addfb_prefer_host_byte_order) {/** Drivers must set the* quirk_addfb_prefer_host_byte_order quirk to make* the drm_mode_addfb() compat code work correctly on* bigendian machines.** If they dont they interpret pixel_format values* incorrectly for bug compatibility, which in turn* implies the ADDFB2 ioctl does not work correctly* then. So block it to make userspace fallback to* ADDFB.*/drm_dbg_kms(dev, addfb2 broken on bigendian);return -EOPNOTSUPP;}
#endifreturn drm_mode_addfb2(dev, data, file_priv);
}
drm_mode_addfb2_ioctl函数只是一层简单封装实际的工作交给了drm_mode_addfb2函数。它就在上边代码如下
/*** drm_mode_addfb2 - add an FB to the graphics configuration* dev: drm device for the ioctl* data: data pointer for the ioctl* file_priv: drm file for the ioctl call** Add a new FB to the specified CRTC, given a user request with format. This is* the 2nd version of the addfb ioctl, which supports multi-planar framebuffers* and uses fourcc codes as pixel format specifiers.** Called by the user via ioctl.** Returns:* Zero on success, negative errno on failure.*/
int drm_mode_addfb2(struct drm_device *dev,void *data, struct drm_file *file_priv)
{struct drm_mode_fb_cmd2 *r data;struct drm_framebuffer *fb;if (!drm_core_check_feature(dev, DRIVER_MODESET))return -EOPNOTSUPP;fb drm_internal_framebuffer_create(dev, r, file_priv);if (IS_ERR(fb))return PTR_ERR(fb);drm_dbg_kms(dev, [FB:%d]\n, fb-base.id);r-fb_id fb-base.id;/* Transfer ownership to the filp for reaping on close */mutex_lock(file_priv-fbs_lock);list_add(fb-filp_head, file_priv-fbs);mutex_unlock(file_priv-fbs_lock);return 0;
}
实际上前文DRM全解析 —— ADD_FB2中曾给出drm_mode_addfb函数的代码
/*** drm_mode_addfb - add an FB to the graphics configuration* dev: drm device for the ioctl* or: pointer to request structure* file_priv: drm file** Add a new FB to the specified CRTC, given a user request. This is the* original addfb ioctl which only supported RGB formats.** Called by the user via ioctl, or by an in-kernel client.** Returns:* Zero on success, negative errno on failure.*/
int drm_mode_addfb(struct drm_device *dev, struct drm_mode_fb_cmd *or,struct drm_file *file_priv)
{struct drm_mode_fb_cmd2 r {};int ret;if (!drm_core_check_feature(dev, DRIVER_MODESET))return -EOPNOTSUPP;r.pixel_format drm_driver_legacy_fb_format(dev, or-bpp, or-depth);if (r.pixel_format DRM_FORMAT_INVALID) {drm_dbg_kms(dev, bad {bpp:%d, depth:%d}\n, or-bpp, or-depth);return -EINVAL;}/* convert to new format and call new ioctl */r.fb_id or-fb_id;r.width or-width;r.height or-height;r.pitches[0] or-pitch;r.handles[0] or-handle;ret drm_mode_addfb2(dev, r, file_priv);if (ret)return ret;or-fb_id r.fb_id;return 0;
}
从这里就能看出drm_mode_addfb()实际上也是调用了drm_mode_addfb2()这俩本质上是一回事。只是drm_mode_addfb函数中多了一些预准备和预处理。
drm_mode_fb_cmd2结构在本系列第一篇文章中已经介绍过了为了便于理解再次给出其代码在include/drm/drm_mode.h中如下
struct drm_mode_fb_cmd2 {__u32 fb_id;__u32 width;__u32 height;__u32 pixel_format; /* fourcc code from drm_fourcc.h */__u32 flags; /* see above flags *//** In case of planar formats, this ioctl allows up to 4* buffer objects with offsets and pitches per plane.* The pitch and offset order is dictated by the fourcc,* e.g. NV12 (https://fourcc.org/yuv.php#NV12) is described as:** YUV 4:2:0 image with a plane of 8 bit Y samples* followed by an interleaved U/V plane containing* 8 bit 2x2 subsampled colour difference samples.** So it would consist of Y as offsets[0] and UV as* offsets[1]. Note that offsets[0] will generally* be 0 (but this is not required).** To accommodate tiled, compressed, etc formats, a* modifier can be specified. The default value of zero* indicates native format as specified by the fourcc.* Vendor specific modifier token. Note that even though* it looks like we have a modifier per-plane, we in fact* do not. The modifier for each plane must be identical.* Thus all combinations of different data layouts for* multi plane formats must be enumerated as separate* modifiers.*/__u32 handles[4];__u32 pitches[4]; /* pitch for each plane */__u32 offsets[4]; /* offset of each plane */__u64 modifier[4]; /* ie, tiling, compress */
};
struct drm_framebuffer 当然是在include/drm/drm_framebuffer.h中定义代码如下
/*** 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];
};
了解了相关的结构体定义之后可以开始对于drm_mode_addfb2函数的正式解析了。请看下回。