飞道的博客

Android 图形架构 之四——图形缓冲区的申请和消费流程及核心类

656人阅读  评论(0)

前言

Android应用的UI显示到Display的过程中,SurfaceFlinger扮演的角色只是“Flinger”,就是定于检查Layer更新,然后计算DirtyRegion,然后将结果推送给底层显示驱动进行显示。

应用层把UI内容 写入到GraphicBuffer,SurfaceFlinger读取数据后 ,合成显示。BufferQueue 是用来管理GraphicBuffer的

Android 图形架构 之一 ——概述
Android 图形架构 之二—— SurfaceFlinger 启动和连接
Android 图形架构 之三—— 创建Layer、Surface、SurfaceControl
Android 图形架构 之四——图形缓冲区的申请和消费流程及核心类
Android 图形架构 之五——深入分析addView所发生的的一切
Android 图形架构 之六——深入分析draw()是如何工作的
Android 图形架构 之七——Choreographer 源码分析
Android图形架构 之八——硬件VSync、VSync-app、Vsync-sf

一、生产者消费者模型

对GraphicBuffer的管理 使用的是生产者消费者模型,app 产生数据,通知SurfaceFlinger ,SurfaceFlinger读取数据。


app属于Java层,BufferQueue/SurfaceFlinger属于native层。也就是说BufferQueue也是隶属SurfaceFlinger,所有工作围绕SurfaceFlinger展开。

二、关于缓冲区的核心类

先看一下这几个类的关系

图二

1.1、BufferQueue

生产者、消费者 和 核心服务BufferQueueCore 是由BufferQueue来创建,BufferQueue的createBufferQueue函数,位于frameworks/native/libs/gui/BufferQueue.cpp:

代码一:
void BufferQueue::createBufferQueue(sp<IGraphicBufferProducer>* outProducer,
        sp<IGraphicBufferConsumer>* outConsumer,
        const sp<IGraphicBufferAlloc>& allocator) {
   //allocator == NULL
    ......
    //创建一个BufferQueueCore,她是核心
    sp<BufferQueueCore> core(new BufferQueueCore(allocator));
    ......
    //用BufferQueueCore创建生产者
    sp<IGraphicBufferProducer> producer(new BufferQueueProducer(core));
    ......
    //用core创建消费者
    sp<IGraphicBufferConsumer> consumer(new BufferQueueConsumer(core));
    ......
    //向外面传入指针赋值
    *outProducer = producer;
    *outConsumer = consumer;
}

1.2、 BufferQueueCore

核心都是这个BufferQueueCore,创建生产者 消费者,也使用到了它的对象,他是管理图形缓冲区的中枢。这里举一个SurfaceTexture的例子,来看看他们之间的关系:

可以认为BufferQueueCore是一个服务中心,生产者、消费者都要通过它来管理buffer。下面来看一下,它的构造函数

代码二:
// BufferQueueCore.h
class BufferQueueCore : public virtual RefBase {
   

    friend class BufferQueueProducer;
    friend class BufferQueueConsumer;

public:
    ...
    typedef Vector<BufferItem> Fifo;
private:
    ...
    String8 mConsumerName;
    sp<IConsumerListener> mConsumerListener;
    sp<IProducerListener> mConnectedProducerListener;

    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;
    ...
}
  • mQueue
    是一个新建先出队列,存储了一队 BufferItem 数据,即一组缓存区。

  • mSlots
    一个数据类型 是BufferSlot 的数组(通常是64个),每个 BufferSlot对应一个缓存。

    • BufferSlot 的成员变量:sp< GraphicBuffer >mGraphicBuffer;记录这个slot所涉及的缓冲区
    • BufferSlot 的成员变量:mBufferState;用于跟踪这个缓冲区的状态
  • mConsumerListener
    通知消费者 ,进行数据的处理。

  • mConnectedProducerListener
    当前生产消费模型中的,生产者回调接口。

其余变量的都有注释,就不翻译了

1.3、BufferState

在最新的Android 10 代码中,使用变量来表示缓冲区的各状态的数量

BufferSlot的定义位于frameworks/native/include/gui/BufferSlot.h中:它是一个结构体

代码三:
struct BufferState {
   

    // All slots are initially FREE (not dequeued, queued, acquired, or shared).
    BufferState()
    : mDequeueCount(0),
      mQueueCount(0),
      mAcquireCount(0),
      mShared(false) {
   
    }

    uint32_t mDequeueCount;
    uint32_t mQueueCount;
    uint32_t mAcquireCount;
    bool mShared;

    // 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当前可用,可以被生产者dequeued,此时owner是BufferQueueCore,当 dequeuebuffer调用时,状态可以转为dequeued。
  • DEQUEUED:buffer已经被dequeued,还没被queue或canceld,此时owner是producer。
  • QUEUED:buffer已经被生产者填充,并被queued,此时的owner是bufferQueueCore。
  • ACQUIRED:buffer已经被消费者获得,此时的owner是consumer。

一般的buffer大致会经过FREE->DEQUEUED->QUEUED->ACQUIRED->FREE这个流程,涉及到的函数,下面会讲到,这些函数,通常在systrace 性能分析的时候,会经常看到,是有标志性的意义,你可能需要寻找这几个关键函数的,来判断是否丢帧、卡顿的原因

1.4、BufferSlot

代码四:
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;
};
  • mGraphicBuffer代表一块图形缓冲区GraphicBuffer,用于应用绘制UI。
  • mBufferState类型为BufferState

接下来,我们分别从生产者 消费者的角度来分析

三、生产者

IGraphicBufferProducer/IProducerListener 生产者

IGraphicBufferProducer 是生产者接口,实现了 IInterface 可以用于跨进程通信。

代码五:
// IGraphicBufferProducer.h
class IGraphicBufferProducer : public IInterface
{
   
public:
    DECLARE_HYBRID_META_INTERFACE(GraphicBufferProducer, 
        HGraphicBufferProducer)
    ...
    // 根据指定参数申请一块 Buffer ,索引值为 slot ,同步为 fence
    // 从 BufferQueue 中出队一块缓存 GraphicBuffer
    virtual status_t dequeueBuffer(int* slot, sp<Fence>* fence, 
        uint32_t w, uint32_t h,
        PixelFormat format, uint64_t usage, uint64_t* outBufferAge,
        FrameEventHistoryDelta* outTimestamps) = 0;
    // 获取 slot 位置的 GraphicBuffer
    virtual status_t requestBuffer(int slot, sp<GraphicBuffer>* buf) = 0;
    // 客户端已经向 slot 位置的 Buffer 填充完数据 
    // IGraphicBufferProducer 得到 Buffer 的输入信息,
    // slot 这块缓存 GraphicBuffer 进入队列 BufferQueue
    virtual status_t queueBuffer(int slot, const QueueBufferInput& input,
            QueueBufferOutput* output) = 0;
    // 释放 slot 位置的 GraphicBuffer
    virtual status_t detachBuffer(int slot) = 0;
    virtual status_t detachNextBuffer(sp<GraphicBuffer>* outBuffer,
            sp<Fence>* outFence) = 0;
    // 根据指定的 buffer 获取 slot
    virtual status_t attachBuffer(int* outSlot,
            const sp<GraphicBuffer>& buffer) = 0;
    // 释放 slot 位置的 buffer
    virtual status_t cancelBuffer(int slot, const sp<Fence>& fence) = 0;
    ...
    // 客户端根据 api 类型,连接 IGraphicBufferProducer ,
    // 客户端得到缓存的相关信息 QueueBufferOutput
    virtual status_t connect(const sp<IProducerListener>& listener,
            int api, bool producerControlledByApp, 
            QueueBufferOutput* output) = 0;
    // 断开连接
    virtual status_t disconnect(int api, 
        DisconnectMode mode = DisconnectMode::Api) = 0;
    // 获取消费者名称
    virtual String8 getConsumerName() const = 0;
    ...
};

IProducerListener 是 IGraphicBufferProducer 对应的回调接口。

代码六:
// IProducerListener.h
class ProducerListener : public virtual RefBase
{
   
public:
    ProducerListener() {
   }
    virtual ~ProducerListener();

    virtual void onBufferReleased() = 0; // Asynchronous
    virtual bool needsReleaseNotify() = 0;
};

class IProducerListener : public ProducerListener, public IInterface
{
   
public:
    DECLARE_META_INTERFACE(ProducerListener)
};

class BnProducerListener : public BnInterface<IProducerListener>
{
   
public:
    virtual status_t onTransact(uint32_t code, const Parcel& data,
            Parcel* reply, uint32_t flags = 0);
    virtual bool needsReleaseNotify();
};

class DummyProducerListener : public BnProducerListener
{
   
public:
    virtual ~DummyProducerListener();
    virtual void onBufferReleased() {
   }
    virtual bool needsReleaseNotify() {
    return false; }
};

BufferQueueProducer 生产者实现类

BufferQueueProducer 是 IGraphicBufferConsumer 的实现类,实现了生产者对应的功能。

代码七:
// BufferQueueProducer.h
class BufferQueueProducer : public BnGraphicBufferProducer,
                            private IBinder::DeathRecipient {
   
    ...
private:
    ...
    sp<BufferQueueCore> mCore;
    // This references mCore->mSlots.
    BufferQueueDefs::SlotsType& mSlots;
    String8 mConsumerName;
    ...
    sp<Fence> mLastQueueBufferFence;
    Rect mLastQueuedCrop;
    uint32_t mLastQueuedTransform;
}

BufferQueueProducer 中持有 BufferQueueCore 对象; mSlots 指向 mCore->mSlots ;同时保持了生产消费模型中,对应消费者的名称。

四、消费者

IGraphicBufferConsumer/IConsumerListener 消费者
IGraphicBufferConsumer 是消费者接口,实现了 IInterface 可以用于跨进程通信。

代码八:
// IGraphicBufferConsumer.h
class IGraphicBufferConsumer : public IInterface {
   
public:
    DECLARE_META_INTERFACE(GraphicBufferConsumer)
    ...
    // 从 BufferQueue 中获取一块准备好了的缓存 GraphicBuffer
    virtual status_t acquireBuffer(BufferItem* buffer, 
        nsecs_t presentWhen, uint64_t maxFrameNumber = 0) = 0;
    // 释放 slot 位置的缓存
    virtual status_t detachBuffer(int slot) = 0;
    // 根据指定的 GraphicBuffer 获取 slot
    virtual status_t attachBuffer(int* outSlot, 
        const sp<GraphicBuffer>& buffer) = 0;
    // 移除指定 slot 位置的缓存
    virtual status_t releaseBuffer(int buf, uint64_t frameNumber, 
        EGLDisplay display, EGLSyncKHR fence, 
        const sp<Fence>& releaseFence) = 0;
    ...
    // 连接一个消费者进入 BufferQueue
    virtual status_t consumerConnect(const sp<IConsumerListener>& consumer,
                                     bool controlledByApp) = 0;
    // 从 BufferQueue 断开连接
    virtual status_t consumerDisconnect() = 0;
    ...
};

IConsumerListener 是 IGraphicBufferConsumer 对应的回调接口:

代码九:
// IConsumerListener.h
class ConsumerListener : public virtual RefBase {
   
public:
    ConsumerListener() {
   }
    virtual ~ConsumerListener();

    // onDisconnect is called when a producer disconnects from the BufferQueue.
    virtual void onDisconnect() {
   } /* Asynchronous */

    // onFrameAvailable is called from queueBuffer each time an additional frame becomes available
    // for consumption. This means that frames that are queued while in asynchronous mode only
    // trigger the callback if no previous frames are pending. Frames queued while in synchronous
    // mode always trigger the callback. The item passed to the callback will contain all of the
    // information about the queued frame except for its GraphicBuffer pointer, which will always be
    // null (except if the consumer is SurfaceFlinger).
    //
    // This is called without any lock held and can be called concurrently by multiple threads.
    virtual void onFrameAvailable(const BufferItem& item) = 0; /* Asynchronous */

    // onFrameReplaced is called from queueBuffer if the frame being queued is replacing an existing
    // slot in the queue. Any call to queueBuffer that doesn't call onFrameAvailable will call this
    // callback instead. The item passed to the callback will contain all of the information about
    // the queued frame except for its GraphicBuffer pointer, which will always be null.
    //
    // This is called without any lock held and can be called concurrently by multiple threads.
    virtual void onFrameReplaced(const BufferItem& /* item */) {
   } /* Asynchronous */

    // onBuffersReleased is called to notify the buffer consumer that the BufferQueue has released
    // its references to one or more GraphicBuffers contained in its slots. The buffer consumer
    // should then call BufferQueue::getReleasedBuffers to retrieve the list of buffers.
    //
    // This is called without any lock held and can be called concurrently by multiple threads.
    virtual void onBuffersReleased() = 0; /* Asynchronous */

    // onSidebandStreamChanged is called to notify the buffer consumer that the BufferQueue's
    // sideband buffer stream has changed. This is called when a stream is first attached and when
    // it is either detached or replaced by a different stream.
    virtual void onSidebandStreamChanged() = 0; /* Asynchronous */

    // Notifies the consumer of any new producer-side timestamps and returns the combined frame
    // history that hasn't already been retrieved.
    //
    // WARNING: This method can only be called when the BufferQueue is in the consumer's process.
    virtual void addAndGetFrameTimestamps(const NewFrameEventsEntry* /*newTimestamps*/,
                                          FrameEventHistoryDelta* /*outDelta*/) {
   }
};

class IConsumerListener : public ConsumerListener, public IInterface {
   
public:
    DECLARE_META_INTERFACE(ConsumerListener)
};

class BnConsumerListener : public SafeBnInterface<IConsumerListener> {
   
public:
    BnConsumerListener() : SafeBnInterface<IConsumerListener>("BnConsumerListener") {
   }

    status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply,
                        uint32_t flags = 0) override;
};

BufferQueueConsumer 是 IGraphicBufferConsumer 的实现类,实现了消费者对应的功能。是一个回调接口,如果BufferQueue中有数据准备好了通知消费者取走数据。取走数据的时候,需要调用acquireBuffer函数,将缓冲区状态变成ACQUIRED,使用完之后调用releaseBuffer函数可以把缓冲区数据归还给BufferQueueCore,这样缓冲区就变成FREE。

代码十:
// BufferQueueConsumer.h
class BufferQueueConsumer : public BnGraphicBufferConsumer {
   
    ...
private:
    sp<BufferQueueCore> mCore;
    // This references mCore->mSlots.
    BufferQueueDefs::SlotsType& mSlots;
    String8 mConsumerName;
}

BufferQueueConsumer 中持有 BufferQueueCore 对象; mSlots 指向 mCore->mSlots 。

五、图形缓冲区的生产和消费

这里依然使用Android 图形架构 之一 ——概述 中图片

5.1、申请图形缓冲区

申请图形缓冲区,是从队列中取出数据 ,所以函数名叫dequeueBuffer ,它的作用是在应用程序一端请求绘制图像时,向BufferQueue中申请一块可用的GraphicBuffer,有了这个buffer就可以绘制图像数据了。

bufferqueuecore中mSlots数组管理缓冲区,最大容量是64,这个mSlots一开始静态分配了64个bufferslot大小的空间,但是其中的数据缓冲区GraphicBuffer的分配是动态的

在UI绘制的draw阶段会调用 dequeueBuffer,详见文章Android 图形架构 之六——深入分析draw()是如何工作的

代码路径:frameworks/native/libs/gui/BufferQueueProducer.cpp

代码十一:
status_t BufferQueueProducer::dequeueBuffer(int* outSlot, sp<android::Fence>* outFence,
                                            uint32_t width, uint32_t height, PixelFormat format,
                                            uint64_t usage, uint64_t* outBufferAge,
                                            FrameEventHistoryDelta* outTimestamps) {
   
    ATRACE_CALL();
    {
    // Autolock scope
        std::lock_guard<std::mutex> lock(mCore->mMutex);
        mConsumerName = mCore->mConsumerName;
        // 队列的状态为被抛弃的,就直接返回了
        if (mCore->mIsAbandoned) {
   
            BQ_LOGE("dequeueBuffer: BufferQueue has been abandoned");
            return NO_INIT;
        }
        //是否与BufferQueue建立连接
        if (mCore->mConnectedApi == BufferQueueCore::NO_CONNECTED_API) {
   
            BQ_LOGE("dequeueBuffer: BufferQueue has no connected producer");
            return NO_INIT;
        }
    } // Autolock scope

    BQ_LOGV("dequeueBuffer: w=%u h=%u format=%#x, usage=%#" PRIx64, width, height, format, usage);
     //宽高不正常,则返回失败
    if ((width && !height) || (!width && height)) {
   
        BQ_LOGE("dequeueBuffer: invalid size: w=%u h=%u", width, height);
        return BAD_VALUE;
    }
	//定义返回值
    status_t returnFlags = NO_ERROR;
    EGLDisplay eglDisplay = EGL_NO_DISPLAY;
    EGLSyncKHR eglFence = EGL_NO_SYNC_KHR;
    bool attachedByConsumer = false;

    {
    // Autolock scope
        std::unique_lock<std::mutex> lock(mCore->mMutex);

        // If we don't have a free buffer, but we are currently allocating, we wait until allocation
        // is finished such that we don't allocate in parallel.
        // mFreeBuffers 表示 状态为FREE,其已经绑定了GraphicBuffer的BufferSlot 的集合
        // 这种集合为空,并且 正在 为GraphicBuffer分配内存空间
        if (mCore->mFreeBuffers.empty() && mCore->mIsAllocating) {
   
            mDequeueWaitingForAllocation = true;
            //等待分配完成
            mCore->waitWhileAllocatingLocked(lock);
            mDequeueWaitingForAllocation = false;
            mDequeueWaitingForAllocationCondition.notify_all();
        }

        if (format == 0) {
   
            format = mCore->mDefaultBufferFormat;
        }

        // Enable the usage bits the consumer requested
        usage |= mCore->mConsumerUsageBits;

        const bool useDefaultSize = !width && !height;
        if (useDefaultSize) {
   
            width = mCore->mDefaultWidth;
            height = mCore->mDefaultHeight;
        }
        //寻找 BufferSlot
        int found = BufferItem::INVALID_BUFFER_SLOT;
        while (found == BufferItem::INVALID_BUFFER_SLOT) {
   
            //获取到可用的BufferSlot,它在mSlots的下标保存在found中
            status_t status = waitForFreeSlotThenRelock(FreeSlotCaller::Dequeue, lock, &found);
            if (status != NO_ERROR) {
   
                return status;
            }

            // found 值没有发生变化,说明创建失败
            if (found == BufferQueueCore::INVALID_BUFFER_SLOT) {
   
                BQ_LOGE("dequeueBuffer: no available buffer slots");
                return -EBUSY;
            }

            //获取found 索引对应的BufferSlot 对应的GraphicBuffer。后面需要为该GraphicBuffer分配空间
            const sp<GraphicBuffer>& buffer(mSlots[found].mGraphicBuffer);

            // If we are not allowed to allocate new buffers,
            // waitForFreeSlotThenRelock must have returned a slot containing a
            // buffer. If this buffer would require reallocation to meet the
            // requested attributes, we free it and attempt to get another one.
            //  官方注释说的很清楚了,我再啰嗦一下,当前不允许分配buffers,但是新获得的这个BufferSlot,需要为它分配一个buffer
            // 那么就把这个BufferSlot 归还,continue,再分配一次
            if (!mCore->mAllowAllocation) {
   
                if (buffer->needsReallocation(width, height, format, BQ_LAYER_COUNT, usage)) {
   
                    if (mCore->mSharedBufferSlot == found) {
   
                        BQ_LOGE("dequeueBuffer: cannot re-allocate a sharedbuffer");
                        return BAD_VALUE;
                    }
                    mCore->mFreeSlots.insert(found);
                    mCore->clearBufferSlotLocked(found);
                    found = BufferItem::INVALID_BUFFER_SLOT;
                    continue;
                }
            }
        }
		//到此,说明已经找到了一个BufferSlot,并且它所对应的GraphicBuffer,不用再次分配
        const sp<GraphicBuffer>& buffer(mSlots[found].mGraphicBuffer);
        if (mCore->mSharedBufferSlot == found &&
                buffer->needsReallocation(width, height, format, BQ_LAYER_COUNT, usage)) {
   
            BQ_LOGE("dequeueBuffer: cannot re-allocate a shared"
                    "buffer");

            return BAD_VALUE;
        }

        //如果不是共享buffer,就把这个BufferSlot对应的下标,加入到mActiveBuffers中
        // mActiveBuffers 是BufferQueueCore 中的一个变量,见代码二
        if (mCore->mSharedBufferSlot != found) {
   
            mCore->mActiveBuffers.insert(found);
        }
        //outSlot是最终返回给Surface
        *outSlot = found;
        ATRACE_BUFFER_INDEX(found);
       
        attachedByConsumer = mSlots[found].mNeedsReallocation;
        //表示不需要重新分配空间
        mSlots[found].mNeedsReallocation = false;
        //BufferSlot 对应的 GraphicBuffer 状态设置为dequeue
        mSlots[found].mBufferState.dequeue();

        //这里再次判断,buffer 是否为空,或者 是否需要重新分配空间
        if ((buffer == nullptr) ||
                buffer->needsReallocation(width, height, format, BQ_LAYER_COUNT, usage))
        {
   
           //重置BufferSlot的变量值,
            mSlots[found].mAcquireCalled = false;
            mSlots[found].mGraphicBuffer = nullptr;
            mSlots[found].mRequestBufferCalled = false;
            mSlots[found].mEglDisplay = EGL_NO_DISPLAY;
            mSlots[found].mEglFence = EGL_NO_SYNC_KHR;
            mSlots[found].mFence = Fence::NO_FENCE;
            mCore->mBufferAge = 0;
            mCore->mIsAllocating = true;

            returnFlags |= BUFFER_NEEDS_REALLOCATION;
        } else {
   
            // We add 1 because that will be the frame number when this buffer
            // is queued
            mCore->mBufferAge = mCore->mFrameCounter + 1 - mSlots[found].mFrameNumber;
        }

        BQ_LOGV("dequeueBuffer: setting buffer age to %" PRIu64,
                mCore->mBufferAge);

        if (CC_UNLIKELY(mSlots[found].mFence == nullptr)) {
   
            BQ_LOGE("dequeueBuffer: about to return a NULL fence - "
                    "slot=%d w=%d h=%d format=%u",
                    found, buffer->width, buffer->height, buffer->format);
        }

        eglDisplay = mSlots[found].mEglDisplay;
        //因为GraphicBuffer 最终是要到Gpu去消费,而当前的操作都是在cpu,为了同步cpu和Gpu对同一数据的使用,产生了这中Fence机制,后面的文章会讲解
        eglFence = mSlots[found].mEglFence;
        // Don't return a fence in shared buffer mode, except for the first
        // frame.
        *outFence = (mCore->mSharedBufferMode &&
                mCore->mSharedBufferSlot == found) ?
                Fence::NO_FENCE : mSlots[found].mFence;
        mSlots[found].mEglFence = EGL_NO_SYNC_KHR;
        mSlots[found].mFence = Fence::NO_FENCE;

        // If shared buffer mode has just been enabled, cache the slot of the
        // first buffer that is dequeued and mark it as the shared buffer.
        if (mCore->mSharedBufferMode && mCore->mSharedBufferSlot ==
                BufferQueueCore::INVALID_BUFFER_SLOT) {
   
            mCore->mSharedBufferSlot = found;
            mSlots[found].mBufferState.mShared = true;
        }
    } // Autolock scope
    
    //当前BufferSlot 是否需要分配空间
    if (returnFlags & BUFFER_NEEDS_REALLOCATION) {
   
        BQ_LOGV("dequeueBuffer: allocating a new buffer for slot %d", *outSlot);
        //使用Gralloc HAL进行内存分配,是在匿名内存中分配空间
        sp<GraphicBuffer> graphicBuffer = new GraphicBuffer(
                width, height, format, BQ_LAYER_COUNT, usage,
                {
   mConsumerName.string(), mConsumerName.size()});

        status_t error = graphicBuffer->initCheck();

        {
    // Autolock scope
            std::lock_guard<std::mutex> lock(mCore->mMutex);
            //分配正确,把graphicBuffer 与BufferSlot 进行关联
            if (error == NO_ERROR && !mCore->mIsAbandoned) {
   
                //设置生成数量
                graphicBuffer->setGenerationNumber(mCore->mGenerationNumber);
                mSlots[*outSlot].mGraphicBuffer = graphicBuffer;
            }
            //分配完成,设置变量值
            mCore->mIsAllocating = false;
            //唤醒  等待的线程,这些线程因为正在分配而进入了等待
            mCore->mIsAllocatingCondition.notify_all();

            //分配graphicBuffer 出错,把BufferSlot 插入到mFreeSlots 等操作
            if (error != NO_ERROR) {
   
                mCore->mFreeSlots.insert(*outSlot);
                mCore->clearBufferSlotLocked(*outSlot);
                BQ_LOGE("dequeueBuffer: createGraphicBuffer failed");
                return error;
            }
            //同上
            if (mCore->mIsAbandoned) {
   
                mCore->mFreeSlots.insert(*outSlot);
                mCore->clearBufferSlotLocked(*outSlot);
                BQ_LOGE("dequeueBuffer: BufferQueue has been abandoned");
                return NO_INIT;
            }

            VALIDATE_CONSISTENCY();
        } // Autolock scope
    }

    if (attachedByConsumer) {
   
        returnFlags |= BUFFER_NEEDS_REALLOCATION;
    }

    if (eglFence != EGL_NO_SYNC_KHR) {
   
        //等待Buffer状态就绪,,然后fence围栏放行
        EGLint result = eglClientWaitSyncKHR(eglDisplay, eglFence, 0,
                1000000000);
        // If something goes wrong, log the error, but return the buffer without
        // synchronizing access to it. It's too late at this point to abort the
        // dequeue operation.
        if (result == EGL_FALSE) {
   
            BQ_LOGE("dequeueBuffer: error %#x waiting for fence",
                    eglGetError());
        } else if (result == EGL_TIMEOUT_EXPIRED_KHR) {
   
            BQ_LOGE("dequeueBuffer: timeout waiting for fence");
        }
        eglDestroySyncKHR(eglDisplay, eglFence);
    }

    BQ_LOGV("dequeueBuffer: returning slot=%d/%" PRIu64 " buf=%p flags=%#x",
            *outSlot,
            mSlots[*outSlot].mFrameNumber,
            mSlots[*outSlot].mGraphicBuffer->handle, returnFlags);

    if (outBufferAge) {
   
        *outBufferAge = mCore->mBufferAge;
    }
    addAndGetFrameTimestamps(nullptr, outTimestamps);

    return returnFlags;
}

代码中都有注释,明白了主要的逻辑过程,下面我们了看看其中的函数 waitForFreeSlotThenRelock,它的作用是在mSlot数组中查找FREE状态的slot,如果找到了就返回这个slot中的index。

代码十二:
status_t BufferQueueProducer::waitForFreeSlotThenRelock(FreeSlotCaller caller,
        std::unique_lock<std::mutex>& lock, int* found) const {
   
    //是从 dequeueBuffer 还是attachBuffer 调用当前的函数
    auto callerString = (caller == FreeSlotCaller::Dequeue) ?
            "dequeueBuffer" : "attachBuffer";
    bool tryAgain = true;
    //本函数主要就是这个while循环,直到找到可用的BufferSlot 或发生错误
    while (tryAgain) {
   
        if (mCore->mIsAbandoned) {
   
            BQ_LOGE("%s: BufferQueue has been abandoned", callerString);
            return NO_INIT;
        }
        //统计mActiveBuffers中状态为DEQUEUED的BufferSlot数量
        int dequeuedCount = 0;
        //统计mActiveBuffers中状态为ACQUIRED的BufferSlot数量
        int acquiredCount = 0;
        for (int s : mCore->mActiveBuffers) {
   
            if (mSlots[s].mBufferState.isDequeued()) {
   
                ++dequeuedCount;
            }
            if (mSlots[s].mBufferState.isAcquired()) {
   
                ++acquiredCount;
            }
        }

        // Producers are not allowed to dequeue more than
        // mMaxDequeuedBufferCount buffers.
        // This check is only done if a buffer has already been queued
        if (mCore->mBufferHasBeenQueued &&
                dequeuedCount >= mCore->mMaxDequeuedBufferCount) {
   
            // Supress error logs when timeout is non-negative.
            if (mDequeueTimeout < 0) {
   
                BQ_LOGE("%s: attempting to exceed the max dequeued buffer "
                        "count (%d)", callerString,
                        mCore->mMaxDequeuedBufferCount);
            }
            return INVALID_OPERATION;
        }

        *found = BufferQueueCore::INVALID_BUFFER_SLOT;

        // If we disconnect and reconnect quickly, we can be in a state where
        // our slots are empty but we have many buffers in the queue. This can
        // cause us to run out of memory if we outrun the consumer. Wait here if
        // it looks like we have too many buffers queued up.
        // 获取BufferQueue最大buffer数量,该值一般为2 或者 3
        const int maxBufferCount = mCore->getMaxBufferCountLocked();
        // 当前队列中的Buffer 数量,是否大于maxBufferCount
        bool tooManyBuffers = mCore->mQueue.size()
                            > static_cast<size_t>(maxBufferCount);
        if (tooManyBuffers) {
   
            BQ_LOGV("%s: queue size is %zu, waiting", callerString,
                    mCore->mQueue.size());
        } else {
   
            // If in shared buffer mode and a shared buffer exists, always
            // return it.
            if (mCore->mSharedBufferMode && mCore->mSharedBufferSlot !=
                    BufferQueueCore::INVALID_BUFFER_SLOT) {
   
                *found = mCore->mSharedBufferSlot;
            } else {
   
                //不是共享buffer模式
                //是从dequeueBuffer 中调用当前函数的
                if (caller == FreeSlotCaller::Dequeue) {
   
                    
                    //优先从mFreeBuffers中寻找BufferSlot,找不到再从mFreeSlots寻找BufferSlot。
                    
                    // If we're calling this from dequeue, prefer free buffers
                    //mFreeBuffers(状态为FREE,并绑定了GraphicBuffer的BufferSlot集合)
                    //从mFreeBuffers头部获取BufferSlot ,返回的是BufferSlot的索引值
                    int slot = getFreeBufferLocked();
                    if (slot != BufferQueueCore::INVALID_BUFFER_SLOT) {
   
                        *found = slot;
                    } else if (mCore->mAllowAllocation) {
   
                       // 上面分配失败,并且BufferQueueCore 需要重新给GraphicBuffer分配内存空间
                       //mFreeSlots(状态为FREE,并没有绑定GraphicBuffer的BufferSlot集合)
                       //从mFreeSlots头部获取BufferSlot ,返回的是BufferSlot的索引值
                        *found = getFreeSlotLocked();
                    }
                } else {
   
                    //是从attachBuffer 中调用当前函数的
                    
                    // If we're calling this from attach, prefer free slots
                    int slot = getFreeSlotLocked();
                    if (slot != BufferQueueCore::INVALID_BUFFER_SLOT) {
   
                        *found = slot;
                    } else {
   
                        *found = getFreeBufferLocked();
                    }
                }
            }
        }

        // If no buffer is found, or if the queue has too many buffers
        // outstanding, wait for a buffer to be acquired or released, or for the
        // max buffer count to change.
        tryAgain = (*found == BufferQueueCore::INVALID_BUFFER_SLOT) ||
                   tooManyBuffers;
        //获取失败,或者当前的Buffer 已经到达最大值,则重试           
        if (tryAgain) {
   
            // Return an error if we're in non-blocking mode (producer and
            // consumer are controlled by the application).
            // However, the consumer is allowed to briefly acquire an extra
            // buffer (which could cause us to have to wait here), which is
            // okay, since it is only used to implement an atomic acquire +
            // release (e.g., in GLConsumer::updateTexImage())
            if ((mCore->mDequeueBufferCannotBlock || mCore->mAsyncMode) &&
                    (acquiredCount <= mCore->mMaxAcquiredBufferCount)) {
   
                return WOULD_BLOCK;
            }
            if (mDequeueTimeout >= 0) {
   
                std::cv_status result = mCore->mDequeueCondition.wait_for(lock,
                        std::chrono::nanoseconds(mDequeueTimeout));
                if (result == std::cv_status::timeout) {
   
                    return TIMED_OUT;
                }
            } else {
   
               //等待有buffer可以返回
                mCore->mDequeueCondition.wait(lock);
            }
        }
    } // while (tryAgain)

    return NO_ERROR;
}

代码中 重要语句都有注释了

5.2、消费图形缓冲区

我们再来看,缓冲区有了数据后,消费者是如何消费的

在UI绘制的draw阶段会调用 queueBuffer,详见文章Android 图形架构 之六——深入分析draw()是如何工作的

代码路径:frameworks/native/libs/gui/BufferQueueProducer.cpp

queueBuffer 的逻辑比较简单,就是把根据Surface 传进来的数据,封装一个BufferItem,放入BufferQueueCore的mQueue(生产者-消费者队列),通知SurfaceFlinger 开始消费

代码十三:
status_t BufferQueueProducer::queueBuffer(int slot,
        const QueueBufferInput &input, QueueBufferOutput *output) {
   
    ATRACE_CALL();
    ATRACE_BUFFER_INDEX(slot);

    int64_t requestedPresentTimestamp;
    bool isAutoTimestamp;
    android_dataspace dataSpace;
    Rect crop(Rect::EMPTY_RECT);
    int scalingMode;
    uint32_t transform;
    uint32_t stickyTransform;
    sp<Fence> acquireFence;
    bool getFrameTimestamps = false;
 
    //保存Surface传递过来的input里面封装的buffer信息
    input.deflate(&requestedPresentTimestamp, &isAutoTimestamp, &dataSpace,
            &crop, &scalingMode, &transform, &acquireFence, &stickyTransform,
            &getFrameTimestamps);
    const Region& surfaceDamage = input.getSurfaceDamage();
    const HdrMetadata& hdrMetadata = input.getHdrMetadata();

    ......
    //回调接口
    sp<IConsumerListener> frameAvailableListener;
    sp<IConsumerListener> frameReplacedListener;
    int callbackTicket = 0;
    uint64_t currentFrameNumber = 0;
    BufferItem item;
    {
    // Autolock scope
        std::lock_guard<std::mutex> lock(mCore->mMutex);
        //BufferQueue 是否被弃用
        if (mCore->mIsAbandoned) {
   
            BQ_LOGE("queueBuffer: BufferQueue has been abandoned");
            return NO_INIT;
        }
         
        if (mCore->mConnectedApi == BufferQueueCore::NO_CONNECTED_API) {
   
            BQ_LOGE("queueBuffer: BufferQueue has no connected producer");
            return NO_INIT;
        }
        //BufferSlot 对应的slot 是否合法,状态是否为DEQUEUE
        if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS) {
   
            BQ_LOGE("queueBuffer: slot index %d out of range [0, %d)",
                    slot, BufferQueueDefs::NUM_BUFFER_SLOTS);
            return BAD_VALUE;
        } else if (!mSlots[slot].mBufferState.isDequeued()) {
   
            BQ_LOGE("queueBuffer: slot %d is not owned by the producer "
                    "(state = %s)", slot, mSlots[slot].mBufferState.string());
            return BAD_VALUE;
        } else if (!mSlots[slot].mRequestBufferCalled) {
   
            //是否调用了requestBuffer 函数
            BQ_LOGE("queueBuffer: slot %d was queued without requesting "
                    "a buffer", slot);
            return BAD_VALUE;
        }
        // If shared buffer mode has just been enabled, cache the slot of the
        // first buffer that is queued and mark it as the shared buffer.
        if (mCore->mSharedBufferMode && mCore->mSharedBufferSlot ==
                BufferQueueCore::INVALID_BUFFER_SLOT) {
   
            mCore->mSharedBufferSlot = slot;
            mSlots[slot].mBufferState.mShared = true;
        }

        ......
        //当前queue的具体buffer
        const sp<GraphicBuffer>& graphicBuffer(mSlots[slot].mGraphicBuffer);
        //根据当前的graphicBuffer 创建矩形区域
        Rect bufferRect(graphicBuffer->getWidth(), graphicBuffer->getHeight());
        //创建裁剪区域,
        Rect croppedRect(Rect::EMPTY_RECT);
        //裁剪区域 赋值为crop和bufferRect相交部分
        crop.intersect(bufferRect, &croppedRect);
        if (croppedRect != crop) {
   
            BQ_LOGE("queueBuffer: crop rect is not contained within the "
                    "buffer in slot %d", slot);
            return BAD_VALUE;
        }

        // Override UNKNOWN dataspace with consumer default
        if (dataSpace == HAL_DATASPACE_UNKNOWN) {
   
            dataSpace = mCore->mDefaultBufferDataSpace;
        }

        mSlots[slot].mFence = acquireFence;
        //改变入队的slot的状态为QUEUED
        mSlots[slot].mBufferState.queue();

        //把mSlots(类型是BufferSlot)和 graphicBuffer ,封装为BufferItem,后续会把这个BufferItem加入到队列中

        // Increment the frame counter and store a local version of it
        // for use outside the lock on mCore->mMutex.
        ++mCore->mFrameCounter;
        currentFrameNumber = mCore->mFrameCounter;
        mSlots[slot].mFrameNumber = currentFrameNumber;

        item.mAcquireCalled = mSlots[slot].mAcquireCalled;
        item.mGraphicBuffer = mSlots[slot].mGraphicBuffer;
        item.mCrop = crop;
        item.mTransform = transform &
                ~static_cast<uint32_t>(NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY);
        item.mTransformToDisplayInverse =
                (transform & NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY) != 0;
        item.mScalingMode = static_cast<uint32_t>(scalingMode);
        item.mTimestamp = requestedPresentTimestamp;
        item.mIsAutoTimestamp = isAutoTimestamp;
        item.mDataSpace = dataSpace;
        item.mHdrMetadata = hdrMetadata;
        item.mFrameNumber = currentFrameNumber;
        item.mSlot = slot;
        item.mFence = acquireFence;
        item.mFenceTime = acquireFenceTime;
        item.mIsDroppable = mCore->mAsyncMode ||
                (mConsumerIsSurfaceFlinger && mCore->mQueueBufferCanDrop) ||
                (mCore->mLegacyBufferDrop && mCore->mQueueBufferCanDrop) ||
                (mCore->mSharedBufferMode && mCore->mSharedBufferSlot == slot);
        item.mSurfaceDamage = surfaceDamage;
        item.mQueuedBuffer = true;
        item.mAutoRefresh = mCore->mSharedBufferMode && mCore->mAutoRefresh;
        item.mApi = mCore->mConnectedApi;

        mStickyTransform = stickyTransform;

        // Cache the shared buffer data so that the BufferItem can be recreated.
        if (mCore->mSharedBufferMode) {
   
            mCore->mSharedBufferCache.crop = crop;
            mCore->mSharedBufferCache.transform = transform;
            mCore->mSharedBufferCache.scalingMode = static_cast<uint32_t>(
                    scalingMode);
            mCore->mSharedBufferCache.dataspace = dataSpace;
        }
      
        output->bufferReplaced = false;
        if (mCore->mQueue.empty()) {
   
            //如果mQueue队列为空,则直接push进入这个mQueue,不用考虑阻塞
            // When the queue is empty, we can ignore mDequeueBufferCannotBlock
            // and simply queue this buffer
            mCore->mQueue.push_back(item);
            //取出 BufferQueueCore 的回调接口,下面调用这个接口的onFrameAvailable 函数,来通知SurfaceFlinger 进行渲染
            frameAvailableListener = mCore->mConsumerListener;
        } else {
   
            // When the queue is not empty, we need to look at the last buffer
            // in the queue to see if we need to replace it
            const BufferItem& last = mCore->mQueue.itemAt(
                    mCore->mQueue.size() - 1);
            //判断最后一个BufferItem 是否可以丢弃        
            if (last.mIsDroppable) {
   

                if (!last.mIsStale) {
   
                    mSlots[last.mSlot].mBufferState.freeQueued();

                    // After leaving shared buffer mode, the shared buffer will
                    // still be around. Mark it as no longer shared if this
                    // operation causes it to be free.
                    if (!mCore->mSharedBufferMode &&
                            mSlots[last.mSlot].mBufferState.isFree()) {
   
                        mSlots[last.mSlot].mBufferState.mShared = false;
                    }
                    // Don't put the shared buffer on the free list.
                    if (!mSlots[last.mSlot].mBufferState.isShared()) {
   
                        mCore->mActiveBuffers.erase(last.mSlot);
                        mCore->mFreeBuffers.push_back(last.mSlot);
                        output->bufferReplaced = true;
                    }
                }

                // Overwrite the droppable buffer with the incoming one
                //用当前BufferItem,替换了队列最后一个BufferItem
                mCore->mQueue.editItemAt(mCore->mQueue.size() - 1) = item;
                //取出回调接口,因为是替换,所以 后续调用接口的函数 onFrameReplaced
                frameReplacedListener = mCore->mConsumerListener;
            } else {
   
                //与队列为空的逻辑一样
                mCore->mQueue.push_back(item);
                frameAvailableListener = mCore->mConsumerListener;
            }
        }
        // 表示 buffer已经queued,此时入队完成
        mCore->mBufferHasBeenQueued = true;
        // mDequeueCondition是C++条件变量用作等待/唤醒,这里调用notify_all会唤醒调用了wait的线程
        // 例如:在代码十二中 倒数第7行,就等待在这个变量上,当一块buffer被queued之后,就可以继续dequeue了
        mCore->mDequeueCondition.notify_all();
        mCore->mLastQueuedSlot = slot;
        
        //output 参数,会在Surface中继续使用
        output->width = mCore->mDefaultWidth;
        output->height = mCore->mDefaultHeight;
        output->transformHint = mCore->mTransformHint;
        output->numPendingBuffers = static_cast<uint32_t>(mCore->mQueue.size());
        output->nextFrameNumber = mCore->mFrameCounter + 1;

        ......
    } // Autolock scope

    ......

    {
    // scope for the lock
        std::unique_lock<std::mutex> lock(mCallbackMutex);
        while (callbackTicket != mCurrentCallbackTicket) {
   
            mCallbackCondition.wait(lock);
        }
        //通知SurfaceFlinger 进行渲染,此处调用接口的不同,是有上面,是否替换最后一个BufferItem 决定的
        if (frameAvailableListener != nullptr) {
   
            frameAvailableListener->onFrameAvailable(item);
        } else if (frameReplacedListener != nullptr) {
   
            frameReplacedListener->onFrameReplaced(item);
        }

        connectedApi = mCore->mConnectedApi;
        lastQueuedFence = std::move(mLastQueueBufferFence);

        mLastQueueBufferFence = std::move(acquireFence);
        mLastQueuedCrop = item.mCrop;
        mLastQueuedTransform = item.mTransform;

        ++mCurrentCallbackTicket;
        mCallbackCondition.notify_all();
    }
    ......

    return NO_ERROR;
}

到此queueBuffer 就分析完了。其中会调用了 mCore->mConsumerListener; 的回调接口,来通知SurfaceFlinger 消费数据,那么这个回调接口是在何时被传入的,接口的是什么?

从图二可以看出,app进程和surfaceFlinger进程的通信(这里指通知类消息)通过Binder实现,所以该接口mConsumerListener 需要支持进程通信。这里我们先分析数据已经传输到surfaceFlinger进程 后,BufferQueueCore 开始处理数据。

创建Layer的时候,会创建BufferQueueLayer,详见文章 Android 图形架构 之三—— 创建Layer、Surface、SurfaceControl中代码六

在BufferQueueLayer 第一次被引用的时候,执行到onFirstRef,在这里创建了监听

文件路径:frameworks/native/services/surfaceflinger/BufferQueueLayer.cpp

代码十四:
void BufferQueueLayer::onFirstRef() {
   
    BufferLayer::onFirstRef();

    // Creates a custom BufferQueue for SurfaceFlingerConsumer to use
    //创建了生产者和消费者缓冲区,这两个缓冲区将来会存放UI的内容数据
    sp<IGraphicBufferProducer> producer;
    sp<IGraphicBufferConsumer> consumer;
    //BufferQueue创建图形缓冲区管理成员,这里为producer、consumer 赋值
    BufferQueue::createBufferQueue(&producer, &consumer, true);
    //new 一个 生成者,它继承了BnGraphicBufferProducer,MonitoredProducer只是一个代理类,真正的实现是producer参数。
    // *gbp 就是mProducer
    mProducer = new MonitoredProducer(producer, mFlinger, this);
    {
   
        // Grab the SF state lock during this since it's the only safe way to access RenderEngine
        Mutex::Autolock lock(mFlinger->mStateLock);
        //new 一个 消费者,
        mConsumer = new BufferLayerConsumer(consumer, mFlinger->getRenderEngine(), mTextureName, this);
    }
    //消费者相关设置
    mConsumer->setConsumerUsageBits(getEffectiveUsage(0));
    // 设置回调,从 ConsumerListener 回调到  Layer 层 ContentsChangedListener
    mConsumer->setContentsChangedListener(this);
    mConsumer->setName(mName);

    // BufferQueueCore::mMaxDequeuedBufferCount is default to 1
    if (!mFlinger->isLayerTripleBufferingDisabled()) {
   
        //如果不是三级缓冲,就使用两级缓冲
        mProducer->setMaxDequeuedBufferCount(2);
    }
    //获取默认显示器
    if (const auto display = mFlinger->getDefaultDisplayDevice()) {
   
        //
        updateTransformHint(display);
    }
}

在BufferQueueLayer 对象第一次被引用的时候,会创建BufferQueue 和 BufferLayerConsumer

BufferLayerConsumer 就是用来消费缓冲区内容的,它继承了ConsumerBase, 后者继承了ConsumerListener(代码九),当缓冲区中有数据的时候,BufferQueueCore就会调用接口中的onFrameAvailable。总体思路清楚了,那么就来看看这个回调是如何设置到BufferQueueCore中去的

先来看看ConsumerBase的构造函数

代码十五:
class ConsumerBase : public virtual RefBase,
        protected ConsumerListener 
代码十六:
ConsumerBase::ConsumerBase(const sp<IGraphicBufferConsumer>& bufferQueue, bool controlledByApp) :
        mAbandoned(false),
        mConsumer(bufferQueue),
        mPrevFinalReleaseFence(Fence::NO_FENCE) {
   
    // Choose a name using the PID and a process-unique ID.
    mName = String8::format("unnamed-%d-%d", getpid(), createProcessUniqueId());

    // Note that we can't create an sp<...>(this) in a ctor that will not keep a
    // reference once the ctor ends, as that would cause the refcount of 'this'
    // dropping to 0 at the end of the ctor.  Since all we need is a wp<...>
    // that's what we create.
    //创建监听者对象,因为ConsumerBase 继承了 ConsumerListener,所以这里参数是this
    wp<ConsumerListener> listener = static_cast<ConsumerListener*>(this);
    //包装成一个代理
    sp<IConsumerListener> proxy = new BufferQueue::ProxyConsumerListener(listener);
     //mConsumer 就是BufferQueueConsumer,它在这里创建 :代码十四第十行 -> 代码一 
     //调用它的consumerConnect函数,通过mConsumer,把consumerListener注册到服务者类bufferQueuecore中
   
    status_t err = mConsumer->consumerConnect(proxy, controlledByApp);
    if (err != NO_ERROR) {
   
        CB_LOGE("ConsumerBase: error connecting to BufferQueue: %s (%d)",
                strerror(-err), err);
    } else {
   
        mConsumer->setConsumerName(mName);
    }
}

接着看看BufferQueueConsumer的consumerConnect函数:

文件路径frameworks/native/libs/gui/include/gui/BufferQueueConsumer.h

代码十七:
    virtual status_t consumerConnect(const sp<IConsumerListener>& consumer,
            bool controlledByApp) {
   
        return connect(consumer, controlledByApp);
    }

文件路径:frameworks/native/libs/gui/BufferQueueConsumer.cpp

代码十八:
status_t BufferQueueConsumer::connect(
        const sp<IConsumerListener>& consumerListener, bool controlledByApp) {
   
    ATRACE_CALL();

    if (consumerListener == nullptr) {
   
        BQ_LOGE("connect: consumerListener may not be NULL");
        return BAD_VALUE;
    }

    BQ_LOGV("connect: controlledByApp=%s",
            controlledByApp ? "true" : "false");

    std::lock_guard<std::mutex> lock(mCore->mMutex);

    if (mCore->mIsAbandoned) {
   
        BQ_LOGE("connect: BufferQueue has been abandoned");
        return NO_INIT;
    }
	//在这里处理接口,设置到了BufferQueueCore中
    mCore->mConsumerListener = consumerListener;
    mCore->mConsumerControlledByApp = controlledByApp;

    return NO_ERROR;
}

那么问题又来了,数据最终是要到Layer层去处理的,应该把这个事件 在传递到Layer中去,这是怎样的实现的呢?

接着回到代码十一往下分析,来到mConsumer->setContentsChangedListener(this);

BufferQueueLayer 的头文件中,可以看到,它是继承了ContentsChangedListener,所以上面的参数可以传入this

代码十九:
class BufferQueueLayer : public BufferLayer, public BufferLayerConsumer::ContentsChangedListener

文件路径:frameworks/native/services/surfaceflinger/BufferLayerConsumer.cpp

代码二十:
void BufferLayerConsumer::setContentsChangedListener(const wp<ContentsChangedListener>& listener) {
   
    //该函数是父类ConsumerBase中实现的
    setFrameAvailableListener(listener);
    Mutex::Autolock lock(mMutex);
    mContentsChangedListener = listener;
}

来看看ConsumerBase中的setFrameAvailableListener

文件路径:frameworks/native/libs/gui/ConsumerBase.cpp

代码二十一:
void ConsumerBase::setFrameAvailableListener(
        const wp<FrameAvailableListener>& listener) {
   
    CB_LOGV("setFrameAvailableListener");
    Mutex::Autolock lock(mFrameAvailableMutex);
    mFrameAvailableListener = listener;
}

onFrameAvailable 被调用后,会调用mFrameAvailableListener 接口中的onFrameAvailable

代码二十二:
void ConsumerBase::onFrameAvailable(const BufferItem& item) {
   
    CB_LOGV("onFrameAvailable");

    sp<FrameAvailableListener> listener;
    {
    // scope for the lock
        Mutex::Autolock lock(mFrameAvailableMutex);
        listener = mFrameAvailableListener.promote();
    }

    if (listener != nullptr) {
   
        CB_LOGV("actually calling onFrameAvailable");
        listener->onFrameAvailable(item);
    }
}

最终会调用到acquireBuffer 获取一个缓冲区,通过SurfaceFlinger 进行合成,最后再释放

逻辑看上去有点复杂,主要是因为这几个类名太相似,再总结一下:

  1. 向 BufferQueueCore 设置回调接口 ConsumerListener
  2. 向 ConsumerBase 设置回调接口 ContentsChangedListener
  3. 有可用数据 BufferQueueCore -> ConsumerBase#onFrameAvailable() -> ContentsChangedListener#onFrameAvailable()

参考:

AndroidQ 图形系统(3)dequeueBuffer函数分析

Android 图形显示简述

Android SurfaceFlinger 学习之路(七)----创建图形缓冲区GraphicBuffer
Android P 图形显示系统(六) SurfaceFlinger合成流程(一)

Android 图形显示框架


转载:https://blog.csdn.net/xx326664162/article/details/109029695
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场