BufferQueueProducer简介

GUI/BufferQueueProducer 之 buf 产生者

第一个问题,何为Producer?

我们先看一下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。

一般的步骤:

  • 先调用dequeueBuffer拿到一个slot;
  • 然后依据这个slot,调用requestBuffer,拿到buffer。

重要数据结构:

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是什么?

所谓的mCore,其实是BufferQueueCore结构 。它主要是几个数据成员:mFreeSlotsmFreeBuffers以及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,所谓共享是在“物理内存”层面的共享。

BufferQueueCore中slots和slotsType结构

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;
}
赞(5)
未经允许不得转载:极客笔记 » BufferQueueProducer简介
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址