GPUImageFramebuffer

總述

從總體上來講它是容納一個紋理的容器。這個類寫得太別的散,讓人一眼看不出什么主旨要義來封断,可能是因?yàn)樽髡呦褡屵@個類處理太多東西了。它接收一個紋理和這個紋理的大小舶担,然后經(jīng)過一番處理然后生成一個什么東西坡疼,雖然主要就是個圖片而已。此外衣陶,它還涉及到2個重要的操作柄瑰,一個是內(nèi)存上的控制,一個是并發(fā)上的控制剪况。

內(nèi)部構(gòu)成

GLuint framebuffer:這個就是緩沖區(qū)的實(shí)質(zhì)教沾,它就是緩沖區(qū)。
CVPixelBufferRef renderTarget:它就是渲染的目標(biāo)拯欧。
CVOpenGLESTextureRef renderTexture:這是需要被渲染的紋理详囤。
NSUInteger readLockCount: 這個應(yīng)該是讀寫鎖,好像是說只要這個緩沖區(qū)被讀取它就不能被更改镐作,所以上個鎖藏姐。
NSUInteger framebufferReferenceCount:這就是那個引用計(jì)數(shù),每個對象的引用計(jì)數(shù)该贾。這個類似OC對象的引用計(jì)數(shù)羔杨。
BOOL referenceCountingDisabled:這個是引用計(jì)數(shù)的開關(guān)。
-(void)generateFramebuffer:用來生成一個緩沖區(qū)杨蛋,這里面的過程就比較復(fù)雜了兜材。
-(void)generateTexture:用來生成一個紋理理澎,內(nèi)部使用的。
-(void)destroyFramebuffer:用于銷毀幀緩沖區(qū)曙寡。
這里還有兩個C語言的回調(diào)dataProviderReleaseCallback和dataProviderUnlockCallback糠爬。

generateTexture

從這個名字就可以看出來它是用來生成紋理的,具體是怎么生成紋理的举庶,全是都用OpenGL ES 2.0來生成的执隧。這里面首先是要選擇一個待激活的紋理單元,紋理單元的數(shù)量至少是8個户侥。然后是生成紋理的名字镀琉,用一個數(shù)組來存儲存儲生成的名字,有幾個名字?jǐn)?shù)組的元素個數(shù)就是幾個蕊唐。接下來是要把名字和激活的紋理單元綁定屋摔,我想這個過程就是給紋理單元命名吧。最后是把紋理以某種方式映射成像素替梨。反正全都是OpenGL ES的操作钓试。

generateFramebuffer

這個就是生成幀緩沖區(qū),整個過程都是同步執(zhí)行的耙替。在OpenGL ES中生成幀緩沖區(qū)和生成紋理有點(diǎn)相似亚侠。首先指定一下上下文曹体,然后就是幀緩沖區(qū)的專屬部分了俗扇。首先要生成幀緩沖區(qū)的名字,一個幀緩沖區(qū)配一個名字箕别。然后通過名字把對應(yīng)的幀緩沖區(qū)綁定到某目標(biāo)上去铜幽。須知與設(shè)備有關(guān)的一個屬性是在iOS 5.0及以上所有的幀緩沖區(qū)都是備份在紋理的緩存中,所以該方法的邏輯進(jìn)行到這都需要進(jìn)行一個判斷串稀,如果是支持備份的話除抛,是一種處理,否則是另一種處理方式母截。
如果是支持這種特性的到忽,首先要獲取紋理的緩存,這個緩存是CVOpenGLESTextureCacheRef類型的清寇。然后用一個可變字典去獲取屬性喘漏,然后把這些屬性賦值給一個不可變字典。在這個過程中华烟,有一個error對象翩迈,這就好像是一個異常對象一樣,從該對象中可以獲取錯誤信息盔夜。前半過程已經(jīng)處理完了负饲,這一段就是獲取屬性堤魁,獲取完了以后就釋放臨時的變量。接下來是純的OpenGL ES的處理過程返十,簡單就是獲取當(dāng)前的紋理妥泉,并從當(dāng)前的紋理獲取幀緩沖區(qū)。
如果不支持特性洞坑,此時就代表該設(shè)備不支持從紋理緩存獲取幀緩沖區(qū)涛漂。那就新生成1個紋理,然后通過這個紋理獲取幀緩沖區(qū)检诗。
這兩個分支都走完以后匈仗,就獲取緩沖區(qū)的狀態(tài),最后是綁定紋理逢慌,但是為什么最后要綁定紋理呢悠轩?

destroyFramebuffer

很顯然嘛,這就是用來釋放幀緩沖區(qū)用的攻泼。它是同步處理的火架,處理的過程是這樣的。首先獲取上下文忙菠,然后如果緩沖區(qū)不空的話就釋放幀緩沖區(qū)何鸡。接下來的處理過程也分兩種情況,就是如果設(shè)備支持紋理緩存和不支持紋理緩存的情況牛欢,另外還有一個判斷條件是是否允許丟失幀緩沖區(qū)骡男。
如果支持并且還不支持丟失幀緩沖區(qū)的話,那就釋放渲染目標(biāo)和渲染的紋理傍睹。
否則隔盛,直接就刪除紋理即可。

activateFramebuffer

激活幀緩沖區(qū)用的拾稳,但是這里面的實(shí)現(xiàn)極其簡單吮炕,就兩句話。它首先是要把幀緩沖區(qū)綁定到指定目標(biāo)上面访得,然后是要把這個幀緩沖區(qū)轉(zhuǎn)換成一個size大小的圖片紋理龙亲,由此可見幀緩沖區(qū)最終要被轉(zhuǎn)換成一個size的,而且轉(zhuǎn)換的步驟就在此處啊悍抑,不過這個size具體是多大鳄炉,它決定于類外部的設(shè)置。

幀緩沖區(qū)的引用計(jì)數(shù)機(jī)制

這個就是參考了OC對象的引用計(jì)數(shù)機(jī)制传趾,概述一下就是這個緩沖區(qū)被引用的話迎膜,引用計(jì)數(shù)就+1,放棄引用浆兰,引用計(jì)數(shù)就-1磕仅,減到0以后珊豹,按照oc的機(jī)制的話是釋放對象,但是在GPUImage中則是把幀緩沖區(qū)歸還到幀緩沖區(qū)的緩存中榕订。

lock

它是手動增加引用計(jì)數(shù)的方法店茶。它先檢查是否禁用了引用計(jì)數(shù),如果禁用了劫恒,就什么都不做直接返回不从,否則把該緩沖區(qū)的引用計(jì)數(shù)+1.

unlock

這是手動減少引用計(jì)數(shù)的方法亮瓷。如果引用計(jì)數(shù)被禁用了,就直接返回。如果引用計(jì)數(shù)沒有被減的時候就已經(jīng)是0孟抗,則會觸發(fā)斷言猖任,而不是直接歸還到緩存中去尺上。

clearAllLocks

這個沒啥好說的金顿,就是清空引用計(jì)數(shù),但是它沒有歸還幀緩沖區(qū)贰您。

disableReferenceCounting

禁用引用計(jì)數(shù)坏平。

enableReferenceCounting

激活引用計(jì)數(shù)。

圖像捕捉

就是說從幀緩沖區(qū)能夠計(jì)算出圖像锦亦。

dataProviderReleaseCallback

釋放數(shù)據(jù)舶替,一個C語言的語法,看上去有點(diǎn)類似于內(nèi)聯(lián)函數(shù)杠园。這是一個回調(diào)顾瞪,傳進(jìn)來的數(shù)據(jù)就是希望被釋放的數(shù)據(jù)。

dataProviderUnlockCallback

這也是個回調(diào)返劲,它用于把回調(diào)進(jìn)來的數(shù)據(jù)降低它的引用計(jì)數(shù)玲昧。因?yàn)檫@個幀緩沖區(qū)總是要綁定到一個目標(biāo)上的,你不能因?yàn)檫@個幀緩沖區(qū)不要了也不要這個與之綁定的目標(biāo)了篮绿,于是要先恢復(fù)它的渲染目標(biāo)。然后引用計(jì)數(shù)減一吕漂,然后亲配,因?yàn)樗荒茉诒挥糜讷@取圖像了嘛,所以你需要把它從能用于獲取圖片的幀緩沖列表中刪除惶凝。

newCGImageFromFramebufferContents

它是能夠從幀緩沖區(qū)中獲取一個新的cg圖像吼虎。整個過程也是同步進(jìn)行的。首先是要獲取上下文苍鲜。接下來是獲取生成圖片所需要的總的字節(jié)數(shù)思灰,這個字節(jié)數(shù)是圖像的寬度×高度×4,而這個寬度和高度是通過屬性外部設(shè)置的size混滔。
如果設(shè)備是支持紋理緩存的話洒疚,它要從渲染目標(biāo)中獲取每行的像素的字節(jié)數(shù)歹颓,再除以4,得到每行中的單元數(shù)油湖,至于什么單元巍扛,我就不知道了,然后寬度×高度×4乏德,知道尺寸以后撤奸,要先把引用計(jì)數(shù)+1,然后讀取喊括。獲取渲染目標(biāo)的地址胧瓜,通過數(shù)據(jù)獲取數(shù)據(jù)的提供者,這些提供者是什么呀郑什?然后把幀緩沖區(qū)添加入到可以獲取圖片的激活的圖像鏈表中贷痪。
如果設(shè)備不支持紋理緩存的話,則直接激活幀緩沖區(qū)蹦误,然后通過屬性設(shè)置的size來獲取圖片的像素?cái)?shù)和字節(jié)數(shù)劫拢,進(jìn)而得到數(shù)據(jù)提供者,然后幀緩沖區(qū)降低引用計(jì)數(shù)强胰。
接下來舱沧,是從設(shè)備上獲取RGB顏色空間。
如果設(shè)備支持紋理緩存的話偶洋,通過上面的數(shù)據(jù)提供器還有RGB顏色空間并且使用渲染目標(biāo)就可以得到cg圖像熟吏。
如果設(shè)備不支持紋理緩存的話,就通過屬性size設(shè)置的數(shù)據(jù)來獲取cg圖像玄窝。
最后得到結(jié)果牵寺,就是一個cg圖像。

restoreRenderTarget

恢復(fù)渲染的目標(biāo)恩脂。這個實(shí)現(xiàn)很簡單帽氓,也是兩行代碼,就是在讀完以后降低它的引用計(jì)數(shù)俩块,并且釋放渲染目標(biāo)黎休。

數(shù)據(jù)讀取機(jī)制

就是在讀取數(shù)據(jù),控制引用計(jì)數(shù)玉凯。就是在讀的時候引用計(jì)數(shù)+1势腮,不讀的時候引用計(jì)數(shù)-1.

lockForReading

只有設(shè)備支持紋理緩存的時候,才進(jìn)行此操作漫仆,這里面涉及到了另外一個讀計(jì)數(shù)捎拯,一開始的時候計(jì)數(shù)是0就先鎖定像素緩沖區(qū)的基址,然后讀計(jì)數(shù)+1.

unlockAfterReading

它也是只針對支持紋理緩存的設(shè)備而言的盲厌,讀計(jì)數(shù)減1署照,到了0以后就解鎖像素緩沖區(qū)的基址祸泪。

bytesPerRow

它返回圖像紋理每行的字節(jié)數(shù)。如果設(shè)備支持紋理藤树,則只通過渲染目標(biāo)就可以得到每行的字節(jié)數(shù)浴滴。如果不是iPhone或者模擬器或者不支持紋理緩存,則返回通過屬性設(shè)置的size的寬度×4.

byteBuffer

就是通過渲染目標(biāo)獲取像素緩沖區(qū)的基址岁钓,之前要鎖定來讀取升略,之后要解鎖。

pixelBuffer

其實(shí)就是返回渲染目標(biāo)屡限,而對于非iPhone或者模擬器平臺則直接返回NULL品嚣。

texture

用于持久化輸入的紋理。

上一篇:分析GPUImage-GPUImageInput
下一篇:GPUImageFramebufferCache

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末钧大,一起剝皮案震驚了整個濱河市翰撑,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌啊央,老刑警劉巖眶诈,帶你破解...
    沈念sama閱讀 222,807評論 6 518
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異瓜饥,居然都是意外死亡逝撬,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,284評論 3 399
  • 文/潘曉璐 我一進(jìn)店門乓土,熙熙樓的掌柜王于貴愁眉苦臉地迎上來宪潮,“玉大人,你說我怎么就攤上這事趣苏〗葡啵” “怎么了?”我有些...
    開封第一講書人閱讀 169,589評論 0 363
  • 文/不壞的土叔 我叫張陵食磕,是天一觀的道長尽棕。 經(jīng)常有香客問我,道長芬为,這世上最難降的妖魔是什么萄金? 我笑而不...
    開封第一講書人閱讀 60,188評論 1 300
  • 正文 為了忘掉前任,我火速辦了婚禮媚朦,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘日戈。我一直安慰自己询张,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,185評論 6 398
  • 文/花漫 我一把揭開白布浙炼。 她就那樣靜靜地躺著份氧,像睡著了一般唯袄。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上蜗帜,一...
    開封第一講書人閱讀 52,785評論 1 314
  • 那天恋拷,我揣著相機(jī)與錄音,去河邊找鬼厅缺。 笑死蔬顾,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的湘捎。 我是一名探鬼主播诀豁,決...
    沈念sama閱讀 41,220評論 3 423
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼窥妇!你這毒婦竟也來了舷胜?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 40,167評論 0 277
  • 序言:老撾萬榮一對情侶失蹤活翩,失蹤者是張志新(化名)和其女友劉穎烹骨,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體材泄,經(jīng)...
    沈念sama閱讀 46,698評論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡沮焕,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,767評論 3 343
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了脸爱。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片遇汞。...
    茶點(diǎn)故事閱讀 40,912評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖簿废,靈堂內(nèi)的尸體忽然破棺而出空入,到底是詐尸還是另有隱情,我是刑警寧澤族檬,帶...
    沈念sama閱讀 36,572評論 5 351
  • 正文 年R本政府宣布歪赢,位于F島的核電站,受9級特大地震影響单料,放射性物質(zhì)發(fā)生泄漏埋凯。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,254評論 3 336
  • 文/蒙蒙 一扫尖、第九天 我趴在偏房一處隱蔽的房頂上張望白对。 院中可真熱鬧,春花似錦换怖、人聲如沸甩恼。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,746評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽条摸。三九已至悦污,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間钉蒲,已是汗流浹背切端。 一陣腳步聲響...
    開封第一講書人閱讀 33,859評論 1 274
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留顷啼,地道東北人踏枣。 一個月前我還...
    沈念sama閱讀 49,359評論 3 379
  • 正文 我出身青樓,卻偏偏與公主長得像线梗,于是被迫代替她去往敵國和親椰于。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,922評論 2 361

推薦閱讀更多精彩內(nèi)容