• Android 9.0 BufferQueue中的BufferSlot/BufferState注解


    源码位置

    /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的状态BufferState

    源码位置

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

    一个buffer有5种可能的状态:FREE/DEQUEUED/QUEUED/ACQUIRED/SHARED

        // 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状态,表示此缓冲区正在共享缓冲区模式下使用

     状态转换示意图

    BufferQueue种有几个队列大概解释

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

        // mSlots is an array of buffer slots that must be mirrored on the producer
        // side. This allows buffer ownership to be transferred between the producer
        // and consumer without sending a GraphicBuffer over Binder. The entire
        // array is initialized to NULL at construction time, and buffers are
        // allocated for a slot when requestBuffer is called with that slot's index.
    // typedef BufferSlot SlotsType[NUM_BUFFER_SLOTS];
    // static constexpr int NUM_BUFFER_SLOTS = 64;

    BufferQueueDefs::SlotsType mSlots; // mQueue is a FIFO of queued buffers used in synchronous mode. Fifo mQueue; // mFreeSlots contains all of the slots which are FREE and do not currently // have a buffer attached. std::set<int> mFreeSlots; // mFreeBuffers contains all of the slots which are FREE and currently have // a buffer attached. 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 contains all slots which have a non-FREE buffer attached. std::set<int> mActiveBuffers;
    • mSlots是总的一个buffer队列
    • mActiveBuffers是活跃的,不包含free的状态的
    • mFreeBuffers表示Buffer是Free的,这个序号对应的Buffer已经被分配出来了,只是现在没有被使用。
    • mFreeSlots表示,序号是Free的,这些序号还没有被用过,说明对应的是没有Buffer,Buffer还没有分配。
    • mQueue是一个FIFO的队列,应用(生产者producer)绘制完成后,queue到BufferQueue中,其实就是queue到这个队列里面
    心有猛虎,细嗅蔷薇,生活就该无惧无悔..... PS:文章系作者工作学习总结,受作者知识水平的限制,文章难免有错误之处,仅供参考,转载请注明出处:http://www.cnblogs.com/roger-yu/
  • 相关阅读:
    oracle实验13:单行函数-数字函数
    oracle实验12:单行函数-字符函数
    oracle实验41:编写存储过程
    oracle实验40:编写函数
    oracle实验31:使用PL/SQL,书写一个最简单的块
    oracle实验9-11:使用where和order by子句
    oracle实验6-8:关于null值,列的别名,去掉重复行
    oracle实验5:查询当前用户的所有表和视图
    MD5
    时间戳 日期 转换
  • 原文地址:https://www.cnblogs.com/roger-yu/p/15156497.html
Copyright © 2020-2023  润新知