前面我们使用surfaceComposerClient->createSurface创建了surfaceControl 《SurfaceFinger layer创建过程》;要想绘制图像还得创建Surface,我们可以使用SurfaceControl::getSurface()来创建Surface
getSurface实现
sp<Surface> SurfaceControl::getSurface()
{
if (mSurfaceData == nullptr) {
return generateSurfaceLocked();
}
return mSurfaceData;
}
mutable sp<Surface> mSurfaceData;
此函数的目的只有一个,获取mSurfaceData;而mSurfaceData是Surface。由于mSurfaceData不为空直接返回,则一个SurfaceControl里只会有一个Surface。第一次进入mSurfaceData肯定为空,会调用generateSurfaceLocked
创建Surface,构建BLASTBufferQueue
sp<Surface> SurfaceControl::generateSurfaceLocked()
{
uint32_t ignore;
auto flags = mCreateFlags & (ISurfaceComposerClient::eCursorWindow |
ISurfaceComposerClient::eOpaque);
mBbqChild = mClient->createSurface(String8("bbq-wrapper"), 0, 0, mFormat,
flags, mHandle, {}, &ignore);
mBbq = sp<BLASTBufferQueue>::make("bbq-adapter", mBbqChild, mWidth, mHeight, mFormat);
mSurfaceData = mBbq->getSurface(true);
return mSurfaceData;
}
主要作用:
- 再创建一个名为bbq-wrapper的SurfaceControl
- 使用创建的SurfaceControl,构建BLASTBufferQueue
- 通过构建的BLASTBufferQueue创建Surface。
通过SurfaceComposerClient::createSurface创建SurfaceControl的详细过程前面已经解析过了。《SurfaceFinger layer创建过程》
先看下BLASTBufferQueue的构造函数
BLASTBufferQueue的构造函数
- 创建生产者和消费者
- 将BLASTBufferQueue设置为FrameAvailableListener和BufferFreedListener;设置mBufferItemConsumer的其他属性
- 清空mNumAcquired,mNumFrameAvailable
BLASTBufferQueue::BLASTBufferQueue(const std::string& name, const sp<SurfaceControl>& surface,
int width, int height, int32_t format)
: mSurfaceControl(surface),
mSize(width, height),
mRequestedSize(mSize),
mFormat(format),
mNextTransaction(nullptr) {
createBufferQueue(&mProducer, &mConsumer);
mProducer->setMaxDequeuedBufferCount(2);
mBufferItemConsumer = new BLASTBufferItemConsumer(mConsumer,
GraphicBuffer::USAGE_HW_COMPOSER |
GraphicBuffer::USAGE_HW_TEXTURE,
1, false);
static int32_t id = 0;
mName = name + "#" + std::to_string(id);
auto consumerName = mName + "(BLAST Consumer)" + std::to_string(id);
mQueuedBufferTrace = "QueuedBuffer - " + mName + "BLAST#" + std::to_string(id);
id++;
mBufferItemConsumer->setName(String8(consumerName.c_str()));
mBufferItemConsumer->setFrameAvailableListener(this);
mBufferItemConsumer->setBufferFreedListener(this);
mBufferItemConsumer->setxxx();
ComposerService::getComposerService()->getMaxAcquiredBufferCount(&mMaxAcquiredBuffers);
mBufferItemConsumer->setMaxAcquiredBufferCount(mMaxAcquiredBuffers);
mTransformHint = mSurfaceControl->getTransformHint();
mBufferItemConsumer->setTransformHint(mTransformHint);
SurfaceComposerClient::Transaction()
.setFlags(surface, layer_state_t::eEnableBackpressure,
layer_state_t::eEnableBackpressure)
.setApplyToken(mApplyToken)
.apply();
mNumAcquired = 0;
mNumFrameAvailable = 0;
BQA_LOGV("BLASTBufferQueue created width=%d height=%d format=%d mTransformHint=%d", width,
height, format, mTransformHint);
}
BLASTBufferItemConsumer的构造函数
BLASTBufferItemConsumer(const sp<IGraphicBufferConsumer>& consumer, uint64_t consumerUsage,
int bufferCount, bool controlledByApp)
: BufferItemConsumer(consumer, consumerUsage, bufferCount, controlledByApp),
mCurrentlyConnected(false),
mPreviouslyConnected(false),
mBLASTBufferQueue(nullptr) {}
BufferItemConsumer::BufferItemConsumer(
const sp<IGraphicBufferConsumer>& consumer, uint64_t consumerUsage,
int bufferCount, bool controlledByApp) :
ConsumerBase(consumer, controlledByApp)
ConsumerBase的构造函数,创建listerner 调用BufferQueueConsumer的consumerConnect
android12\frameworks\native\libs\gui\ConsumerBase.cpp
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());
wp<ConsumerListener> listener = static_cast<ConsumerListener*>(this);
sp<IConsumerListener> proxy = new BufferQueue::ProxyConsumerListener(listener);
status_t err = mConsumer->consumerConnect(proxy, controlledByApp);
mConsumer->setConsumerName(mName);
}
设置ConsumerListener
android12\frameworks\native\libs\gui\include\gui\BufferQueueConsumer.h
virtual status_t consumerConnect(const sp<IConsumerListener>& consumer,
bool controlledByApp) {
return connect(consumer, controlledByApp);
}
status_t BufferQueueConsumer::connect(
const sp<IConsumerListener>& consumerListener, bool controlledByApp) {
mCore->mConsumerListener = consumerListener;
mCore->mConsumerControlledByApp = controlledByApp;
}
再回去看下mBufferItemConsumer->setFrameAvailableListener(this);BLASTBufferItemConsumer一路继承,最后的子类是ConsumerBase,所以会调用ConsumerBase::setFrameAvailableListener
void ConsumerBase::setFrameAvailableListener(
const wp<FrameAvailableListener>& listener) {
mFrameAvailableListener = listener;
}
所有的东西都准备得差不多了,现在开始创建BBQSurface;
BBQSurface是给生产者使用,所以要传入生产者,还有surfaceflinger创建得layer得handle,然后对Surface的成员进行初始化等待;
这样只要拿到Surface就拿到了BLASTBufferQueue,拿到了生产者等等。内容不多,这里只贴下代码。
BLASTBufferQueue getSurface
sp<Surface> BLASTBufferQueue::getSurface(bool includeSurfaceControlHandle) {
sp<IBinder> scHandle = nullptr;
if (includeSurfaceControlHandle && mSurfaceControl) {
scHandle = mSurfaceControl->getHandle();
}
return new BBQSurface(mProducer, true, scHandle, this); //scHandle 就是SurfaceControl里的mHandle
}
BBQSurface的构造函数
BBQSurface(const sp<IGraphicBufferProducer>& igbp, bool controlledByApp,
const sp<IBinder>& scHandle, const sp<BLASTBufferQueue>& bbq)
: Surface(igbp, controlledByApp, scHandle), mBbq(bbq) {}
Surface::Surface(const sp<IGraphicBufferProducer>& bufferProducer, bool controlledByApp,
const sp<IBinder>& surfaceControlHandle)
: mGraphicBufferProducer(bufferProducer),
mCrop(Rect::EMPTY_RECT),
mBufferAge(0),
mGenerationNumber(0),
mSharedBufferMode(false),
mAutoRefresh(false),
mAutoPrerotation(false),
mSharedBufferSlot(BufferItem::INVALID_BUFFER_SLOT),
mSharedBufferHasBeenQueued(false),
mQueriedSupportedTimestamps(false),
mFrameTimestampsSupportsPresent(false),
mEnableFrameTimestamps(false),
mFrameEventHistory(std::make_unique<ProducerFrameEventHistory>()) {
// Initialize the ANativeWindow function pointers.
ANativeWindow::setSwapInterval = hook_setSwapInterval;
ANativeWindow::dequeueBuffer = hook_dequeueBuffer;
ANativeWindow::cancelBuffer = hook_cancelBuffer;
ANativeWindow::queueBuffer = hook_queueBuffer;
ANativeWindow::query = hook_query;
ANativeWindow::perform = hook_perform;
ANativeWindow::dequeueBuffer_DEPRECATED = hook_dequeueBuffer_DEPRECATED;
ANativeWindow::cancelBuffer_DEPRECATED = hook_cancelBuffer_DEPRECATED;
ANativeWindow::lockBuffer_DEPRECATED = hook_lockBuffer_DEPRECATED;
ANativeWindow::queueBuffer_DEPRECATED = hook_queueBuffer_DEPRECATED;
const_cast<int&>(ANativeWindow::minSwapInterval) = 0;
const_cast<int&>(ANativeWindow::maxSwapInterval) = 1;
mReqWidth = 0;
mReqHeight = 0;
mReqFormat = 0;
mReqUsage = 0;
mTimestamp = NATIVE_WINDOW_TIMESTAMP_AUTO;
mDataSpace = Dataspace::UNKNOWN;
mScalingMode = NATIVE_WINDOW_SCALING_MODE_FREEZE;
mTransform = 0;
mStickyTransform = 0;
mDefaultWidth = 0;
mDefaultHeight = 0;
mUserWidth = 0;
mUserHeight = 0;
mTransformHint = 0;
mConsumerRunningBehind = false;
mConnectedToCpu = false;
mProducerControlledByApp = controlledByApp;
mSwapIntervalZero = false;
mMaxBufferCount = NUM_BUFFER_SLOTS;
mSurfaceControlHandle = surfaceControlHandle;
}
总结:
SurfaceControl::getSurface()返回的实际是BBQSurface,BBQSurface继承Surface,可以使用Surface表示。BBQSurface是对生产者,handle的封装,其中包含了对buffer的操作。并且本文对FrameAvailableListener的初始化进行了简要阐述,后面会聊到FrameAvailableListener的具体用处,敬请期待。
创造不易,欢迎点赞收藏。