写在前面
BLastBufferQueue 的全称: Buffer Layer Async Transaction BufferQueue,BLastBufferQueue 作为桥梁连接了 App 和 SurfaceFlinger。App 需要通过事务 Transaction 来向 SurfaceFlinger 来提交 Buffer,然后再做进一步的合成。
BLastBufferQueue 由 Producer + Comsumer + BufferQueueCore 组成
- Producer: 从
Buffer Queue中申请GraphicBuffer,当 App 把 UI 渲染到这块Buffer之后,负责把这块Buffer插入Buffer Queue - Comsumer: 可以消费插入到
Buffer Queue的GraphicBuffer,并且把GraphicBuffer提交到SurfaceFlinger - BufferQueueCore: 管理
Buffer Queue
BLastBufferQueue 整个架构图如下:
BLASTBufferQueue 的创建
BLASTBufferQueue 创建发生在 SurfaceControl 创建之后
//frameworks/base/services/core/java/com/android/server/wm/WindowManagerService.java
public int relayoutWindow(Session session, IWindow client, LayoutParams attrs,
int requestedWidth, int requestedHeight, int viewVisibility, int flags, int seq,
int lastSyncSeqId, WindowRelayoutResult outRelayoutResult) {
...
// 创建一个 SurfaceControl
result = createSurfaceControl(outSurfaceControl, result, win, winAnimator);
...
if (mSurfaceControl.isValid()) {
updateBlastSurfaceIfNeeded();
}
...
}
在 updateBlastSurfaceIfNeeded 中会创建 BLASTBufferQueue
void updateBlastSurfaceIfNeeded() {
// 创建 BLASTBufferQueue
mBlastBufferQueue = new BLASTBufferQueue(mTag, true /* updateDestinationFrame */);
mBlastBufferQueue.setApplyToken(mBbqApplyToken);
mBlastBufferQueue.update(mSurfaceControl, mSurfaceSize.x, mSurfaceSize.y,
mWindowAttributes.format);
mBlastBufferQueue.setTransactionHangCallback(sTransactionHangCallback);
mBlastBufferQueue.setWaitForBufferReleaseCallback(mChoreographer::onWaitForBufferRelease);
Surface blastSurface;
// 创建 blastSurface
if (addSchandleToVriSurface()) {
blastSurface = mBlastBufferQueue.createSurfaceWithHandle();
} else {
blastSurface = mBlastBufferQueue.createSurface();
}
// Only call transferFrom if the surface has changed to prevent inc the generation ID and
// 把创建的 blastSurface 给 mSurface
mSurface.transferFrom(blastSurface);
...
}
这里 new BLASTBufferQueue 会调用 BLASTBufferQueue 的构造函数
//frameworks/base/graphics/java/android/graphics/BLASTBufferQueue.java
public BLASTBufferQueue(String name, boolean updateDestinationFrame) {
mNativeObject = nativeCreate(name, updateDestinationFrame);
}
nativeCreate 是一个 native方法
// frameworks/base/core/jni/android_graphics_BLASTBufferQueue.cpp
static jlong nativeCreate(JNIEnv* env, jclass clazz, jstring jName,
jboolean updateDestinationFrame) {
sp<BLASTBufferQueue> queue = sp<BLASTBufferQueue>::make(name.c_str(), updateDestinationFrame);
queue->incStrong((void*)nativeCreate);
return reinterpret_cast<jlong>(queue.get());
}
在这里创建了 native 层的 BLASTBufferQueue 对象,它的构造函数如下
// frameworks/native/libs/gui/BLASTBufferQueue.cpp
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) {
// 重点1:创建 BufferQueueCore,mProducer 和 mConsumer
createBufferQueue(&mProducer, &mConsumer);
// 重点2:创建 mBufferItemConsumer
mBufferItemConsumer = sp<BLASTBufferItemConsumer>::make(mConsumer,GraphicBuffer::USAGE_HW_COMPOSER |GraphicBuffer::USAGE_HW_TEXTURE, 1, false, this);
mProducer->setDequeueTimeout(std::numeric_limits<int64_t>::max());
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()));
// 重点3:把 FrameAvailableListener 的回调设置成自己, 也就是 BLASTBufferQueue
mBufferItemConsumer->setFrameAvailableListener(this);
...
}
在 BLASTBufferQueue 的构造函数中
- 初始化
BufferQueueCore,Comsumer和Producer - 创建
BufferItemConsumer对象,和设置各种参数,特别地,把FrameAvailableListener的回调设置成BLASTBufferQueue自己,为什么会这么做,下一小节会提到。 接下来详细分析这两步的实现
createBufferQueue
void BLASTBufferQueue::createBufferQueue(sp<IGraphicBufferProducer>* outProducer,
sp<IGraphicBufferConsumer>* outConsumer) {
#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BUFFER_RELEASE_CHANNEL)
auto core = sp<BBQBufferQueueCore>::make(this);
#else
auto core = sp<BufferQueueCore>::make();
#endif
...
auto producer = sp<BBQBufferQueueProducer>::make(core, this);
auto consumer = sp<BufferQueueConsumer>::make(core);
*outProducer = producer;
*outConsumer = consumer;
}
在 createBufferQueue 中
- 创建
BufferQueueCore - 创建
BBQBufferQueueProducer并赋给mProducer - 创建
BufferQueueConsumer并赋给mConsumer
创建 BufferQueueCore
BBQBufferQueueCore 是 BufferQueueCore 的一个装饰,比 BufferQueueCore 多了一个 notify Buffer released 的功能。所以我们可以只看 BufferQueueCore
BufferQueueCore::BufferQueueCore()
: mMutex(),
mIsAbandoned(false),
mConsumerControlledByApp(false),
mConsumerName(getUniqueName()),
mConsumerListener(),
mConsumerUsageBits(0),
mConsumerIsProtected(false),
mConnectedApi(NO_CONNECTED_API),
mLinkedToDeath(),
mConnectedProducerListener(),
mBufferReleasedCbEnabled(false),
mBufferAttachedCbEnabled(false),
#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_UNLIMITED_SLOTS)
mSlots(BufferQueueDefs::NUM_BUFFER_SLOTS),
#else
mSlots(),
#endif
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),
#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_UNLIMITED_SLOTS)
mAllowExtendedSlotCount(false),
#endif
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);
}
}
BufferQueueCore 的构造函数,只是对 BufferQueueCore 的成员变量进行初始化,这些成员变量中,比较重要的就是 mSlots 和 mQueue
frameworks/native/libs/gui/include/gui/BufferQueueCore.h
...
BufferQueueDefs::SlotsType mSlots;
// mQueue is a FIFO of queued buffers used in synchronous mode.
Fifo mQueue;
...
BufferQueueDefs::SlotsType mSlots
mSlots 是一个 BufferSlot 的 Vector
// frameworks/native/libs/gui/include/gui/BufferQueueDefs.h
typedef std::vector<BufferSlot> SlotsType;
而 BufferSlot 则用来表达一块 GraphicBuffer 以及这块 GraphicBuffer 的状态
// frameworks/native/libs/gui/include/gui/BufferSlot.h
struct BufferSlot {
// mGraphicBuffer points to the buffer allocated for this slot or is NULL
sp<GraphicBuffer> mGraphicBuffer;
// mBufferState is the current state of this buffer slot.
BufferState mBufferState;
...
}
Fifo mQueue
BufferQueueCore 的另外一个成员 mQueue 本质上也是一个 BufferItem 类型 Vector
// frameworks/native/libs/gui/include/gui/BufferQueueCore.h
typedef Vector<BufferItem> Fifo;
BufferItem 和 BufferSlot 类似,也是代表一个 GraphicBuffer
//
class BufferItem : public Flattenable<BufferItem> {
...
sp<GraphicBuffer> mGraphicBuffer;
...
}
但是 BufferItem 和 BufferSlot 不同的是,BufferItem 支持序列化,意味着它可以通过 IPC 传递,那这两者之间是如何协作的呢?
Producer从mSlots中拿到一块BufferSlot, 写入BufferSlot转换成BufferItem插入mQueueComsumer从mQueue中取出BufferItemBufferItem转换成BufferSlot提交给SurfaceFlinger所以,我们可以看出mQueue的主要作用是 “控制 Buffer 的出队顺序”
创建 BBQBufferQueueProducer
BBQBufferQueueProducer 负责从 BufferQueueCore 里面 queuebuffer
class BBQBufferQueueProducer : public BufferQueueProducer {
public:
BBQBufferQueueProducer(const sp<BufferQueueCore>& core, const wp<BLASTBufferQueue>& bbq)
: BufferQueueProducer(core, false /* consumerIsSurfaceFlinger*/),
mBLASTBufferQueue(bbq) {}
}
BBQBufferQueueProducer 构造函数中创建了它的父类 BufferQueueProducer,在 BufferQueueProducer 中提供了核心方法
// frameworks/native/libs/gui/include/gui/BufferQueueProducer.h
...
virtual status_t queueBuffer(int slot,
const QueueBufferInput& input, QueueBufferOutput* output);
...
创建 BufferQueueConsumer
BufferQueueConsumer 负责从 BufferQueueCore 获取 GraphicBuffer,所以在 BufferQueueConsumer 中提供了 acquireBuffer 和 releaseBuffer 等核心方法
// prebuilts/vndk/v30/arm/include/frameworks/native/libs/gui/include/gui/BufferQueueConsumer.h
class BufferQueueConsumer : public BnGraphicBufferConsumer {
...
virtual status_t acquireBuffer(BufferItem* outBuffer,
nsecs_t expectedPresent, uint64_t maxFrameNumber = 0) override;
virtual status_t releaseBuffer(int buf, uint64_t frameNumber,
EGLDisplay display, EGLSyncKHR fence,
const sp<Fence>& releaseFence) {
return releaseBuffer(buf, frameNumber, releaseFence, display, fence);
}
...
sp<BufferQueueCore> mCore;
}
创建 BLASTBufferItemConsumer
// frameworks/native/libs/gui/BLASTBufferQueue.cpp
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) {
...
mBufferItemConsumer = sp<BLASTBufferItemConsumer>::make(mConsumer,GraphicBuffer::USAGE_HW_COMPOSER |GraphicBuffer::USAGE_HW_TEXTURE, 1, false, this);
...
}
BLASTBufferItemConsumer 的构造函数如下
// prebuilts/vndk/v30/x86/include/frameworks/native/libs/gui/include/gui/BLASTBufferQueue.h
BLASTBufferItemConsumer(const sp<IGraphicBufferConsumer>& consumer, uint64_t consumerUsage,int bufferCount, bool controlledByApp)
: BufferItemConsumer(consumer, consumerUsage, bufferCount, controlledByApp),
mCurrentlyConnected(false),
mPreviouslyConnected(false) {}
BLASTBufferItemConsumer 的构造函数会调用父类 BufferItemConsumer 的构造函数
// frameworks/native/libs/gui/BufferItemConsumer.cpp
BufferItemConsumer::BufferItemConsumer(
const sp<IGraphicBufferConsumer>& consumer, uint64_t consumerUsage,
int bufferCount, bool controlledByApp) :
ConsumerBase(consumer, controlledByApp)
{
initialize(consumerUsage, bufferCount);
}
进而调用 ConsumerBase 的构造函数
// frameworks/native/libs/gui/ConsumerBase.cpp
ConsumerBase::ConsumerBase(const sp<IGraphicBufferConsumer>& bufferQueue, bool controlledByApp)
:
mSlots(BufferQueueDefs::NUM_BUFFER_SLOTS),
mAbandoned(false),
mConsumer(bufferQueue),
mPrevFinalReleaseFence(Fence::NO_FENCE) {
initialize(controlledByApp);
}
void ConsumerBase::initialize(bool controlledByApp) {
...
// 这个 listener 就是 BLASTBufferItemConsumer 本身
wp<ConsumerListener> listener = static_cast<ConsumerListener*>(this);
sp<IConsumerListener> proxy = new BufferQueue::ProxyConsumerListener(listener);
// mConsumer是 BufferQueueConsumer
status_t err = mConsumer->consumerConnect(proxy, controlledByApp);
}
这里把 BLASTBufferItemConsumer 和 BufferQueueConsumer 通过 consumerConnect 关联起来,我们接下来看 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) {
...
把 BufferQueueCore 的 mConsumerListener 设置成 BLASTBufferItemConsumer
mCore->mConsumerListener = consumerListener;
mCore->mConsumerControlledByApp = controlledByApp;
return NO_ERROR;
}
这里绕了一大圈,最终实现的就是把 BufferQueueCore->mConsumerListener 设置成BLASTBufferItemConsumer, 为什么要这么做,在下一个小节会提到。
到这里为止,BLASTBufferQueue 就介绍完了,BLASTBufferQueue 连接了 App 和 SurfaceFlinger。