帧缓冲设备编程

来源:互联网 发布:mac 战网安装包打不开 编辑:程序博客网 时间:2024/06/10 18:57
帧缓冲(framebuffer)是Linux为显示设备提供的一个接口,把显存抽象后的一种设备,他允许上层应用程序在图形模式下直接对显示缓冲区进行读写操作。这种操作是抽象的,统一的。用户不必关心物理显存的位置、换页机制等等具体细节。这些都是由Framebuffer设备驱动来完成的。
帧缓冲驱动的应用广泛,在linux的桌面系统中,Xwindow服务器就是利用帧缓冲进行窗口的绘制。尤其是通过帧缓冲可显示汉字点阵,成为Linux汉化的唯一可行方案。
Linux FrameBuffer 本质上只是提供了对图形设备的硬件抽象,在开发者看来,FrameBuffer 是一块显示缓存,往显示缓存中写入特定格式的数据就意味着向屏幕输出内容。所以说FrameBuffer就是一块白板。例如对于初始化为16 位色的FrameBuffer 来说, FrameBuffer中的两个字节代表屏幕上一个点,从上到下,从左至右,屏幕位置与内存地址是顺序的线性关系。
帧缓存可以在系统存储器(内存)的任意位置,视频控制器通过访问帧缓存来刷新屏幕。 帧缓存也叫刷新缓存 Frame buffer 或 refresh buffer, 这里的帧(frame)是指整个屏幕范围。
帧缓存有个地址,是在内存里。我们通过不停的向frame buffer中写入数据, 显示控制器就自动的从frame buffer中取数据并显示出来。全部的图形都共享内存中同一个帧缓存。
-------以上内容摘自百度百科
#include <unistd.h>#include <stdio.h>#include <fcntl.h>#include <linux/fb.h>#include <sys/mman.h>#include <stdlib.h>#define FB_PATH"/dev/fb0"  /*帧缓冲设备在linux系统中对应的设备文件*/#define IMG_LENGTH800*600*4#include <sys/types.h>#include <sys/stat.h>/*************************************************Function: init_fbDescription: 打开帧缓冲设备,获得帧缓冲设备固定结构体数据和可变结构体数据,设置映射Input:帧缓冲设备的设备文件位置Output: 标识帧缓冲设备的文件描述符Return: 帧缓冲设备映射后的起始地址Others: *************************************************/char *init_fb(char *fbpath, int *fbfd){*fbfd = open(fbpath, O_RDWR);if(*fbfd < 0){perror("open frambuffer device failed!");return (char *)-1;}struct fb_var_screeninfo vinfo;struct fb_fix_screeninfo  finfo;if (ioctl(*fbfd,FBIOGET_FSCREENINFO,&finfo)){perror("reading fixed information failed");return (char *)-1;}if (ioctl(*fbfd,FBIOGET_VSCREENINFO,&vinfo)){perror("reading variable information failed");return (char *)-1;}/* struct fb_var_screeninfo 和 struct fb_fix_screeninfo 兩个数据结构是在/usr/include/linux/fb.h中定义的,它们都是无符号32位的整数在fb_fix_screeninfo中有__u32 smem_len 是這个/dev/fb0的大小,也就是內存大小。__u32 line_length 是屏幕上一行的点在內存中占有的空间(即字节数),不是一行上的点数。在fb_var_screeninfo 中有__u32 xres ,__u32 yres 是x和y方向的分辨率,就是兩個方向上的点数。__u32 bits_per_pixel 是每一点占有的內存空间。 */unsigned int screensize = vinfo.xres_virtual * vinfo.yres_virtual * vinfo.bits_per_pixel / 8;//unsigned int screensize = vinfo.xres * vinfo.yres * vinfo.bits_per_pixel / 8;printf("-----------------------------------------\n");printf("The mem is :%d\n",finfo.smem_len);printf("The line_length is :%d\n",finfo.line_length);printf("The xres is :%d\n",vinfo.xres);printf("The yres is :%d\n",vinfo.yres);printf("bits_per_pixel is :%d\n",vinfo.bits_per_pixel);printf("the screensize is %d\n", screensize);printf("-----------------------------------------\n");/*帧缓冲设备的内存位于内核空间,需要用mmap将其映射到用户空间(提高访问速度)*/char *fbp = (char *)mmap(NULL, screensize, PROT_READ | PROT_WRITE, MAP_SHARED, *fbfd, 0);if(fbp == (char *)-1){perror("map framebuffer device to usr memory failed");return (char *)-1;}return fbp;}/*************************************************Function: write_data_to_fbDescription: 向帧缓冲设备写入数据Input:fbp(缓冲区起始地址);fbfd(标识缓冲区的文件描述符);img_buf(存放图片数据的缓冲区)img_width(图片数据的宽); img_height(图片数据的高);img_bits(图片数据的位深度)Output: 无Return: int(成功返回0, 失败返回 -1)Others: 用于向缓冲区打印图片*************************************************/int write_data_to_fb(char *fbp, int fbfd, char *img_buf, unsigned int img_width, unsigned int img_height, unsigned int img_bits){struct fb_var_screeninfo vinfo;if (ioctl(fbfd,FBIOGET_VSCREENINFO,&vinfo)){perror("reading variable information failed");return -1;}struct fb_fix_screeninfo  finfo;if (ioctl(fbfd,FBIOGET_FSCREENINFO,&finfo)){perror("reading fixed information failed");return -1;}unsigned int screensize = vinfo.xres_virtual * vinfo.yres_virtual * vinfo.bits_per_pixel / 8;//unsigned int screensize = vinfo.xres * vinfo.yres * vinfo.bits_per_pixel / 8;int row, column;int num = 0;//img_buf 中的某个字节元素对应下标/*直接打印出来的图片是倒着的,需要反着打印*/for(row = img_height - 1; row>=0; row--){for(column = 0; column< img_width * img_bits / 8; column++){fbp[row * finfo.line_length+column] = img_buf[num];/*finfo.line_length为帧缓冲设备每一行所占字节数finfo.line_length * row+column为帧缓冲设备第finfo.line_length * row行第column个字节开始赋值。*/num++;}//fbp += (vinfo.xres_virtual - img_width)*img_bits / 8;/*屏幕每行所占字节是固定的,不是随图片变化的,不能使用此句*///fbp += finfo.line_length - img_width*img_bits / 8;/*finfo.line_length指屏幕每行所占字节数*/}return 0;}/*test 环境:ubuntu12.04 32位(运行在vmware-workstation虚拟机中)帧缓冲设备:显示器test.bmp为测试bmp图片文件,分辨率为800 * 600,32位深度。为了看到演示效果,请在纯字符界面下操作(ctrl+alt+F1)*/#if 1void main(){int fbfd = 0;char img_buf[IMG_LENGTH];char * fbp = init_fb(FB_PATH, &fbfd);struct stat filestatus;int ret = stat("test.bmp", &filestatus);if(ret < 0){perror("get file stat failed!");return;}int imgsize = filestatus.st_size;printf("img size is%d\n", imgsize);FILE *imgfp = fopen("test.bmp","r");if(imgfp < 0){perror("open test.bmp failed!");return;}if (fread(img_buf, imgsize, 1, imgfp) < 0){printf("read test3.bmp data error!\n");}fclose(t);write_data_to_fb(fbp, fbfd, img_buf+54, 800, 600, 32);fclose(imgfp);}#endif

0 0
原创粉丝点击