/*
使用说明:
全志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);
}
网友评论