frame buffer 双缓冲应用示例

/*
使用说明:
全志SDK设备树文件中fb0示例如下,表示fb0使能旋转(disp_rotation_used=1),旋转角度为0(0:0, 1:90, 2:180, 3:270)。

LCD原始分辨率为320*820,设置旋转时一定注意宽高的设置。

旋转角度为0度
[disp]
    disp_rotation_used=1
    degree0=0//0,1,2,3
    fb0_width=320
    fb0_height=820

旋转角度为90度
[disp]
    disp_rotation_used=1
    degree0=1//0,1,2,3
    fb0_width=820
    fb0_height=320
*/
#include <stdlib.h>
#include <stdint.h>
#include <sys/ioctl.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <pthread.h>
#include <time.h>
#include <linux/videodev2.h>
#include <linux/fb.h>
#include <sys/mman.h>


//#define SCREEN_DBG(format, args...) 
#define SCREEN_DBG(format, args...) (printf("[SCREEN] %s:%04d-->%s:"format, __FILE__, __LINE__, __func__, ##args))

typedef struct __SCREEN_INFO_ST {
    int fd_fb;
    struct fb_var_screeninfo vinfo;
    struct fb_fix_screeninfo finfo;
    unsigned char *fb_base;
    unsigned char *fb_cure;
    int buf_num;
    int buf_idx;
    int screen_size;
}ScreenInfoSt;

int ScreenOpen(char *dev_name, ScreenInfoSt *pScreenInfo) {
    pScreenInfo->fd_fb = open (dev_name,O_RDWR);
    if (pScreenInfo->fd_fb < 0) {
        char log_buf[100];
        memset(log_buf, 0, sizeof(log_buf));
        sprintf(log_buf, "%s open error!\n", dev_name);
        perror(log_buf);
        return -1;
    }
    ioctl(pScreenInfo->fd_fb, FBIOGET_VSCREENINFO,&pScreenInfo->vinfo);
    ioctl(pScreenInfo->fd_fb, FBIOGET_FSCREENINFO,&pScreenInfo->finfo);
    pScreenInfo->screen_size = pScreenInfo->vinfo.xres * pScreenInfo->vinfo.yres * pScreenInfo->vinfo.bits_per_pixel / 8;
    SCREEN_DBG("finfo.smem_len = %d\n", pScreenInfo->finfo.smem_len);
    SCREEN_DBG("vinfo.xres = %d, vinfo.yres=%d, bits_per_pixel = %d, screen_size = %d\n", \
        pScreenInfo->vinfo.xres, pScreenInfo->vinfo.yres, pScreenInfo->vinfo.bits_per_pixel, pScreenInfo->screen_size);
    SCREEN_DBG("vinfo.xres_virtual = %d, vinfo.yres_virtual = %d, vinfo.xoffset = %d, vinfo.yoffset = %d\n", \
        pScreenInfo->vinfo.xres_virtual, pScreenInfo->vinfo.yres_virtual, pScreenInfo->vinfo.xoffset, pScreenInfo->vinfo.yoffset);
        
    SCREEN_DBG("vinfo.red offset = %d, length = %d, msb_right = %d\n", \
        pScreenInfo->vinfo.red.offset, pScreenInfo->vinfo.red.length, pScreenInfo->vinfo.red.msb_right);
    SCREEN_DBG("vinfo.green offset = %d, length = %d, msb_right = %d\n", \
        pScreenInfo->vinfo.green.offset, pScreenInfo->vinfo.green.length, pScreenInfo->vinfo.green.msb_right);
    SCREEN_DBG("vinfo.blue offset = %d, length = %d, msb_right = %d\n", \
        pScreenInfo->vinfo.blue.offset, pScreenInfo->vinfo.blue.length, pScreenInfo->vinfo.blue.msb_right);
    SCREEN_DBG("vinfo.transp offset = %d, length = %d, msb_right = %d\n", \
        pScreenInfo->vinfo.transp.offset, pScreenInfo->vinfo.transp.length, pScreenInfo->vinfo.transp.msb_right);
    
    SCREEN_DBG("vinfo.rotate = 0x%x, vinfo.activate = 0x%x\n", pScreenInfo->vinfo.rotate, pScreenInfo->vinfo.activate);
    pScreenInfo->buf_num = pScreenInfo->finfo.smem_len/pScreenInfo->screen_size;
    SCREEN_DBG("buf_num = %d\n", pScreenInfo->buf_num);
    if(pScreenInfo->buf_num < 1){
        goto __exit_close;
    }
    pScreenInfo->fb_base  = (unsigned char *) mmap (0, pScreenInfo->finfo.smem_len, PROT_READ | PROT_WRITE, MAP_SHARED, pScreenInfo->fd_fb, 0);
    SCREEN_DBG("fb_base map = 0x%08x\n", (uint32_t)pScreenInfo->fb_base );
    if(pScreenInfo->fb_base == MAP_FAILED){
        perror("mmap error!\n");
        goto __exit_close;
    }
    if(pScreenInfo->vinfo.yres_virtual != pScreenInfo->buf_num * pScreenInfo->vinfo.yres){
        SCREEN_DBG("vinfo.yres_virtual not right! enable multi buffer!\n");
        pScreenInfo->vinfo.yres_virtual = pScreenInfo->buf_num * pScreenInfo->vinfo.yres;
        ioctl(pScreenInfo->fd_fb, FBIOPUT_VSCREENINFO, &pScreenInfo->vinfo);
    }
    pScreenInfo->buf_idx = 0;
    pScreenInfo->fb_cure = pScreenInfo->fb_base + pScreenInfo->buf_idx * pScreenInfo->screen_size;
    return 0;
__exit_close:
    close(pScreenInfo->fd_fb);
    return -1;
}

int ScreenFlush(ScreenInfoSt *pScreenInfo){
    pScreenInfo->vinfo.yoffset = pScreenInfo->buf_idx * pScreenInfo->vinfo.yres;
    if (ioctl(pScreenInfo->fd_fb, FBIOPAN_DISPLAY, &pScreenInfo->vinfo) < 0) {
        perror("ioctl() / FBIOPAN_DISPLAY");
    }
    if (ioctl(pScreenInfo->fd_fb, FBIO_WAITFORVSYNC, 0) < 0) {
        perror("ioctl() / FBIO_WAITFORVSYNC");
    }
    if(pScreenInfo->buf_num > 1){
        pScreenInfo->buf_idx = (pScreenInfo->buf_idx++)%2;
    }
    pScreenInfo->fb_cure = pScreenInfo->fb_base + pScreenInfo->buf_idx * pScreenInfo->screen_size;
}

int ScreenClose(ScreenInfoSt *pScreenInfo){
    munmap(pScreenInfo->fb_base, pScreenInfo->finfo.smem_len);
    close(pScreenInfo->fd_fb);
}

void FillTestColorToARGB(unsigned char *pData, int dataLen, int width, int height)
{
    if(dataLen < width*height*4){
        printf("FillTestColorToARGB param not ok!");
        return;
    }
    unsigned int *tmpData = 0;
    for(int j = 0; j < height; j++){
        for(int i = 0; i < width; i++){
            tmpData = (unsigned int *)&pData[(i+j*width)*4 + 0];
            if(j >= height/2){
                *tmpData = 0xFF00FF00;//ARGB
                //*tmpData = 0x00000000;//ARGB
            }else{
                *tmpData = 0xFF0000FF;//ARGB
                //*tmpData = 0xFFFFFFFF;//ARGB
            }
        }
    }
}

int main (int argc, char* argv[]){
    ScreenInfoSt screenInfo;
    memset(&screenInfo, 0, sizeof(screenInfo));
    printf("build time: %s %s\n", __DATE__, __TIME__);
    for(int i = 0; i < argc; i++){
        printf("param[%d] = %s\n", i, argv[i]);
    }
    char *screen_dev_name = "/dev/fb0";
    if(argc > 1){
        screen_dev_name = argv[1];
    }
    if(ScreenOpen(screen_dev_name, &screenInfo) != 0){
        printf("ScreenOpen failed!!!\n");
        return -1;
    }
    for(int i = 0;;i++){
        if(i%2 == 0){
            memset(screenInfo.fb_cure, 0x00, screenInfo.screen_size);
        }else{
            memset(screenInfo.fb_cure, 0xff, screenInfo.screen_size);
        }
        ScreenFlush(&screenInfo);
        sleep(1);
    }
    ScreenClose(&screenInfo);
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值