BufferQueue原創(chuàng) - 基礎(chǔ)篇1

首先 BufferSlot 是 Buffer 的封裝鸥诽, BufferQueueCore 使用 mSlots 來管理所有Buffer, mSlots 是一個 BufferSlot 數(shù)組谦絮, 包含了所有的BufferSlot. BufferSlot里面最重要的兩個成員是: mGraphicBuffer 和 mBufferState

BufferItem是 mQueue 中的元素征椒, mQueue是 BufferQueueCore中另一個重要的成員梧奢, 是一個FIFO隊列忧陪。 生產(chǎn)者調(diào)用queueBuffer的時候惨险, 會把這個Buffer封裝成BufferItem搞糕,然后放入到 mQueue中。 消費者調(diào)用acquireBuffer的時候會取出來mQueue中的第一個元素進(jìn)行消費蜂科。

我們知道Buffer有四種狀態(tài): Dequeued, Queued, Acquired, Free. 這種狀態(tài)使用 BufferState來封裝顽决, 就是我們上面提到的 BufferSlot中的 mBufferState.

整個BufferQueue機(jī)制是通過 BufferQueue.cpp 的 createBufferQueue來創(chuàng)建的, 會創(chuàng)建三個角色: BufferQueueCore, BufferQueueProducer, BufferQueueConsusmer. 其中 BufferQueueProducer 和 BufferQueueConsumer都是Binder导匣, 可以跨進(jìn)程調(diào)用才菠。
但是我們一般都是在消費者進(jìn)程創(chuàng)建的BufferQ, 所以一般只要把 BufferQueueProducer傳遞給遠(yuǎn)端就可以了。

BufferQueueProducer和BufferQueueConsumer都可以直接訪問 BufferQueueCore, 其中 BufferQueueProducer中還包含了BufferQueueCore中的mSlots的一個 引用贡定, 這樣會方便 BufferQueueProducer更快捷的操作 mSlots.

BufferQueueConsumer 和 BufferQueueProducer 的回調(diào) 都是在各自的 connect 方法中執(zhí)行的赋访。 會向 BufferQueueCore中分別注冊自己的回調(diào): ProxyConsumerListener 和 IProducerListener 這兩個回調(diào), 因為 Producer一般在遠(yuǎn)端, 所以 IProducerListener這個回調(diào)里面還包含了Binder死亡回調(diào)的實現(xiàn)蚓耽。

BufferItem中定義了索引值mSlot, 這個是 mSlots這個數(shù)組的下標(biāo)渠牲, 這樣通過BufferItem就可以得到具體的BufferSlot了。

BufferSlot的狀態(tài)分為: Active狀態(tài)和Free狀態(tài)步悠, Active狀態(tài)代表了正在被生產(chǎn)者或者消費者使用的狀態(tài)嘱兼, Free狀態(tài)代表了空閑的BufferSlot, 而Free狀態(tài)又被分為了: FreeBuffer 和 FreeSlot, FreeBuffer代表了已經(jīng)擁有Buffer的BufferSlot, FreeSlot代表還沒有擁有Buffer的BufferSlot.
Active狀態(tài)的BufferSlot的下標(biāo) 被放在了 mActiveBuffers 這個 vector中贤徒。
FreeBuffer狀態(tài)的BufferSlot的下標(biāo) 被放在了 mFreeBuffers 這個 vector 中芹壕。
FreeSlot狀態(tài)的BufferSlot的下標(biāo)被放在了mFreeSlot這個vector中。

BufferSlot沒有實現(xiàn)任何Binder或者Flattenable接口接奈, 不能跨進(jìn)程傳遞踢涌, 所以只能在BufferQueueCore中接受管理, 同時 BufferQueueProducer 作為bn端序宦, 和BufferQueueCore在同一個進(jìn)程中睁壁, 也保存了 mSlots 的一個引用。
BufferItem和GraphicBuffer都實現(xiàn)了Flattenable互捌, 可以跨進(jìn)程傳遞潘明。

生產(chǎn)和消費過程

首先看一下生產(chǎn)者最常見的操作: dequeueBuffer 和 queueBuffer

dequeueBuffer的主要工作:

  1. 調(diào)用 waitForFreeSlotThenRelock 方法, 這個方法的作用就是: 如果是dequeue, 就優(yōu)先嘗試從 mFreeBuffers 里面找slot, 然后嘗試從 mFreeSlots里面找slot. 如果是attach, 就優(yōu)先嘗試從mFreeSlots里面找slot, 然后嘗試從mFreeBuffers里面找slot. waitForFreeSlotThenRelock 這個方法只是返回slot, 并不會真的去分配GraphicBuffer.
    這里面有一些細(xì)節(jié)秕噪, 比如如果開啟了BufferManager, 那么 waitForFreeSlotThenRelock 就只會返回 FreeBuffer了钳降, 但是如果這個FreeBuffer需要重新分配空間來滿足Buffer的一些屬性, 那么這個FreeBuffer就不能使用腌巾, 我們就要把這個FreeBuffer清空遂填, 放入到FreeSlot中, 然后再次去循環(huán)調(diào)用 waitForFreeSlotThenRelock, 知道找到合適的slot澈蝙。
  2. 把找到的slot放入到 mActiveBuffer中吓坚, 并更改BufferState狀態(tài)為 Dequeue狀態(tài)。
    并看一下是不是需要分配GraphicBuffer, 如果需要分配就分配新的GraphicBuffer. 當(dāng)GraphicBuffer好了之后灯荧,通知 ConsumerListener的onFrameDequeued方法礁击, 這個方法傳入的參數(shù)是分配好的GraphicBuffer。
    如果是Consumer通過 attachBuffer 添加的一個Buffer到BQ逗载, 那么生產(chǎn)者在 dequeueBuffer的時候遇到了這樣的Buffer, 肯定需要重新分配一遍哆窿, 因為消費者attach進(jìn)來的Buffer是不符合生產(chǎn)者要求的。

dequeueBuffer這個方法會返回一個可用的GraphicBuffer, 而waitForFreeSlotThenRelock只是會返回可用的slot.
requestBuffer這個方法就是根據(jù)傳入的slot, 把這個slot對應(yīng)的GraphicBuffer放入到指定的buffer指針中撕贞, 這個方法并不會分配新的Buffer. 也就是說requestBuffer得到的Buffer也有可能是空的更耻。

queueBuffer的流程:

  1. 創(chuàng)建 BufferItem, 并且更改BufferState狀態(tài)為 Queued, 并且把BufferItem關(guān)聯(lián)到GraphicBuffer测垛, 然后嘗試放入FIFO中捏膨, 之所以嘗試放入, 是因為要看FIFO中最后一個元素是否需要被Replace. 然后會把 BufferItem關(guān)聯(lián)的GraphicBuffer的引用給清空, 也就是說BufferItem應(yīng)該只包含slot号涯, 并不包含GraphicBuffer的引用目胡。
  2. 然后根據(jù)是否被Replace了, 來調(diào)用 ConsumerListener的 onFrameAvailable 或者 onFrameRepleaced 方法链快。

queueBuffer的流程是比較簡單的誉己。

attachBuffer的流程

attachBuffer就是把本來不屬于該BQ的Buffer放入該BQ中讓該BQ管理。

  1. 首先調(diào)用 waitForFreeSlotThenRelock方法域蜗, 只不過這一次是優(yōu)先從 mFreeSlots 中尋找 slot.
  2. 找到這個slot之后 把它放入到 mActiveBuffers中管理巨双, 并且把狀態(tài)改成Dequeued, 也就是說 生產(chǎn)者調(diào)用的 attachBuffer, 相當(dāng)于是Dequeue出去一個Buffer.

detachBuffer的流程

  1. 調(diào)用 ConsumerListener 的 onFrameDetached方法
  2. 更改BufferStatus狀態(tài)為Dequeue--, 然后把BufferSlot 從mActiveBuffers中移除霉祸,放入到 mFreeSlots中筑累, 并且清空這個BufferSlot.
  3. 調(diào)用 ConsumerListener 的 onBuffersReleased方法。
    這里會調(diào)用兩個ConsumerListener的回調(diào)丝蹭。

也就是說 Producer 的 attach 和 detach方法慢宗, 都不會往FIFO中放入BufferItem, 僅僅是把Buffer放入了BufferQueueCore中進(jìn)行管理。 attachBuffer之后奔穿, 這個Buffer的狀態(tài)是Dequeued, 是活躍的镜沽。 detachBuffer之后, 這個buffer的狀態(tài)是Queued--的贱田, 是FreeSlot狀態(tài)缅茉。

從上面的分析可以知道, 生產(chǎn)者直接attach一個buffer到BQ中是不能被消費的男摧, 必須 attach+queue才可以宾舅。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市彩倚,隨后出現(xiàn)的幾起案子筹我,更是在濱河造成了極大的恐慌,老刑警劉巖帆离,帶你破解...
    沈念sama閱讀 221,273評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蔬蕊,死亡現(xiàn)場離奇詭異,居然都是意外死亡哥谷,警方通過查閱死者的電腦和手機(jī)岸夯,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,349評論 3 398
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來们妥,“玉大人猜扮,你說我怎么就攤上這事〖嗌簦” “怎么了旅赢?”我有些...
    開封第一講書人閱讀 167,709評論 0 360
  • 文/不壞的土叔 我叫張陵齿桃,是天一觀的道長。 經(jīng)常有香客問我煮盼,道長短纵,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,520評論 1 296
  • 正文 為了忘掉前任僵控,我火速辦了婚禮香到,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘报破。我一直安慰自己悠就,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 68,515評論 6 397
  • 文/花漫 我一把揭開白布充易。 她就那樣靜靜地躺著理卑,像睡著了一般。 火紅的嫁衣襯著肌膚如雪蔽氨。 梳的紋絲不亂的頭發(fā)上藐唠,一...
    開封第一講書人閱讀 52,158評論 1 308
  • 那天,我揣著相機(jī)與錄音鹉究,去河邊找鬼宇立。 笑死,一個胖子當(dāng)著我的面吹牛自赔,可吹牛的內(nèi)容都是我干的妈嘹。 我是一名探鬼主播,決...
    沈念sama閱讀 40,755評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼绍妨,長吁一口氣:“原來是場噩夢啊……” “哼润脸!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起他去,我...
    開封第一講書人閱讀 39,660評論 0 276
  • 序言:老撾萬榮一對情侶失蹤毙驯,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后灾测,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體爆价,經(jīng)...
    沈念sama閱讀 46,203評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,287評論 3 340
  • 正文 我和宋清朗相戀三年媳搪,在試婚紗的時候發(fā)現(xiàn)自己被綠了铭段。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,427評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡秦爆,死狀恐怖序愚,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情等限,我是刑警寧澤爸吮,帶...
    沈念sama閱讀 36,122評論 5 349
  • 正文 年R本政府宣布芬膝,位于F島的核電站,受9級特大地震影響拗胜,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜怒允,卻給世界環(huán)境...
    茶點故事閱讀 41,801評論 3 333
  • 文/蒙蒙 一埂软、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧纫事,春花似錦勘畔、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,272評論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至钾唬,卻和暖如春万哪,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背抡秆。 一陣腳步聲響...
    開封第一講書人閱讀 33,393評論 1 272
  • 我被黑心中介騙來泰國打工奕巍, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人儒士。 一個月前我還...
    沈念sama閱讀 48,808評論 3 376
  • 正文 我出身青樓的止,卻偏偏與公主長得像,于是被迫代替她去往敵國和親着撩。 傳聞我的和親對象是個殘疾皇子诅福,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,440評論 2 359

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