博客
关于我
Android SurfaceFlinger4 提交Buffer
阅读量:291 次
发布时间:2019-03-03

本文共 11261 字,大约阅读时间需要 37 分钟。

在这里插入图片描述

本章节思维导图如上。主要讲述了 surafce 测试程序 demo 的第3步中的提交 Buffer 阶段。解锁定(最关键)并提交 Buffer 的过程。

一 概述

该部分代码是在上一章节中 Surface 测试程序源码的精简版,保存了最关键的流程,如下所示:

#include 
#include
#include
#include
#include
#include
#include
#include
using namespace android; int main(int argc, char** argv){ //... //1 创建surfaceflinger的客户端 sp
client = new SurfaceComposerClient(); //2 获取surface sp
surfaceControl = client->createSurface(String8("resize"), 160, 240, PIXEL_FORMAT_RGB_565, 0); sp
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
producer; sp
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
hw(mFlinger->getDefaultDisplayDevice()); updateTransformHint(hw);}

3.1.1 SurfaceFlingerConsumer对象分析

这里专注分析 SurfaceFlingerConsumer 类构造器代码如下:

SurfaceFlingerConsumer(const sp
& consumer, uint32_t tex) : GLConsumer(consumer, tex, GLConsumer::TEXTURE_EXTERNAL, false, false), mTransformToDisplayInverse(false){ }

它是继承 GLConsumer 的,继续分析 GLConsumer 的构造器,代码如下:

GLConsumer::GLConsumer(const sp
& 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
& 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
listener = static_cast
(this); //使用listener初始化BufferQueue内部的mConsumerListener成员变量 sp
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): mConsumerListener(consumerListener) { }

仔细分析会得出:主要是将 SurfaceFlingerConsumer 的 mConsumerListener 对象赋值给 Proxy 的 mConsumerListener 对象。

consumerConnect的代码实现如下:

virtual status_t consumerConnect(const sp
& consumer, bool controlledByApp) { return connect(consumer, controlledByApp);}

继续分析 connect,代码如下:

status_t BufferQueueConsumer::connect(        const sp
& 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
& listener) { setFrameAvailableListener(listener); Mutex::Autolock lock(mMutex); mContentsChangedListener = listener;}

继续分析 setFrameAvailableListener,代码实现如下:

void ConsumerBase::setFrameAvailableListener(        const wp
& 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
frameAvailableListener; sp
frameReplacedListener; int callbackTicket = 0; BufferItem item; { // Autolock scope //... const sp
& 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
listener(mConsumerListener.promote()); if (listener != NULL) { listener->onFrameAvailable(item); }}

这里的 listener 是 SurfaceFlingerConsumer 类的对象(继承 GLConsumer->继承 ConsumerBase),代码实现如下:

void ConsumerBase::onFrameAvailable(const BufferItem& item) {       sp
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。

转载地址:http://dqom.baihongyu.com/

你可能感兴趣的文章
VTK:图片之ImageValueRange
查看>>
VTK:图片之Interpolation
查看>>
VTK:图片之PickPixel
查看>>
VTK:图片之RGBToHSV
查看>>
VTK:图片之ResizeImageDemo
查看>>
VTK:隐式函数之ImplicitQuadric
查看>>
VTK:隐式函数之ImplicitSphere
查看>>
VTK:InfoVis之DelimitedTextReader
查看>>
CCF 201912-2 回收站选址 满分代码
查看>>
基于DFA算法实现文章敏感词过滤
查看>>
Git commit代码后撤销方法
查看>>
数据结构与算法学习1-----稀疏数组
查看>>
java手动实现JWT(我和别人的不一样)
查看>>
LetCode刷题记录--No3-无重复字符的最长子串
查看>>
Java转换xml格式时间 (yyyy-MM-ddTHH:mm:ss.SSSZ)
查看>>
Python 使用 __getstate__ 和 __setstate__ 魔法方法
查看>>
hook钩子介绍
查看>>
关于json
查看>>
焦点事件
查看>>
webpack打包常见报错
查看>>