浅谈Android之SurfaceFlinger相关介绍(二)

发布于 2019-09-26 作者 风铃 79次 浏览 版块 前端

3.2 绘图表面相关(Surface& Layer & BufferQueue)


App和SurfaceFlinger连接后,接下去就可以调用mClient->createSurface创建Surface,
然后SurfaceFlinger会对应的创建Layer,然后Layer内部会创建BufferQueueProducer和


BufferQueueConsumer,一个负责生产graphic buffer,一个负责消费


接下去看下它们之间简单的关系图



上面章节说过,Surface是一个派生自ANativeWindow的本地窗口,从图上可知,这个本地窗口其实只是一个代理,它对应的真正的绘图表面其实是SurfaceFlinger中的Layer,所以,Surface
的dequeuebuffer其实对应的就是从Layer关联的BufferQueueProducer获取graphicbuffer的过程,至于queuebuffer,对应则是将已经绘制好的graphic
buffer通知并给到Layer关联的BufferQueueConsumer。


这里有两个问题要解决:


1)  Surface如何从Layer关联的BufferQueueProducer获取buffer,以及如何将绘制完buffer通知到BufferQueueConsumer


2)  Buffer如何在两个间快速传输?


SurfaceFlinger的解决方案是:


1) 
直接将BufferQueueProducer定义成binderservice,派生自BnGraphicBufferProducer,然后在mClient.createSurface时,直接将BufferQueueProducer返回给App
Client


2)  封装GraphicBuffer用来实现进程间数据共享


3.2.1 GraphicBuffer介绍


先介绍下GraphicBuffer是如何实现进程间数据共享:


1)  包含GraphicBufferAllocator实例,在GraphicBufferAllocator构造的时会打开


int err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID,&module);


gralloc_open(module, &mAllocDev);


然后调用GraphicBufferAllocator.alloc分配buffer,如果成功,会返回这个buffer对应的handle,对应数据类型为buffer_handle_t


这个是HAL层Gralloc提供的方法


2)  包含GraphicBufferMapper实例,同样的,GraphicBufferMapper在构造时会打开

int err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID,&module);
mAllocMod = (gralloc_module_t const *)module;

两个不同点是,一个调用gralloc_open,一个直接使用module指针,至于区别,Gralloc的代码没看过,不清楚

可以调用GraphicBufferMapper.lock并传入buffer_handle_t,它才会锁定对应的内存并返回首地址,然后内存使用结束后,调用GraphicBufferMapper.unlock解锁

3)  GraphicBuffer要支持序列化(Flattenable),主要是序列化内部的buffer_handle_t值。

接着看类介绍

class GraphicBuffer

    : public ANativeObjectBase< ANativeWindowBuffer, GraphicBuffer, RefBase>,

      public Flattenable

{

ANativeObjectBase模板我觉得更多的还是为了兼容性设计的,由于ANativeWindowBuffer是个结构体,然后ANativeWindowBuffer内存布局的第一个变量是:

struct android_native_base_t common;

这个模板的用意是,通过定义getSelf来实现android_native_base_t类型的地址和GraphicBuffer之间的转换,还有,通过调用incRef和decRef,并传入android_native_base_t指针,由于android_native_base_t是类的第一个变量,可以通过reinterpret_cast又重新将其转换成GraphicBuffer对象,然后在对应的调用incStrong和decStrong,但是在我看的代码里面没发现对android_native_base_t使用,所以对其使用场景就不是很了解了。

不过通过类定义,可以很清晰的知道,GraphicBuffer派生自ANativeWindowBuffer,而且支持Flattenable

构造GraphicBuffer新分配buffer,得到buffer_handle_t:

GraphicBuffer::GraphicBuffer(uint32_t w, uint32_t h,

        PixelFormat reqFormat, uint32_t reqUsage)

    : BASE(), mOwner(ownData), mBufferMapper(GraphicBufferMapper::get()),

      mInitCheck(NO_ERROR), mId(getUniqueId())

{

    width  =

    height =

    stride =

    format =

    usage  = 0;

    handle = NULL;

    mInitCheck = initSize(w, h, reqFormat, reqUsage);

}

接着看initSize:

status_t GraphicBuffer::initSize(uint32_t w, uint32_t h, PixelFormat format,

        uint32_t reqUsage)

{

    GraphicBufferAllocator& allocator = GraphicBufferAllocator::get();

    status_t err = allocator.alloc(w, h, format, reqUsage, &handle, &stride);

    if (err == NO_ERROR) {

        this->width  = w;

        this->height = h;

        this->format = format;

        this->usage  = reqUsage;

    }

    return err;

}

通过已有的buffer_handle_t来创建GraphicBuffer对象

GraphicBuffer::GraphicBuffer(uint32_t w, uint32_t h,

        PixelFormat inFormat, uint32_t inUsage,

        uint32_t inStride, native_handle_t* inHandle, bool keepOwnership)

    : BASE(), mOwner(keepOwnership ? ownHandle : ownNone),

      mBufferMapper(GraphicBufferMapper::get()),

      mInitCheck(NO_ERROR), mId(getUniqueId())

{

    width  = w;

    height = h;

    stride = inStride;

    format = inFormat;

    usage  = inUsage;

    handle = inHandle;

}

3.2.2 Surface,SurfaceControl, Layer和BufferQueue的创建

接下去,我们从SurfaceComposerClient.createSurface作为入口,从代码的角度完整的介绍整个创建流程

sp SurfaceComposerClient::createSurface(

        const String8& name,

        uint32_t w,

        uint32_t h,

        PixelFormat format,

        uint32_t flags)

{

    sp sur;

    if (mStatus == NO_ERROR) {

        sp handle;

        sp gbp;

        status_t err = mClient->createSurface(name, w, h, format, flags,

                &handle, &gbp);

        ALOGE_IF(err, "SurfaceComposerClient::createSurface error %s", strerror(-err));

        if (err == NO_ERROR) {

            sur = new SurfaceControl(this, handle, gbp);

        }

    }

    return sur;

}

直接将调用转发到mClient->createSurface,这是一个RPC调用,代码直接跑到SurfaceFlinger端对应的Client::createSurface,这个函数内部创建一个Message,然后添加到SurfaceFlinger的消息队列里,接着同步等待执行结束将结果返回,这个Message在执行时,会调用

SurfaceFlingerde.createLayer:

status_t SurfaceFlinger::createLayer(

        const String8& name,

        const sp& client,

        uint32_t w, uint32_t h, PixelFormat format, uint32_t flags,

        sp* handle, sp* gbp)

{

    //ALOGD("createLayer for (%d x %d), name=%s", w, h, name.string());

    if (int32_t(w|h) < 0) {

        ALOGE("createLayer() failed, w or h is negative (w=%d, h=%d)",

                int(w), int(h));

        return BAD_VALUE;

    }

 

    status_t result = NO_ERROR;

 

    sp layer;

 

    switch (flags & ISurfaceComposerClient::eFXSurfaceMask) {

        case ISurfaceComposerClient::eFXSurfaceNormal:

            result = createNormalLayer(client,

                    name, w, h, flags, format,

                    handle, gbp, &layer);

            break;

        case ISurfaceComposerClient::eFXSurfaceDim:

            result = createDimLayer(client,

                    name, w, h, flags,

                    handle, gbp, &layer);

            break;

        default:

            result = BAD_VALUE;

            break;

    }

 

    if (result == NO_ERROR) {

        addClientLayer(client, *handle, *gbp, layer);

        setTransactionFlags(eTransactionNeeded);

    }

    return result;

}

从代码可以看出,这里可以创建两个类型的Layer,Normal或者Dim, 这里基于

createNormalLayer来介绍:

status_t SurfaceFlinger::createNormalLayer(const sp& client,

        const String8& name, uint32_t w, uint32_t h, uint32_t flags, PixelFormat& format,

        sp* handle, sp* gbp, sp* outLayer)

{

    // initialize the surfaces

    switch (format) {

    case PIXEL_FORMAT_TRANSPARENT:

    case PIXEL_FORMAT_TRANSLUCENT:

        format = PIXEL_FORMAT_RGBA_8888;

        break;

    case PIXEL_FORMAT_OPAQUE:

        format = PIXEL_FORMAT_RGBX_8888;

        break;

    }

 

    *outLayer = new Layer(this, client, name, w, h, flags);

    status_t err = (*outLayer)->setBuffers(w, h, format, flags);

    if (err == NO_ERROR) {

        *handle = (*outLayer)->getHandle();

        *gbp = (*outLayer)->getProducer();

    }

 

    ALOGE_IF(err, "createNormalLayer() failed (%s)", strerror(-err));

    return err;

}

函数内通过new Layer创建Layer对象,接着在Layer::onFirstRef时创建BufferQueue

void Layer::onFirstRef() {

    // Creates a custom BufferQueue for SurfaceFlingerConsumer to use

    sp producer;

    sp consumer;

    BufferQueue::createBufferQueue(&producer, &consumer);

    mProducer = new MonitoredProducer(producer, mFlinger);

    mSurfaceFlingerConsumer = new SurfaceFlingerConsumer(consumer, mTextureName);

    mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));

    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);

}

接着调用BufferQueue::createBufferQueue创建BufferQueue:

void BufferQueue::createBufferQueue(sp* outProducer,

        sp* outConsumer,

        const sp& allocator) {

    LOG_ALWAYS_FATAL_IF(outProducer == NULL,

            "BufferQueue: outProducer must not be NULL");

    LOG_ALWAYS_FATAL_IF(outConsumer == NULL,

            "BufferQueue: outConsumer must not be NULL");

 

    sp core(new BufferQueueCore(allocator));

    LOG_ALWAYS_FATAL_IF(core == NULL,

            "BufferQueue: failed to create BufferQueueCore");

 

    sp producer(new BufferQueueProducer(core));

    LOG_ALWAYS_FATAL_IF(producer == NULL,

            "BufferQueue: failed to create BufferQueueProducer");

 

    sp consumer(new BufferQueueConsumer(core));

    LOG_ALWAYS_FATAL_IF(consumer == NULL,

            "BufferQueue: failed to create BufferQueueConsumer");

 

    *outProducer = producer;

    *outConsumer = consumer;

}

从函数可以看出,BufferQueueCore是核心,那它应该就负责BufferQueue的管理,然后

BufferQueueProducer负责从BufferQueueCore拿出空闲buffer,塞满数据后,给到

BufferQueueConsumer用于消费,也就是给到SurfaceFlinger进行混合输出

当然,上面是我认为的设计应该是这样的,但是实际从代码来看,Android这块代码的编写人员虽然设计成生产者,消费者,数据管理中心的模式,但是具体内部代码实现,感觉没有完全基于这一点,代码耦合度还是非常高的。

BufferQueueCore主要做了:

1)  创建BufferSlot数组,默认长度为64,用于存放分配的GraphicBuffer,还有Buffer状态

2)  初始化sp mAllocator;用于创建GraphicBuffer

其实就是初始化两个变量,其他比如寻找empty slot的操作,都是在BufferQueueProducer里完成的,这个后续介绍。

接着看代码,BufferQueueCore定义了如下变量用于保存bufferqueue:

BufferQueueDefs::SlotsType mSlots;

接着看SlotsType的定义:

namespace BufferQueueDefs {

        // BufferQueue will keep track of at most this value of buffers.

        // Attempts at runtime to increase the number of buffers past this

        // will fail.

        enum { NUM_BUFFER_SLOTS = 64 };

 

        typedef BufferSlot SlotsType[NUM_BUFFER_SLOTS];

} // namespace BufferQueueDefs

可以看出,SlotsType对应的就是BufferSlot数组,注意,这个数组内部是没有数据的

接着看构造函数对mAllocator变量的初始化:

BufferQueueCore::BufferQueueCore(const sp& allocator) :

{

    if (allocator == NULL) {

        sp composer(ComposerService::getComposerService());

        mAllocator = composer->createGraphicBufferAlloc();

        if (mAllocator == NULL) {

            BQ_LOGE("createGraphicBufferAlloc failed");

        }

    }

}

默认allocator为null,所以这里直接调用composer->createGraphicBufferAlloc(),ISurfaceComposer上面介绍过,对应的就是SurfaceFlingerbinder service,所以对应调用到

SurfaceFlinger.createGraphicBufferAlloc:

sp SurfaceFlinger::createGraphicBufferAlloc()

{

    sp gba(new GraphicBufferAlloc());

    return gba;

}

这个函数直接构造了GraphicBufferAlloc对象并返回:

class GraphicBufferAlloc : public BnGraphicBufferAlloc {

public:

    GraphicBufferAlloc();

    virtual ~GraphicBufferAlloc();

    virtual sp createGraphicBuffer(uint32_t w, uint32_t h,

        PixelFormat format, uint32_t usage, status_t* error);

};

看类派生自BnGraphicBufferAlloc,说明其是nativebinder service,可以跨进程调用,接着看

createGraphicBuffer是如何创建GraphicBuffer的:

sp GraphicBufferAlloc::createGraphicBuffer(uint32_t w, uint32_t h,

        PixelFormat format, uint32_t usage, status_t* error) {

    sp graphicBuffer(new GraphicBuffer(w, h, format, usage));

    status_t err = graphicBuffer->initCheck();

    *error = err;

    if (err != 0 || graphicBuffer->handle == 0) {

        if (err == NO_MEMORY) {

            GraphicBuffer::dumpAllocationsToSystemLog();

        }

        ALOGE("GraphicBufferAlloc::createGraphicBuffer(w=%d, h=%d) "

             "failed (%s), handle=%p",

                w, h, strerror(-err), graphicBuffer->handle);

        return 0;

    }

    return graphicBuffer;

}

一目了然,直接通过new GraphicBuffer创建对象并返回。

BufferQueueCore创建完成后,我们再回到void BufferQueue::createBufferQueue函数,接着就是基于BufferQueueCore创建:

sp producer(new BufferQueueProducer(core));

sp consumer(new BufferQueueConsumer(core));

继续看BufferQueueProducer类定义:

class BufferQueueProducer : public BnGraphicBufferProducer,

                            private IBinder::DeathRecipient {

接着看BufferQueueConsumer定义:

class BufferQueueConsumer : public BnGraphicBufferConsumer {

可以看出,两个都是native binder service

至此,Layer创建结束,接下去重新回来SurfaceFlinger::createNormalLayer,看Layer创建成功后做了什么

  *outLayer = new Layer(this, client, name, w, h, flags);

    status_t err = (*outLayer)->setBuffers(w, h, format, flags);

    if (err == NO_ERROR) {

        *handle = (*outLayer)->getHandle();

        *gbp = (*outLayer)->getProducer();

    }

主要是返回两个native binder service,一个是BufferQueueProducer,这个app拿过去用于获取graphicbuffer,那handle是什么?继续看getHandle:

sp Layer::getHandle() {

    Mutex::Autolock _l(mLock);

    mHasSurface = true;

 

    class Handle : public BBinder, public LayerCleaner {

        wp mOwner;

    public:

        Handle(const sp& flinger, const sp& layer)

            : LayerCleaner(flinger, layer), mOwner(layer) {

        }

    };

    return new Handle(mFlinger, this);

}

直接返回一个Handle对象,由于它派生自BBinder,所以它是一个native binder service,可以作为这个Layer的唯一标识(原理看第二章),Handle内部保存SurfaceFlinger对象和关联的Layer对象。

接着回到SurfaceFlinger::createLayer, 看createNormalLayer结束后做了什么

   if (result == NO_ERROR) {

        addClientLayer(client, *handle, *gbp, layer);

        setTransactionFlags(eTransactionNeeded);

    }

继续看addClientLayer的实现:

void SurfaceFlinger::addClientLayer(const sp& client,

        const sp& handle,

        const sp& gbc,

        const sp& lbc)

{

    // attach this layer to the client

    client->attachLayer(handle, lbc);

 

    // add this layer to the current state list

    Mutex::Autolock _l(mStateLock);

    mCurrentState.layersSortedByZ.add(lbc);

    mGraphicBufferProducerList.add(gbc->asBinder());

}

Client->attachLayer函数对应代码:

void Client::attachLayer(const sp& handle, const sp& layer)

{

    Mutex::Autolock _l(mLock);

    mLayers.add(handle, layer);

}

这个函数将新创建Layer对应的handle作为key,Layer对象作为value,保存到Client内部变量mLayers Map中,这样就可以通过Handle快速的找到对应的Layer

接着调用mCurrentState.layersSortedByZ.add(lbc);将新创建的Layer添加到Z order顺序列表中,同时调用mGraphicBufferProducerList.add(gbc->asBinder());将BufferQueueProducer添加到mGraphicBufferProducerList列表中。

到这里,SurfaceComposerClient::createSurface RPC调用在SurfaceFlinger这边已经执行结束,接着返回到AppClient端:

sp SurfaceComposerClient::createSurface(

        const String8& name,

        uint32_t w,

        uint32_t h,

        PixelFormat format,

        uint32_t flags)

{

    sp sur;

    if (mStatus == NO_ERROR) {

        sp handle;

        sp gbp;

        status_t err = mClient->createSurface(name, w, h, format, flags,

                &handle, &gbp);

        ALOGE_IF(err, "SurfaceComposerClient::createSurface error %s", strerror(-err));

        if (err == NO_ERROR) {

            sur = new SurfaceControl(this, handle, gbp);

        }

    }

    return sur;

通过mClient->createSurface返回Layer关联的handle和GraphicBufferProducer,然后基于这两个关键数据,创建SurfaceControl。

既然叫SurfaceControl,说明其既要包含Surface对象,又要负责对这个Surface关联的Layer进行状态控制;Surface对象主要用于图形绘制,这就涉及到GraphicBuffer的dequeue和queue,所以肯定要基于GraphicBufferProducer来创建;至于Surface关联Layer的控制,肯定要通过Handle来操作了。

所以SurfaceControl就是一个代理封装类,对应操作Handle关联Layer的代码:

status_t SurfaceControl::setAlpha(float alpha) {

    status_t err = validate();

    if (err < 0) return err;

    return mClient->setAlpha(mHandle, alpha);

}

生成Surface的代码:

sp SurfaceControl::getSurface() const

{

    Mutex::Autolock _l(mLock);

    if (mSurfaceData == 0) {

        // This surface is always consumed by SurfaceFlinger, so the

        // producerControlledByApp value doesn't matter; using false.

        mSurfaceData = new Surface(mGraphicBufferProducer, false);

    }

    return mSurfaceData;

}

接着看Surface的构造函数:

Surface::Surface(

        const sp& bufferProducer,

        bool controlledByApp)

    : mGraphicBufferProducer(bufferProducer)

{

    // 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(ANativeWindow::minSwapInterval) = 0;

    const_cast(ANativeWindow::maxSwapInterval) = 1;

}

Surface派生自ANativeWindow,ANativeWindow上头已经做过介绍,是一个结构体,需要在构造时手动对其函数变量进行赋值。就这样,Surface创建结束。

3.2.3 SurfacedequeueBuffer流程介绍

先简单介绍下整个流程:

1)  Surface::dequeuebuffer直接调用mGraphicBufferProducer->dequeueBuffer获取free的buffer slot id并返回buffer对应的status

2)  如果buffer空间未分配或者status标明需要重新分配,则调用

mGraphicBufferProducer->requestBuffer(buf, &gbuf);

请求为这个buffer slot分配新空间

3)  最后将buffer slot关联的GraphicBuffer对象返回

上面只是描述了App端的流程,由于SurfaceFlinger端只是RPC执行对应的函数,这里就没有写出,直接通过代码来描述

先看Surface::dequeueBuffer函数部分代码:

int Surface::dequeueBuffer(android_native_buffer_t** buffer, int* fenceFd) {

    ATRACE_CALL();

    ALOGV("Surface::dequeueBuffer");

 

    int reqW;

    int reqH;

    bool swapIntervalZero;

    uint32_t reqFormat;

    uint32_t reqUsage;

 

    {

        Mutex::Autolock lock(mMutex);

 

        reqW = mReqWidth ? mReqWidth : mUserWidth;

        reqH = mReqHeight ? mReqHeight : mUserHeight;

 

        swapIntervalZero = mSwapIntervalZero;

        reqFormat = mReqFormat;

        reqUsage = mReqUsage;

    } // Drop the lock so that we can still touch the Surface while blocking in IGBP::dequeueBuffer

 

    int buf = -1;

    sp fence;

    status_t result = mGraphicBufferProducer->dequeueBuffer(&buf, &fence, swapIntervalZero,

            reqW, reqH, reqFormat, reqUsage);

 

    Mutex::Autolock lock(mMutex);

 

    sp& gbuf(mSlots[buf].buffer);

 

    if (result & IGraphicBufferProducer::RELEASE_ALL_BUFFERS) {

        freeAllBuffers();

    }

 

    if ((result & IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION) || gbuf == 0) {

        result = mGraphicBufferProducer->requestBuffer(buf, &gbuf);

        if (result != NO_ERROR) {

            ALOGE("dequeueBuffer: IGraphicBufferProducer::requestBuffer failed: %d", result);

            mGraphicBufferProducer->cancelBuffer(buf, fence);

            return result;

        }

    }

 

    *buffer = gbuf.get();

    return OK;

}

大家可能会奇怪,最后GraphicBuffer怎么保存到android_native_buffer_t*类型的buffer里了呢? 这个之前有过介绍,GraphicBuffer派生自ANativeWindowBuffer,再看如下代码:

typedef ANativeWindowBuffer_t android_native_buffer_t;

所以,将GraphicBuffer返回给*buffer没有任何问题。

接着主要看看SurfaceFlinger端的代码,先看BufferQueueProducer::dequeueBuffer的实现,

函数先调用BufferQueueProducer::waitForFreeSlotThenRelock,这个函数主要代码

    *found = BufferQueueCore::INVALID_BUFFER_SLOT;

        int dequeuedCount = 0;

        int acquiredCount = 0;

        for (int s = 0; s < maxBufferCount; ++s) {

            switch (mSlots[s].mBufferState) {

                case BufferSlot::DEQUEUED:

                    ++dequeuedCount;

                    break;

                case BufferSlot::ACQUIRED:

                    ++acquiredCount;

                    break;

                case BufferSlot::FREE:

                    // We return the oldest of the free buffers to avoid

                    // stalling the producer if possible, since the consumer

                    // may still have pending reads of in-flight buffers

                    if (*found == BufferQueueCore::INVALID_BUFFER_SLOT ||

                            mSlots[s].mFrameNumber < mSlots[*found].mFrameNumber) {

                        *found = s;

                    }

                    break;

                default:

                    break;

            }

        }

遍历mSlots中状态为free的buffer,如果找到,将buffer slot id,也就是数组索引返回

接着判断是否需要重新分配内存,如果需要,则重新创建GraphicBuffer并保存到对应的slot:

  if (returnFlags & BUFFER_NEEDS_REALLOCATION) {

        status_t error;

        BQ_LOGV("dequeueBuffer: allocating a new buffer for slot %d", *outSlot);

        sp graphicBuffer(mCore->mAllocator->createGraphicBuffer(

                    width, height, format, usage, &error));

        if (graphicBuffer == NULL) {

            BQ_LOGE("dequeueBuffer: createGraphicBuffer failed");

            return error;

        }

 

        { // Autolock scope

            Mutex::Autolock lock(mCore->mMutex);

 

            if (mCore->mIsAbandoned) {

                BQ_LOGE("dequeueBuffer: BufferQueue has been abandoned");

                return NO_INIT;

            }

 

            mSlots[*outSlot].mFrameNumber = UINT32_MAX;

            mSlots[*outSlot].mGraphicBuffer = graphicBuffer;

        } // Autolock scope

    }

接着将slot id返回给App Client

接着通过调用BufferQueueProducer::requestBuffer并传入slot id拿到id对应的GraphicBuffer

status_t BufferQueueProducer::requestBuffer(int slot, sp* buf) {

    ATRACE_CALL();

    BQ_LOGV("requestBuffer: slot %d", slot);

    Mutex::Autolock lock(mCore->mMutex);

 

    if (mCore->mIsAbandoned) {

        BQ_LOGE("requestBuffer: BufferQueue has been abandoned");

        return NO_INIT;

    }

 

    if (slot < 0 || slot>= BufferQueueDefs::NUM_BUFFER_SLOTS) {

        BQ_LOGE("requestBuffer: slot index %d out of range [0, %d)",

                slot, BufferQueueDefs::NUM_BUFFER_SLOTS);

        return BAD_VALUE;

    } else if (mSlots[slot].mBufferState != BufferSlot::DEQUEUED) {

        BQ_LOGE("requestBuffer: slot %d is not owned by the producer "

                "(state = %d)", slot, mSlots[slot].mBufferState);

        return BAD_VALUE;

    }

 

    mSlots[slot].mRequestBufferCalled = true;

    *buf = mSlots[slot].mGraphicBuffer;

    return NO_ERROR;

}

3.2.4 SurfacequeueBuffer流程介绍

Surface通过DequeueBuffer拿到buffer后,接着在buffer上绘制图形数据,绘制好后通知SurfaceFlinger做后续的图形混合操作,通知的过程,其实就是queueBuffer的过程

流程很简单,直接看代码

int Surface::queueBuffer(android_native_buffer_t* buffer, int fenceFd) {

    ATRACE_CALL();

    ALOGV("Surface::queueBuffer");

    Mutex::Autolock lock(mMutex);

    int64_t timestamp;

    bool isAutoTimestamp = false;

    if (mTimestamp == NATIVE_WINDOW_TIMESTAMP_AUTO) {

        timestamp = systemTime(SYSTEM_TIME_MONOTONIC);

        isAutoTimestamp = true;

        ALOGV("Surface::queueBuffer making up timestamp: %.2f ms",

            timestamp / 1000000.f);

    } else {

        timestamp = mTimestamp;

    }

    int i = getSlotFromBufferLocked(buffer);

    if (i < 0) {

        return i;

    }

 

 

    // Make sure the crop rectangle is entirely inside the buffer.

    Rect crop;

    mCrop.intersect(Rect(buffer->width, buffer->height), &crop);

 

    sp fence(fenceFd >= 0 ? new Fence(fenceFd) : Fence::NO_FENCE);

    IGraphicBufferProducer::QueueBufferOutput output;

    IGraphicBufferProducer::QueueBufferInput input(timestamp, isAutoTimestamp,

            crop, mScalingMode, mTransform ^ mStickyTransform, mSwapIntervalZero,

            fence, mStickyTransform);

    status_t err = mGraphicBufferProducer->queueBuffer(i, input, &output);

    if (err != OK)  {

        ALOGE("queueBuffer: error queuing buffer to SurfaceTexture, %d", err);

    }

    uint32_t numPendingBuffers = 0;

    uint32_t hint = 0;

    output.deflate(&mDefaultWidth, &mDefaultHeight, &hint,

            &numPendingBuffers);

 

    // Disable transform hint if sticky transform is set.

    if (mStickyTransform == 0) {

        mTransformHint = hint;

    }

 

    mConsumerRunningBehind = (numPendingBuffers >= 2);

 

    return err;

}

这个函数先找到buffer对应的slot id,然后再通过mGraphicBufferProducer->queueBuffer传入slot id将对应的buffer入列

接着在BufferQueueProducer::quequeBuffer中,先根据slot id从mSlots中拿到对应的

GraphicBuffer

const sp& graphicBuffer(mSlots[slot].mGraphicBuffer);

接着转换成BufferItem并放入BufferQueueCore的mQueue中

mCore->mQueue.push_back(item);

然后通过回调通知有新的Buffer可用:

frameAvailableListener = mCore->mConsumerListener;

frameAvailableListener->onFrameAvailable(item);

到这里,唯一的疑问就是mCore->mConsumerListener这个回调指向哪里?它是如何被设置的?我们回过头重新看BufferQueue::createBufferQueue的代码,它在创建BufferQueueCore之后,接着调用如下代码:

sp consumer(new BufferQueueConsumer(core));

基于core创建了consumer,接着看BufferQueueConsumer的构造函数

BufferQueueConsumer::BufferQueueConsumer(const sp& core) :

    mCore(core),

    mSlots(core->mSlots),

    mConsumerName() {}

简单的保存core和mSlots两个变量的引用

所以到这里,mCore->mConsumerListener还未被设置,接着看Layer::onFirstRef在调用

BufferQueue::createBufferQueue(&producer,&consumer);创建BufferQueue后做了什么:

void Layer::onFirstRef() {

    sp producer;

    sp consumer;

    BufferQueue::createBufferQueue(&producer, &consumer);

    mProducer = new MonitoredProducer(producer, mFlinger);

    mSurfaceFlingerConsumer = new SurfaceFlingerConsumer(consumer, mTextureName);

    mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));

    mSurfaceFlingerConsumer->setContentsChangedListener(this);

    mSurfaceFlingerConsumer->setName(mName);

}

先看SurfaceFlingerConsumer类的定义:

SurfaceFlingerConsumer : public GLConsumer:public ConsumerBase

先看SurfaceFlingerConsumer构造:

   SurfaceFlingerConsumer(const sp& consumer,

            uint32_t tex)

        : GLConsumer(consumer, tex, GLConsumer::TEXTURE_EXTERNAL, false, false),

          mTransformToDisplayInverse(false)

    {}

接着看GLConsumer构造:

GLConsumer::GLConsumer(const sp& bq, uint32_t tex,

        uint32_t texTarget, bool useFenceSync, bool isControlledByApp) :

    ConsumerBase(bq, isControlledByApp),

{

    ST_LOGV("GLConsumer");

 

    memcpy(mCurrentTransformMatrix, mtxIdentity,

            sizeof(mCurrentTransformMatrix));

 

    mConsumer->setConsumerUsageBits(DEFAULT_USAGE_FLAGS);

}

最后看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());

 

    wp listener = static_cast(this);

    sp proxy = new BufferQueue::ProxyConsumerListener(listener);

 

    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);

    }

}

终于找到你了,先将IGraphicBufferConsumer保存到mConsumer,接着调用

mConsumer->consumerConnect(proxy,controlledByApp);

virtual status_t BufferQueueConsumer::consumerConnect(const sp& consumer,

            bool controlledByApp) {

        return connect(consumer, controlledByApp);

    }

啥都没做,直接转到BufferQueueConsumer::connect:

status_t BufferQueueConsumer::connect(

        const sp& consumerListener, bool controlledByApp) {

    if (consumerListener == NULL) {

        BQ_LOGE("connect(C): consumerListener may not be NULL");

        return BAD_VALUE;

    }

 

    mCore->mConsumerListener = consumerListener;

    mCore->mConsumerControlledByApp = controlledByApp;

 

    return NO_ERROR;

}

到这里清楚了,mCore->mConsumerListener实际指向的就是SurfaceFlingerConsumer,

SurfaceFlingerConsumer没有实现onFrameAvailable,咱们看父类的默认实现:

void ConsumerBase::onFrameAvailable(const BufferItem& item) {

    CB_LOGV("onFrameAvailable");

 

    sp listener;

    { // scope for the lock

        Mutex::Autolock lock(mMutex);

        listener = mFrameAvailableListener.promote();

    }

 

    if (listener != NULL) {

        CB_LOGV("actually calling onFrameAvailable");

        listener->onFrameAvailable(item);

    }

}

mFrameAvailableListener是一个若引用,通过对其尝试提升获取绑定对象,如果还存在,则调用其onFrameAvailable,所以,最终还是要看mFrameAvailableListener被设置成那个对象了,回到Layer创建SurfaceFlingerConsumer的地方:

mSurfaceFlingerConsumer = new SurfaceFlingerConsumer(consumer, mTextureName);

mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));

mSurfaceFlingerConsumer->setContentsChangedListener(this);

    mSurfaceFlingerConsumer->setName(mName);

看setContentsChangedListener代码:

void SurfaceFlingerConsumer::setContentsChangedListener(

        const wp& listener) {

    setFrameAvailableListener(listener);

    Mutex::Autolock lock(mMutex);

    mContentsChangedListener = listener;

}

接着看setFrameAvailableListener:

void ConsumerBase::setFrameAvailableListener(

        const wp& listener) {

    CB_LOGV("setFrameAvailableListener");

    Mutex::Autolock lock(mMutex);

    mFrameAvailableListener = listener;

}

终于知道了mFrameAvailableListener最终被设置为Layer对象,也就是说,Surfacequeuebuffer最终被回调到了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();

}

这里将buffer item添加到mQueueItems,然后通知SurfaceFlinger Layer内部有更新。

3.2.5 Layer状态参数设置

Layer提供了很多函数用以设置其自身状态,比如position,alpha值,但是如果每改动一次Layer的状态数据,就通知SurfaceFlinger调整Layer显示效果,这样明显是不合理的,所以,最好能提供批量处理,一次设置多个数据,然后集中提交。

上面说过,每个Layer在创建的时候,对应创建BBinder作为handler传给App client端,所以我们在配置Layer数据的时候,就可以通过Handle来指定要设置的Layer,然后和配置数据一同保存到ComposerState对象中,通过创建ComposerState数组,一次设置多个Layer的配置数据,最后调用ISurfaceComposer. setTransactionState把数组传到SurfaceFlinger,SurfaceFlinger.setTransactionState接着遍历数组,依次调用setClientStateLocked,

setClientStateLocked则会通过Handle从Client中找到对应的Layer,然后将ComposerState中保存的数据设置到Layer中。

下面介绍下上述操作在App Client端的封装:

  SurfaceComposerClient::openGlobalTransaction();

  control->setLayer(0x40000000);

  SurfaceComposerClient::closeGlobalTransaction();

之前介绍过,Composer就是封装Layer数据配置相关操作的,所以上面代码,最终肯定跑到Composer对应实现中

void Composer::openGlobalTransactionImpl() {

    { // scope for the lock

        Mutex::Autolock _l(mLock);

        mTransactionNestCount += 1;

    }

}

void Composer::closeGlobalTransactionImpl(bool synchronous) {

    sp sm(ComposerService::getComposerService());

 

    Vector transaction;

    Vector displayTransaction;

    uint32_t flags = 0;

 

    { // scope for the lock

        Mutex::Autolock _l(mLock);

        mForceSynchronous |= synchronous;

        if (!mTransactionNestCount) {

            ALOGW("At least one call to closeGlobalTransaction() was not matched by a prior "

                    "call to openGlobalTransaction().");

        } else if (--mTransactionNestCount) {

            return;

        }

 

        transaction = mComposerStates;

        mComposerStates.clear();

 

        displayTransaction = mDisplayStates;

        mDisplayStates.clear();

 

        if (mForceSynchronous) {

            flags |= ISurfaceComposer::eSynchronous;

        }

        if (mAnimation) {

            flags |= ISurfaceComposer::eAnimation;

        }

 

        mForceSynchronous = false;

        mAnimation = false;

    }

 

   sm->setTransactionState(transaction, displayTransaction, flags);

}

openGlobalTransactionImpl啥也没做,就是将mTransactionNestCount加1,这个变量用来确保open和close操作必须要成对出现。

closeGlobalTransactionImpl首先mComposerStates和mDisplayStates拷贝到对应的transaction和displayTransaction中,接着清除mComposerStates和mDisplayStates内的数据,接着调用sm->setTransactionState将transaction和displayTransaction的数据传到SurfaceFlinger

接着看control->setLayer(0x40000000);

status_t SurfaceControl::setLayer(int32_t layer) {

    status_t err = validate();

    if (err < 0) return err;

    return mClient->setLayer(mHandle, layer);

}

直接调用SurfaceComposerClient::setLayer

status_t SurfaceComposerClient::setLayer(const sp& id, int32_t z) {

    return getComposer().setLayer(this, id, z);

}

接着到Composer::setLayer

status_t Composer::setLayer(const sp& client,

        const sp& id, int32_t z) {

    Mutex::Autolock _l(mLock);

    layer_state_t* s = getLayerStateLocked(client, id);

    if (!s)

        return BAD_INDEX;

    s->what |= layer_state_t::eLayerChanged;

    s->z = z;

    return NO_ERROR;

}

通过getLayerStateLocked拿到layer_state_t数据结构指针

layer_state_t* Composer::getLayerStateLocked(

        const sp& client, const sp& id) {

 

    ComposerState s;

    s.client = client->mClient;

    s.state.surface = id;

 

    ssize_t index = mComposerStates.indexOf(s);

    if (index < 0) {

        // we don't have it, add an initialized layer_state to our list

        index = mComposerStates.add(s);

    }

 

    ComposerState* const out = mComposerStates.editArray();

    return &(out[index].state);

很简单,先通过client和handle信息判断Layer是否已经存在mComposerStates中,如果不存在,则将其添加到mComposerStates中,然后返回ComposerState内部state变量的地址。

接着通过layer_state_t*指针修改数据即可

收藏
暂无回复