Buffer隊(duì)列的創(chuàng)建
從Suface創(chuàng)建流程中分析可以鬓催,創(chuàng)建每一個(gè)Layer的時(shí)候,在Layer初始化的時(shí)候會為當(dāng)前Layer創(chuàng)建一個(gè)BufferQueue隊(duì)列淮菠,用于App端的Surface和SurfaceFlinger端的Layer間圖像傳遞森逮。
// Creates a custom BufferQueue for SurfaceFlingerConsumer to use
sp<IGraphicBufferProducer> producer;
sp<IGraphicBufferConsumer> consumer;
BufferQueue::createBufferQueue(&producer, &consumer);
mProducer = new MonitoredProducer(producer, mFlinger);
mSurfaceFlingerConsumer = new SurfaceFlingerConsumer(consumer, mTextureName);
mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
mSurfaceFlingerConsumer->setContentsChangedListener(this);
mSurfaceFlingerConsumer->setName(mName);
這段代碼在Surface創(chuàng)建流程中已經(jīng)分析過了
1:BufferQueue創(chuàng)建了一個(gè)的生產(chǎn)者和一個(gè)消費(fèi)者
2:生產(chǎn)者被封裝到了MonitoredProducer中妖谴,傳遞了App端,由Surface持有其代理
3:消費(fèi)這被封裝到了SurfaceFlingerComsumer中酵熙,設(shè)置Layer為內(nèi)容變換監(jiān)聽者轧简,當(dāng)有新的Buffer到來,Layer進(jìn)行處理匾二。
先看下如何創(chuàng)建Buffer隊(duì)列
sp<IGraphicBufferProducer> producer;
sp<IGraphicBufferConsumer> consumer;
BufferQueue::createBufferQueue(&producer, &consumer);
初始化一個(gè)producer指針和一個(gè)consumer指針作為出參給創(chuàng)建BufferQueue的函數(shù)哮独。創(chuàng)建好BufferQueue之后,會將BufferQueue的生產(chǎn)者和消費(fèi)者分別保存在這兩個(gè)變量中假勿。
void BufferQueue::createBufferQueue(sp<IGraphicBufferProducer>* outProducer,
sp<IGraphicBufferConsumer>* outConsumer,
const sp<IGraphicBufferAlloc>& allocator) {
//創(chuàng)建一個(gè)BufferQueueCore對象
sp<BufferQueueCore> core(new BufferQueueCore(allocator));
//創(chuàng)建一個(gè)BufferQueueProducer
sp<IGraphicBufferProducer> producer(new BufferQueueProducer(core));
//創(chuàng)建一個(gè)BufferQueueConsumer
sp<IGraphicBufferConsumer> consumer(new BufferQueueConsumer(core));
//將創(chuàng)建的producer和consumer分別保存在出參中
*outProducer = producer;
*outConsumer = consumer;
}
createBufferQueue是BufferQueue的靜態(tài)函數(shù)借嗽,該函數(shù)中首先創(chuàng)建了一個(gè)BufferQueueCore對象,然后再以該對象作為參數(shù)創(chuàng)建了BufferQueueProducer和BufferQueueConsumer转培。
BufferQueueCore定義
class BufferQueueCore : public virtual RefBase {
friend class BufferQueueProducer;
friend class BufferQueueConsumer;
public:
typedef Vector<BufferItem> Fifo;
private:
sp<IGraphicBufferAlloc> mAllocator;
// mMutex 用于同步producer和consumer對BufferQueueCore中變量的訪問
mutable Mutex mMutex;
// mIsAbandoned 表示BufferQueue是否還能處理生產(chǎn)者傳遞的圖像
bool mIsAbandoned;
// mConsumerName 用來在日志中表示唯一的BufferQueue
String8 mConsumerName;
// mConsumerListener 用于通知已經(jīng)連接的Consumer有新Buffer到來
sp<IConsumerListener> mConsumerListener;
// mConnectedApi 表示生產(chǎn)者是否已經(jīng)連接到BufferQueue
int mConnectedApi;
// mConnectedProducerToken 用于通知生產(chǎn)者BufferQueue是否已經(jīng)死亡
sp<IProducerListener> mConnectedProducerListener;
// mSlots 是一個(gè)大小為64的bufferSlot數(shù)組,每個(gè)BufferSlot描述了一個(gè)GraphicBuffer與其相關(guān)的屬性
BufferQueueDefs::SlotsType mSlots;
// mQueue is a FIFO of queued buffers used in synchronous mode.
Fifo mQueue;
// mFreeSlots 表示所有的FREE狀態(tài)的BufferSlot, 這個(gè)BufferSlot還沒有分配GraphicBuffer緩沖區(qū)
std::set<int> mFreeSlots;
// mFreeBuffers 表示所有的FREE狀態(tài)的BufferSlot, 這個(gè)BufferSlot已經(jīng)分配了GraphicBuffer緩沖區(qū)
std::list<int> mFreeBuffers;
// mUnusedSlots contains all slots that are currently unused. They should be
// free and not have a buffer attached.
std::list<int> mUnusedSlots;
// mActiveBuffers 所有包含有使用狀態(tài)GraphicBuffer的slot.
std::set<int> mActiveBuffers;
// mDequeueCondition 用于dequeuebuffer的同步
mutable Condition mDequeueCondition;
// mDefaultBufferFormat BufferQueue分配的GraphicBuffer的默認(rèn)format
PixelFormat mDefaultBufferFormat;
// mDefaultWidth BufferQueue分配的GraphicBuffer的默認(rèn)width
uint32_t mDefaultWidth;
// mDefaultHeight BufferQueue分配的GraphicBuffer的默認(rèn)height
uint32_t mDefaultHeight;
// mDefaultBufferDataSpace BufferQueue分配的GraphicBuffer的默認(rèn)DataSpace
android_dataspace mDefaultBufferDataSpace;
// mMaxBufferCount BufferQueue可以分配的GraphicBuffer的最大數(shù)量. 可以被consumer設(shè)置.
int mMaxBufferCount;
// mMaxAcquiredBufferCount Consumer一次可以acquire Buffer的最大數(shù)量恶导,默認(rèn)為1
int mMaxAcquiredBufferCount;
// mMaxDequeuedBufferCount Producer一次可以dqueue Buffer的最大數(shù)量,默認(rèn)為1
int mMaxDequeuedBufferCount;
// mBufferHasBeenQueued 當(dāng)有buffer queue到隊(duì)列中時(shí)設(shè)置為true, 當(dāng)釋放掉所有buffer的時(shí)候設(shè)置為false
bool mBufferHasBeenQueued;
// mFrameCounter 每當(dāng)隊(duì)列中queuebuffer的之后 +1
uint64_t mFrameCounter;
// mTransformHint screen rotations標(biāo)志.
uint32_t mTransformHint;
// mSidebandStream is a handle to the sideband buffer stream
sp<NativeHandle> mSidebandStream;
// mIsAllocating 表明生產(chǎn)者是否正在請求Gralloc分配GraphicBuffer
bool mIsAllocating;
// mAllowAllocation 表明 dequeueBuffer 是否允許請求Gralloc分配新的GraphicBuffer
bool mAllowAllocation;
// mAsyncMode 是否啟用異步模式:生產(chǎn)者將graphicBuffer入隊(duì)的時(shí)候不會block
bool mAsyncMode;
// mSharedBufferMode 是否啟用share模式
bool mSharedBufferMode;
// ShareBufferMode情況下浸须,即使producer沒有通知有新的Buffer可用惨寿,consumer也會去獲取Buffer
bool mAutoRefresh;
// 上一次queue buffer的slot
int mLastQueuedSlot;
const uint64_t mUniqueId;
}; // class BufferQueueCore
BufferQueueCore是BufferQueue的核心,定義了Buffer隊(duì)列一些基本的屬性删窒,BufferQueueProducer和BufferQueueConsumer持有同一個(gè)BufferQueueCore對象裂垦,所以生產(chǎn)者和消費(fèi)者都可以訪問BufferQueue定義的屬性。
BufferQueue中定義了一些關(guān)鍵的熟悉
1:BufferQueueDefs::SlotsType mSlots;
mSlots是一個(gè)大小為64的BufferSlot數(shù)組肌索,表示一個(gè)Buffer隊(duì)列中最多可以有64個(gè)Buffer蕉拢。BufferSlot是一個(gè)GraphicBuffer的封裝類,定義了和GraphicBuffer相關(guān)的一些屬性诚亚。
如:GraphicBuffer指針晕换,指向一個(gè)Gralloc分配的GraphicBuffer。
BufferState, 描述了當(dāng)前slot位置Buffer的狀態(tài)站宗。BufferState定義的狀態(tài)分為以下幾種:
- FREE:當(dāng)前這個(gè)BufferSlot的所有者為BufferQueue闸准,當(dāng)前狀態(tài)可以被Producer調(diào)用dequeue方法從隊(duì)列中取出。當(dāng)Producer調(diào)用dequeue方法獲取這個(gè)BufferSlot之后梢灭,狀態(tài)會切換成DEQUEUED夷家。
- DEQUEUED:當(dāng)前BufferSlot被Producer從隊(duì)列中dequeue出來蒸其,但是此時(shí)Producer仍然不能填充或者修改Buffer內(nèi)容,直到上一個(gè)使用Buffer的消費(fèi)者發(fā)出釋放Buffer的Fence信號之后才可以库快。此時(shí)Buffer歸生產(chǎn)者所有摸袁。當(dāng)生產(chǎn)者填充完成調(diào)用queue方法將其放入隊(duì)列之后會切換為QUEUED狀態(tài),或者調(diào)用取消重新切換為FREE狀態(tài)缺谴。
- QUEUED:此時(shí)Buffer被生產(chǎn)者調(diào)用queue方法放入隊(duì)列但惶,歸BufferQueue所屬耳鸯。此時(shí)這個(gè)slot描述的Buffer可以被Consumer取走湿蛔。
- ACQUIRED:Buffer被Consumer調(diào)用acquire方法從隊(duì)列取走之后,狀態(tài)變?yōu)锳CQUIRED狀態(tài)县爬,此時(shí)Consumer并不可訪問Buffer的內(nèi)容阳啥,直到收到相關(guān)的Fence信號才可以。
2:其他Slot列表
set<int> mFreeSlots -- 表示mSlots中處于FREE狀態(tài)的BufferSlot财喳,而且此時(shí)BufferSlot還沒有分配真正的GraphicBuffer
list<int> mFreeBuffers -- 表示mSlots中處于FREE狀態(tài)的BufferSlot, 且此BufferSlot已經(jīng)分配了真正的GraphicBuffer察迟。
set<int> mActiveBuffers -- 表示mSlots所有有GraphicBuffer且不屬于FREE狀態(tài)的slot。
BufferQueueCore中其他的屬性也已經(jīng)在注釋中解釋過了耳高,不在一一分析扎瓶。
BufferQueueProducer定義
class BufferQueueProducer : public BnGraphicBufferProducer,
private IBinder::DeathRecipient {
...
virtual status_t dequeueBuffer(int* outSlot, sp<Fence>* outFence, uint32_t width,
uint32_t height, PixelFormat format, uint64_t usage,
uint64_t* outBufferAge,
FrameEventHistoryDelta* outTimestamps) override;
virtual status_t queueBuffer(int slot,
const QueueBufferInput& input, QueueBufferOutput* output);
virtual status_t cancelBuffer(int slot, const sp<Fence>& fence);
virtual status_t connect(const sp<IProducerListener>& listener,
int api, bool producerControlledByApp, QueueBufferOutput* output);
// See IGraphicBufferProducer::disconnect
virtual status_t disconnect(int api, DisconnectMode mode = DisconnectMode::Api);
sp<BufferQueueCore> mCore;
// This references mCore->mSlots. Lock mCore->mMutex while accessing.
BufferQueueDefs::SlotsType& mSlots;
}
BufferQueueProducer定義只取了部分內(nèi)容,有個(gè)BufferQueueCore的指針泌枪,指向BufferQueueCore對象概荷。還定義了一個(gè)引用類型的SlotsType, 和BufferQueueCore中mSlots指向的是同一個(gè)mSlots數(shù)組對象碌燕。
此外误证,還定義了Producer常用的幾個(gè)方法
dequeueBuffer: 從BufferQueue中申請新的Buffer
queueBuffer: 將填充好內(nèi)容的Buffer放入BufferQueue隊(duì)列
connect: Producer從BufferQueue申請Buffer或者放入填充好的Buffer,必須先調(diào)用connect連接到BufferQueue隊(duì)列上
disconnect: Producer不在對BufferQueue操作的時(shí)候修壕,調(diào)用disconnect和BufferQueue隊(duì)列斷開連接愈捅。
BufferQueueConsumer定義
class BufferQueueConsumer : public BnGraphicBufferConsumer {
virtual status_t acquireBuffer(BufferItem* outBuffer,
nsecs_t expectedPresent, uint64_t maxFrameNumber = 0) override;
virtual status_t releaseBuffer(int slot, uint64_t frameNumber,
const sp<Fence>& releaseFence, EGLDisplay display,
EGLSyncKHR fence);
virtual status_t connect(const sp<IConsumerListener>& consumerListener,
bool controlledByApp);
virtual status_t disconnect();
sp<BufferQueueCore> mCore;
// This references mCore->mSlots. Lock mCore->mMutex while accessing.
BufferQueueDefs::SlotsType& mSlots;
}
BufferQueueConsumer定義也只取了部分內(nèi)容,和Producer定義基本類似慈鸠。同樣也有一個(gè)BufferQueueCore的指針指向BufferQueueCore對象蓝谨,也定義了一個(gè)引用類型的SlotsType,和BufferQueueCore的mSlote指向了同一個(gè)mSlots數(shù)組對象青团,大小為64譬巫。
acquireBuffer: 從BufferQueue隊(duì)列中獲取填充好內(nèi)容,等待顯示的Buffer壶冒,這些Buffer是生產(chǎn)者放入隊(duì)列中的缕题。
releaseBuffer:當(dāng)Consumer處理完Buffer后,釋放Buffer胖腾,這樣Producer可以重新從隊(duì)列中申請?zhí)畛洹?br>
connect: Consumer想要從BufferQueue獲取Buffer來處理烟零,必須先調(diào)用connect連接到BufferQueue隊(duì)列上
disconnect: Consumer不在對BufferQueue操作的時(shí)候瘪松,調(diào)用disconnect和BufferQueue隊(duì)列斷開連接。
總結(jié)
BufferQueue隊(duì)列簡單的分析基本完成了锨阿,從BufferQueue的創(chuàng)建已經(jīng)BufferQueue宵睦,BufferQueueProducer和BufferQueueConsumer的定義可以簡單了解BufferQueue隊(duì)列的內(nèi)容。
BufferQueueCore定義了Buffer隊(duì)列的核心內(nèi)容墅诡,保存有一個(gè)默認(rèn)大小為64的BufferSlot數(shù)組壳嚎,表示隊(duì)列中最多可以有64個(gè)圖像Buffer,但是我們可以自己定義大小末早,Layer初始化的時(shí)候目前設(shè)置為Buffer的數(shù)量為3烟馅,以前版本是2,這就是Android所說的UI雙緩存或者三緩存然磷,也就是時(shí)候一個(gè)窗口Surface到Layer之間有幾個(gè)Buffer在其間進(jìn)行傳遞郑趁,雙緩存就是一個(gè)在Surface端繪制一個(gè)在Layer端顯示。BufferQueueProducer和BufferQueueConsumer同時(shí)持有BufferQueueCore的對象姿搜。
BufferQueueProducer繼承自IBufferQueueProducer的Bn端寡润,可以在進(jìn)程間調(diào)用。dequeuebuffer舅柜,從隊(duì)列中申請Buffer, 當(dāng)填充完內(nèi)容后梭纹,調(diào)用queuebuffer將Buffer入隊(duì)。
BufferQueueConsumer繼承自IBufferQueueConsumer的Bn端致份,可以在進(jìn)程間調(diào)用变抽,acquirebuffer從隊(duì)列中取得填充好的buffer,處理完成后調(diào)用releasebuffer釋放buffer為FREE狀態(tài)后重新回到隊(duì)列知举。