0 引言
在Android图形框架之SurfaceComposerClient 提交事务过程中,构建了通过SurfaceControl构建了一个事务Transaction,并将该事务提交给SurfaceFlinger进行处理。接下来我们将创建一个BLASTBufferQueue。
在 Android 图形框架中,BLASTBufferQueue 是一个与 SurfaceFlinger 配合使用的组件,它处理多个图层的缓冲区交换和合成。BLASTBufferQueue 是 SurfaceFlinger 中用于实现 BufferQueue 功能的一个关键部分,它支持高效的缓冲区管理,并帮助 SurfaceFlinger 实现低延迟的图层合成和显示。
下面是本文即将分析的代码:
sp<BLASTBufferQueue> mBlastBufferQueue = new BLASTBufferQueue("DemoBLASTBufferQueue", surfaceControl ,
resolution.getWidth(), resolution.getHeight(),
PIXEL_FORMAT_RGBA_8888);
1 BLASTBufferQueue类
首先来看看BLASTBufferQueue类的定义:
class BLASTBufferQueue : public ConsumerBase::FrameAvailableListener {
public:
BLASTBufferQueue(const std::string& name, const sp<SurfaceControl>& surface, int width,
int height, int32_t format);
sp<IGraphicBufferProducer> getIGraphicBufferProducer() const {
return mProducer;
}
sp<Surface> getSurface(bool includeSurfaceControlHandle);
void update(const sp<SurfaceControl>& surface, uint32_t width, uint32_t height, int32_t format);
private:
sp<IGraphicBufferConsumer> mConsumer;
sp<IGraphicBufferProducer> mProducer;
sp<BLASTBufferItemConsumer> mBufferItemConsumer;
可以看到BLASTBufferQueue是继承自FrameAvailableListener的一个类,而FrameAvailableListener 是一个接口类,定义了与缓冲区项(BufferItem)相关的回调方法。它继承自 RefBase,并包含多个纯虚函数,这些函数通常用于在消费端接收到帧或缓冲区项时进行处理。它的定义如下:
struct FrameAvailableListener : public virtual RefBase {
// See IConsumerListener::onFrame{Available,Replaced}
virtual void onFrameAvailable(const BufferItem& item) = 0;
virtual void onFrameReplaced(const BufferItem& /* item */) {}
virtual void onFrameDequeued(const uint64_t){};
virtual void onFrameCancelled(const uint64_t){};
virtual void onFrameDetached(const uint64_t){};
};
创建BLASTBufferQueue首先调用的是它的构造函数,如下:
BLASTBufferQueue::BLASTBufferQueue(const std::string& name, const sp<SurfaceControl>& surface,
int width, int height, int32_t format)
: BLASTBufferQueue(name) {
update(surface, width, height, format);
}
从构造函数中可以看到,首先会调用一个重载的BLASTBufferQueue(name)构造函数,然后再调用函数update,它将根据参数surface、width、height和format来完成内部更新。首先看一下这个重载的构造函数:
2 BLASTBufferQueue(name)构造函数
BLASTBufferQueue构造函数主要完成BufferQueue的初始化,以及创建一个BLASTBufferItemConsumer,其他的则是基本参数配置。
BLASTBufferQueue::BLASTBufferQueue(const std::string& name, bool updateDestinationFrame)
: mSurfaceControl(nullptr),
mSize(1, 1),
mRequestedSize(mSize),
mFormat(PIXEL_FORMAT_RGBA_8888),
mTransactionReadyCallback(nullptr),
mSyncTransaction(nullptr),
mUpdateDestinationFrame(updateDestinationFrame) {
// 调用createBufferQueue创建生产者和消费者端对象
createBufferQueue(&mProducer, &mConsumer);
// since the adapter is in the client process, set dequeue timeout
// explicitly so that dequeueBuffer will block
mProducer->setDequeueTimeout(std::numeric_limits<int64_t>::max());
// safe default, most producers are expected to override this
mProducer->setMaxDequeuedBufferCount(2);
mBufferItemConsumer = new BLASTBufferItemConsumer(mConsumer,
GraphicBuffer::USAGE_HW_COMPOSER |
GraphicBuffer::USAGE_HW_TEXTURE,
1, false, this);
static std::atomic<uint32_t> nextId = 0;
mProducerId = nextId++;
mName = name + "#" + std::to_string(mProducerId);
auto consumerName = mName + "(BLAST Consumer)" + std::to_string(mProducerId);
mQueuedBufferTrace = "QueuedBuffer - " + mName + "BLAST#" + std::to_string(mProducerId);
mBufferItemConsumer->setName(String8(consumerName.c_str()));
mBufferItemConsumer->setFrameAvailableListener(this);
ComposerServiceAIDL::getComposerService()->getMaxAcquiredBufferCount(&mMaxAcquiredBuffers);
mBufferItemConsumer->setMaxAcquiredBufferCount(mMaxAcquiredBuffers);
mCurrentMaxAcquiredBufferCount = mMaxAcquiredBuffers;
mNumAcquired = 0;
mNumFrameAvailable = 0;
TransactionCompletedListener::getInstance()->addQueueStallListener(
[&](const std::string& reason) {
std::function<void(const std::string&)> callbackCopy;
{
std::unique_lock _lock{mMutex};
callbackCopy = mTransactionHangCallback;
}
if (callbackCopy) callbackCopy(reason);
},
this);
BQA_LOGV("BLASTBufferQueue created");
}
2.1 createBufferQueue函数
下面的代码比较简洁易懂,它分别new了三个对象:BufferQueueCore、BBQBufferQueueProducer和BufferQueueConsumer。
void BLASTBufferQueue::createBufferQueue(sp<IGraphicBufferProducer>* outProducer,
sp<IGraphicBufferConsumer>* outConsumer) {
LOG_ALWAYS_FATAL_IF(outProducer == nullptr, "BLASTBufferQueue: outProducer must not be NULL");
LOG_ALWAYS_FATAL_IF(outConsumer == nullptr, "BLASTBufferQueue: outConsumer must not be NULL");
// 创建BufferQueueCore
sp<BufferQueueCore> core(new BufferQueueCore());
LOG_ALWAYS_FATAL_IF(core == nullptr, "BLASTBufferQueue: failed to create BufferQueueCore");
// 创建BBQBufferQueueProducer
sp<IGraphicBufferProducer> producer(new BBQBufferQueueProducer(core, this));
LOG_ALWAYS_FATAL_IF(producer == nullptr,
"BLASTBufferQueue: failed to create BBQBufferQueueProducer");
// 创建BufferQueueConsumer
sp<BufferQueueConsumer> consumer(new BufferQueueConsumer(core));
consumer->setAllowExtraAcquire(true);
LOG_ALWAYS_FATAL_IF(consumer == nullptr,
"BLASTBufferQueue: failed to create BufferQueueConsumer");
*outProducer = producer;
*outConsumer = consumer;
}
2.1.1 创建 BufferQueueCore
BufferQueueCore::BufferQueueCore 是 BufferQueue 核心部分的构造函数,它初始化了内部数据结构和状态变量。这些变量用于管理缓冲区的分配、释放、排队、消费等操作。
BufferQueueCore::BufferQueueCore()
: mMutex(),
mIsAbandoned(false),
mConsumerControlledByApp(false),
mConsumerName(getUniqueName()),
mConsumerListener(),
mConsumerUsageBits(0),
mConsumerIsProtected(false),
mConnectedApi(NO_CONNECTED_API),
mLinkedToDeath(),
mConnectedProducerListener(),
mBufferReleasedCbEnabled(false),
mSlots(),
mQueue(),
mFreeSlots(),
mFreeBuffers(),
mUnusedSlots(),
mActiveBuffers(),
mDequeueCondition(),
mDequeueBufferCannotBlock(false),
mQueueBufferCanDrop(false),
mLegacyBufferDrop(true),
mDefaultBufferFormat(PIXEL_FORMAT_RGBA_8888),
mDefaultWidth(1),
mDefaultHeight(1),
mDefaultBufferDataSpace(HAL_DATASPACE_UNKNOWN),
mMaxBufferCount(BufferQueueDefs::NUM_BUFFER_SLOTS),
mMaxAcquiredBufferCount(1),
mMaxDequeuedBufferCount(1),
mBufferHasBeenQueued(false),
mFrameCounter(0),
mTransformHint(0),
mIsAllocating(false),
mIsAllocatingCondition(),
mAllowAllocation(true),
mBufferAge(0),
mGenerationNumber(0),
mAsyncMode(false),
mSharedBufferMode(false),
mAutoRefresh(false),
mSharedBufferSlot(INVALID_BUFFER_SLOT),
mSharedBufferCache(Rect::INVALID_RECT, 0, NATIVE_WINDOW_SCALING_MODE_FREEZE,
HAL_DATASPACE_UNKNOWN),
mLastQueuedSlot(INVALID_BUFFER_SLOT),
mUniqueId(getUniqueId()),
mAutoPrerotation(false),
mTransformHintInUse(0) {
int numStartingBuffers = getMaxBufferCountLocked();
for (int s = 0; s < numStartingBuffers; s++) {
mFreeSlots.insert(s);
}
for (int s = numStartingBuffers; s < BufferQueueDefs::NUM_BUFFER_SLOTS;
s++) {
mUnusedSlots.push_front(s);
}
}
上面的构造函数太多初始化变量了,我们找到最关键的几个:
BufferQueueDefs::SlotsType mSlots; // 等同于 BufferSlot[64] mSlots
Fifo mQueue; // 等同于 Vector<BufferItem> mQueue
std::set<int> mFreeSlots;
std::list<int> mFreeBuffers;
std::list<int> mUnusedSlots;
std::set<int> mActiveBuffers;
SlotsType的原类型为BufferSlot[NUM_BUFFER_SLOTS](64),因此mSlots为大小为64的BufferSlot类型数组,Fifo的原类型为Vector<BufferItem>,因此mQueue为存放BufferItem的数组。
因此我们先去看一下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指向一个GraphicBuffer
sp<GraphicBuffer> mGraphicBuffer;
// mEglDisplay is the EGLDisplay used to create EGLSyncKHR objects.
EGLDisplay mEglDisplay;
// 定义buffer slot的当前状态,有五种状态:.FREE DEQUEUED QUEUED ACQUIRED SHARED
BufferState mBufferState;
// 用于调试,确保生产者调用了 requestBuffer()
bool mRequestBufferCalled;
// 该slot对应帧队列的帧编号
uint64_t mFrameNumber;
// 已废弃,被mFence替代
EGLSyncKHR mEglFence;
// 用于指示生产者是否完成了对buffer的写操作,或者消费者是否完成对buffer的读操作
sp<Fence> mFence;
// 用于指示该buffer是否已被消费者获取
bool mAcquireCalled;
// 指示该buffer是否需要在没有通知生产者的情况下被重新分配,如果是,则在出队时需要标记为true。
bool mNeedsReallocation;
};
从代码和注释中可以看到,这里主要是定义了buffer的状态和行为模式。我们深入看一下BufferState这个类:
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;
inline bool isFree() const {
return !isAcquired() && !isDequeued() && !isQueued();
}
inline bool isDequeued() const {
return mDequeueCount > 0;
}
inline bool isQueued() const {
return mQueueCount > 0;
}
inline bool isAcquired() const {
return mAcquireCount > 0;
}
inline bool isShared() const {
return mShared;
}
inline void reset() {
*this = BufferState();
}
const char* string() const;
inline void dequeue() {
mDequeueCount++;
}
inline void detachProducer() {
if (mDequeueCount > 0) {
mDequeueCount--;
}
}
inline void attachProducer() {
mDequeueCount++;
}
inline void queue() {
if (mDequeueCount > 0) {
mDequeueCount--;
}
mQueueCount++;
}
inline void cancel() {
if (mDequeueCount > 0) {
mDequeueCount--;
}
}
inline void freeQueued() {
if (mQueueCount > 0) {
mQueueCount--;
}
}
inline void acquire() {
if (mQueueCount > 0) {
mQueueCount--;
}
mAcquireCount++;
}
inline void acquireNotInQueue() {
mAcquireCount++;
}
inline void release() {
if (mAcquireCount > 0) {
mAcquireCount--;
}
}
inline void detachConsumer() {
if (mAcquireCount > 0) {
mAcquireCount--;
}
}
inline void attachConsumer() {
mAcquireCount++;
}
};
BufferState定义了五个状态,它们可以用下面这张表表示:
| 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 |
同样的,根据上面的代码可以总结出下面这张状态机演示:
大致解释一下这个状态机:通常情况下,初始buffer的状态为FREE,当对它执行dequeue操作后,它会进入DEQUEUED状态,此时Producer可以对buffer进行写入操作。Producer写完数据后,对该buffer执行queue操作,进入QUEUED状态。这个时候如果有Consumer想要读取该buffer的数据,可以对其进行acquire操作,此时buffer进入ACQUIRED状态。当Consumer读取完数据后,可以进行release操作,将buffer重新变为FREE状态。
当然buffer还有一些其他的操作,这里不详细讨论。
下面讲一下Fifo mQueue,即Fifo其实是Vector<BufferItem> 的别名。看一下BufferItem的定义:
class BufferItem : public Flattenable<BufferItem> {
friend class Flattenable<BufferItem>;
size_t getPodSize() const;
size_t getFlattenedSize() const;
size_t getFdCount() const;
status_t flatten(void*& buffer, size_t& size, int*& fds, size_t& count) const;
status_t unflatten(void const*& buffer, size_t& size, int const*& fds, size_t& count);
public:
// The default value of mBuf, used to indicate this doesn't correspond to a slot.
enum { INVALID_BUFFER_SLOT = -1 };
BufferItem();
~BufferItem();
BufferItem(const BufferItem&) = default;
BufferItem& operator=(const BufferItem&) = default;
static const char* scalingModeName(uint32_t scalingMode);
// 指向一个GraphicBuffer,和BufferSlot一样
sp<GraphicBuffer> mGraphicBuffer;
// 用于指示buffer何时处于空闲状态
sp<Fence> mFence;
// 用于表示buffer的时间戳
std::shared_ptr<FenceTime> mFenceTime{FenceTime::NO_FENCE};
// 用于表示buffer的裁剪矩形区域
Rect mCrop;
// 用于表示buffer的变换标志(旋转、镜像)
uint32_t mTransform;
// 用于表示buffer的缩放模式
uint32_t mScalingMode;
// 表示buffer的时间戳
int64_t mTimestamp;
// 指示时间戳是否由系统自动生成
bool mIsAutoTimestamp;
// 表示buffer的色彩空间
android_dataspace mDataSpace;
// 表示buffer的HDR元数据
HdrMetadata mHdrMetadata;
// buffer所属帧的编号
uint64_t mFrameNumber;
// buffer所在slot的索引
int mSlot;
// 该buffer是否可丢弃
bool mIsDroppable;
// 该buffer是否已被消费者获取
bool mAcquireCalled;
// 指示是否应将buffer逆转以适应显示屏
bool mTransformToDisplayInverse;
// 描述自上一帧以来已修改的surface区域。
Region mSurfaceDamage;
// 指示消费者是否应尽早获取下一帧,不等待缓冲区变得可用,仅在共享缓冲区模式下有效。
bool mAutoRefresh;
// 指示该缓冲区是否已由生产者排队
bool mQueuedBuffer;
// 指示该缓冲区是否已经被release
bool mIsStale;
// 指示buffer的API类型
int mApi;
};
可以看到BufferItem 和 BufferSlot 比较类似,尤其是它们内部都有一个智能指针sp<GraphicBuffer> mGraphicBuffer,可以指向一个GraphicBuffer。而slot也是通过它来进行区分,例如:mFreeSlot指的是mGraphicBuffer为null且BufferState为FREE的BufferSlot;mFreeBuffers指的是mGraphicBuffer不为null
但BufferState为FREE的BufferSlot;mUnusedSlots指的是尚未参与使用的BufferSlot;mActiveBuffers指的是mGraphicBuffer不为null且BufferState不为FREE的BufferSlot。
根据上面的分析总结成下面这张表格:
| 成员变量 | 含义 |
|---|---|
| mSlots | SlotsType的原类型为BufferSlot[NUM_BUFFER_SLOTS](64),因此mSlots为大小为64的BufferSlot类型数组 |
| mQueue | Fifo的原类型为Vector<BufferItem>,因此mQueue为存放BufferItem的数组 |
| mFreeSlots | mFreeSlot指的是mGraphicBuffer为null且BufferState为FREE的BufferSlot |
| mFreeBuffers | mFreeBuffers指的是mGraphicBuffer不为null但BufferState为FREE的BufferSlot |
| mUnusedSlots | mUnusedSlots指的是尚未参与使用的BufferSlot |
| mActiveBuffers | mActiveBuffers指的是mGraphicBuffer不为null且BufferState不为FREE的BufferSlot |
2.1.2 创建 BBQBufferQueueProducer
BBQBufferQueueProducer顾名思义是buffer的消费者,它的构造函数如下:
BBQBufferQueueProducer(const sp<BufferQueueCore>& core, wp<BLASTBufferQueue> bbq)
: BufferQueueProducer(core, false /* consumerIsSurfaceFlinger*/),
mBLASTBufferQueue(std::move(bbq)) {}
BufferQueueProducer::BufferQueueProducer(const sp<BufferQueueCore>& core,
bool consumerIsSurfaceFlinger) :
mCore(core),
mSlots(core->mSlots),
mConsumerName(),
mStickyTransform(0),
mConsumerIsSurfaceFlinger(consumerIsSurfaceFlinger),
mLastQueueBufferFence(Fence::NO_FENCE),
mLastQueuedTransform(0),
mCallbackMutex(),
mNextCallbackTicket(0),
mCurrentCallbackTicket(0),
mCallbackCondition(),
mDequeueTimeout(-1),
mDequeueWaitingForAllocation(false) {}
从上述代码可以看出,BBQBufferQueueProducer主要通过前面创建的BufferQueueCore类对应的实例core来初始化变量mCore和mSlots。我们再来看看BBQBufferQueueProducer 类的定义,它是继承并扩展 BufferQueueProducer 的一个类。
#ifndef NO_BINDER
class BufferQueueProducer : public BnGraphicBufferProducer,
private IBinder::DeathRecipient {
#else
class BufferQueueProducer : public BnGraphicBufferProducer {
#endif
public:
friend class BufferQueue;
explicit BufferQueueProducer(const sp<BufferQueueCore>& core,
bool consumerIsSurfaceFlinger = false);
~BufferQueueProducer() override;
// 从某个slot中请求一个buffer
virtual status_t requestBuffer(int slot, sp<GraphicBuffer>* buf);
// 设置最大可出队缓冲区的数量
virtual status_t setMaxDequeuedBufferCount(int maxDequeuedBuffers);
// 设置队列是否工作在异步模式
virtual status_t setAsyncMode(bool async);
// 从某个slot中分离一个buffer
virtual status_t detachBuffer(int slot);
virtual status_t detachNextBuffer(sp<GraphicBuffer>* outBuffer,
sp<Fence>* outFence);
// 从某个slot中加入一个buffer
virtual status_t attachBuffer(int* outSlot, const sp<GraphicBuffer>& buffer);
// 将某个slot中的buffer加入到队列中
virtual status_t queueBuffer(int slot,
const QueueBufferInput& input, QueueBufferOutput* output);
// 取消对一个buffer的操作
virtual status_t cancelBuffer(int slot, const sp<Fence>& fence);
// 将生产者连接到 BufferQueue
virtual status_t connect(const sp<IProducerListener>& listener,
int api, bool producerControlledByApp, QueueBufferOutput* output);
// 断开生产者与 BufferQueue的连接
virtual status_t disconnect(int api, DisconnectMode mode = DisconnectMode::Api);
virtual String8 getConsumerName() const override;
// 设置共享缓冲区模式
virtual status_t setSharedBufferMode(bool sharedBufferMode) override;
// 设置自动刷新
virtual status_t setAutoRefresh(bool autoRefresh) override;
protected:
status_t setMaxDequeuedBufferCount(int maxDequeuedBuffers, int* maxBufferCount);
private:
sp<BufferQueueCore> mCore;
BufferQueueDefs::SlotsType& mSlots;
String8 mConsumerName;
};
从上面的代码中可以看到BufferQueueProducer类定义了许多虚函数,例如requestBuffer、detachBuffer、attachBuffer和queueBuffer等等。这些接口用于对slot中的buffer进行各种操作。
2.1.3 创建 BufferQueueConsumer
BufferQueueConsumer顾名思义是buffer的消费者,它继承自BnGraphicBufferConsumer类,它的构造函数更加简单一些:
BufferQueueConsumer::BufferQueueConsumer(const sp<BufferQueueCore>& core) :
mCore(core),
mSlots(core->mSlots),
mConsumerName() {}
我们再来看看BufferQueueConsumer类的定义:
class BufferQueueConsumer : public BnGraphicBufferConsumer {
public:
explicit BufferQueueConsumer(const sp<BufferQueueCore>& core);
~BufferQueueConsumer() override;
// 请求一个BufferItem
virtual status_t acquireBuffer(BufferItem* outBuffer,
nsecs_t expectedPresent, uint64_t maxFrameNumber = 0) override;
// 将某个slot从队列中分离
virtual status_t detachBuffer(int slot);
// 将buffer添加到某个槽中
virtual status_t attachBuffer(int* slot, const sp<GraphicBuffer>& buffer);
// 释放某个slot,以便生产者可以重新使用
virtual status_t releaseBuffer(int slot, uint64_t frameNumber,
const sp<Fence>& releaseFence, EGLDisplay display,
EGLSyncKHR fence);
// 连接消费者到BufferQueue,使其能够获取缓冲区。
virtual status_t connect(const sp<IConsumerListener>& consumerListener,
bool controlledByApp);
// 断开消费者与BufferQueue的连接
virtual status_t disconnect();
// 获取已经被释放但尚未重新分配的slot的掩码
virtual status_t getReleasedBuffers(uint64_t* outSlotMask);
// 设置buffer的默认尺寸
virtual status_t setDefaultBufferSize(uint32_t width, uint32_t height);
// 调整BufferQueue的容量
virtual status_t setMaxBufferCount(int bufferCount);
// 设置消费者可以同时获取的最大buffer数量
virtual status_t setMaxAcquiredBufferCount(int maxAcquiredBuffers);
status_t setConsumerName(const String8& name) override;
// 连接消费者和BufferQueue
virtual status_t consumerConnect(const sp<IConsumerListener>& consumer,
bool controlledByApp) {
return connect(consumer, controlledByApp);
}
// 断开消费者和BufferQueue的连接
virtual status_t consumerDisconnect() { return disconnect(); }
private:
sp<BufferQueueCore> mCore;
// This references mCore->mSlots. Lock mCore->mMutex while accessing.
BufferQueueDefs::SlotsType& mSlots;
String8 mConsumerName;
};
BufferQueueConsumer 提供了消费者端缓冲区管理的完整功能:
- 缓冲区获取与释放:
acquireBuffer、releaseBuffer、detachBuffer、attachBuffer - 队列配置与控制:
setMaxBufferCount、setDefaultBufferSize。 - 连接与状态管理:
consumerConnect、consumerDisconnect
与生产者类似,消费者通过这些接口高效管理缓冲区,确保图形系统中的帧数据流畅传递。
2.2 new BLASTBufferItemConsumer
当BufferQueueCore、BBQBufferQueueProducer、BufferQueueConsumer都创建好后,createBufferQueue函数也就执行完毕了。让我们回到BLASTBufferQueue的构造函数中,继续往下看非常重要的内容就是BLASTBufferItemConsumer的初始化了:
mBufferItemConsumer = new BLASTBufferItemConsumer(mConsumer,
GraphicBuffer::USAGE_HW_COMPOSER |
GraphicBuffer::USAGE_HW_TEXTURE,
1, false, this);
BLASTBufferItemConsumer的构造函数如下:
BLASTBufferItemConsumer(const sp<IGraphicBufferConsumer>& consumer, uint64_t consumerUsage,
int bufferCount, bool controlledByApp, wp<BLASTBufferQueue> bbq)
: BufferItemConsumer(consumer, consumerUsage, bufferCount, controlledByApp),
mBLASTBufferQueue(std::move(bbq)),
mCurrentlyConnected(false),
mPreviouslyConnected(false) {}
BLASTBufferItemConsumer继承自BufferItemConsumer,因此它的构造函数实际上就是对BufferItemConsumer的构造,以及初始化mBLASTBufferQueue。接下来将重点分析BufferItemConsumer类。
BufferItemConsumer的类定义代码如下:
class BufferItemConsumer: public ConsumerBase
{
public:
typedef ConsumerBase::FrameAvailableListener FrameAvailableListener;
// 定义了一个监听接口:用于监听buffer状态变为FREE的情况
struct BufferFreedListener : public virtual RefBase {
virtual void onBufferFreed(const wp<GraphicBuffer>& graphicBuffer) = 0;
};
enum { DEFAULT_MAX_BUFFERS = -1 }; // 默认最大buffer数量
enum { INVALID_BUFFER_SLOT = BufferQueue::INVALID_BUFFER_SLOT };
enum { NO_BUFFER_AVAILABLE = BufferQueue::NO_BUFFER_AVAILABLE };
BufferItemConsumer(const sp<IGraphicBufferConsumer>& consumer,
uint64_t consumerUsage, int bufferCount = DEFAULT_MAX_BUFFERS,
bool controlledByApp = false);
~BufferItemConsumer() override;
// 设置buffer空闲监听器
void setBufferFreedListener(const wp<BufferFreedListener>& listener);
// 获取一个可用的BufferItem
status_t acquireBuffer(BufferItem* item, nsecs_t presentWhen,
bool waitForFence = true);
// 释放当前的BufferItem
status_t releaseBuffer(const BufferItem &item,
const sp<Fence>& releaseFence = Fence::NO_FENCE);
private:
void freeBufferLocked(int slotIndex) override;
wp<BufferFreedListener> mBufferFreedListener;
};
从上面的代码中可以知道BufferItemConsumer可以获取BufferItem然后进行使用,它是BLASTBufferQueue的消费者。
3 update函数
void BLASTBufferQueue::update(const sp<SurfaceControl>& surface, uint32_t width, uint32_t height,
int32_t format) {
LOG_ALWAYS_FATAL_IF(surface == nullptr, "BLASTBufferQueue: mSurfaceControl must not be NULL");
std::lock_guard _lock{mMutex};
// 更新格式
if (mFormat != format) {
mFormat = format;
mBufferItemConsumer->setDefaultBufferFormat(convertBufferFormat(format));
}
// 判断SurfaceControl是否发生变化
const bool surfaceControlChanged = !SurfaceControl::isSameSurface(mSurfaceControl, surface);
if (surfaceControlChanged && mSurfaceControl != nullptr) {
BQA_LOGD("Updating SurfaceControl without recreating BBQ");
}
bool applyTransaction = false;
// 更新当前SurfaceControl
mSurfaceControl = surface;
// 创建新的事务,如果SurfaceControl发生变化则将准备应用新的事务
SurfaceComposerClient::Transaction t;
if (surfaceControlChanged) {
t.setFlags(mSurfaceControl, layer_state_t::eEnableBackpressure,
layer_state_t::eEnableBackpressure);
applyTransaction = true;
}
// 设置变化提示并打印信息
mTransformHint = mSurfaceControl->getTransformHint();
mBufferItemConsumer->setTransformHint(mTransformHint);
BQA_LOGV("update width=%d height=%d format=%d mTransformHint=%d", width, height, format,
mTransformHint);
// 构造新的ui::size,如果和之前的不同则进行更新
ui::Size newSize(width, height);
if (mRequestedSize != newSize) {
mRequestedSize.set(newSize);
// 设置新的缓冲区size
mBufferItemConsumer->setDefaultBufferSize(mRequestedSize.width, mRequestedSize.height);
// 如果缓冲区的缩放模式不是冻结(`NATIVE_WINDOW_SCALING_MODE_FREEZE`)
// 并且设置了 `mUpdateDestinationFrame`
// 则更新 `SurfaceControl` 的目标帧(`setDestinationFrame`)以反映新的尺寸。
if (mLastBufferInfo.scalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE) {
mSize = mRequestedSize;
if (mUpdateDestinationFrame) {
t.setDestinationFrame(mSurfaceControl, Rect(newSize));
applyTransaction = true;
}
}
}
// 如果需要提交新的事务
if (applyTransaction) {
// All transactions on our apply token are one-way. See comment on mAppliedLastTransaction
t.setApplyToken(mApplyToken).apply(false, true);
}
}
BLASTBufferQueue::update 方法的作用是更新 BLASTBufferQueue 的各种属性,包括 SurfaceControl、尺寸、格式、变换提示等。如果发生了变化,它会创建并应用一个事务,确保图形系统的状态与新的参数一致。通过使用事务,能够确保图形操作的原子性,并在多线程环境中安全地进行图形更新。