Android 9.0 BufferSlot注解

源码位置

/frameworks/native/libs/gui/include/gui/BufferSlot.h

 

源码

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) {
    }

    // mGraphicBuffer points to the buffer allocated for this slot or is NULL
    // if no buffer has been allocated.
    sp<GraphicBuffer> mGraphicBuffer;

    // mEglDisplay is the EGLDisplay used to create EGLSyncKHR objects.
    EGLDisplay mEglDisplay;

    // mBufferState is the current state of this buffer slot.
    BufferState mBufferState;

    // mRequestBufferCalled is used for validating that the producer did
    // call requestBuffer() when told to do so. Technically this is not
    // needed but useful for debugging and catching producer bugs.
    bool mRequestBufferCalled;

    // mFrameNumber is the number of the queued frame for this slot.  This
    // is used to dequeue buffers in LRU order (useful because buffers
    // may be released before their release fence is signaled).
    uint64_t mFrameNumber;

    // mEglFence is the EGL sync object that must signal before the buffer
    // associated with this buffer slot may be dequeued. It is initialized
    // to EGL_NO_SYNC_KHR when the buffer is created and may be set to a
    // new sync object in releaseBuffer.  (This is deprecated in favor of
    // mFence, below.)
    EGLSyncKHR mEglFence;

    // mFence is a fence which will signal when work initiated by the
    // previous owner of the buffer is finished. When the buffer is FREE,
    // the fence indicates when the consumer has finished reading
    // from the buffer, or when the producer has finished writing if it
    // called cancelBuffer after queueing some writes. When the buffer is
    // QUEUED, it indicates when the producer has finished filling the
    // buffer. When the buffer is DEQUEUED or ACQUIRED, the fence has been
    // passed to the consumer or producer along with ownership of the
    // buffer, and mFence is set to NO_FENCE.
    sp<Fence> mFence;

    // Indicates whether this buffer has been seen by a consumer yet
    bool mAcquireCalled;

    // Indicates whether the buffer was re-allocated without notifying the
    // producer. If so, it needs to set the BUFFER_NEEDS_REALLOCATION flag when
    // dequeued to prevent the producer from using a stale cached buffer.
    bool mNeedsReallocation;
};

成员注解

  • sp<GraphicBuffer> mGraphicBuffer;   // mGraphicBuffer指向这个槽位分配的缓冲区,如果没有分配缓冲区则为NULL
  • EGLDisplay mEglDisplay;  // 用于创建EGLSyncKHR对象的EGLDisplay
  • BufferState mBufferState; // 缓冲槽的当前状态
  • bool mRequestBufferCalled; // mRequestBufferCalled用于验证生产者是否在被告知时调用了requestBuffer()。从技术上讲,这不是必需的,但对于调试和捕获生产者bug非常有用。
  • uint64_t mFrameNumber; // mFrameNumber是此插槽的排队帧编号。这用于按LRU顺序将缓冲区出列(很有用,因为缓冲区可能在释放围栏发出信号之前被释放)。
  • EGLSyncKHR mEglFence; // mEglFence是EGL sync对象,必须在与此缓冲槽关联的缓冲区退出队列之前发出信号。当创建缓冲区时,它被初始化为EGL_NO_SYNC_KHR,并且可以设置为releaseBuffer中的新同步对象(支持mFence时mEglFence被弃用)
  • sp<Fence> mFence;  // mFence是一个围栏,当缓冲区的前所有者启动的工作完成时,它将发出信号。
  1. 当Buffer处在FREE时,Fence指示消费者何时已完成从缓冲区的读取,或者生产者何时已完成写入
  2. 当Buffer处在QUEUED时,它指示生产者何时完成缓冲区填充。
  3. 当Buffer处在DEQUEUED or ACQUIRED时,Fence连同缓冲区的所有权一起传递给消费者或生产者,并且mFence设置为NO_FENCE。
  • bool mAcquireCalled; // 指示消费者consumer是否已看到此缓冲区
  • bool mNeedsReallocation; //指示是否在未通知生产者的情况下重新分配了缓冲区。如果是这样,它需要在退出队列时设置BUFFER_NEEDS_REALLOCATION标志,以防止生产者使用过时的缓存缓冲区。

 

buffer的状态

    // A buffer can be in one of five states, represented as below:
    //
    //         | mShared | mDequeueCount | mQueueCount | mAcquireCount |
    // --------|---------|---------------|-------------|---------------|
    // FREE    |  false  |       0       |      0      |       0       |
    // DEQUEUED|  false  |       1       |      0      |       0       |
    // QUEUED  |  false  |       0       |      1      |       0       |
    // ACQUIRED|  false  |       0       |      0      |       1       |
    // SHARED  |  true   |      any      |     any     |      any      |
    //
    // FREE indicates that the buffer is available to be dequeued by the
    // producer. The slot is "owned" by BufferQueue. It transitions to DEQUEUED
    // when dequeueBuffer is called.
    //
    // DEQUEUED indicates that the buffer has been dequeued by the producer, but
    // has not yet been queued or canceled. The producer may modify the
    // buffer's contents as soon as the associated release fence is signaled.
    // The slot is "owned" by the producer. It can transition to QUEUED (via
    // queueBuffer or attachBuffer) or back to FREE (via cancelBuffer or
    // detachBuffer).
    //
    // QUEUED indicates that the buffer has been filled by the producer and
    // queued for use by the consumer. The buffer contents may continue to be
    // modified for a finite time, so the contents must not be accessed until
    // the associated fence is signaled. The slot is "owned" by BufferQueue. It
    // can transition to ACQUIRED (via acquireBuffer) or to FREE (if another
    // buffer is queued in asynchronous mode).
    //
    // ACQUIRED indicates that the buffer has been acquired by the consumer. As
    // with QUEUED, the contents must not be accessed by the consumer until the
    // acquire fence is signaled. The slot is "owned" by the consumer. It
    // transitions to FREE when releaseBuffer (or detachBuffer) is called. A
    // detached buffer can also enter the ACQUIRED state via attachBuffer.
    //
    // SHARED indicates that this buffer is being used in shared buffer
    // mode. It can be in any combination of the other states at the same time,
    // except for FREE (since that excludes being in any other state). It can
    // also be dequeued, queued, or acquired multiple times.
  • FREE状态,buffer及slot属于BufferQueue,producer可以通过调用dequeueBuffer获取该buffer,其状态转为DEQUEUED
  • DEQUEUED状态,表示该buffer已经被producer出队列,但时还被queued或canceled。一旦与该buffer相关联的fence发出信号,producer就可以修改buffer的内容。这种状态下slot属于producer所有,当调用queueBuffer or attachBuffer后转为QUEUED,或调用cancelBuffer or detachBuffer转为FREE
  • QUEUED状态,表示该buffer已经被producer填充数据,入队列让consumer使用。buffer内容可能会在有限的时间内继续修改,因此在相关fence发出信号之前,不得访问内容。此时slot归BufferQueue所有,buffer状态可以转为ACQUIRED(via acquireBuffer) 或FREE(另一个buffer异步模式下入队列)
  • ACQUIRED状态,表示该buffer被consumer取得。fence信号发出后,消费者就可以访问其内容了。slot被consumer所拥有。 当调用releaseBuffer (or detachBuffer)可以转为FREE
  • SHARED状态,表示此缓冲区正在共享缓冲区模式下使用