Frame Buffer
2010年11月18日
大家都知道Unix/Linux系统是由命令驱动的。X-Window-System是Unix/Linux上的图形系统,它是通过X-Server来控制硬件的。但有一些Linux的发行版在引导的时候就会在屏幕上出现图形,这时的图形是不可能由X来完成的,那是什么机制呢?答案是FrameBuffer。
帧缓冲(framebuffer)是 Linux 为显示设备提供的一个接口,把显存抽象后的一种设备,他允许上层应用程序在图形模式下直接对显示缓冲区进行读写操作。这种操作是抽象的,统一的。用户不必关心物理显存的位置、换页机制等等具体细节。这些都是由Framebuffer 设备驱动来完成的,所以可知其具有良好的移植性。
帧缓冲设备对应的设备文件为/dev/fb*,如果系统有多个显示卡,Linux 下还可支持多个帧缓冲设备,最多可达32 个,分别为/dev/fb0 到/dev/fb31,当前缺省的帧缓冲设备通常指向/dev/fb0。当然在嵌入式系统中支持一个显示设备就够了。帧缓冲设备为标准字符设备,主设备号为29,次设备号则从0到31。分别对应/dev/fb0-/dev/fb31。在MID上,设备信息是/dev/graphics/fb0,在PC机上有显卡的原因是找不到fb的。
通过/dev/fb,应用程序的操作主要有这几种:
1.读/写(read/write)/dev/fb:相当于读/写屏幕缓冲区。在MID上,采用的方式是cat /dev/graphics/fb0 tmp和cat tmp > /dev/graphics/fb0可以实现屏幕内存存储和重现,但是本人试了没有效果(原因不知)。
2.映射(map)操作:由于 Linux 工作在保护模式,每个应用程序都有自己的虚拟地址空间,在应用程序中是不能直接访问物理缓冲区地址的。为此,Linux 在文件操作 file_operations 结构中提供了 mmap 函数,可将文件的内容映射到用户空间。对于帧缓冲设备,则可通过映射操作,可将屏幕缓冲区的物理地址映射到用户空间的一段虚拟地址中,之后用户就可以通过读写这段虚拟地址访问屏幕缓冲区,在屏幕上绘图了。
mmap将一个文件或者其它对象映射进内存。文件被映射到多个页上,如果文件的大小不是所有页的大小之和,最后一个页不被使用的空间将会清零。munmap执行相反的操作,删除特定地址区域的对象映射。成功执行时,mmap()返回被映射区的指针,munmap()返回0。
基于文件的映射,在mmap和munmap执行过程的任何时刻,被映射文件的st_atime可能被更新。如果st_atime字段在前述的情况下没有得到更新,用PROT_WRITE 和 MAP_SHARED标志建立起来的文件映射,其st_ctime 和 st_mtime在对映射区写入之后,在msync()通过MS_SYNC 和 MS_ASYNC两个标志调用之前会被更新。
3.I/O控制:对于帧缓冲设备,对设备文件的 ioctl操作可读取/设置显示设备及屏幕的参数,如分辨率,显示颜色数,屏幕大小等等。ioctl 的操作是由底层的驱动程序来完成的。
典型程序段如下:
#include
#include
#include
#include
#include
int main () {
int fp=0;
struct fb_var_screeninfo vinfo;
struct fb_fix_screeninfo finfo;
fp = open ("/dev/graphics/fb0",O_RDWR);
if (fp 内存大小。__u32 line_length 是屏幕上一行的点在内存中占有的空间,不是一行上的点数。在fb_var_screeninfo 中有__u32 xres ,__u32 yres 是x和y方向的分辨率,就是两个方向上的点数。__u32 bits_per_pixel 是每一点占有的内存空间。
如上:内存长度是1536000B,一行占的内存是1600B,分辨率是800*480,每像素占2B。你会发现1536000/(800*480*2)=2,分配的内存空间是单帧画面需要的内存空间的2倍?这是因为在现代的图形系统中大多有缓冲技术,显存中存有两页屏幕数据,这是方便快速的交换屏幕内容。
参考地址:http://blog.ednchina.com/exbob/37028/category.aspx
参考地址:http://blog.csdn.net/scwinter/archive/2010/01/08/5 148967.aspx 如对Android原生(Natvie)C开发还任何疑问,请参阅http://emck.avaw.com/?p=205
虽然现在能通过交叉环境编译程序,并push到Android上执行,但那只是console台程序,是不是有些单调呢?下面就要看如何通过Linux的 framebuffer 技术在Android上画图形,关于Linux的framebuffer技术,这里就不再详细讲解了,请大家google一下。
操作framebuffer的主要步骤如下:
1、打开一个可用的FrameBuffer设备;
2、通过mmap调用把显卡的物理内存空间映射到用户空间;
3、更改内存空间里的像素数据并显示;
4、退出时关闭framebuffer设备。
下面的这个例子简单地用framebuffer画了一个渐变的进度条,代码 framebuf.c 如下:
#include
#include
#include
#include
#include
inline static unsigned short int make16color(unsigned char r, unsigned char g, unsigned char b)
{
return (
(((r >> 3) & 31) > 2) & 63) > 3) & 31) );
}
int main() {
int fbfd = 0;
struct fb_var_screeninfo vinfo;
struct fb_fix_screeninfo finfo;
long int screensize = 0;
char *fbp = 0;
int x = 0, y = 0;
int guage_height = 20, step = 10;
long int location = 0;
// Open the file for reading and writing
fbfd = open("/dev/graphics/fb0″, O_RDWR);
if (!fbfd) {
printf("Error: cannot open framebuffer device.\n");
exit(1);
}
printf("The framebuffer device was opened successfully.\n");
// Get fixed screen information
if (ioctl(fbfd, FBIOGET_FSCREENINFO, &finfo)) {
printf("Error reading fixed information.\n");
exit(2);
}
// Get variable screen information
if (ioctl(fbfd, FBIOGET_VSCREENINFO, &vinfo)) {
printf("Error reading variable information.\n");
exit(3);
}
printf("sizeof(unsigned short) = %d\n", sizeof(unsigned short));
printf("%dx%d, %dbpp\n", vinfo.xres, vinfo.yres, vinfo.bits_per_pixel );
printf("xoffset:%d, yoffset:%d, line_length: %d\n", vinfo.xoffset, vinfo.yoffset, finfo.line_length );
// Figure out the size of the screen in bytes
screensize = vinfo.xres * vinfo.yres * vinfo.bits_per_pixel / 8;;
// Map the device to memory
fbp = (char *)mmap(0, screensize, PROT_READ | PROT_WRITE, MAP_SHARED,
fbfd, 0);
if ((int)fbp == -1) {
printf("Error: failed to map framebuffer device to memory.\n");
exit(4);
}
printf("The framebuffer device was mapped to memory successfully.\n");
//set to black color first
memset(fbp, 0, screensize);
//draw rectangle
y = (vinfo.yres guage_height) / 2 2; // Where we are going to put the pixel
for (x = step 2; x 内存,然后就可以操作这块内存空间来显示你想画的图形了。
最后别忘了关闭设备:
munmap(fbp, screensize);
close(fbfd);
效果图如下:
Android framebuffer截图 Linux的帧缓冲(Frame Buffer)之二:显示图形和图像
现在你应该对FrameBuffer有一个大概的了解了吧。那么接下来你一定会想在屏幕上画一些东西,让我们先从画一个方块开始吧。先说说我的想法:在类Unix系统中,一切东西都是文件。我们对屏幕的读写就可以转换成对帧缓冲设备的读写。那么就把帧缓冲设备用open打开,再用lseek定位要读写的位置,最后调用read或者write来操作。通过这么一大段的操作我们才完成了对一个点的读或者写。
这种方法开销太大了。还有一种方法,我们把/dev/fb0映射到程序进程的内存空间中来,然后得到一个指向这段存储空间的指针,这样就可以方便的读写了。但是我们要知道能映射多少和该映射多少,这能很方便的从上面一个程序得出的参数来决定。
#include
#include
#include
#include
#include
int main () {
int fp=0;
struct fb_var_screeninfo vinfo;
struct fb_fix_screeninfo finfo;
long screensize=0;
char *fbp = 0;
int x = 0, y = 0;
long location = 0;
fp = open ("/dev/graphics/fb0",O_RDWR);
if (fp 代码有点不清晰,不易理解。但是有了这个基本的代码实现,我们可以很容易写一些DrawPoint之类的函数去包装一下低层的对线性存储空间的读写。有了画点的程序,再写出画线画圆的函数就不是非常困难了。
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/scwinter/archive/2010/01/08/5 148967.aspx
发表评论
-
系统优化法则
2012-01-20 08:35 539系统优化法则 2010年11月13日 系统优化法则 ... -
【详解】如何编写Linux下Nand Flash驱动 1/2
2012-01-20 08:35 798【详解】如何编写Linux ... -
网络编程常见问题总结
2012-01-20 08:35 569网络编程常见问题总结 2010年10月26日 网络编程常 ... -
KXML
2012-01-20 08:35 531KXML 2010年07月05日 ... -
Windows系统的Regsvr32
2012-01-19 13:41 737Windows系统的Regsvr32 2011 ... -
as3面试题
2012-01-19 13:41 573as3面试题 2011年09月13日 ... -
电脑高手应用技巧荟萃(电脑知识二十六)
2012-01-19 13:41 405电脑高手应用技巧荟萃(电脑知识二十六) 2010年12月07 ... -
各种文件后缀名与打开方式大全a-d
2012-01-19 13:41 809各种文件后缀名与打开方式大全a-d 2012年01月11日 ... -
安全bios手册(2)
2012-01-17 03:31 662安全bios手册(2) 2010年06月20日 BIOS ... -
最全的硬盘修复专题帖(转贴)
2012-01-17 03:31 652最全的硬盘修复专题帖( ... -
行云流水
2012-01-17 03:31 574行云流水 2010年06月03日 行至水穷处,坐看云起 ... -
电脑BIOS的设置
2012-01-17 03:30 736电脑BIOS的设置 2010年08月14日 关于BIOS ... -
硬盘数据恢复原理和方法
2012-01-17 03:30 661硬盘数据恢复原理和方法 2011年03月02日 硬盘数我 ... -
中国古代的衣食住行
2012-01-16 02:06 685中国古代的衣食住行 2010年04月06日 对中国古 ... -
中国古代衣食住行 3
2012-01-16 02:06 398中国古代衣食住行 3 2009年09月27日 体衣:制衣 ... -
恳谈会
2012-01-16 02:06 432恳谈会 2010年12月28日 ... -
由“认知窄化”引起的思考
2012-01-16 02:06 824由“认知窄化”引起的 ...
相关推荐
arm的图像压缩格式简介,让你对帧压缩有个基本了解。
6410 LCD驱动 frame buffer
frame buffer example
en virtual frame buffer device.
6410 LCD驱动 frame buffer
RFB协议(remote frame buffer)
linux frame buffer 相关的资料。相关framebuffer 的学习还可以参考Linux 2.2 Framebuffer Device Programming Tutorial
s3c2410_lcd & frame buffer 驱动分析
Linux下LCD的frame buffer测试源码,仅供参考学习。
framebuffer device 在内核里面作为显卡驱动模型,许多函数和数据结构都是特定,正是这些特定的东西为我们的编程提供了方便。
zynq-7000学习笔记(九)——frame buffer图像显示编程-附件资源
使用最新的opengl扩展fbo编写的程序,该扩展提供了替代pbuffer的功能,使MRT的实现更加方便。使用vc6和ogl2.0编写。
在lvgl上实现nes游戏机模拟器的显示和控制,基于Linux平台的frame buffer。 演示视频: https://www.bilibili.com/video/BV1gt4y1L7Aw
SurfaceFlinger服务在启动的过程中,会对系统的硬件帧缓冲区进行初始化。由于系统的硬件帧缓冲区一般只有一个,并且不是谁都可以随便访问的,因此,它就需要由一个服务来统一管理。在Android系统中,这个服务便是...
该系统通过顶层模块,调用7底层模块实现。7大模块底层模块为:理想信源数据接收模块,理想信源数据缓存模块,LAPS成帧模块,加扰并发送LAPS帧模块,接收LAPS帧并解扰模块,接收LAPS帧数据缓存模块,解帧并发送数据给...
以三星公司的嵌入式微处理器S3C2440A和夏普公司3.5inLCD屏LQ035Q7DH01为基础,设计了显示硬件电路,介绍了帧缓冲设备的处理机制及底层驱动的接口函数,针对本显示系统给出了如何开发其Linux帧缓冲设备驱动程序。
XILINX MPMC的官方介绍 Integrating a Video Frame Buffer Controller (VFBC) in System Generator
In this paper, we propose a novel model-based overdrive (OD) algorithm with frame buffer compression. Different from conventional OD algorithms, our proposed OD algorithm adds a model to predict the ...
fb 该库首先是学习framebuffer的一些例程,后面就是使用framebuffer实现linux的屏幕截屏,然后再使用framebuffer实现一款android app的屏幕截屏,最后,尝试使用frame buffer来实现屏幕录制.