libdrm全解析三十六 —— 源码全解析(33)

接前一篇文章:libdrm全解析三十五 —— 源码全解析(32)

本文参考以下博文:

DRM 驱动程序开发(VKMS)

特此致谢!

前一篇文章讲解完了mmap()显存映射,本篇文章继续讲解DRM一般流程的下一步。为了便于理解,再次贴出一般流程示例:

int main(int argc, char **argv)
{
	/* open the drm device */
	open("/dev/dri/card0");
 
	/* get crtc/encoder/connector id */
	drmModeGetResources(...);
 
	/* get connector for display mode */
	drmModeGetConnector(...);
 
	/* create a dumb-buffer */
	drmIoctl(DRM_IOCTL_MODE_CREATE_DUMB);
 
	/* bind the dumb-buffer to an FB object */
	drmModeAddFB(...);
 
	/* map the dumb buffer for userspace drawing */
	drmIoctl(DRM_IOCTL_MODE_MAP_DUMB);
	mmap(...);
 
	/* start display */
	drmModeSetCrtc(crtc_id, fb_id, connector_id, mode);
}

下一步是drmModeSetCrtc(crtc_id, fb_id, connector_id, mode)。

62. DRM_IOCTL_MODE_SETCRTC

第62个宏是DRM_IOCTL_MODE_SETCRTC,相应代码如下:

#define DRM_IOCTL_MODE_SETCRTC		DRM_IOWR(0xA2, struct drm_mode_crtc)

结合之前文章中的_IOWR(type,nr,size)的最终定义,得到如下代码:

#define DRM_IOCTL_MODE_SETCRTC        ( ((3)  << 30) | (('d') << 8) | ((0xA2)   << 0) | ((sizeof(struct drm_mode_crtc)) << 16) )

struct drm_mode_crtc在同文件(include/drm/drm.h)中定义,代码如下:

struct drm_mode_crtc {
	__u64 set_connectors_ptr;
	__u32 count_connectors;

	__u32 crtc_id; /**< Id */
	__u32 fb_id; /**< Id of framebuffer */

	__u32 x; /**< x Position on the framebuffer */
	__u32 y; /**< y Position on the framebuffer */

	__u32 gamma_size;
	__u32 mode_valid;
	struct drm_mode_modeinfo mode;
};

struct drm_mode_modeinfo的定义同样在include/drm/drm.h中,如下:

/**
 * struct drm_mode_modeinfo - Display mode information.
 * @clock: pixel clock in kHz
 * @hdisplay: horizontal display size
 * @hsync_start: horizontal sync start
 * @hsync_end: horizontal sync end
 * @htotal: horizontal total size
 * @hskew: horizontal skew
 * @vdisplay: vertical display size
 * @vsync_start: vertical sync start
 * @vsync_end: vertical sync end
 * @vtotal: vertical total size
 * @vscan: vertical scan
 * @vrefresh: approximate vertical refresh rate in Hz
 * @flags: bitmask of misc. flags, see DRM_MODE_FLAG_* defines
 * @type: bitmask of type flags, see DRM_MODE_TYPE_* defines
 * @name: string describing the mode resolution
 *
 * This is the user-space API display mode information structure. For the
 * kernel version see struct drm_display_mode.
 */
struct drm_mode_modeinfo {
	__u32 clock;
	__u16 hdisplay;
	__u16 hsync_start;
	__u16 hsync_end;
	__u16 htotal;
	__u16 hskew;
	__u16 vdisplay;
	__u16 vsync_start;
	__u16 vsync_end;
	__u16 vtotal;
	__u16 vscan;

	__u32 vrefresh;

	__u32 flags;
	__u32 type;
	char name[DRM_DISPLAY_MODE_LEN];
};

DRM_IOCTL_MODE_SETCRTC对应的Userspace API为:drmModeSetCrtc()。该函数在xf86drmMode.c中,代码如下:

drm_public int drmModeSetCrtc(int fd, uint32_t crtcId, uint32_t bufferId,
		   uint32_t x, uint32_t y, uint32_t *connectors, int count,
		   drmModeModeInfoPtr mode)
{
	struct drm_mode_crtc crtc;

	memclear(crtc);
	crtc.x             = x;
	crtc.y             = y;
	crtc.crtc_id       = crtcId;
	crtc.fb_id         = bufferId;
	crtc.set_connectors_ptr = VOID2U64(connectors);
	crtc.count_connectors = count;
	if (mode) {
	  memcpy(&crtc.mode, mode, sizeof(struct drm_mode_modeinfo));
	  crtc.mode_valid = 1;
	}

	return DRM_IOCTL(fd, DRM_IOCTL_MODE_SETCRTC, &crtc);
}

函数的作用是初始化整个硬件管线(pipeline)并显示图像。

对于drmModeSetCrtc函数的详细解析,将在下篇文章中进行。

猜你喜欢

转载自blog.csdn.net/phmatthaus/article/details/132582768