BufferQueue分析:Buffer队列
Buffer队列的创建
从Suface创建流程中分析可以,创建每一个Layer的时候,在Layer初始化的时候会为当前Layer创建一个BufferQueue队列,用于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创建流程中已经分析过了
1:BufferQueue创建了一个的生产者和一个消费者
2:生产者被封装到了MonitoredProducer中,传递了App端,由Surface持有其代理
3:消费这被封装到了SurfaceFlingerComsumer中,设置Layer为内容变换监听者,当有新的Buffer到来,Layer进行处理。
先看下如何创建Buffer队列
sp<IGraphicBufferProducer> producer;
sp<IGraphicBufferConsumer> consumer;
BufferQueue::createBufferQueue(&producer, &consumer);
初始化一个producer指针和一个consumer指针作为出参给创建BufferQueue的函数。创建好BufferQueue之后,会将BufferQueue的生产者和消费者分别保存在这两个变量中。
void BufferQueue::createBufferQueue(sp<IGraphicBufferProducer>* outProducer,
sp<IGraphicBufferConsumer>* outConsumer,
const sp<IGraphicBufferAlloc>& allocator) {
//创建一个BufferQueueCore对象
sp<BufferQueueCore> core(new BufferQueueCore(allocator));
//创建一个BufferQueueProducer
sp<IGraphicBufferProducer> producer(new BufferQueueProducer(core));
//创建一个BufferQueueConsumer
sp<IGraphicBufferConsumer> consumer(new BufferQueueConsumer(core));
//将创建的producer和consumer分别保存在出参中
*outProducer = producer;
*outConsumer = consumer;
}
createBufferQueue是BufferQueue的静态函数,该函数中首先创建了一个BufferQueueCore对象,然后再以该对象作为参数创建了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是否还能处理生产者传递的图像
bool mIsAbandoned;
// mConsumerName 用来在日志中表示唯一的BufferQueue
String8 mConsumerName;
// mConsumerListener 用于通知已经连接的Consumer有新Buffer到来
sp<IConsumerListener> mConsumerListener;
// mConnectedApi 表示生产者是否已经连接到BufferQueue
int mConnectedApi;
// mConnectedProducerToken 用于通知生产者BufferQueue是否已经死亡
sp<IProducerListener> mConnectedProducerListener;
// mSlots 是一个大小为64的bufferSlot数组,每个BufferSlot描述了一个GraphicBuffer与其相关的属性
BufferQueueDefs::SlotsType mSlots;
// mQueue is a FIFO of queued buffers used in synchronous mode.
Fifo mQueue;
// mFreeSlots 表示所有的FREE状态的BufferSlot, 这个BufferSlot还没有分配GraphicBuffer缓冲区
std::set<int> mFreeSlots;
// mFreeBuffers 表示所有的FREE状态的BufferSlot, 这个BufferSlot已经分配了GraphicBuffer缓冲区
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 所有包含有使用状态GraphicBuffer的slot.
std::set<int> mActiveBuffers;
// mDequeueCondition 用于dequeuebuffer的同步
mutable Condition mDequeueCondition;
// mDefaultBufferFormat BufferQueue分配的GraphicBuffer的默认format
PixelFormat mDefaultBufferFormat;
// mDefaultWidth BufferQueue分配的GraphicBuffer的默认width
uint32_t mDefaultWidth;
// mDefaultHeight BufferQueue分配的GraphicBuffer的默认height
uint32_t mDefaultHeight;
// mDefaultBufferDataSpace BufferQueue分配的GraphicBuffer的默认DataSpace
android_dataspace mDefaultBufferDataSpace;
// mMaxBufferCount BufferQueue可以分配的GraphicBuffer的最大数量. 可以被consumer设置.
int mMaxBufferCount;
// mMaxAcquiredBufferCount Consumer一次可以acquire Buffer的最大数量,默认为1
int mMaxAcquiredBufferCount;
// mMaxDequeuedBufferCount Producer一次可以dqueue Buffer的最大数量,默认为1
int mMaxDequeuedBufferCount;
// mBufferHasBeenQueued 当有buffer queue到队列中时设置为true, 当释放掉所有buffer的时候设置为false
bool mBufferHasBeenQueued;
// mFrameCounter 每当队列中queuebuffer的之后 +1
uint64_t mFrameCounter;
// mTransformHint screen rotations标志.
uint32_t mTransformHint;
// mSidebandStream is a handle to the sideband buffer stream
sp<NativeHandle> mSidebandStream;
// mIsAllocating 表明生产者是否正在请求Gralloc分配GraphicBuffer
bool mIsAllocating;
// mAllowAllocation 表明 dequeueBuffer 是否允许请求Gralloc分配新的GraphicBuffer
bool mAllowAllocation;
// mAsyncMode 是否启用异步模式:生产者将graphicBuffer入队的时候不会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队列一些基本的属性,BufferQueueProducer和BufferQueueConsumer持有同一个BufferQueueCore对象,所以生产者和消费者都可以访问BufferQueue定义的属性。
BufferQueue中定义了一些关键的熟悉
1:BufferQueueDefs::SlotsType mSlots;
mSlots是一个大小为64的BufferSlot数组,表示一个Buffer队列中最多可以有64个Buffer。BufferSlot是一个GraphicBuffer的封装类,定义了和GraphicBuffer相关的一些属性。
如:GraphicBuffer指针,指向一个Gralloc分配的GraphicBuffer。
BufferState, 描述了当前slot位置Buffer的状态。BufferState定义的状态分为以下几种:
- FREE:当前这个BufferSlot的所有者为BufferQueue,当前状态可以被Producer调用dequeue方法从队列中取出。当Producer调用dequeue方法获取这个BufferSlot之后,状态会切换成DEQUEUED。
- DEQUEUED:当前BufferSlot被Producer从队列中dequeue出来,但是此时Producer仍然不能填充或者修改Buffer内容,直到上一个使用Buffer的消费者发出释放Buffer的Fence信号之后才可以。此时Buffer归生产者所有。当生产者填充完成调用queue方法将其放入队列之后会切换为QUEUED状态,或者调用取消重新切换为FREE状态。
- QUEUED:此时Buffer被生产者调用queue方法放入队列,归BufferQueue所属。此时这个slot描述的Buffer可以被Consumer取走。
- ACQUIRED:Buffer被Consumer调用acquire方法从队列取走之后,状态变为ACQUIRED状态,此时Consumer并不可访问Buffer的内容,直到收到相关的Fence信号才可以。
2:其他Slot列表
set<int> mFreeSlots -- 表示mSlots中处于FREE状态的BufferSlot,而且此时BufferSlot还没有分配真正的GraphicBuffer
list<int> mFreeBuffers -- 表示mSlots中处于FREE状态的BufferSlot, 且此BufferSlot已经分配了真正的GraphicBuffer。
set<int> mActiveBuffers -- 表示mSlots所有有GraphicBuffer且不属于FREE状态的slot。
BufferQueueCore中其他的属性也已经在注释中解释过了,不在一一分析。
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定义只取了部分内容,有个BufferQueueCore的指针,指向BufferQueueCore对象。还定义了一个引用类型的SlotsType, 和BufferQueueCore中mSlots指向的是同一个mSlots数组对象。
此外,还定义了Producer常用的几个方法
dequeueBuffer: 从BufferQueue中申请新的Buffer
queueBuffer: 将填充好内容的Buffer放入BufferQueue队列
connect: Producer从BufferQueue申请Buffer或者放入填充好的Buffer,必须先调用connect连接到BufferQueue队列上
disconnect: Producer不在对BufferQueue操作的时候,调用disconnect和BufferQueue队列断开连接。
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定义也只取了部分内容,和Producer定义基本类似。同样也有一个BufferQueueCore的指针指向BufferQueueCore对象,也定义了一个引用类型的SlotsType,和BufferQueueCore的mSlote指向了同一个mSlots数组对象,大小为64。
acquireBuffer: 从BufferQueue队列中获取填充好内容,等待显示的Buffer,这些Buffer是生产者放入队列中的。
releaseBuffer:当Consumer处理完Buffer后,释放Buffer,这样Producer可以重新从队列中申请填充。
connect: Consumer想要从BufferQueue获取Buffer来处理,必须先调用connect连接到BufferQueue队列上
disconnect: Consumer不在对BufferQueue操作的时候,调用disconnect和BufferQueue队列断开连接。
总结
BufferQueue队列简单的分析基本完成了,从BufferQueue的创建已经BufferQueue,BufferQueueProducer和BufferQueueConsumer的定义可以简单了解BufferQueue队列的内容。
BufferQueue
BufferQueueCore定义了Buffer队列的核心内容,保存有一个默认大小为64的BufferSlot数组,表示队列中最多可以有64个图像Buffer,但是我们可以自己定义大小,Layer初始化的时候目前设置为Buffer的数量为3,以前版本是2,这就是Android所说的UI双缓存或者三缓存,也就是时候一个窗口Surface到Layer之间有几个Buffer在其间进行传递,双缓存就是一个在Surface端绘制一个在Layer端显示。BufferQueueProducer和BufferQueueConsumer同时持有BufferQueueCore的对象。
BufferQueueProducer继承自IBufferQueueProducer的Bn端,可以在进程间调用。dequeuebuffer,从队列中申请Buffer, 当填充完内容后,调用queuebuffer将Buffer入队。
BufferQueueConsumer继承自IBufferQueueConsumer的Bn端,可以在进程间调用,acquirebuffer从队列中取得填充好的buffer,处理完成后调用releasebuffer释放buffer为FREE状态后重新回到队列。