SurfaceFlinger的渲染客户端Surface初始化

Posted 白嫩豆腐

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SurfaceFlinger的渲染客户端Surface初始化相关的知识,希望对你有一定的参考价值。

关于SurfaceFlinger他大部分都是三层架构

SurfaceFlinger是针对整个系统,

用户类本地binder服务端binder
ComposerServiceBpSurfaceComposerSurfaceFlinger
SurfaceComposerClientBpSurfaceComposerClientClient
SurfaceSurfaceControlIBinderLayer

这里数据结构三层,是方便管理,一个系统只有一个SurfaceFlinger。

每个应用拥有 一个SurfaceComposerClient,

每个窗体或者surface对应一个layer。

前两个业务逻辑相对简单,主要维护数据。而Surface,是比较复杂的,主要通过layer生成共享内存的管理类。然后交给程序端渲染。

高版本的android主要通过生产消费者模式。对于客户程序其实是一个生产者(Producer)。而服务端则是一个消费端(交个hw层渲染)。

下面我们主要分析一下surface以及layer的具体实现类。

Layer真实类型为BufferQueueLayer

我们从SurfaceComposerClientcreat出Surface这个过程追踪一下代码。了解一下过程。

2.1 用户端请求

这个过程相对简单,开始是通过调用SurfaceComposerClient的函数

sp<SurfaceControl> control = session()->createSurface(String8("uitest"),
        resolution.getWidth(), resolution.getHeight(), PIXEL_FORMAT_RGB_565);
sp<SurfaceControl> SurfaceComposerClient::createSurface(const String8& name, uint32_t w, uint32_t h,
                                                        PixelFormat format, uint32_t flags,
                                                        SurfaceControl* parent,
                                                        LayerMetadata metadata,
                                                        uint32_t* outTransformHint) {
    sp<SurfaceControl> s;
    createSurfaceChecked(name, w, h, format, &s, flags, parent, std::move(metadata),
                         outTransformHint);
    return s;
}
status_t SurfaceComposerClient::createSurfaceChecked(const String8& name, uint32_t w, uint32_t h,
                                                     PixelFormat format,
                                                     sp<SurfaceControl>* outSurface, uint32_t flags,
                                                     SurfaceControl* parent, LayerMetadata metadata,
                                                     uint32_t* outTransformHint) {
    sp<SurfaceControl> sur;
    status_t err = mStatus;

    if (mStatus == NO_ERROR) {
        sp<IBinder> handle;
        sp<IBinder> parentHandle;
        sp<IGraphicBufferProducer> gbp;

        if (parent != nullptr) {
            parentHandle = parent->getHandle();
        }

        uint32_t transformHint = 0;
        err = mClient->createSurface(name, w, h, format, flags, parentHandle, std::move(metadata),
                                     &handle, &gbp, &transformHint);
        if (outTransformHint) {
            *outTransformHint = transformHint;
        }
        ALOGE_IF(err, "SurfaceComposerClient::createSurface error %s", strerror(-err));
        if (err == NO_ERROR) {
            *outSurface = new SurfaceControl(this, handle, gbp, transformHint);
        }
    }
    return err;
}

这里其实相对加单,就是调用client的createSurface,因为client类型是BpSurfaceComposerClient,其实这里客户端已经完成了任务,已经通过binder把请求发送给服务端的Client中了。下面我们进入第二阶段的代码阅读。他主要是服务端构造Layer,生成共享buffer,实现卡进程的数据(帧数据)共享

2.2 服务端处理

处理端其实到了Client.cpp的函数,其实相对比较简单,直接交给SurfaceFlinger处理:

status_t Client::createSurface(const String8& name, uint32_t w, uint32_t h, PixelFormat format,
                               uint32_t flags, const sp<IBinder>& parentHandle,
                               LayerMetadata metadata, sp<IBinder>* handle,
                               sp<IGraphicBufferProducer>* gbp, uint32_t* outTransformHint) {
    // We rely on createLayer to check permissions.
    return mFlinger->createLayer(name, this, w, h, format, flags, std::move(metadata), handle, gbp,
                                 parentHandle, nullptr, outTransformHint);
}

具体代码如下:

status_t SurfaceFlinger::createLayer(const String8& name, const sp<Client>& client, uint32_t w,
                                     uint32_t h, PixelFormat format, uint32_t flags,
                                     LayerMetadata metadata, sp<IBinder>* handle,
                                     sp<IGraphicBufferProducer>* gbp,
                                     const sp<IBinder>& parentHandle, const sp<Layer>& parentLayer,
                                     uint32_t* outTransformHint) {


    sp<Layer> layer;


    switch (flags & ISurfaceComposerClient::eFXSurfaceMask) {
        case ISurfaceComposerClient::eFXSurfaceBufferQueue:
            result = createBufferQueueLayer(client, std::move(uniqueName), w, h, flags,
                                            std::move(metadata), format, handle, gbp, &layer);

            break;
        case ISurfaceComposerClient::eFXSurfaceBufferState:
            result = createBufferStateLayer(client, std::move(uniqueName), w, h, flags,
                                            std::move(metadata), handle, &layer);
            break;
        case ISurfaceComposerClient::eFXSurfaceEffect:
            // check if buffer size is set for color layer.
            if (w > 0 || h > 0) {
                ALOGE("createLayer() failed, w or h cannot be set for color layer (w=%d, h=%d)",
                      int(w), int(h));
                return BAD_VALUE;
            }

            result = createEffectLayer(client, std::move(uniqueName), w, h, flags,
                                       std::move(metadata), handle, &layer);
            break;
        case ISurfaceComposerClient::eFXSurfaceContainer:
            // check if buffer size is set for container layer.
            if (w > 0 || h > 0) {
                ALOGE("createLayer() failed, w or h cannot be set for container layer (w=%d, h=%d)",
                      int(w), int(h));
                return BAD_VALUE;
            }
            result = createContainerLayer(client, std::move(uniqueName), w, h, flags,
                                          std::move(metadata), handle, &layer);
            break;
        default:
            result = BAD_VALUE;
            break;
    }

//保存layer,为了surfaceflinger维护layer
    result = addClientLayer(client, *handle, *gbp, layer, parentHandle, parentLayer,
                            addToCurrentState, outTransformHint);
    if (result != NO_ERROR) {
        return result;
    }
    //不重要
    mInterceptor->saveSurfaceCreation(layer);

	//binder相关
    setTransactionFlags(eTransactionNeeded);
    return result;
}

这段代码其实业务比较简单,通过特定的flag,生成不同的layer,然后配置layer,然后调用binder。关键是传入的flag。我们直接通过最简单的,阅读BufferQueueLayer相关代码。

status_t SurfaceFlinger::createBufferQueueLayer(const sp<Client>& client, std::string name,
                                                uint32_t w, uint32_t h, uint32_t flags,
                                                LayerMetadata metadata, PixelFormat& format,
                                                sp<IBinder>* handle,
                                                sp<IGraphicBufferProducer>* gbp,
                                                sp<Layer>* outLayer) {

	......
    sp<BufferQueueLayer> layer;
    LayerCreationArgs args(this, client, std::move(name), w, h, flags, std::move(metadata));
    args.textureName = getNewTexture();
    {
        // Grab the SF state lock during this since it's the only safe way to access
        // RenderEngine when creating a BufferLayerConsumer
        // TODO: Check if this lock is still needed here
        Mutex::Autolock lock(mStateLock);
        layer = getFactory().createBufferQueueLayer(args);
    }

    status_t err = layer->setDefaultBufferProperties(w, h, format);
    if (err == NO_ERROR) {
        *handle = layer->getHandle();
        *gbp = layer->getProducer();
        *outLayer = layer;
    }

    ALOGE_IF(err, "createBufferQueueLayer() failed (%s)", strerror(-err));
    return err;
}

mFactory具体类型为DefaultFactory。具体代码就比较加单了:

sp<BufferQueueLayer> DefaultFactory::createBufferQueueLayer(const LayerCreationArgs& args) {
    return new BufferQueueLayer(args);
}

BufferQueueLayer 构造函数不算复杂,关键是onFirstRef的功能:

void BufferQueueLayer::onFirstRef() {
    BufferLayer::onFirstRef();

    // Creates a custom BufferQueue for SurfaceFlingerConsumer to use
    sp<IGraphicBufferProducer> producer;
    sp<IGraphicBufferConsumer> consumer;
    mFlinger->getFactory().createBufferQueue(&producer, &consumer, true);
    mProducer = mFlinger->getFactory().createMonitoredProducer(producer, mFlinger, this);
    mConsumer =
            mFlinger->getFactory().createBufferLayerConsumer(consumer, mFlinger->getRenderEngine(),
                                                             mTextureName, this);
    mConsumer->setConsumerUsageBits(getEffectiveUsage(0));

    mContentsChangedListener = new ContentsChangedListener(this);
    mConsumer->setContentsChangedListener(mContentsChangedListener);
    mConsumer->setName(String8(mName.data(), mName.size()));

    // BufferQueueCore::mMaxDequeuedBufferCount is default to 1
    if (!mFlinger->isLayerTripleBufferingDisabled()) {
        mProducer->setMaxDequeuedBufferCount(2);
    }
}

这里通过SurfaceFlinger的factory生成消费者和生产者,供给客户程序调用,我们稍微观察一下:

sp<IGraphicBufferProducer> DefaultFactory::createMonitoredProducer(
        const sp<IGraphicBufferProducer>& producer, const sp<SurfaceFlinger>& flinger,
        const wp<Layer>& layer) {
    return new MonitoredProducer(producer, flinger, layer);
}

sp<BufferLayerConsumer> DefaultFactory::createBufferLayerConsumer(
        const sp<IGraphicBufferConsumer>& consumer, renderengine::RenderEngine& renderEngine,
        uint32_t textureName, Layer* layer) {
    return new BufferLayerConsumer(consumer, renderEngine, textureName, layer);
}

其实这里已经介绍完毕,最终会吧BufferQueueLayer传入到客户端,生成control。最终封装成Surface。用于绘制内容。

2.3 服务端收到回复处理

客户端处理基本上就是通过binder返回的数据,构造一个SurfaceControl,这里没有特别复杂的,核心是通过SurfaceControl获取surface。

sp<Surface> SurfaceControl::getSurface() const
{
    Mutex::Autolock _l(mLock);
    if (mSurfaceData == nullptr) {
        return generateSurfaceLocked();
    }
    return mSurfaceData;
}

类似与一个单利。

sp<Surface> SurfaceControl::generateSurfaceLocked() const
{
    // This surface is always consumed by SurfaceFlinger, so the
    // producerControlledByApp value doesn't matter; using false.
    mSurfaceData = new Surface(mGraphicBufferProducer, false);

    return mSurfaceData;
}

其实这里就比较简单了,关键是mGraphicBufferProducer,其实是Layer中的一个一个变量,传入到客户端了。

后记

下一篇着重分析一下mGraphicBufferProducer,的数据结构,以及如何实现跨进程数据传输的,如何吧我们的buffer交到surfaceflnger的,最后一片大概分析一下hw层,了解一下数据下传的过程,整个androidUI相关基本算是搞定。如果有机会再开一篇,介绍一下activity的窗口如何显示。

以上是关于SurfaceFlinger的渲染客户端Surface初始化的主要内容,如果未能解决你的问题,请参考以下文章

SurfaceFlinger的渲染客户端Surface初始化

SurfaceFlinger的渲染客户端Surface初始化

Android使用surfaceView原生绘制

SurfaceFlinger系列01--Android应用与SurfaceFlinger的连接过程

显示系统[2] APP创建SurfaceFlinger客户端(client)的过程

一文了解surface,surfaceview,surfaceTexture,GLsurfaceView