framebuffer 双缓冲问题

FireBirdCN 2009-08-20 02:20:07
刚刚接触linux,不太了解,可能会问一些比较低级的问题,请包涵。
我看了网上的一些Framebuffer的资料,有提到通过设置yoffset的值来实现双缓冲的。
百度知道里的一段:
如果你的屏幕为800x600,各参数设定为:
xres = 800
yres = 600
xres_virtual = 800
xres_virtual = 600x2 = 1200
缺省的yoffset = 0;
显示的是(0,0)到(800,600)到可视区
当你设定yoffset = 600时
(0,600)到(800,1200)将显示到可视区,就这样实现双缓冲

但实际使用中遇到问题。使用
fb_vmeminfo.xoffset=0;
fb_vmeminfo.yoffset=600;
if(-1==(ioctl(fdtem,FBIOPAN_DISPLAY,&fb_vmeminfo)))//此处会执行错误
……
返回值总是-1。
FBIOPAN_DISPLAY,FBIOPUT_VSCREENINFO两个宏好像不起作用。
先FBIOGET_VSCREENINFO得到struct fb_var_screeninfo fb_vinfo
修改fb_vinfo的一些成员值后用FBIOPUT_VSCREENINFO设置,但不起作用。
网上看到有人也提了这样的问题,可是没有答复。
望达人指点一下。谢谢
说的不清楚的地方请指出 我补充
...全文
2216 27 打赏 收藏 转发到动态 举报
写回复
用AI写文章
27 条回复
切换为时间正序
请发表友善的回复…
发表回复
hepanlong2014 2011-11-22
  • 打赏
  • 举报
回复
楼主
请你一下你的 双缓冲现在实现了么?
如果实现,请教一下具体的步骤,我现在也遇到了这个问题。
wboy181818 2011-09-28
  • 打赏
  • 举报
回复
一个选项条也会闪动吗,会不会是对framebuffer的刷新过于频繁才会闪动,没必要加双缓冲吧
buou0619 2011-06-28
  • 打赏
  • 举报
回复
和你一样的问题,get成果返回,参数正常。
put返回值也没有错,但是就是不起作用。

还有看了几个老外的贴,对这个问题也都没有什么明确答案。
TGB1989 2011-04-18
  • 打赏
  • 举报
回复
我的情况和你一样啊,不知能否通过将分辨率设置低一点来实现!希望高手指点啊
古月XYZ 2011-04-15
  • 打赏
  • 举报
回复
设备不支持双缓冲。。。。看看下面这个程序的输出:

#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>
#include <linux/fb.h>
#include <sys/mman.h>

int main () {
int fp=0;
struct fb_var_screeninfo vinfo;
struct fb_fix_screeninfo finfo;
fp = open ("/dev/fb0",O_RDWR);

if (fp < 0){
printf("Error : Can not open framebuffer device\n");
exit(1);
}

if (ioctl(fp,FBIOGET_FSCREENINFO,&finfo)){
printf("Error reading fixed information\n");
exit(2);
}

if (ioctl(fp,FBIOGET_VSCREENINFO,&vinfo)){
printf("Error reading variable information\n");
exit(3);
}

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);
close (fp);
}


输出:

The mem is :4194304
The line_length is :5440
The xres is :1360
The yres is :768
bits_per_pixel is :32

很悲剧,我的只是单缓冲。不知道能不能改。同求各路大侠
geldqb 2009-08-25
  • 打赏
  • 举报
回复
[Quote=引用 18 楼 firebirdcn 的回复:]
显卡:NVIDIA GeForce 8600GT
[/Quote]

很可能是显卡驱动的问题。
把显卡的驱动下载下来再安装一遍吧。
hardbeyond 2009-08-25
  • 打赏
  • 举报
回复
学习!
geldqb 2009-08-24
  • 打赏
  • 举报
回复
感觉是X Windows的设置问题。
有没有改动过X的设定文件?
[Quote=引用 18 楼 firebirdcn 的回复:]
PC主机:普通兼容机
CPU:intel Pentium E2180
显卡:NVIDIA GeForce 8600GT
系统:Ubuntu 8.10
开发板:
  主控:JZ4750
  系统:linux 2.6.24
  构架:mips
在开发板上 FBIOPAN_DISPLAY 这句能顺利执行过去 (PC上一直返回-1)
但不知是步骤没搞对 还是什么原因
没效果
[/Quote]
FireBirdCN 2009-08-24
  • 打赏
  • 举报
回复
FireBirdCN 2009-08-22
  • 打赏
  • 举报
回复
[Quote=引用 17 楼 geldqb 的回复:]
参数无效啊,好像很有可能不支持FBIOPAN_DISPLAY。
能否公开你的硬件平台的一些信息?

[/Quote]
PC主机:普通兼容机
CPU:intel Pentium E2180
显卡:NVIDIA GeForce 8600GT
系统:Ubuntu 8.10
开发板:
主控:JZ4750
系统:linux 2.6.24
构架:mips
在开发板上 FBIOPAN_DISPLAY 这句能顺利执行过去 (PC上一直返回-1)
但不知是步骤没搞对 还是什么原因
没效果
FireBirdCN 2009-08-21
  • 打赏
  • 举报
回复
[Quote=引用 15 楼 showman 的回复:]
这个就是做滚屏的,但不是每个fb驱动都实现这些的。
双缓冲也是,yoffset便宜过了以后,还需要设置很多寄存器才可以把屏幕的显示转过来。
[/Quote]
正是这 “yoffset便宜过了以后,还需要设置很多寄存器才可以把屏幕的显示转过来”
让我抓耳挠腮啊~~
geldqb 2009-08-21
  • 打赏
  • 举报
回复
参数无效啊,好像很有可能不支持FBIOPAN_DISPLAY。
能否公开你的硬件平台的一些信息?

[Quote=引用 7 楼 firebirdcn 的回复:]
打印出来了
Invalid argument

这参数都是这么来的啊  难道使用FBIOPAN_DISPLAY时 参数不同?
[/Quote]
ShowMan 2009-08-20
  • 打赏
  • 举报
回复
这个就是做滚屏的,但不是每个fb驱动都实现这些的。
双缓冲也是,yoffset便宜过了以后,还需要设置很多寄存器才可以把屏幕的显示转过来。
FireBirdCN 2009-08-20
  • 打赏
  • 举报
回复
到此为止了么?
FireBirdCN 2009-08-20
  • 打赏
  • 举报
回复
看网上的文章说的 好简单
前几个成员决定了分辨率。xres和yres 是在屏幕上可见的实际分辨率,在通常的vga模式将为640和400(也许是480,by highbar)。*res-virtual决定了构建屏幕时视频卡读取屏幕内存的方式。当实际的垂直分辨率为400,虚拟分辨率可以是800。这意味着 800行的数据被保存在了屏幕内存区中。因为只有400行可以被显示,决定从那一行开始显示就是你的事了。这个可以通过设置*offset来实现。给 yoffset赋0将显示前400行,赋35将显示第36行到第435行,如此重复。这个功能在许多情形下非常方便实用。它可以用来做双缓冲。双缓冲就是你的程序分配了可以填充两个屏幕的内存。将offset设为0,将显示前400行(假设是标准的vga),同时可以秘密的在400行到799行构建另一个屏幕,当构建结束时,将yoffset设为400,新的屏幕将立刻显示出来。现在将开始在第一块内存区中构建下一个屏幕的数据,如此继续。这在动画中十分有用。

另外一个应用就是用来平滑的滚动整个屏幕。就像在前面屏幕中一样,在内存分配800行的空间。每隔10毫秒设定一个定时器(timer,见man settimer和man
signal / man sigaction),将offset设为1或是比上次更多,瞧,你看到了一个平滑滚动的屏幕。确保你的信号(signal)不要因为最佳输出的原因被信号处理程序阻塞。
ShowMan 2009-08-20
  • 打赏
  • 举报
回复
gdb 跟不到kernel mode。
内核模式要用kgdb。
你这种情况还是printk吧。

估计就是不支持pan_display
FireBirdCN 2009-08-20
  • 打赏
  • 举报
回复
还有请问Showman
我想在 if(0==ioctl(fdtem,FBIOPUT_VSCREENINFO,&fb_vmeminfo))
用GDB 跟进去
设了break
s
s
好像跟不进去
应该怎么跟到驱动里面去?
FireBirdCN 2009-08-20
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 showman 的回复:]
那你要好好看看你的fb驱动了,我估计你的驱动不支持这两个选项。
报-1也不应该,毕竟抽象层都是实现的。

你说的具体点,把驱动和测试代码联系起来看
[/Quote]
我试验了FBIOPUT_VSCREENINFO 不报-1
fb_vmeminfo.yoffset=300;
if(0==ioctl(fdtem,FBIOPUT_VSCREENINFO,&fb_vmeminfo))
printf("success");
执行过去了 并且打印了 success
但再GET回来 yoffset=0 不是我设定的值 晕了
我用的Ubuntu 8.10
要是真的驱动不支持 该怎么办?
ShowMan 2009-08-20
  • 打赏
  • 举报
回复
那你要好好看看你的fb驱动了,我估计你的驱动不支持这两个选项。
报-1也不应该,毕竟抽象层都是实现的。

你说的具体点,把驱动和测试代码联系起来看
FireBirdCN 2009-08-20
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 ma100 的回复:]
显示模式是否设定(vga=0xxxx)
比如640*480*256色 vga=0x301
[/Quote]
这些也影响双缓冲?
现在时我的framebuffer能用
做的界面也都正常
有一个选项条 移动一下选择下一项 这样的过程会有闪烁
所以才要研究双缓冲
加载更多回复(7)

23,127

社区成员

发帖
与我相关
我的任务
社区描述
Linux/Unix社区 应用程序开发区
社区管理员
  • 应用程序开发区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧