本章节思维导图如上。主要讲述了 surafce 测试程序 demo 的第3步中的提交 Buffer 阶段。解锁定(最关键)并提交 Buffer 的过程。
一 概述
该部分代码是在上一章节中 Surface 测试程序源码的精简版,保存了最关键的流程,如下所示:
#include <cutils/memory.h>
#include <utils/Log.h>
#include <binder/IPCThreadState.h>
#include <binder/ProcessState.h>
#include <binder/IServiceManager.h>
#include <gui/Surface.h>
#include <gui/SurfaceComposerClient.h>
#include <android/native_window.h>
using namespace android;
int main(int argc, char** argv)
{
//...
//1 创建surfaceflinger的客户端
sp<SurfaceComposerClient> client = new SurfaceComposerClient();
//2 获取surface
sp<SurfaceControl> surfaceControl = client->createSurface(String8("resize"),
160, 240, PIXEL_FORMAT_RGB_565, 0);
sp<Surface> surface = surfaceControl->getSurface();
//设置layer,layer值越大,显示层越靠前
SurfaceComposerClient::openGlobalTransaction();
surfaceControl->setLayer(100000);
SurfaceComposerClient::closeGlobalTransaction();
//3 获取buffer->锁定buffer->写入buffer->解锁并提交buffer
//这里主要关注:申请Buff 和 提交Buff
ANativeWindow_Buffer outBuffer;
surface->lock(&outBuffer, NULL);
ssize_t bpr = outBuffer.stride * bytesPerPixel(outBuffer.format);
android_memset16((uint16_t*)outBuffer.bits, 0xF800, bpr*outBuffer.height);
surface->unlockAndPost();
//...
return 0;
}
主要的步骤为:
- 获取 SurfaceFlinger(后简称 SF)的客户端,通过 SF 的客户端获取 SurfaceControl,进而获得 Surface
- 通过 SurfaceControl 设置 Layer 层数值(忽略),通过 Surface 获取 Buffer,锁定 Buffer 并写入 Buffer
- 最后提交 Buffer
本章节主要关注第3步中的提交 Buffer 阶段。
surface->unlockAndPost();
status_t Surface::unlockAndPost()
{
//...
int fd = -1;
status_t err = mLockedBuffer->unlockAsync(&fd);
err = queueBuffer(mLockedBuffer.get(), fd);
mPostedBuffer = mLockedBuffer;
mLockedBuffer = 0;
return err;
}
二 GraphicBuffer.unlockAsync
status_t GraphicBuffer::unlockAsync(int *fenceFd)
{
status_t res = getBufferMapper().unlockAsync(handle, fenceFd);
return res;
}
这里调用了 GraphicBufferMapper 的 unlockAsync 方法,内容如下:
status_t GraphicBufferMapper::unlockAsync(buffer_handle_t handle, int *fenceFd)
{
//...
if (mAllocMod->common.module_api_version >= GRALLOC_MODULE_API_VERSION_0_3) {
err = mAllocMod->unlockAsync(mAllocMod, handle, fenceFd);
} else {
*fenceFd = -1;
err = mAllocMod->unlock(mAllocMod, handle);
}
return err;
}
再往下就是 HAL 层 Gralloc 模块的调用了,接下来最后调用的是 Gralloc 的 gralloc_unlock 方法,代码如下:
int gralloc_unlock(gralloc_module_t const* /*module*/,
buffer_handle_t handle)
{
// we're done with a software buffer. nothing to do in this
// implementation. typically this is used to flush the data cache.
if (private_handle_t::validate(handle) < 0)
return -EINVAL;
return 0;
}
这里什么都没做,但实际上该是刷新数据的操作,即确保数据完全写入到缓冲区中。
三 queueBuffer分析
int Surface::queueBuffer(android_native_buffer_t* buffer, int fenceFd) {
//...
//获取Buffer的slots索引值
int i = getSlotFromBufferLocked(buffer);
//...
//根据索引值i执行queueBuffer操作
status_t err = mGraphicBufferProducer->queueBuffer(i, input, &output);
//...
return err;
}
因为这里涉及 Layer 层的消费者部分代码,因此在分析 queueBuffer 方法前我们首先回顾下之前分析的 Layer 层初始化关于消费者部分的代码,之后在此基础上分析 mGraphicBufferProducer 的 queueBuffer 方法。
3.1 Layer对象生产者消费者
关于 Layer层的生产者和消费者,主要分析 Layer 的 onFirstRef 方法,代码如下:
void Layer::onFirstRef() {
// Creates a custom BufferQueue for SurfaceFlingerConsumer to use
sp<IGraphicBufferProducer> producer;
sp<IGraphicBufferConsumer> consumer;
BufferQueue::createBufferQueue(&producer, &consumer);
mProducer = new MonitoredProducer(producer, mFlinger);
//关键点1
mSurfaceFlingerConsumer = new SurfaceFlingerConsumer(consumer, mTextureName);
mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
//关键点2
mSurfaceFlingerConsumer->setContentsChangedListener(this);
mSurfaceFlingerConsumer->setName(mName);
#ifdef TARGET_DISABLE_TRIPLE_BUFFERING
#warning "disabling triple buffering"
mSurfaceFlingerConsumer->setDefaultMaxBufferCount(2);
#else
mSurfaceFlingerConsumer->setDefaultMaxBufferCount(3);
#endif
const sp<const DisplayDevice> hw(mFlinger->getDefaultDisplayDevice());
updateTransformHint(hw);
}
3.1.1 SurfaceFlingerConsumer对象分析
这里专注分析 SurfaceFlingerConsumer 类构造器代码如下:
SurfaceFlingerConsumer(const sp<IGraphicBufferConsumer>& consumer,
uint32_t tex)
: GLConsumer(consumer, tex, GLConsumer::TEXTURE_EXTERNAL, false, false),
mTransformToDisplayInverse(false)
{}
它是继承 GLConsumer 的,继续分析 GLConsumer 的构造器,代码如下:
GLConsumer::GLConsumer(const sp<IGraphicBufferConsumer>& bq, uint32_t tex,
uint32_t texTarget, bool useFenceSync, bool isControlledByApp) :
ConsumerBase(bq, isControlledByApp),
//...
mAttached(true)
{
ST_LOGV("GLConsumer");
memcpy(mCurrentTransformMatrix, mtxIdentity,
sizeof(mCurrentTransformMatrix));
mConsumer->setConsumerUsageBits(DEFAULT_USAGE_FLAGS);
}
GLConsumer 是继承 ConsumerBase 的,这里继续分析 ConsumerBase 的构造器,代码如下:
ConsumerBase::ConsumerBase(const sp<IGraphicBufferConsumer>& bufferQueue,
bool controlledByApp) : mAbandoned(false), mConsumer(bufferQueue) {
// Choose a name using the PID and a process-unique ID.
mName = String8::format("unnamed-%d-%d", getpid(), createProcessUniqueId());
//这里的this就是SurfaceFlingerConsumer对象
wp<ConsumerListener> listener = static_cast<ConsumerListener*>(this);
//使用listener初始化BufferQueue内部的mConsumerListener成员变量
sp<IConsumerListener> proxy = new BufferQueue::ProxyConsumerListener(listener);
//使用proxy 初始化BufferQueueConsumer内部的mConsumerListener成员变量
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);
}
}
这里主要看下 BufferQueue::ProxyConsumerListener 和 mConsumer->consumerConnect 的实现。
BufferQueue的ProxyConsumerListener构造器代码实现如下:
BufferQueue::ProxyConsumerListener::ProxyConsumerListener(
const wp<ConsumerListener>& consumerListener):
mConsumerListener(consumerListener) {}
仔细分析会得出:主要是将 SurfaceFlingerConsumer 的 mConsumerListener 对象赋值给 Proxy 的 mConsumerListener 对象。
consumerConnect的代码实现如下:
virtual status_t consumerConnect(const sp<IConsumerListener>& consumer,
bool controlledByApp) {
return connect(consumer, controlledByApp);
}
继续分析 connect,代码如下:
status_t BufferQueueConsumer::connect(
const sp<IConsumerListener>& consumerListener, bool controlledByApp) {
//...
Mutex::Autolock lock(mCore->mMutex);
//...
mCore->mConsumerListener = consumerListener;
mCore->mConsumerControlledByApp = controlledByApp;
return NO_ERROR;
}
仔细分析会得出:主要是将 Proxy 的 mConsumerListener 对象赋值给 BufferQueueConsumer 的 mConsumerListener 对象。
3.2.2 SurfaceFlingerConsumer.setContentsChangedListener
void SurfaceFlingerConsumer::setContentsChangedListener(
const wp<ContentsChangedListener>& listener) {
setFrameAvailableListener(listener);
Mutex::Autolock lock(mMutex);
mContentsChangedListener = listener;
}
继续分析 setFrameAvailableListener,代码实现如下:
void ConsumerBase::setFrameAvailableListener(
const wp<FrameAvailableListener>& listener) {
Mutex::Autolock lock(mMutex);
mFrameAvailableListener = listener;
}
这里主要是把 SurfaceFlingerConsumer 的 mFrameAvailableListener 设置为 Layer(上面的 listener 就是 Layer 对象)。
3.1.3 小结
- SurfaceFlingerConsumer 的 mConsumerListener 对象赋值给 ProxyConsumerListener 的 mConsumerListener 对象
- ProxyConsumerListener 的 mConsumerListener 对象赋值给 BufferQueueConsumer 的 mConsumerListener 对象
- SurfaceFlingerConsumer 的 mFrameAvailableListener 设置为 Layer 对象
3.2 mGraphicBufferProducer.queueBuffer
这里继续分析 mGraphicBufferProducer 的 queueBuffer 方法,代码如下:
status_t BufferQueueProducer::queueBuffer(int slot,
const QueueBufferInput &input, QueueBufferOutput *output) {
//...
sp<IConsumerListener> frameAvailableListener;
sp<IConsumerListener> frameReplacedListener;
int callbackTicket = 0;
BufferItem item;
{ // Autolock scope
//...
const sp<GraphicBuffer>& graphicBuffer(mSlots[slot].mGraphicBuffer);
Rect bufferRect(graphicBuffer->getWidth(), graphicBuffer->getHeight());
Rect croppedRect;
crop.intersect(bufferRect, &croppedRect);
//mSlots item 初始化...
if (mCore->mQueue.empty()) {
//将构造的item放入队列mQueue中
mCore->mQueue.push_back(item);
//将之前分析的proxy的Listener赋值给frameAvailableListener
frameAvailableListener = mCore->mConsumerListener;
} else {
// When the queue is not empty, we need to look at the front buffer
// state to see if we need to replace it
BufferQueueCore::Fifo::iterator front(mCore->mQueue.begin());
if (front->mIsDroppable) {
if (mCore->stillTracking(front)) {
mSlots[front->mSlot].mBufferState = BufferSlot::FREE;
mSlots[front->mSlot].mFrameNumber = 0;
}
// Overwrite the droppable buffer with the incoming one
*front = item;
frameReplacedListener = mCore->mConsumerListener;
} else {
mCore->mQueue.push_back(item);
frameAvailableListener = mCore->mConsumerListener;
}
}
mCore->mBufferHasBeenQueued = true;
mCore->mDequeueCondition.broadcast();
output->inflate(mCore->mDefaultWidth, mCore->mDefaultHeight,
mCore->mTransformHint, mCore->mQueue.size());
callbackTicket = mNextCallbackTicket++;
} // Autolock scope
//...
// Call back without the main BufferQueue lock held, but with the callback
// lock held so we can ensure that callbacks occur in order
{
Mutex::Autolock lock(mCallbackMutex);
while (callbackTicket != mCurrentCallbackTicket) {
mCallbackCondition.wait(mCallbackMutex);
}
if (frameAvailableListener != NULL) {
//关键方法
frameAvailableListener->onFrameAvailable(item);
} else if (frameReplacedListener != NULL) {
frameReplacedListener->onFrameReplaced(item);
}
++mCurrentCallbackTicket;
mCallbackCondition.broadcast();
}
return NO_ERROR;
}
这里关注 frameAvailableListener->onFrameAvailable(item) 的实现,通过前面的分析可知 listener 是 proxyConsumerListener 类对象,因此代码如下:
void BufferQueue::ProxyConsumerListener::onFrameAvailable(
const android::BufferItem& item) {
sp<ConsumerListener> listener(mConsumerListener.promote());
if (listener != NULL) {
listener->onFrameAvailable(item);
}
}
这里的 listener 是 SurfaceFlingerConsumer 类的对象(继承 GLConsumer->继承 ConsumerBase),代码实现如下:
void ConsumerBase::onFrameAvailable(const BufferItem& item) {
sp<FrameAvailableListener> listener;
{ // scope for the lock
Mutex::Autolock lock(mMutex);
listener = mFrameAvailableListener.promote();
}
if (listener != NULL) {
listener->onFrameAvailable(item);
}
}
这里的 mFrameAvailableListener.promote() 返回的是 Layer 对象,Layer 的 onFrameAvailable 方法实现如下:
void Layer::onFrameAvailable(const BufferItem& item) {
// Add this buffer from our internal queue tracker
{ // Autolock scope
Mutex::Autolock lock(mQueueItemLock);
mQueueItems.push_back(item);
}
android_atomic_inc(&mQueuedFrames);
mFlinger->signalLayerUpdate();
}
这里调用了 SF 相关操作,继续分析 mFlinger->signalLayerUpdate(),代码如下:
void SurfaceFlinger::signalLayerUpdate() {
mEventQueue.invalidate();
}
这里就是唤醒另外一个线程了,本章节的分析就先到这里。
总结:
listener 的监听通知顺序从下到上依次是:生产者->消费者->Layer->SF。即 queueBuffer 的流程是将加入队列的 Buffer 的消息通知 proxyConsumerListener,进而通知消费者 SurafceFlingerConsumer,进而通知 Layer,通知 SF。