BufferQueue分析:Buffer队列

2020-01-04  本文已影响0人  泡面先生_Jack

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定义的状态分为以下几种:

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状态后重新回到队列。

上一篇下一篇

猜你喜欢

热点阅读