日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

DRM实例教程

發布時間:2024/9/27 49 豆豆
生活随笔 收集整理的這篇文章主要介紹了 DRM实例教程 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

DRM實例教程

DRM是一個顯示驅動框架,也就是把功能封裝成 open/close/ioctl 等標準接口,應用程序調用這些接口來驅動設備,顯示數據。我們這里將從使用的角度來看看,怎么驗證和使用DRM驅動。

DRM設備節點

DRM驅動會在/dev/dri下創建3個設備節點:

?

card0 controlD64 renderD128

libdrm庫

DRM驅動,對用戶空間,提供了專門的的調用庫libdrm.so,用戶空間通過該庫可以間接的調用和使用驅動。

打開設備

?

int fd = open("/dev/dri/card0", O_RDWR | O_CLOEXEC);if (fd < 0) {ret = -errno;fprintf(stderr, "cannot open '%s': %m\n", node);return ret;}

打開設備有專門的接口:drmOpen

檢查DRM的能力

DRM的能力通過drmGetCap接口獲取,用drm_get_cap結構描述:

?

/** DRM_IOCTL_GET_CAP ioctl argument type */ struct drm_get_cap {__u64 capability;__u64 value; };int drmGetCap(int fd, uint64_t capability, uint64_t *value) {struct drm_get_cap cap;int ret;memclear(cap);cap.capability = capability;ret = drmIoctl(fd, DRM_IOCTL_GET_CAP, &cap);if (ret)return ret;*value = cap.value;return 0; }

使用示例:

?

uint64_t has_dumb;if (drmGetCap(fd, DRM_CAP_DUMB_BUFFER, &has_dumb) < 0 ||!has_dumb) {fprintf(stderr, "drm device '%s' does not support dumb buffers\n",node);close(fd);return -EOPNOTSUPP;}

檢索Resource

Resource的獲取需要兩次,第一次,獲取數量大小,第二次才真正獲取具體的Resource。具體看這個函數:

?

drmModeResPtr drmModeGetResources(int fd)

Resource結構封裝:

?

struct drm_mode_card_res {__u64 fb_id_ptr;__u64 crtc_id_ptr;__u64 connector_id_ptr;__u64 encoder_id_ptr;__u32 count_fbs;__u32 count_crtcs;__u32 count_connectors;__u32 count_encoders;__u32 min_width, max_width;__u32 min_height, max_height; };

?

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;

實例

?

/* retrieve resources */int ret = drmModeGetResources(fd);if (!res) {fprintf(stderr, "cannot retrieve DRM resources (%d): %m\n",errno);return -errno;}

獲取Connector

_drmModeConnector描述結構:

?

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;

示例:

?

drmModeConnector *conn = drmModeGetConnector(fd, res->connectors[i]);if (!conn) {fprintf(stderr, "cannot retrieve DRM connector %u:%u (%d): %m\n",i, res->connectors[i], errno);continue;}

Encoder

Encoder的結構描述:

?

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;

示例:

?

if (conn->encoder_id)drmModeEncoder *enc = drmModeGetEncoder(fd, conn->encoder_id);}

?

drmModeEncoderPtr drmModeGetEncoder(int fd, uint32_t encoder_id) {struct drm_mode_get_encoder enc;drmModeEncoderPtr r = NULL;memclear(enc);enc.encoder_id = encoder_id;if (drmIoctl(fd, DRM_IOCTL_MODE_GETENCODER, &enc))return 0;if (!(r = drmMalloc(sizeof(*r))))return 0;r->encoder_id = enc.encoder_id;r->crtc_id = enc.crtc_id;r->encoder_type = enc.encoder_type;r->possible_crtcs = enc.possible_crtcs;r->possible_clones = enc.possible_clones;return r; }

crtc

CRTC結構描述:

?

struct crtc {drmModeCrtc *crtc;drmModeObjectProperties *props;drmModePropertyRes **props_info;drmModeModeInfo *mode; };

?

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;

FrameBuffer

創建DUMB Buffer

?

ret = drmIoctl(fd, DRM_IOCTL_MODE_CREATE_DUMB, &creq);if (ret < 0) {fprintf(stderr, "cannot create dumb buffer (%d): %m\n",errno);return -errno;}

添加FB

?

/* create framebuffer object for the dumb-buffer */ret = drmModeAddFB(fd, dev->width, dev->height, 24, 32, dev->stride,dev->handle, &dev->fb);if (ret) {fprintf(stderr, "cannot create framebuffer (%d): %m\n",errno);ret = -errno;goto err_destroy;}

準備map

?

/* prepare buffer for memory mapping */memset(&mreq, 0, sizeof(mreq));mreq.handle = dev->handle;ret = drmIoctl(fd, DRM_IOCTL_MODE_MAP_DUMB, &mreq);if (ret) {fprintf(stderr, "cannot map dumb buffer (%d): %m\n",errno);ret = -errno;goto err_fb;}

做map操作:

?

/* perform actual memory mapping */dev->map = mmap(0, dev->size, PROT_READ | PROT_WRITE, MAP_SHARED,fd, mreq.offset);if (dev->map == MAP_FAILED) {fprintf(stderr, "cannot mmap dumb buffer (%d): %m\n",errno);ret = -errno;goto err_fb;}

CRTC的準備

drmModeGetCrtc
drmModeSetCrtc

?

drmModeCrtcPtr drmModeGetCrtc(int fd, uint32_t crtcId) {struct drm_mode_crtc crtc;drmModeCrtcPtr r;memclear(crtc);crtc.crtc_id = crtcId;if (drmIoctl(fd, DRM_IOCTL_MODE_GETCRTC, &crtc))return 0;/** return*/if (!(r = drmMalloc(sizeof(*r))))return 0;r->crtc_id = crtc.crtc_id;r->x = crtc.x;r->y = crtc.y;r->mode_valid = crtc.mode_valid;if (r->mode_valid) {memcpy(&r->mode, &crtc.mode, sizeof(struct drm_mode_modeinfo));r->width = crtc.mode.hdisplay;r->height = crtc.mode.vdisplay;}r->buffer_id = crtc.fb_id;r->gamma_size = crtc.gamma_size;return r; }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); }

繪制

?

static void modeset_draw(void) {uint8_t r, g, b;bool r_up, g_up, b_up;unsigned int i, j, k, off;struct modeset_dev *iter;srand(time(NULL));r = rand() % 0xff;g = rand() % 0xff;b = rand() % 0xff;r_up = g_up = b_up = true;for (i = 0; i < 50; ++i) {r = next_color(&r_up, r, 20);g = next_color(&g_up, g, 10);b = next_color(&b_up, b, 5);for (iter = modeset_list; iter; iter = iter->next) {for (j = 0; j < iter->height; ++j) {for (k = 0; k < iter->width; ++k) {off = iter->stride * j + k * 4;*(uint32_t*)&iter->map[off] =(r << 16) | (g << 8) | b;}}}usleep(100000);} }

具體的代碼,可以參考how-to實例:
how-to代碼實例



作者:夕月風
鏈接:https://www.jianshu.com/p/f41f98a40455
來源:簡書
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。

總結

以上是生活随笔為你收集整理的DRM实例教程的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。