日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

【Linux】FrameBuffer操作入门

發布時間:2025/4/16 linux 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【Linux】FrameBuffer操作入门 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

所有的這些操作,都是在控制臺界面下,root登錄。

一,先變一個魔法

???????? $ cat /dev/fb0?> sreensnap????? /*獲取一屏的數據*/ ?

???????? $ clear???????????????????????????????????????? /*清楚屏幕的輸出*/

???????? $ cat sreensnap > /dev/fb0 ? ? /*將剛才的屏幕數據顯示*/


二,操作/dev/fb0?

??????? 1)查看/dev/fb0 的信息

[html]?view plaincopy
  • #include?<unistd.h>??
  • #include?<stdio.h>??
  • #include?<fcntl.h>??
  • #include?<linux/fb.h>??
  • #include?<sys/mman.h>??
  • #include?<stdlib.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);??
  • }??
  • ??????? 2)改變屏幕上某一個點的顏色

    [html]?view plaincopy
  • #include?<unistd.h>??
  • #include?<stdio.h>??
  • #include?<stdlib.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;??
  • ?????long?screensize=0;??
  • ?????char?*fbp?=?0;??
  • ?????int?x?=?0,?y?=?0;??
  • ?????long?location?=?0;??
  • ?????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);??
  • ?????}??
  • ??
  • ??????screensize?=?vinfo.xres?*?vinfo.yres?*?vinfo.bits_per_pixel?/?8;??
  • ?????/*這就是把fp所指的文件中從開始到screensize大小的內容給映射出來,得到一個指向這塊空間的指針*/??
  • ?????fbp?=(char?*)?mmap?(0,?screensize,?PROT_READ?|?PROT_WRITE,?MAP_SHARED,?fp,0);??
  • ?????if?((int)?fbp?==?-1)??
  • ?????{??
  • ????????printf?("Error:?failed?to?map?framebuffer?device?to?memory./n");??
  • ????????exit?(4);??
  • ?????}??
  • ?????/*這是你想畫的點的位置坐標,(0,0)點在屏幕左上角*/??
  • ?????x?=?100;??
  • ?????y?=?100;??
  • ?????location?=?x?*?(vinfo.bits_per_pixel?/?8)?+?y??*??finfo.line_length;??
  • ??
  • ?????*(fbp?+?location)?=?100;??/*?藍色的色深?*/??/*直接賦值來改變屏幕上某點的顏色*/??
  • ?????*(fbp?+?location?+?1)?=?15;?/*?綠色的色深*/????
  • ?????*(fbp?+?location?+?2)?=?200;?/*?紅色的色深*/????
  • ?????*(fbp?+?location?+?3)?=?0;??/*?是否透明*/???
  • ??
  • ?????munmap?(fbp,?screensize);?/*解除映射*/??
  • ?????close?(fp);????/*關閉文件*/??
  • ?????return?0;??
  • ??
  • }??


  • 三,framebuffer 內部結構

    ? ? 數據結構:framebuffer 設備很大程度上依靠了下面四個數據結構。這三個結構在fb.h 中聲明。

    ?????????????????????? Struct fb_var_screeninfo?? //用來描述圖形卡的特性的。通常是被用戶設置的。

    ?????????????????????? Struct fb_fix_screeninfo??? //?定義了圖形卡的硬件特性, 是不能改變的,用戶選定了哪一個圖形卡,那么它的硬件特性也就定下來了。

    ?????????????????????? Struct fb_info????????????????????? //定義了當前圖形卡framebuffer 設備的獨立狀態,一個圖形卡可能有兩個framebuffer, 在這種情況下,就需要兩個fb_info 結構。這個結構是唯一在內核空間可見的。
    ? ??
    ???
    ? ??1)fb_var_screeninfo解析

    ?

    [html]?view plaincopy
  • struct?fb_var_screeninfo?{??
  • ????__u32?xres;?/*?visible?resolution?*/??
  • ????__u32?yres;??
  • ??
  • ????__u32?xres_virtual;?/*?virtual?resolution?*/??
  • ????__u32?yres_virtual;??
  • ??
  • ????__u32?xoffset;?/*?offset?from?virtual?to?visible?*/??
  • ????__u32?yoffset;?/*?resolution?*/??
  • ??
  • ????__u32?bits_per_pixel;?/*?guess?what?*/??
  • ????__u32?grayscale;?/*?!=?0?Graylevels?instead?of?colors*/??
  • ??
  • ????struct?fb_bitfield?red;?/*bitfield?in?fb?mem?if?true?color,?*/??
  • ????struct?fb_bitfield?green;?/*else?only?length?is?significant?*/??
  • ????struct?fb_bitfield?blue;??
  • ????struct?fb_bitfield?transp;?/*transparency?*/??
  • ??
  • ????__u32?nonstd;?????/*?!=?0?Non?standard?pixel?format?*/??
  • ????__u32?activate;?/*?see?FB_ACTIVATE_*?*/??
  • ??
  • ????__u32?height;?/*?height?of?picture?in?mm???*/??
  • ????__u32?width;?/*?width?of?picture?in?mm????*/??
  • ??
  • ????__u32?accel_flags;?/*?acceleration?flags?(hints)?*/??
  • ??
  • ????/*?Timing:?All?values?in?pixclocks,?except?pixclock?(of?course)?*/??
  • ??
  • ????__u32?pixclock;?/*?pixel?clock?in?ps?(pico?seconds)?*/??
  • ??
  • ????__u32?left_margin;?/*?time?from?sync?to?picture?*/??
  • ????__u32?right_margin;?/*?time?from?picture?to?sync?*/??
  • ????__u32?upper_margin;?/*?time?from?sync?to?picture?*/??
  • ????__u32?lower_margin;??
  • ??
  • ????__u32?hsync_len;?/*?length?of?horizontal?sync?*/??
  • ????__u32?vsync_len;?/*?length?of?vertical?sync?*/??
  • ??
  • ????__u32?sync;?/*?see?FB_SYNC_*?*/??
  • ????__u32?vmode;?/*?see?FB_VMODE_*?*/??
  • ??
  • ????__u32?reserved[6];?/*?Reserved?for?future?compatibility*/??
  • ??
  • };??


  • 前幾個成員決定了分辨率。

    ??????? ?? xres和yres是在屏幕上可見的實際分辨率,

    ????????? xres-virtual決定了構建屏幕時視頻卡讀取屏幕內存的方式。

    ????????? bits_per_pixel 設為1,2,4,8,16,24或32來改變顏色深度


    ??????? 2)? fb_fix_screeninfo

    [html]?view plaincopy
  • struct?fb_fix_screeninfo?{??
  • ??
  • ????char?id[16];?/*?identification?string?eg?"TT?Builtin"?*/??
  • ??
  • ????unsigned?long?smem_start;?/*?Start?of?frame?buffer?mem?*/??
  • ??
  • ????/*?(physical?address)?*/??
  • ??
  • ????__u32?smem_len;?/*?Length?of?frame?buffer?mem?*/??
  • ??
  • ????__u32?type;?/*?see?FB_TYPE_*?*/??
  • ??
  • ????__u32?type_aux;?/*?Interleave?for?interleaved?Planes?*/??
  • ??
  • ????__u32?visual;?/*?see?FB_VISUAL_*?*/??
  • ??
  • ????__u16?xpanstep;?/*?zero?if?no?hardware?panning?*/??
  • ??
  • ????__u16?ypanstep;?/*?zero?if?no?hardware?panning?*/??
  • ??
  • ????__u16?ywrapstep;?/*?zero?if?no?hardware?ywrap?*/??
  • ??
  • ????__u32?line_length;?/*?length?of?a?line?in?bytes?*/??
  • ??
  • ????unsigned?long?mmio_start;?/*?Start?of?Memory?Mapped?I/O?*/??
  • ??
  • ????/*?(physical?address)?*/??
  • ??
  • ????__u32?mmio_len;?/*?Length?of?Memory?Mapped?I/O?*/??
  • ??
  • ????__u32?accel;?/*?Type?of?acceleration?available?*/??
  • ??
  • ????__u16?reserved[3];?/*?Reserved?for?future?compatibility?*/??
  • ??
  • };??

  • ????????????????? 3) 顯示說明


    【雙顯示器例子】

    ? ? ? ? ?? 一個例子,可能就是雙顯示,最近剛剛看到實際某開發者的系統,就是兩個顯示器,鼠標移動超過單個顯示器,到最右邊的時候,就跑到另一個顯示器了。對于常常用多系統或者需要打開很多東西的開發人員,這個功能很實用。

    ? ??????? 幀緩沖可以用于?頁面交換page flipping(也常叫做?雙緩沖double buffering),許多游戲都是采用此技術,以實現更流暢的視頻輸出,以便用戶獲得更好的游戲體驗。此技術也被用于3D圖形加速。

    【雙緩沖的主要實現原理】

    ? ? ? ? ? 假如你的顯示器是VGA模式,640×400,也就是虛擬的分辨率是640X800,也就是800線(每一行的數據,稱為一條線,也就是640X1的數據了)。800線的數據存儲于Framebuffer,而實際的顯示內容,只是400線,

    ???????? Linux內核中的Framebuffer模型中,對應有個變量yoffset,就是表示的這個具體的縱坐標,默認是0,所以顯示的內容就是,0-399線,由于和實際顯示 頁面大小等同,所以此處可以簡稱為第一幀。

    ???????? 如果yoffset改變了,比如此例中變為400,那就是顯示剩余的部分,400-799線。此處簡稱為第二幀。

    ? ? ? ???在系統顯示第一幀的時候,系統在后臺悄悄地準備第二幀的數據,所以,等第一幀顯示完成,多數時候,第二幀的數據也準備好了,就可以直接顯示,同時系統又在準備接下來的一幀的數據,這樣就可以大大提高顯示效率。


    【平滑地滾動頁面的實現原理】

    ? ? ? ? ?? 同上,在顯示完第一幀數據的時候,也就是0-399線的時候,將yoffset設置為1,就可以顯示1-400線的數據了,顯示完成后,再設置yoffset為2,就顯示2-401線的數據,這樣,就可以一點點地,平滑地顯示整個滾動畫面了。其實也就是畫面在垂直方向的滾動。其中yoffset的增加,可以使用定時器,各個一段時間,比如10us,增加1,系統自動會更新顯示對應的內容,這樣我們所看到的內容就是滾動的畫面了。

    ? ??????? 此外,Linux中的Framebuffer模型中,提供了一些ioctl功能,給定一些參數,然后系統可以實現對應的功能,其中有個參數就是FBIOPAN_DISPLAY。具體也就是類似如下調用:

    ? ? ? ? ? ioctl (framebuffer_handler, FBIOPAN_DISPLAY, &variable_info);

    ? ? ? ? ? 而這個調用,如果顯示不支持framebuffer的雙緩沖的話,那么其framebuffer的緩沖大小,就是和物理上的顯示器大小等同,那么對應的yoffset也就不會像雙緩沖那樣變化了。

    ? ??????? 也就是說,如果顯卡/顯示屏控制器不支持雙緩沖,那么yoffset就應該一直為0,并且在運行時候,也不應該改變,也不應該去給FBIOPAN_DISPLAY的參數調用ioctl。

    總結

    以上是生活随笔為你收集整理的【Linux】FrameBuffer操作入门的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。