2025年02月01日 BufferQueueProducer简介 极客笔记
GUI/BufferQueueProducer 之 buf 产生者
我们先看一下BufferQueueProducer类的关键成员函数:
requestBuffer
    返回slot对应的GraphicBuffer.正常情况下,dequeuBuffer会返回一个slot值,然后我们按照这个slot值取请求
    GraphicBuffer.如果之前的dequeueBuffer返回flags揭示之前的buffer不再合法,一定要再次调用requestBuffer函数.
dequeueBuffer
    为BufferQueueProducer拿到下一个buffer的index。从BufferQueue中。
    outFense是说,只有在NO_FENSE时候,才能立即写。其他的情况会返回-EBUSY.
    width,height,format,musage是描述buffer的属性。
    返回值如果是OK的话,紧接着调用requestBuffer拿到对应这个槽的buffer。
queueBuffer
    会把填充好的buffer放到BufferQueue中。
    需要一个timeStamp做输入,描述buffer,单位ns。
    输出是含有buffer信息的结构,包括已经queued的buffer的个数。
Query
    寻味native window的属性。输入window.h定义的,比如NATIVE_WINDOW_FORMAT
Connect
    尝试链接producer api到bufferQueue中。填充app的listener。
一般的步骤:
重要数据结构:
mSlot,它是BufferSlot结构。
namespace android {
    class BufferQueueCore;
    namespace BufferQueueDefs {
        enum { NUM_BUFFER_SLOTS = 64 };
        typedef BufferSlot SlotsType[NUM_BUFFER_SLOTS];
    } // namespace BufferQueueDefs
} // namespace android
struct BufferSlot {
    BufferSlot()
    : mGraphicBuffer(nullptr),
      mEglDisplay(EGL_NO_DISPLAY),
      mBufferState(),
      mRequestBufferCalled(false),
      mFrameNumber(0),
      mEglFence(EGL_NO_SYNC_KHR),
      mFence(Fence::NO_FENCE),
      mAcquireCalled(false),
      mNeedsReallocation(false) {
    }
   // 指向分配的GraphicBuffer
    sp<GraphicBuffer> mGraphicBuffer;
    // 用来构建 EGLSyncKHR 对象组
    EGLDisplay mEglDisplay;
    // 当前这个slot的状态
    BufferState mBufferState;
// debug用,描述了producer曾发起过requestBuffer请求.
    bool mRequestBufferCalled;
    // mFrameNumber  该slot上装的frame的framenumber,可以利用它以LRU顺序dequeue buffer
    uint64_t mFrameNumber;
// EGL同步对象.必须保证在slot槽dequeue之前触发(signal).
EGLSyncKHR mEglFence;
// 同步信号.揭示上任主人的读写操作是否完成.如果是free态,说明上个consumer的读完成了,或者上个
Producer的写完成了.
    sp<Fence> mFence;
    // buffer是否被consumer请求过.
    bool mAcquireCalled;
    // 是否需要在不通知producer的情况下重新分配buffer,可能是由于现有的buffer的尺寸,用途不合适. 
    bool mNeedsReallocation;
};
所谓的mCore,其实是BufferQueueCore结构 。它主要是几个数据成员:mFreeSlots、 mFreeBuffers以及mActiveBuffers。他们都是int型 数组,数据成员是slot的id。
所谓的slot,是SlotType数组,共64个SlotType的结构 。每个SlotType的结构都含有mGraphicBuffer。
这几个结构的区别是:
mFreeSlots描述的一组slot id,他们是free并没有关联的buffer。mFreeBuffers描述的一组slot id,他们是free但有关联的buffer。mActiveBuffers描述一组有non-free态buffer的slot id。mSharedBufferSlot描述一个shared的GraphicBuffer,所谓共享是在“物理内存”层面的共享。
class BufferQueueCore : public virtual RefBase {
    // mFreeSlots contains all of the slots which are FREE and do not currently
// have a buffer attached.
// 包含所有free态的并且尚未和buffer attached的slot id
    std::set<int> mFreeSlots;
    // mFreeBuffers contains all of the slots which are FREE and currently have
// a buffer attached.
// 包含所有free态的并且已有buffer attached上的slot id
    std::list<int> mFreeBuffers;
    // mUnusedSlots contains all slots that are currently unused. They should be
// free and not have a buffer attached.
// 尚未使用的slot id ,他们是free并且没有buffer attached上的.
    std::list<int> mUnusedSlots;
// mActiveBuffers contains all slots which have a non-FREE buffer attached.
// 含有所有非free态buffer attached的slot id
    std::set<int> mActiveBuffers;
    // mDequeueCondition is a condition variable used for dequeueBuffer in
    // synchronous mode.
mutable Condition mDequeueCondition;
// 是否该slot使能了共享模式.
bool mSharedBufferMode;
// When shared buffer mode is enabled, this indicates whether the consumer
// should acquire buffers even if BufferQueue doesn't indicate that they are
// available.
bool mAutoRefresh;
// When shared buffer mode is enabled, this tracks which slot contains the
// shared buffer.
// 共享buf模式使能时,揭示究竟是哪一个BufferSlot关联的是共享buf,它也是个slot的id.
int mSharedBufferSlot;
}
                                        本文链接:http://so.lmcjl.com/news/22468/