Drm 例程2 双dumb buffer显示

Drm 例程2 双buffer 显示

显示过程中,drm是通过申请framebuffer 填充其中的dumb的buf来显示的,drmModeAddFB对不同的dumb buff拿到的bufid也不一样,

最终使用drmModeSetCrtc来设定参数,使用dumb的bufid来填充相应的buf值

代码

#include <stdio.h>
#include <errno.h>
#include "xf86drmMode.h"
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>
#include <string.h>

#define DRM_CARD    "/dev/dri/card0"
#define Chartreuse  0x7FFF00
#define Yellow      0xFFFF00
#define GoldEnrod   0xDAA520

#define check_ptr(ptr) do{ \
    if(ptr == NULL) { \
        printf("ptr is NULL\n"); \
        return -1; \
    } \
} while (0)


#define drm_print(fmt, args...) \
do \
{ \
	printf("func:%s line:%d "#fmt"\n",  __FUNCTION__, __LINE__, ##args); \
}while (0)

typedef struct _buffer_object {
	unsigned int width;
	unsigned int height;
	unsigned int pitch;
	unsigned int handle;
	unsigned int size;
	unsigned int *vaddr;
	unsigned int fb_id;
}buffer_object;


typedef struct  _drm_ctx{
    int fd;    
    buffer_object buf[2];
    unsigned int conector_id;
    unsigned int crtc_id;
    unsigned int encoder_id;
}drm_ctx;

drm_ctx gdrm_var;

static int creat_fb(int fd, buffer_object *bo, uint32_t color)
{
    struct drm_mode_create_dumb creq;
    struct drm_mode_map_dumb mreq;
    int ret;
    uint32_t i;

    creq.width = bo->width;
    creq.height = bo->height;
    creq.bpp = 32;

    ret = ioctl(fd, DRM_IOCTL_MODE_CREATE_DUMB, &creq);
    if(ret != 0)
    {
        drm_print("ioctl creat dumb fail\n");
        return -1;
    }

    bo->pitch = creq.pitch;
    bo->handle = creq.handle;
    bo->size = creq.size;
    drm_print("bo pitch:%d", bo->pitch);
    drmModeAddFB(fd, bo->width, bo->height, 24, 32, bo->pitch, bo->handle, &bo->fb_id);

    mreq.handle = bo->handle;
    ret = ioctl(fd, DRM_IOCTL_MODE_MAP_DUMB, &mreq);
    if(ret != 0)
    {
        drm_print("ioctl mmap dumb fail\n");
        return -1;
    }
        /* perform actual memory mapping */
    bo->vaddr = mmap(0, creq.size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, mreq.offset);
    check_ptr(bo->vaddr);
    //使用crtc驱动connector
    //memset(bo->vaddr, 0xB4, bo->size);
    drm_print("bo size:%d", bo->size);//按照官方doc size=(height * pitch + width) * bpp / 4  跟实际打印出来的值 height * width *4  不大一样
	for (i = 0; i < (bo->size/4); i++)
		bo->vaddr[i] = color;

    return 0;
}

static int destroy_fb(int fd, buffer_object *bo)
{
    int ret;
    struct drm_mode_destroy_dumb dreq;

    drmModeRmFB(fd, bo->fb_id);
    dreq.handle = bo->handle;
    ret = ioctl(fd, DRM_IOCTL_MODE_DESTROY_DUMB, &dreq);
    if(ret != 0)
    {
        drm_print("ioctl destory dumb fail\n");
        return -1;
    }
    
    munmap(bo->vaddr, bo->size);
}

int main(int argc, char *argv[])
{
    //open card
    drmModeResPtr   resptr;
    drmModeConnectorPtr conptr;

    int ret;
    unsigned int fb;

    gdrm_var.fd = open(DRM_CARD, O_RDWR);
    if(gdrm_var.fd < 0)
    {
        perror("open card fail\n");
        return -1;
    }

    drm_print("fd%d\n", gdrm_var.fd);
    //获取card resource,include crtc connector encoder plane
    resptr = drmModeGetResources(gdrm_var.fd);
    check_ptr(resptr);

    gdrm_var.crtc_id = resptr->crtcs[0];
    gdrm_var.conector_id = resptr->connectors[0];
    drm_print("crtc id:%d conector_id %d", gdrm_var.crtc_id, gdrm_var.conector_id);
    //printf("%s %d crtc_id:%d con_id:%d\n", resptr->count_crtcs, resptr->count_connectors);
    //select which connector used
    conptr = drmModeGetConnector(gdrm_var.fd, gdrm_var.conector_id);
    check_ptr(conptr);
    gdrm_var.buf[0].width = conptr->modes[0].hdisplay;
    gdrm_var.buf[0].height = conptr->modes[0].vdisplay;

    gdrm_var.buf[1].width = conptr->modes[0].hdisplay;
    gdrm_var.buf[1].height = conptr->modes[0].vdisplay;
    drm_print("%d %d %d", gdrm_var.buf[0].width, gdrm_var.buf[0].height, gdrm_var.buf[0].size);
    //create framebuffer, fill dumb buffer
    creat_fb(gdrm_var.fd, &gdrm_var.buf[0], Chartreuse);

    creat_fb(gdrm_var.fd, &gdrm_var.buf[1], GoldEnrod);

    drmModeSetCrtc(gdrm_var.fd, gdrm_var.crtc_id, gdrm_var.buf[0].fb_id,
                   0, 0, &gdrm_var.conector_id, 1, &conptr->modes[0]);

    sleep(2);
    drmModeSetCrtc(gdrm_var.fd, gdrm_var.crtc_id, gdrm_var.buf[1].fb_id,
                   0, 0, &gdrm_var.conector_id, 1, &conptr->modes[0]);
    //destory dumb buffer
    sleep(5);
    destroy_fb(gdrm_var.fd, &gdrm_var.buf[0]);
    destroy_fb(gdrm_var.fd, &gdrm_var.buf[1]);

    drmModeFreeConnector(conptr);
    drmModeFreeResources(resptr);
    close(gdrm_var.fd);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值