当前位置: 首页 > news >正文

小程序制作合同范本企业关键词优化公司

小程序制作合同范本,企业关键词优化公司,电子商务发展的前景,合肥网站定制简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长! 优质专栏:Audio工程师进阶系列【原创干货持续更新中……】🚀 人生格言: 人生…

简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长!

优质专栏:Audio工程师进阶系列原创干货持续更新中……】🚀

人生格言: 人生从来没有捷径,只有行动才是治疗恐惧和懒惰的唯一良药.

更多原创,欢迎关注:Android系统攻城狮

欢迎关注Android系统攻城狮

1.前言

本篇目的:探究DRM基本接口的实现,底层实现到底是如何与DRM驱动通信的?

2.DRM基本接口实现解析

<1>.DRM之drmModeGetResources获取CRTC和Connector的id号

drm_public drmModeResPtr drmModeGetResources(int fd)
{struct drm_mode_card_res res, counts;drmModeResPtr r = 0;retry:memclear(res);if (drmIoctl(fd, DRM_IOCTL_MODE_GETRESOURCES, &res))return 0;counts = res;if (res.count_fbs) {res.fb_id_ptr = VOID2U64(drmMalloc(res.count_fbs*sizeof(uint32_t)));if (!res.fb_id_ptr)goto err_allocs;}if (res.count_crtcs) {res.crtc_id_ptr = VOID2U64(drmMalloc(res.count_crtcs*sizeof(uint32_t)));if (!res.crtc_id_ptr)goto err_allocs;}if (res.count_connectors) {res.connector_id_ptr = VOID2U64(drmMalloc(res.count_connectors*sizeof(uint32_t)));if (!res.connector_id_ptr)goto err_allocs;}if (res.count_encoders) {res.encoder_id_ptr = VOID2U64(drmMalloc(res.count_encoders*sizeof(uint32_t)));if (!res.encoder_id_ptr)goto err_allocs;}if (drmIoctl(fd, DRM_IOCTL_MODE_GETRESOURCES, &res))goto err_allocs;/* The number of available connectors and etc may have changed with a* hotplug event in between the ioctls, in which case the field is* silently ignored by the kernel.*/if (counts.count_fbs < res.count_fbs ||counts.count_crtcs < res.count_crtcs ||counts.count_connectors < res.count_connectors ||counts.count_encoders < res.count_encoders){drmFree(U642VOID(res.fb_id_ptr));drmFree(U642VOID(res.crtc_id_ptr));drmFree(U642VOID(res.connector_id_ptr));drmFree(U642VOID(res.encoder_id_ptr));goto retry;}/** return*/if (!(r = drmMalloc(sizeof(*r))))goto err_allocs;r->min_width     = res.min_width;r->max_width     = res.max_width;r->min_height    = res.min_height;r->max_height    = res.max_height;r->count_fbs     = res.count_fbs;r->count_crtcs   = res.count_crtcs;r->count_connectors = res.count_connectors;r->count_encoders = res.count_encoders;r->fbs        = drmAllocCpy(U642VOID(res.fb_id_ptr), res.count_fbs, sizeof(uint32_t));r->crtcs      = drmAllocCpy(U642VOID(res.crtc_id_ptr), res.count_crtcs, sizeof(uint32_t));r->connectors = drmAllocCpy(U642VOID(res.connector_id_ptr), res.count_connectors, sizeof(uint32_t));r->encoders   = drmAllocCpy(U642VOID(res.encoder_id_ptr), res.count_encoders, sizeof(uint32_t));if ((res.count_fbs && !r->fbs) ||(res.count_crtcs && !r->crtcs) ||(res.count_connectors && !r->connectors) ||(res.count_encoders && !r->encoders)){drmFree(r->fbs);drmFree(r->crtcs);drmFree(r->connectors);drmFree(r->encoders);drmFree(r);r = 0;}err_allocs:drmFree(U642VOID(res.fb_id_ptr));drmFree(U642VOID(res.crtc_id_ptr));drmFree(U642VOID(res.connector_id_ptr));drmFree(U642VOID(res.encoder_id_ptr));return r;
}

核心要点1

1.调用drmIoctl(fd, DRM_IOCTL_MODE_GETRESOURCES, &res)获取CRTC和Connector的id号。

2.drm_mode_card_res数据结构

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;__u32 max_width;__u32 min_height;__u32 max_height;
};

<2>.DRM之drmModeGetConnector连接Connector显示器

static drmModeConnectorPtr
_drmModeGetConnector(int fd, uint32_t connector_id, int probe)
{struct drm_mode_get_connector conn, counts;drmModeConnectorPtr r = NULL;struct drm_mode_modeinfo stack_mode;memclear(conn);conn.connector_id = connector_id;if (!probe) {conn.count_modes = 1;conn.modes_ptr = VOID2U64(&stack_mode);}if (drmIoctl(fd, DRM_IOCTL_MODE_GETCONNECTOR, &conn))return 0;retry:counts = conn;if (conn.count_props) {conn.props_ptr = VOID2U64(drmMalloc(conn.count_props*sizeof(uint32_t)));if (!conn.props_ptr)goto err_allocs;conn.prop_values_ptr = VOID2U64(drmMalloc(conn.count_props*sizeof(uint64_t)));if (!conn.prop_values_ptr)goto err_allocs;}if (conn.count_modes) {conn.modes_ptr = VOID2U64(drmMalloc(conn.count_modes*sizeof(struct drm_mode_modeinfo)));if (!conn.modes_ptr)goto err_allocs;} else {conn.count_modes = 1;conn.modes_ptr = VOID2U64(&stack_mode);}if (conn.count_encoders) {conn.encoders_ptr = VOID2U64(drmMalloc(conn.count_encoders*sizeof(uint32_t)));if (!conn.encoders_ptr)goto err_allocs;}if (drmIoctl(fd, DRM_IOCTL_MODE_GETCONNECTOR, &conn))goto err_allocs;/* The number of available connectors and etc may have changed with a* hotplug event in between the ioctls, in which case the field is* silently ignored by the kernel.*/if (counts.count_props < conn.count_props ||counts.count_modes < conn.count_modes ||counts.count_encoders < conn.count_encoders) {drmFree(U642VOID(conn.props_ptr));drmFree(U642VOID(conn.prop_values_ptr));if (U642VOID(conn.modes_ptr) != &stack_mode)drmFree(U642VOID(conn.modes_ptr));drmFree(U642VOID(conn.encoders_ptr));goto retry;}if(!(r = drmMalloc(sizeof(*r)))) {goto err_allocs;}r->connector_id = conn.connector_id;r->encoder_id = conn.encoder_id;r->connection   = conn.connection;r->mmWidth      = conn.mm_width;r->mmHeight     = conn.mm_height;/* convert subpixel from kernel to userspace */r->subpixel     = conn.subpixel + 1;r->count_modes  = conn.count_modes;r->count_props  = conn.count_props;r->props        = drmAllocCpy(U642VOID(conn.props_ptr), conn.count_props, sizeof(uint32_t));r->prop_values  = drmAllocCpy(U642VOID(conn.prop_values_ptr), conn.count_props, sizeof(uint64_t));r->modes        = drmAllocCpy(U642VOID(conn.modes_ptr), conn.count_modes, sizeof(struct drm_mode_modeinfo));r->count_encoders = conn.count_encoders;r->encoders     = drmAllocCpy(U642VOID(conn.encoders_ptr), conn.count_encoders, sizeof(uint32_t));r->connector_type  = conn.connector_type;r->connector_type_id = conn.connector_type_id;if ((r->count_props && !r->props) ||(r->count_props && !r->prop_values) ||(r->count_modes && !r->modes) ||(r->count_encoders && !r->encoders)) {drmFree(r->props);drmFree(r->prop_values);drmFree(r->modes);drmFree(r->encoders);drmFree(r);r = 0;}err_allocs:drmFree(U642VOID(conn.prop_values_ptr));drmFree(U642VOID(conn.props_ptr));if (U642VOID(conn.modes_ptr) != &stack_mode)drmFree(U642VOID(conn.modes_ptr));drmFree(U642VOID(conn.encoders_ptr));return r;
}

核心要点2

1.drmIoctl(fd, DRM_IOCTL_MODE_GETCONNECTOR, &conn):连接CONNECTOR到显示器

2.drm_mode_get_connector数据结构

struct drm_mode_get_connector {__u64 encoders_ptr;__u64 modes_ptr;__u64 props_ptr;__u64 prop_values_ptr;__u32 count_modes;__u32 count_props;__u32 count_encoders;__u32 encoder_id;__u32 connector_id;__u32 connector_type;__u32 connector_type_id;__u32 connection;__u32 mm_width;__u32 mm_height;__u32 subpixel;__u32 pad;
};

<3>.DRM之modeset_create_fb添加framebuffer设备

static int modeset_create_fb(int fd, struct buffer_object *bo) {struct drm_mode_create_dumb create = {};struct drm_mode_map_dumb map = {};create.width = bo->width;create.height = bo->height;create.bpp = 32;drmIoctl(fd, DRM_IOCTL_MODE_CREATE_DUMB, &create);printf("create dumb w %d h %d\n", bo->width, bo->height);getchar();bo->pitch = create.pitch;bo->size = create.size;bo->handle = create.handle;drmModeAddFB(fd, bo->width, bo->height, 24, 32, bo->pitch, bo->handle,&bo->fb_id);printf("drmModeAddFB\n");getchar();map.handle = create.handle;drmIoctl(fd, DRM_IOCTL_MODE_MAP_DUMB, &map);printf("map dumb\n");getchar();bo->vaddr = static_cast<unsigned char *>(mmap64(0, create.size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, map.offset));memset(bo->vaddr, 0xff, bo->size);return 0;
}

核心要点3

1.drmIoctl(fd, DRM_IOCTL_MODE_CREATE_DUMB, &create): 增加申请DUMB共享内存
2.drmModeAddFB(fd, bo->width, bo->height, 24, 32, bo->pitch, bo->handle,&bo->fb_id);
DRM_IOCTL(fd, DRM_IOCTL_MODE_ADDFB, &f);:添加一个FrameBuffer
3.bo->vaddr = static_cast<unsigned char *>(mmap64( 0, create.size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, map.offset));:映射DRM图形buffer的共享内存到bo->vaddr地址。
memset(bo->vaddr, 0xff, bo->size);:设置白色。
4.drm_mode_create_dumb和drm_mode_map_dumb数据结构

struct drm_mode_create_dumb {__u32 height;__u32 width;__u32 bpp;__u32 flags;__u32 handle;__u32 pitch;__u64 size;
};struct drm_mode_map_dumb {__u32 handle;__u32 pad;__u64 offset;
};

<4>.DRM之drmModeSetCrtcCRTC开始扫描framebuffer数据显示

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);
}

核心要点4

1.DRM_IOCTL(fd, DRM_IOCTL_MODE_SETCRTC, &crtc):CRTC对framebuffer的数据进行扫描

2.drm_mode_crtc数据结构

struct drm_mode_crtc {__u64 set_connectors_ptr;__u32 count_connectors;__u32 crtc_id;__u32 fb_id;__u32 x;__u32 y;__u32 gamma_size;__u32 mode_valid;struct drm_mode_modeinfo mode;
};

<5>.DRM之modeset_destroy_fb关闭framebuffer设备

static void modeset_destroy_fb(int fd, struct buffer_object *bo) {struct drm_mode_destroy_dumb destroy = {};drmModeRmFB(fd, bo->fb_id);munmap(bo->vaddr, bo->size);destroy.handle = bo->handle;drmIoctl(fd, DRM_IOCTL_MODE_DESTROY_DUMB, &destroy);
}

核心要点5

1.drmIoctl(fd, DRM_IOCTL_MODE_DESTROY_DUMB, &destroy);:销毁DUMB共享内存

2.drm_mode_destroy_dumb数据结构

struct drm_mode_destroy_dumb {__u32 handle;
};

<6>.DRM之drmModeFreeConnector断开Connector连接

drm_public void drmModeFreeConnector(drmModeConnectorPtr ptr)
{if (!ptr)return;drmFree(ptr->encoders);drmFree(ptr->prop_values);drmFree(ptr->props);drmFree(ptr->modes);drmFree(ptr);
}

核心要点6

1.调用drmFree释放内存,内部调用free()函数。

2.drmFree函数实现

drm_public void drmFree(void *pt)
{free(pt);
}

<7>.DRM之drmModeFreeResources释放资源

drm_public void drmModeFreeResources(drmModeResPtr ptr)
{if (!ptr)return;drmFree(ptr->fbs);drmFree(ptr->crtcs);drmFree(ptr->connectors);drmFree(ptr->encoders);drmFree(ptr);
}

核心要点7

1.调用drmFree释放资源,本质和drmModeFreeConnector一样,也是释放内存资源。

3.DRM基本接口总结

  • 1.drmModeGetResources函数调用DRM驱动通过ioctl(DRM_IOCTL_MODE_GETRESOURCES):获取CRTC和Connector的id号。
  • 2.drmModeGetConnector函数调用ioctl(DRM_IOCTL_MODE_GETCONNECTOR):连接CONNECTOR到显示器
  • 3.modeset_create_fb函数调用ioctl(DRM_IOCTL_MODE_ADDFB):添加一个FrameBuffer
  • 4.drmModeSetCrtc函数调用ioctl(DRM_IOCTL_MODE_SETCRTC):CRTC对framebuffer的数据进行扫描
  • 5.modeset_destroy_fb函数调用ioctl(DRM_IOCTL_MODE_DESTROY_DUMB):销毁DUMB共享内存
  • 6.drmModeFreeConnector函数调用drmFree释放内存资源
  • 7.drmModeFreeResources函数调用drmFree释放内存资源
http://www.qdjiajiao.com/news/8205.html

相关文章:

  • 用软件做的网站权限管理龙岗seo优化
  • 查一下红之易道学做的什么网站郑州网络推广团队
  • 网站色情营销特点软文标题例子
  • 自己做的网站怎么样合法什么叫软文推广
  • 网站 ca证书怎么做潍坊关键词优化软件
  • 网站建设网站软件有哪些方面上海百度推广优化公司
  • 兰州优秀网站推广北京网站推广机构
  • 腾讯云域名如何建设网站百度排名点击软件
  • 请描述网站开发的一般流程图廊坊首页霸屏排名优化
  • 喀什哪有做网站的国内免费二级域名建站
  • 北京百度seo推广信阳seo
  • 欧铂丽全屋定制价格每平米多少钱陕西优化疫情防控措施
  • 郑州室内设计公司排行长春seo快速排名
  • 网站设计哪家便宜上海专业做网站
  • 做网站的成本费用郑州网站优化排名
  • 做网站多少钱一个月营销网络推广哪家好
  • 移动网站建设生要女网上写文章用什么软件
  • 网站如何备案流程图搜索引擎排名优化公司
  • 全国文明城市创建内容优化网络软件
  • 越辉网站建设综合查询
  • wordpress添加简码青岛关键词优化seo
  • 坪山建设网站专业网页设计和网站制作公司
  • 北京网站建设中心济南优化seo公司
  • 申请免费域名的方法seo行业
  • 网站的设计页面廊坊关键词优化排名
  • 网站开发的在线支付功能网站建设的一般步骤
  • 建设部网站官网造价工程师孙思新免费文件外链网站
  • 广州网络推广培训网站建设网络推广seo
  • 有没有做网站的团队搜索引擎大全
  • 做网站有必要注册商标吗链爱交易平台