小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

VSync信號(hào)

 astrotycoon 2018-03-28


http:///2017/05/21/VSync%E4%BF%A1%E5%8F%B7/


       在我們?cè)敿?xì)分析SurfaceFlinger之前要了解一下VSync信號(hào),為下一節(jié)分析Vsync工作原理打下基礎(chǔ)。

VSync信號(hào)相關(guān)

       首先我們要了解以下幾個(gè)概念:

屏幕刷新率

       即 Refresh Rate 或 Scanning Frequency,單位赫茲/Hz,是指設(shè)備刷新屏幕的頻率,該值對(duì)于特定的設(shè)備來(lái)說(shuō)是個(gè)常量,如 60hz。

       每一臺(tái)CRT顯示器都有自己的刷新率,其單位是Hz,其數(shù)值是顯示器每秒鐘更新畫面的次數(shù)。不同的顯示器支持再不同分辨率下的不同刷新率。它的范圍可以從低到60高到100。注意它不是你游戲中所提到的那個(gè)FPS。如果你設(shè)置了一個(gè)特定的刷新率,顯示器將一直按照這個(gè)速率刷新畫面。甚至畫面沒有任何的改變。
       液晶顯示器就不同了。LCD的每個(gè)像素在被告知改變的時(shí)候?qū)⒁恢笔橇林?。他們不需要刷新。但是因?yàn)閂GA(或是DVI)的工作原理,LCD不得不從顯示卡那里按一定的速率得到新的新畫面。這就是雖然LCD不必要更新,但是他還是有自己的刷新率。

       如下圖,屏幕的刷新過(guò)程是每一行從左到右(行刷新,水平刷新,Horizontal Scanning),從上到下(屏幕刷新,垂直刷新,Vertical Scanning)。當(dāng)整個(gè)屏幕刷新完畢,即一個(gè)垂直刷新周期完成,會(huì)有短暫的空白期,此時(shí)發(fā)出 VSync 信號(hào)。所以,VSync 中的 V 指的是垂直刷新中的垂直/Vertical。
       (顯示器的掃描方式分為“逐行掃描”和“隔行掃描”兩種。逐行掃描比隔行掃描擁有列穩(wěn)定顯示效果。早期的顯示器因?yàn)槌杀舅?,使用逐行掃描方式的產(chǎn)品要比隔行掃描的貴許多,但隨著技術(shù)進(jìn)步,隔行掃描顯示器現(xiàn)在已經(jīng)被淘汰。我們可以翻一翻《電視原理》)

屏幕刷新過(guò)程

       對(duì)于一個(gè)特定的設(shè)備,幀率和刷新頻率沒有必然的大小關(guān)系。

幀率

       即 Frame Rate,單位 fps,是指 gpu 生成幀的速率,如 33 fps,60fps,越高越好。

       我想這里的每一人都明白FPS。它顯示顯示卡在每秒鐘可以描畫多少畫面。這顯然是越高越好。但是對(duì)于快速變化的游戲而言,你的FPS很難一直保持同樣的數(shù)值,他會(huì)隨著你所看到的顯示卡所要描畫的畫面的復(fù)雜程度而變化。

VSync

       安卓系統(tǒng)中有 2 種 VSync 信號(hào):屏幕產(chǎn)生的硬件 VSync 和由 SurfaceFlinger 將其轉(zhuǎn)成的軟件 Vsync 信號(hào)。后者經(jīng)由 Binder 傳遞給 Choreographer。
       硬件 VSync 是一個(gè)脈沖信號(hào),起到開關(guān)或觸發(fā)某種操作的作用。

顯示器參數(shù)

       TFT LCD 有 vsync,hsync,hspw,hbpd,hfpd, vspw,vbpd, vfpd 等參數(shù),這些參數(shù)都是由以前的 CRT(陰極射線顯像管)帶過(guò)來(lái)的, 而 TFT 液晶跟 CRT 顯示方法根本不同, 至于為什么這些參數(shù)也會(huì)引入到 TFT 中,大概是因?yàn)閂GA(或是DVI)工作原理,上文提到過(guò)。
       這網(wǎng)站有更權(quán)威的描述 http://www./HOWTO/2.html ,然后是英文。。。

       CRT 側(cè)面看是個(gè)漏斗狀的真空的東東, 根部就是電子槍, 打出的電子撞擊前面的玻璃面上的熒光物質(zhì), 熒光物發(fā)光. 控制電子槍按規(guī)律射出電子, 逐行的打到熒光物質(zhì)上, 打完一行(也即掃描完一行), 就回頭掃描下一行….. 掃描完一個(gè)顯示屏所有的行后, 就是一幅完整的畫面了, 稱為一幀(frame), 掃描過(guò)程如果非??? 人眼看到是一幅完整畫面, 但實(shí)際是一個(gè)個(gè)點(diǎn)發(fā)不同光組成的. 掃描得慢時(shí), 就會(huì)覺得閃爍了(以前聽老師講課, 說(shuō)在他們的年代, 能明顯看到一行一行刷過(guò)的壯觀場(chǎng)景)。
       一幀掃描完, 再回頭從第一行開始繼續(xù)掃描, 重復(fù)過(guò)程. 看到的就是持續(xù)在顯示的畫面了(實(shí)際上, 電子的運(yùn)動(dòng)軌跡是由磁場(chǎng)控制的, 電子槍沒有機(jī)械的運(yùn)動(dòng), 為好理解, 就當(dāng)是電子槍做了機(jī)械運(yùn)動(dòng)吧)。

       描述方式多數(shù)顯示器選擇從左上角開始, 從左至右, 到了右邊界, 再偏轉(zhuǎn)到左邊界的下一行, 這是所謂的”Z”型掃描。類似地掃描完最后一幀時(shí), 要偏轉(zhuǎn)回左上角起始處, 準(zhǔn)備掃描下一幀。這個(gè)上面那一幅圖描述過(guò)了。

       (科普一下,ignore it。start------)

  • HSYNC 信號(hào)用于告訴電子槍該掃描下一行了, 即要轉(zhuǎn)到下一行起始處了;
  • VSYNC 信號(hào)告訴電子槍該顯示下一幀了, 即該轉(zhuǎn)回左上角起始處了;

       H for Horizontal, V for vertical。在這里 Hsync, Vsync 兩者各表示一種信號(hào), 分別由 HSPW 及 VSPW 兩個(gè)參數(shù)確定信號(hào)持續(xù)時(shí)間, 也就是脈沖的寬度.

       在掃描一行中, 首先

  1. HSYNC 脈沖信號(hào)為高電平, 一發(fā)出此信號(hào), 電子槍迅速移回左邊界, 期間電子槍不發(fā)射電子.
  2. 在 HSYNC 信號(hào)持續(xù)時(shí)間上的某點(diǎn), 電子槍開始再次向右掃描了, 等 HSYNC 信號(hào)結(jié)束, 表示該開始顯示下一行的數(shù)據(jù)了, 電子槍又要開始發(fā)射電子.
  3. 在HSYNC 信號(hào)結(jié)束與開始顯示數(shù)據(jù)之間, 可以插入一段延時(shí)(由 HBPD 參數(shù)控制)讓顯示屏仍然不顯示有效數(shù)據(jù)(效果就是黑色), 是為顯示屏左邊框.
  4. 到 HFPD 結(jié)束, 電子槍才可以發(fā)射電子, 顯示該行的有效數(shù)據(jù).
  5. 顯示完畢. 又該開始發(fā)出 HSYNC 信號(hào)了. 在一行中有效數(shù)據(jù)掃描完畢與 HSYNC 信號(hào)發(fā)出之間也插入一段延時(shí) HFPD, 是為顯示屏右邊框,之后, 就是重復(fù)過(guò)程了.

       因此, 顯示一行時(shí)序?yàn)椋?HSPW -> HBPD -> 掃描數(shù)據(jù) -> HFPD .

       類似地, 垂直掃描一幀的時(shí)序:VSPW -> VBPD -> 掃描有效行 -> VFPD .

       為什么要有邊框(vbpd, vfpd, hbpd, hfpd)? 按上邊貼出網(wǎng)頁(yè)的說(shuō)法:
       Usually, one doesn’t use that feature nowadays, as we have tunable monitors that allow stretching the mode to the physical limits of the monitor.
       我的理解是:確實(shí)是以前的顯示器調(diào)整顯示屏邊界用的,而新的顯示有調(diào)整能力了, 所以不再需要刻意關(guān)注了,但術(shù)語(yǔ)被保留了下來(lái).

舉個(gè)栗子

       對(duì)于 TFT LCD, 但這些參數(shù)作用是同樣的. 但如何確定 ? TFT 的 LCD 的 datasheet 中一定得標(biāo)有。
       如型號(hào) WXCAT35-TG3 3.5 寸的液晶中有表如下:

LCD參數(shù)表

       對(duì)照下邊的時(shí)序圖(注: 時(shí)序圖的 Vsync, Hsync 信號(hào)(紅框圈出的)跟上邊講的有點(diǎn)出入, 信號(hào)都是低電平, 而非高電平, 因此編程時(shí)要設(shè)置信號(hào)反相, 如s3c244a 的 LCDCON5的INVLINE 及 INVFRAME 即是干這活的):

同步信號(hào)時(shí)序

  • tvp 即 VSPW
  • tvb 即 VBPD
  • tvf 即 VFPD
  • thp 即 HSPW
  • thb 即 HBPD
  • thf 即 HFPD

       參考的時(shí)鐘就是 CLK, 一個(gè) CLK 時(shí)鐘, 完成一個(gè)像素點(diǎn)的顯示。

       計(jì)算幀頻率(刷新頻率)的方法就是所有的像素點(diǎn)跟邊沿(邊框,hbpd 之類),同步脈沖的時(shí)間相加, 結(jié)果就是顯示完整一幀所需時(shí)間, 其倒數(shù)即是幀頻率。

Linux 的 LCD 驅(qū)動(dòng)

       LCD 驅(qū)動(dòng)主要得完成兩部分, 一是跟 framebuffer 注冊(cè)驅(qū)動(dòng); 二是設(shè)置 LCD 控制器的寄存器, 以適配 LCD。
       struct fb_info 是關(guān)鍵, 有顯示驅(qū)動(dòng)的所有信息, 要拿此結(jié)構(gòu)跟 framebuffer 注冊(cè), 代表著本驅(qū)動(dòng), 該結(jié)構(gòu)定義在 ,在驅(qū)動(dòng)程序中, 主體部分就是實(shí)現(xiàn) struct fb_info .
       在Android SurfaceFlinger 學(xué)習(xí)之路(一)—-Android圖形顯示之HAL層Gralloc模塊實(shí)現(xiàn)中提到過(guò)這一部分。
       在該結(jié)構(gòu)中, 以下定義的三個(gè)字段也是比較重要的, 要填一些數(shù)據(jù)入去:

1
2
3
struct fb_var_screeninfo var;   /* Current var */
struct fb_fix_screeninfo fix;   /* Current fix */
struct fb_ops *fbops;

       struct fb_fix_screeninfo 里定義的 pixclock 是像素點(diǎn)的周期, 單位是皮秒, 數(shù)值等于像素點(diǎn)顯示頻率的倒數(shù). 如上圖貼出的表格中, Dclk 那行中, 6.4 Mhz 就是頻率, 頻率倒數(shù)即為周期, 換算出來(lái)為 156250 ps, 約為表中給出的 156 ns.

       驅(qū)動(dòng)具體的實(shí)現(xiàn), 要看開發(fā)板對(duì)應(yīng)的驅(qū)動(dòng)源碼文件, 一般位于 kernel_src/drivers/video/ 下,我們以前下的Android源碼,找到對(duì)應(yīng)設(shè)備分支下的,應(yīng)為位于kernel/{branch}/drivers/video/吧。

簡(jiǎn)單描述

       在手機(jī)平臺(tái),LCD,Camera,TV的接線上,都會(huì)用到PCLK,VSYNC和HSYNC這三個(gè)信號(hào)??梢娺@三個(gè)信號(hào)和顯示關(guān)系非常大。首先我們先看這三個(gè)信號(hào)的作用:

  • PCLK:有些方案給他起名字叫:DotCLK。是像素點(diǎn)同步時(shí)鐘信號(hào)。也就是每個(gè)PCLK對(duì)應(yīng)一個(gè)像素點(diǎn)。
  • VSYNC:是場(chǎng)同步信號(hào)。以高電平有效為例,VSYNC置高直到被拉低,這個(gè)區(qū)段所輸出的所有影像數(shù)據(jù)組成一個(gè)frame。
  • HSYNC:是行同步信號(hào)。就是在告訴接收端:“HSYNC”有效時(shí)段內(nèi)接收端接收到的所有的信號(hào)輸出屬同一行。

       若要顯示一個(gè)640x480的畫面,顯示不正確的時(shí)候,若量PCLK,VSYNC和HSYNC這三個(gè)信號(hào),就可以知道這三個(gè)信號(hào)配置是否有問(wèn)題,一般來(lái)講,這種情況是有公式的:

  • VSync = HSYNC x 320;
  • Hsync = PCLK x 640;

       sensor的同步信號(hào)可以簡(jiǎn)單的理解為sensor向其信號(hào)接收端所發(fā)送的宣告信號(hào)。比如HSYNC,就是sensor這告訴接收端:“HSYNC”有效時(shí)段內(nèi)sensor所有的信號(hào)輸出屬同一行。VSYNC同理,以高電平有效為例,VSYNC置高直到被拉低,這個(gè)區(qū)段sensor所輸出的所有影像數(shù)據(jù)組成一個(gè)frame。同步信號(hào)的頻率決定于pixel clock,比如一行有640個(gè)pixel,那么HSYNC的頻率為:PCLK/(640+dummy);Vsync同理。

       (科普結(jié)束,ignore it,too。end------)

VSync 信號(hào)的作用

tearing 畫面撕裂

       首先,我們來(lái)看下,沒有引入 VSync 時(shí),屏幕顯示圖像的工作流程。

單緩沖

       如上圖,CPU/GPU 向 Buffer 中生成圖像,屏幕從 Buffer 中取圖像、刷新后顯示。這是一個(gè)典型的生產(chǎn)者——消費(fèi)者模型。理想的情況是幀率和刷新頻率相等,每繪制一幀,屏幕顯示一幀。而實(shí)際情況是,二者之間沒有必然的大小關(guān)系,如果沒有鎖來(lái)控制同步,很容易出現(xiàn)問(wèn)題。

       所謂”撕裂”就是一種畫面分離的現(xiàn)象,就象你照一張照片,在旋轉(zhuǎn)哪怕一度再照一張照片,然后把兩張照片的從中間裁開,用一張照片的上半部與另一張的下半部對(duì)接起來(lái)。這樣得到的畫像雖然相似但是上半部和下半部確實(shí)明顯的不同。這就被稱之為視覺現(xiàn)實(shí)上的撕裂。它不會(huì)一直從中間分開,它可能靠近上面也可能下面,分離點(diǎn)可能在屏幕上下移動(dòng),也可能在兩點(diǎn)間前后移動(dòng)。(譯者:原文的作者實(shí)在是啰嗦,其實(shí)就是畫面移動(dòng)較快的時(shí)候,畫面看上去是兩截。這種現(xiàn)象恐怕打游戲的都看到過(guò),最好玩過(guò)PS2游戲的,用模擬器,在比較差的顯卡和CPU上面,撕裂現(xiàn)象更為明顯)。

畫面撕裂

       為什么會(huì)發(fā)生這種現(xiàn)象呢?讓我們舉一個(gè)特定的例子。讓我們假定你的顯示器的刷新率是75Hz, 你真在玩你最喜歡的游戲,而且你現(xiàn)在有100的FPS.這就意味著你的顯示器每秒更新75次畫面,而你的顯示卡每秒更新100次,比你的顯示器快33%。這就意味著在你的顯示器更新畫面的時(shí)間里,顯示卡描畫了1+1/3的畫面。這樣在畫面顯示的時(shí)候,那個(gè)1/3的畫面就會(huì)覆蓋那個(gè)完整畫面上部的1/3。在下次的圖像刷新的時(shí)候,顯示卡會(huì)描畫剩下來(lái)得2/3和新的2/3的畫面。這樣,因?yàn)槠聊坏母轮荒芨袭嬅娓碌?/3,這樣圖像的上部的1/3或是下部的1/3就會(huì)和剩下的畫面合不上。如果畫面的變化不大可能不太會(huì)注意到這一點(diǎn),但是如果你快速的環(huán)顧四周那就會(huì)非常的明顯。

Double Buffer 雙緩沖

       現(xiàn)在,一個(gè)很普遍的誤解就產(chǎn)生了。一些人認(rèn)為解決這個(gè)問(wèn)題的方法就是簡(jiǎn)單設(shè)置一個(gè)FPS的限制讓FPS不超過(guò)顯示器的刷新率,這樣顯示卡就不會(huì)超過(guò)75FPS,這樣就可以了。真的嗎?錯(cuò)!

       在我解釋為什么之前,讓我來(lái)講一下雙倍緩沖。雙倍緩沖一種用來(lái)減輕撕裂問(wèn)題,雖然不是很完全。基本上來(lái)說(shuō)你有一個(gè)顯示緩沖和一個(gè)后備緩沖。當(dāng)顯示器要顯示畫面的時(shí)候,就會(huì)從顯示緩沖里“推出”顯示畫面。顯示卡則在后備緩沖里描畫另外一個(gè)新畫面,當(dāng)描畫完成后則將新畫面考入顯示緩沖里。但是這個(gè)過(guò)程需要時(shí)間,如果顯示器的刷新在拷貝過(guò)程中進(jìn)行的話,顯示器上顯示的仍然是個(gè)”撕裂”的畫面。

       VSync 通過(guò)建立一個(gè)不讓在顯示器刷新前將后備緩沖中的畫面拷貝到顯示緩沖中的規(guī)定來(lái)解決這個(gè)問(wèn)題。如果FPS高于刷新率的話,沒有問(wèn)題。后備緩沖的更新完成后,系統(tǒng)處于等待狀態(tài)。當(dāng)顯示器刷新后,后備緩存考入顯示緩存,顯示卡則可以在后備緩存里描畫新的畫面,這樣就很有效的將你的FPS限制在顯示器的刷新率的范圍內(nèi)。

       為了解決單緩存的“tearing”問(wèn)題,雙緩存和 VSync 應(yīng)運(yùn)而生。雙重緩存模型如下圖:

雙緩沖

       兩個(gè)緩存區(qū)分別為 Back Buffer 和 Frame Buffer。GPU 向 Back Buffer 中寫數(shù)據(jù),屏幕從 Frame Buffer 中讀數(shù)據(jù)。VSync 信號(hào)負(fù)責(zé)調(diào)度從 Back Buffer 到 Frame Buffer 的復(fù)制操作,可認(rèn)為該復(fù)制操作在瞬間完成。其實(shí),該復(fù)制操作是等價(jià)后的效果,實(shí)際上雙緩沖的實(shí)現(xiàn)方式是交換 Back Buffer 和 Frame Buffer 的名字,更具體的說(shuō)是交換內(nèi)存地址(有沒有聯(lián)想到那道經(jīng)典的筆試題目:“有兩個(gè)整型數(shù),如何用最優(yōu)的方法交換二者的值?”),通過(guò)二進(jìn)制運(yùn)算“異或”即可完成,所以可認(rèn)為是瞬間完成。(《數(shù)字電路技術(shù)》當(dāng)中有一章節(jié)應(yīng)該講過(guò)運(yùn)算器還是控制器來(lái)著,可以設(shè)計(jì)一個(gè)異或電路。忘了,回去翻一翻~)

       附加小福利:
       假設(shè)兩個(gè)數(shù)x和y,則有:
方法1,算術(shù)運(yùn)算(加減):
x=x+y; //x暫存兩數(shù)之和
y=x-y; //y為兩數(shù)之和減去y,即原來(lái)的x
x=x-y; //x為兩數(shù)之和減去現(xiàn)在的y(原來(lái)的x),變成原來(lái)的y
方法2,邏輯運(yùn)算(異或):
x^=y; //x先存x和y兩者的信息
y^=x; //保持x不變,利用x異或反轉(zhuǎn)y的原始值使其等于x的原始值
x^=y; //保持y不變,利用x異或反轉(zhuǎn)y的原始值使其等于y的原始值

       雙緩沖的模型下,工作流程這樣的:
       在某個(gè)時(shí)間點(diǎn),一個(gè)屏幕刷新周期完成,進(jìn)入短暫的刷新空白期。此時(shí),VSync 信號(hào)產(chǎn)生,先完成復(fù)制操作,然后通知 CPU/GPU 繪制下一幀圖像。復(fù)制操作完成后屏幕開始下一個(gè)刷新周期,即將剛復(fù)制到 Frame Buffer 的數(shù)據(jù)顯示到屏幕上。

       在這種模型下,只有當(dāng) VSync 信號(hào)產(chǎn)生時(shí),CPU/GPU 才會(huì)開始繪制。這樣,當(dāng)幀率大于刷新頻率時(shí),幀率就會(huì)被迫跟刷新頻率保持同步,從而避免“tearing”現(xiàn)象。

Jank 掉幀

       注意,當(dāng) VSync 信號(hào)發(fā)出時(shí),如果 GPU/CPU 正在生產(chǎn)幀數(shù)據(jù),此時(shí)不會(huì)發(fā)生復(fù)制操作。屏幕進(jìn)入下一個(gè)刷新周期時(shí),從 Frame Buffer 中取出的是“老”數(shù)據(jù),而非正在產(chǎn)生的幀數(shù)據(jù),即兩個(gè)刷新周期顯示的是同一幀數(shù)據(jù)。這是我們稱發(fā)生了“掉幀”(Dropped Frame,Skipped Frame,Jank)現(xiàn)象。

       讓我們來(lái)看一個(gè)另外一個(gè)不同的例子。讓我們假定你已經(jīng)玩到了你最喜歡的游戲的最后一關(guān),這個(gè)游戲有很好的圖像.你顯示器的刷新率還是在75。但是你的FPS現(xiàn)在只有50了,比刷新率要低33%.這就意味著每次顯示器刷新圖像,你的顯示卡只能畫出下一楨畫面的2/3。讓我們看看它是如何工作的。

  1. 顯示器剛剛更新,第一楨的畫面已經(jīng)拷貝到顯示緩沖,第二楨的畫面的2/3被寫入后備緩沖。
  2. 這時(shí)顯示器重新刷新,它會(huì)第一次從顯示緩沖里提取第一楨的畫面。然后顯示卡開始完成的第二楨剩下的部分。但是它必須等待,應(yīng)為再下一次刷新之前它是不會(huì)上傳的。
  3. 顯示器再次刷新,顯示器不得不第二次從顯示緩沖里提取第一楨的畫面,然后第二楨的畫面被寫入顯示緩沖。顯示卡在后備緩沖中寫入第三楨的2/3。
  4. 等到顯示器刷新,第一次從顯示緩沖里提取第二楨的畫面,顯示卡開始完成的第三楨剩下的部分。然后又是第二次從顯示緩沖里提取第二楨的畫面,然后第三楨的畫面被寫入顯示緩沖。

       如此類推。這樣4次顯示器刷新,我們只能的到2楨的畫面。如果刷新率是75的話,我們只能得到35的FPS.很明顯這個(gè)數(shù)值要低于顯示卡可以帶到的50FPS.這主要就是應(yīng)為顯示卡不得不在描畫后備緩沖上浪費(fèi)時(shí)間。而在此過(guò)程中,后備緩沖上的畫面是不能被拷貝到顯示緩沖。理論上講,雙緩沖的VSync,FPS將是一組不連續(xù)的整數(shù),其等于刷新率/n,n是正整數(shù)。也就是說(shuō),如果你的刷新率是60hz,你能得到的FPS只能是 60,30,20,15,12,10 等等。你可以注意到60到30是一個(gè)相當(dāng)大的差距。只要的顯示卡的FPS在60到30之間,你說(shuō)得到的真實(shí)FPS都將只能等于30!

       如下圖,A、B 和 C 都是 Buffer。藍(lán)色代表 CPU 生成 Display List,綠色代表 GPU 執(zhí)行 Display List 中的命令從而生成幀,黃色代表生成幀完成。

Jank

       現(xiàn)在,你明白為什么有人不喜歡它了。讓我們回到一開始的那個(gè)例子。你在玩你最喜歡的游戲,刷新率是75HZ,100FPS。你打開VSync.游戲就被限制在75FPS,沒有問(wèn)題,沒有撕裂圖像,看起來(lái)不錯(cuò)。你到了一個(gè)圖像特別復(fù)雜的地方,在不用VSync的時(shí)候,你的FPS下降到了60左右。但是你打開了VSync,你的FPS實(shí)際就只有37.5。這樣你的游戲突然從75FPS變成了37.5FPS,不管37.5仍然很流暢但是你一定會(huì)注意到刷新率突然減少了一半。當(dāng)讓如果以下變到25FPS的話,實(shí)際的現(xiàn)實(shí)率可能就只有17.5。本來(lái)還可以玩的游戲,就變成了幻燈片。這就是大家不喜歡它的原因。

       如果你的游戲的FPS可以一直穩(wěn)定的大于顯示器的刷新率,VSync是個(gè)不錯(cuò)的東西。但是如果FPS忽大忽小。VSync就是讓人煩的東西。如果你的游戲FPS一直都小于刷新率的話,實(shí)際的FPS要遠(yuǎn)遠(yuǎn)小于顯示卡可以顯示的FPS.看上去就象是VSync降低了你的FPS,但是從技術(shù)角度講,不是應(yīng)為圖像太復(fù)雜,而是因?yàn)閂Sync就是這樣工作的。

Triple Buffer 三緩沖

       雙重緩存的缺陷在于:當(dāng) CPU/GPU 繪制一幀的時(shí)間超過(guò) 16 ms 時(shí),會(huì)產(chǎn)生 Jank。更要命的是,產(chǎn)生 Jank 的那一幀的顯示期間,GPU/CPU 都是在閑置的。

       也不是說(shuō)所有的希望都沒有了。現(xiàn)在的triple-buffering技術(shù)可以用來(lái)解決這個(gè)問(wèn)題。讓我們?cè)賮?lái)看刷新率75。FPS50的例子。

  1. 第一楨在顯示緩沖,第二楨的2/3在后備緩沖。
  2. 顯示器刷新第一楨第一次被顯示,在后備緩沖里描畫第二楨的剩下的1/3,在第二后備緩沖里描畫第三楨的1/3(因?yàn)槲覀冇腥?jí)緩沖了)。
  3. 顯示器再次刷新第一楨第二次被顯示,第二楨放入在顯示緩沖,第三楨的的1/3放入后備緩沖,第二后備緩沖里描畫第三楨剩下的2/3。
  4. 接下來(lái)顯示器再次刷新的時(shí)候,第二楨被顯示,第三楨就可以放入顯示緩沖,這樣我們就可以在3次刷新中得到2楨的畫面。

       也就是刷新率的2/3,也就是50FPS.triple-buffering理論上講可以避免緩沖寫入是帶來(lái)的延遲現(xiàn)象,這樣就不會(huì)浪費(fèi)時(shí)間。但是triple-buffering并不是適用于所有的游戲。實(shí)際上它并不是普及(這個(gè)文章可能寫的太早,現(xiàn)在triple-buffering已經(jīng)很普及了),而且它也會(huì)影響顯示卡的性能,應(yīng)為它需要更多的顯示內(nèi)存,需要更多時(shí)間在內(nèi)存之間降數(shù)據(jù)拷貝來(lái)拷貝去。但是triple-buffering確實(shí)是一個(gè)很好的方法,既可以消除撕裂畫面又可以不像普通VSync一樣影響你的FPS.

       如果有第三個(gè) Buffer 能讓 CPU/GPU 在這個(gè)時(shí)候繼續(xù)工作,那就完全可以避免第二個(gè) Jank 的發(fā)生了!

三緩沖

       于是就有了三緩存:

三緩沖交換

       工作原理同雙緩沖類似,只是多了一個(gè) Back Buffer。
       需要注意的是,第三個(gè)緩存并不是總是存在的,只要當(dāng)需要的時(shí)候才會(huì)創(chuàng)建。之所以這樣,是因?yàn)槿彺鏁?huì)顯著增加用戶輸入到顯示的延遲時(shí)間。如上圖,幀 C 是在第 2 個(gè)刷新周期產(chǎn)生的,但卻是在第 4 個(gè)周期顯示的。最壞的情況下,你會(huì)同時(shí)遇到輸入延遲和卡頓現(xiàn)象。

三緩沖局限

       我希望這篇文章是有用的,可以幫出你理解VSync的工作原理。(特別是不再猶豫是否打開VSync)總之,如果沒有triple-buffering的情況下,如何權(quán)衡Vsync的FPS限制和消除撕裂畫面帶來(lái)的視覺感受,那將完全取決于你個(gè)人的喜好。
       譯者按:如果這篇文章的機(jī)理是正確的。triple-buffering也不是萬(wàn)能的,實(shí)際上就是把減少1/2變成了減少1/3而已,如果是FPS恰好卡到了一定的數(shù)值的時(shí)候沒有問(wèn)題,一旦沒有,那就絕對(duì)要損失FPS.所以對(duì)于那種FPS剛剛超過(guò)24的游戲,不管有沒有triple-buffering,都應(yīng)該關(guān).

       所以一定會(huì)有人問(wèn):液晶顯示器的刷新頻率為何不能調(diào)高?
       這里有一個(gè)誤解。
       原來(lái)我們使用的是CRT技術(shù)的顯示器,為保證長(zhǎng)時(shí)間地注視屏幕而眼睛不疲勞,我們一般都會(huì)把刷新率調(diào)到75H甚至是85Hz,這是由于CRT技術(shù)的特性決定的,刷新率越高也就意味著圖像越清楚、越穩(wěn)定。但是對(duì)于LCD來(lái)說(shuō),由于液晶板本身并不發(fā)光,只是液晶分子控制光線的偏轉(zhuǎn)或通過(guò),發(fā)光的是背光源,即熒光燈管,在使用的時(shí)候即使把刷新率調(diào)到60Hz你也不會(huì)感到屏幕在閃爍,“刷新率”對(duì)LCD來(lái)說(shuō)已經(jīng)沒有多大意義了,所以在使用液晶顯示器的時(shí)候,我們是不必過(guò)于苛求刷新率的高低的。

參考

Getting To Know Android 4.1, Part 3: Project Butter - How It Works And What It Added
http://www./2012/07/12/getting-to-know-android-4-1-part-3-project-butter-how-it-works-and-what-it-added/

總結(jié)

       本篇科普一下VSync,下一節(jié)開始分析它在SurfaceFlinger中的工作流程。





    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多