Android显示系统SurfaceFlinger分析

 更新时间:2021年12月19日 17:16:33   作者:Little熊猫  
本文详细讲解了Android显示系统SurfaceFlinger,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

一 Surfaceflinger介绍

surfaceflinger作用是接受多个来源的图形显示数据,将他们合成,然后发送到显示设备。比如打开应用,常见的有三层显示,顶部的statusbar底部或者侧面的导航栏以及应用的界面,每个层是单独更新和渲染,这些界面都是有surfaceflinger合成一个刷新到硬件显示。在显示过程中使用到了bufferqueue,surfaceflinger作为consumer方,比如windwomanager管理的surface作为生产方产生页面,交由surfaceflinger进行合成。

二 bufferqueue 原理

bufferqueue分为生产者和消费者

比如应用通过windowsmanager分配一个surface,需要分配(dequeueBuffer)显示空间在上面进行绘图,在图形绘制完成后需要推送(queueBuffer)到surfaceflinger进行合成显示。

surfaceflinger作为消费者,通过acquireBuffer()得到一个要合成的图形,在合成完毕后再releaseBuffer()将图形释放。

bufferqueue类图关系如下:

三 surfaceflinger 关系图

ComposerService 为单例模式负责与surfaceflinger建立binder连接代码如下:

class ComposerService : public Singleton<ComposerService>
{
    sp<ISurfaceComposer> mComposerService;
    sp<IBinder::DeathRecipient> mDeathObserver;
    Mutex mLock;

    ComposerService();
    void connectLocked();
    void composerServiceDied();
    friend class Singleton<ComposerService>;
public:

    // Get a connection to the Composer Service.  This will block until
    // a connection is established.
    static sp<ISurfaceComposer> getComposerService();
};

void ComposerService::connectLocked() {
    const String16 name("SurfaceFlinger");
    while (getService(name, &mComposerService) != NO_ERROR) {
        usleep(250000);
    }
    assert(mComposerService != NULL);

    // Create the death listener.
    class DeathObserver : public IBinder::DeathRecipient {
        ComposerService& mComposerService;
        virtual void binderDied(const wp<IBinder>& who) {
            ALOGW("ComposerService remote (surfaceflinger) died [%p]",
                  who.unsafe_get());
            mComposerService.composerServiceDied();
        }
     public:
        DeathObserver(ComposerService& mgr) : mComposerService(mgr) { }
    };

    mDeathObserver = new DeathObserver(*const_cast<ComposerService*>(this));
    mComposerService->asBinder()->linkToDeath(mDeathObserver);
}
/*static*/ sp<ISurfaceComposer> ComposerService::getComposerService() {
    ComposerService& instance = ComposerService::getInstance();
    Mutex::Autolock _l(instance.mLock);
    if (instance.mComposerService == NULL) {
        ComposerService::getInstance().connectLocked();
        assert(instance.mComposerService != NULL);
        ALOGD("ComposerService reconnected");
    }
    return instance.mComposerService;
}

SurfaceComposerClient则在于surfaceflinger建立连接后建立与Client的连接,通过client调用createSurface,然后返回SurfaceControl

sp<SurfaceControl> SurfaceComposerClient::createSurface(
        const String8& name,
        uint32_t w,
        uint32_t h,
        PixelFormat format,
        uint32_t flags)
{
    sp<SurfaceControl> sur;
    if (mStatus == NO_ERROR) {
        sp<IBinder> handle;
        sp<IGraphicBufferProducer> 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;
}

SurfaceControl负责这个显示层的控制。

sp<Surface> 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;
}

通过SurfaceControl::getSurface(),得到的真正的显示层,这样之后可以通过Lock和unlock将surface空间分配绘图,再返回给surfaceflinger

上面只是cpp侧的分析,上层比如WMS是java层,他的管理也是同底层一样,只不过是有层JNI的封装。

四 layer显示内存分配

surface创建后得到 mGraphicBufferProducer,通过mGraphicBufferProducer dequeubuffer在surfaceflinger的BnGraphicBufferProducer dequeuebuffer

int Surface::dequeueBuffer(android_native_buffer_t** buffer, int* fenceFd) {
    status_t result = mGraphicBufferProducer->dequeueBuffer(&buf, &fence, mSwapIntervalZero,
            reqW, reqH, mReqFormat, mReqUsage);

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

    if ((result & IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION) || gbuf == 0) {
        result = mGraphicBufferProducer->requestBuffer(buf, &gbuf);
        if (result != NO_ERROR) {
            ALOGE("dequeueBuffer: IGraphicBufferProducer::requestBuffer failed: %d", result);
            return result;
        }
       *buffer = gbuf.get();
    }

}

在producer的server侧,new GraphicBuffer分配一个GraphicBuffer

    if (returnFlags & BUFFER_NEEDS_REALLOCATION) {
        BQ_LOGV("dequeueBuffer: allocating a new buffer for slot %d", *outSlot);
        sp<GraphicBuffer> graphicBuffer = new GraphicBuffer(
                width, height, format, BQ_LAYER_COUNT, usage,
                {mConsumerName.string(), mConsumerName.size()});

在graphicbuffer中就是分配一个共享内存

GraphicBuffer::GraphicBuffer(uint32_t inWidth, uint32_t inHeight,
        PixelFormat inFormat, uint32_t inLayerCount, uint64_t usage, std::string requestorName)
    : GraphicBuffer()
{
    mInitCheck = initWithSize(inWidth, inHeight, inFormat, inLayerCount,
            usage, std::move(requestorName));
}

status_t GraphicBuffer::initWithSize(uint32_t inWidth, uint32_t inHeight,
        PixelFormat inFormat, uint32_t inLayerCount, uint64_t inUsage,
        std::string requestorName)
{
    GraphicBufferAllocator& allocator = GraphicBufferAllocator::get();
    uint32_t outStride = 0;
    status_t err = allocator.allocate(inWidth, inHeight, inFormat, inLayerCount,
            inUsage, &handle, &outStride, mId,
            std::move(requestorName));
    if (err == NO_ERROR) {
        mBufferMapper.getTransportSize(handle, &mTransportNumFds, &mTransportNumInts);

        width = static_cast<int>(inWidth);
        height = static_cast<int>(inHeight);
        format = inFormat;
        layerCount = inLayerCount;
        usage = inUsage;
        usage_deprecated = int(usage);
        stride = static_cast<int>(outStride);
    }
    return err;
}

GraphicBufferAllocator::get() 使用gralloc进行内存分配,分配完成后,得到bufferIdx 将他发给client端也就是surface端

    virtual status_t requestBuffer(int bufferIdx, sp<GraphicBuffer>* buf) {
        Parcel data, reply;
        data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
        data.writeInt32(bufferIdx);
        status_t result =remote()->transact(REQUEST_BUFFER, data, &reply);
        if (result != NO_ERROR) {
            return result;
        }
        bool nonNull = reply.readInt32();
        if (nonNull) {
            *buf = new GraphicBuffer();
            result = reply.read(**buf);
            if(result != NO_ERROR) {
                (*buf).clear();
                return result;
            }
        }
        result = reply.readInt32();
        return result;
    

返回虚拟地址给上层

        void* vaddr;
        status_t res = backBuffer->lockAsync(
                GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
                newDirtyRegion.bounds(), &vaddr, fenceFd);

五 surfaceflinger Layer

上面创建一个surface后,surfaceflinger对应的是一个layer,当上层layer调用刷新后,onFrameAvailable被调用,通知surfaceflinger有layer更新

void BufferLayer::onFrameAvailable(const BufferItem& item) {
    mFlinger->signalLayerUpdate();
}

到此这篇关于Android显示系统SurfaceFlinger分析的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • 快速解决Android适配底部返回键等虚拟键盘的问题

    快速解决Android适配底部返回键等虚拟键盘的问题

    今天小编就为大家分享一篇快速解决Android适配底部返回键等虚拟键盘的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-07-07
  • Kotlin基本类型自动装箱一点问题剖析

    Kotlin基本类型自动装箱一点问题剖析

    这篇文章主要剖析了Kotlin基本类型自动装箱的一点问题,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-10-10
  • Android实现小米相机底部滑动指示器

    Android实现小米相机底部滑动指示器

    这篇文章主要为大家详细介绍了Android实现小米相机底部滑动指示器,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-04-04
  • Flutter webview与网页通讯交互实现

    Flutter webview与网页通讯交互实现

    最近要在Flutter项目的基础上加一个实时定位的功能,下面这篇文章主要给大家介绍了关于Flutter webview与网页通讯交互实现的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考下
    2022-04-04
  • Android编程之TabWidget选项卡用法实例分析

    Android编程之TabWidget选项卡用法实例分析

    这篇文章主要介绍了Android编程之TabWidget选项卡用法,结合实例形式较为详细的分析了TabWidget选项卡的具体实现技巧与使用注意事项,需要的朋友可以参考下
    2015-12-12
  • Android视图绑定方法深入探究

    Android视图绑定方法深入探究

    这篇文章主要介绍了Android视图绑定方法,通过视图绑定viewBinding功能,您可以更轻松地编写可与视图交互的代码。在模块中启用视图绑定之后,系统会为该模块中的每个XML
    2023-01-01
  • Android Filterable实现Recyclerview筛选功能的示例代码

    Android Filterable实现Recyclerview筛选功能的示例代码

    这篇文章主要介绍了Android Filterable实现Recyclerview筛选功能的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-02-02
  • Flow转LiveData数据丢失原理详解

    Flow转LiveData数据丢失原理详解

    这篇文章主要为大家介绍了Flow转LiveData数据丢失原理详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-01-01
  • Python的异常概念介绍以及处理

    Python的异常概念介绍以及处理

    本篇文章给大家分享了关于Python异常的相关概念知识点以及处理方法,对此有需要的朋友赶快学习下吧。
    2018-03-03
  • Android使用ViewPager实现启动引导页

    Android使用ViewPager实现启动引导页

    这篇文章主要为大家详细介绍了Android使用ViewPager实现第一次启动引导页,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2016-07-07

最新评论