Android GUI系统之SurfaceFlinger(02)应用端分析1-获取Surface

114 篇文章 93 订阅

该系列文章总纲链接:Android GUI系统之SurfaceFlinger 系列文章目录


本章关键点总结 & 说明:

本章节思维导图如上。主要讲述了surafce测试程序 demo的 💰2步,获取SurfaceFlinger的客户端,进而获取 SurfaceControl,再获得Surface的过程。


0 关键源码说明

该部分代码是在上一章节中 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.1 创建surfaceflinger的客户端
    sp<SurfaceComposerClient> client = new SurfaceComposerClient();
    
    //1.2 获取surface
    sp<SurfaceControl> surfaceControl = client->createSurface(String8("resize"),
            160, 240, PIXEL_FORMAT_RGB_565, 0);
    sp<Surface> surface = surfaceControl->getSurface();

    //2 设置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;
}

主要的步骤为:

  1. 获取SurfaceFlinger(后简称SF)的客户端,通过SF的客户端 获取 SurfaceControl,进而获得Surface
  2. 通过SurfaceControl 设置 Layer层数值(忽略),通过Surface获取Buffer,锁定Buffer并写入Buffer
  3. 最后提交Buffer

本章节主要关注 第1步的过程。

1 获取SF客户端

我们从下面源码 开始分析:

sp<SurfaceComposerClient> client = new SurfaceComposerClient();

分析SurafceComposerClient,代码如下:

SurfaceComposerClient::SurfaceComposerClient()
    : mStatus(NO_INIT), mComposer(Composer::getInstance())
{
}

主要是初始化了mStatus和mComposer,同时留意下关键的onFirstRef函数,代码如下:

void SurfaceComposerClient::onFirstRef() {
    //获取SF 服务的客户端
    sp<ISurfaceComposer> sm(ComposerService::getComposerService());
    if (sm != 0) {
        //通过 SF服务的createConnection得到
        //一个client对象(ISurfaceComposerClient类型)
        sp<ISurfaceComposerClient> conn = sm->createConnection();
        if (conn != 0) {
            mClient = conn;
            mStatus = NO_ERROR;
        }
    }
}

这里首先获取SF服务,通过访问 SF服务的createConnection方法 获得 client(ISurfaceComposerClient类型,实际上是对应一个APP)对象。代码如下:

sp<ISurfaceComposerClient> SurfaceFlinger::createConnection()
{
    sp<ISurfaceComposerClient> bclient;
    sp<Client> client(new Client(this));
    status_t err = client->initCheck();
    if (err == NO_ERROR) {
        bclient = client;
    }
    return bclient;
}

这里主要是创建了一个client并返回给上一层的conn。(这里整个分析过程中 忽略了 Binder通信部分的分析,Binder通信部分详见系列文章链接:专题分纲目录 android 系统核心机制 binder,这里最后给出一张 该部分的Binder通信架构的UML图,如下所示:

2 获取Surface

我们首先是通过获取SF的客户端,进而获取 SurfaceControl,通过SurfaceControl再获得Surface,所以我们先分析 获取 SurfaceControl的流程,之后分析 获取Surface的流程。关键代码如下:

    sp<SurfaceControl> surfaceControl = client->createSurface(String8("resize"),
            160, 240, PIXEL_FORMAT_RGB_565, 0);
    sp<Surface> surface = surfaceControl->getSurface();

2.1 获取 SurfaceControl

这里关注 上面代码中的第一句,createSurface的实现代码如下:

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

这里的mClient->createSurface方法 最后调用了SF中Client类的createSurface(这个分析过程中 忽略了 Binder通信部分的分析,Binder通信部分详见系列文章链接:专题分纲目录 android 系统核心机制 binder,相关代码如下:

status_t Client::createSurface(
        const String8& name,
        uint32_t w, uint32_t h, PixelFormat format, uint32_t flags,
        sp<IBinder>* handle,
        sp<IGraphicBufferProducer>* gbp)
{
    class MessageCreateLayer : public MessageBase {
        SurfaceFlinger* flinger;
        Client* client;
        sp<IBinder>* handle;
        sp<IGraphicBufferProducer>* gbp;
        status_t result;
        const String8& name;
        uint32_t w, h;
        PixelFormat format;
        uint32_t flags;
    public:
        MessageCreateLayer(SurfaceFlinger* flinger,
                const String8& name, Client* client,
                uint32_t w, uint32_t h, PixelFormat format, uint32_t flags,
                sp<IBinder>* handle,
                sp<IGraphicBufferProducer>* gbp)
            : flinger(flinger), client(client),
              handle(handle), gbp(gbp),
              name(name), w(w), h(h), format(format), flags(flags) {
        }
        status_t getResult() const { return result; }
        virtual bool handler() {
            //通过SF 创建Layer
            result = flinger->createLayer(name, client, w, h, format, flags,
                    handle, gbp);
            return true;
        }
    };

    sp<MessageBase> msg = new MessageCreateLayer(mFlinger.get(),
            name, this, w, h, format, flags, handle, gbp);
    mFlinger->postMessageSync(msg);
    return static_cast<MessageCreateLayer*>( msg.get() )->getResult();
}

这里主要是 通过handler Message机制发送消息,最后通过SF创建了一个Layer,createLayer的代码如下:

status_t SurfaceFlinger::createLayer(
        const String8& name,
        const sp<Client>& client,
        uint32_t w, uint32_t h, PixelFormat format, uint32_t flags,
        sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp)
{
    if (int32_t(w|h) < 0) {
        return BAD_VALUE;
    }
    status_t result = NO_ERROR;
    sp<Layer> 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时会有两个分支,无论是用createNormalLayer还是createDimLayer创建,最终都会对handle和gbp进行赋值,两段代码如下:

status_t SurfaceFlinger::createNormalLayer(const sp<Client>& client,
        const String8& name, uint32_t w, uint32_t h, uint32_t flags, PixelFormat& format,
        sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp, sp<Layer>* 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();
    }

    return err;
}

status_t SurfaceFlinger::createDimLayer(const sp<Client>& client,
        const String8& name, uint32_t w, uint32_t h, uint32_t flags,
        sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp, sp<Layer>* outLayer)
{
    *outLayer = new LayerDim(this, client, name, w, h, flags);
    *handle = (*outLayer)->getHandle();
    *gbp = (*outLayer)->getProducer();
    return NO_ERROR;
}

两者都有 这段代码:

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

即对handle和gbp进行赋值,最后把这两个值传递给新创建的SurfaceControl,之后返回。分析到这里,可以看到每个Client端(对应APP)的SurfaceControl都对应一个Layer。同时上面的代码中LayerDim也是继承Layer的,那么创建Layer到底做了什么?我们继续分析。

2.2 创建的Layer分析

Layer类的构造函数如下:

Layer::Layer(SurfaceFlinger* flinger, const sp<Client>& client,
        const String8& name, uint32_t w, uint32_t h, uint32_t flags)
    :   contentDirty(false),
        //...
        mClientRef(client),
        mPotentialCursor(false)
{
    mCurrentCrop.makeInvalid();
    mFlinger->getRenderEngine().genTextures(1, &mTextureName);
    mTexture.init(Texture::TEXTURE_EXTERNAL, mTextureName);

    uint32_t layerFlags = 0;
    if (flags & ISurfaceComposerClient::eHidden)
        layerFlags |= layer_state_t::eLayerHidden;
    if (flags & ISurfaceComposerClient::eOpaque)
        layerFlags |= layer_state_t::eLayerOpaque;

    if (flags & ISurfaceComposerClient::eNonPremultiplied)
        mPremultipliedAlpha = false;

    mName = name;

    mCurrentState.active.w = w;
    //...
    mCurrentState.requested = mCurrentState.active;

    // drawing state & current state are identical
    mDrawingState = mCurrentState;

    nsecs_t displayPeriod =
            flinger->getHwComposer().getRefreshPeriod(HWC_DISPLAY_PRIMARY);
    mFrameTracker.setDisplayRefreshPeriod(displayPeriod);
}

可以看到以上主要是对一些变量的初始化,暂且忽略,再接着看关键方法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);
    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<const DisplayDevice> hw(mFlinger->getDefaultDisplayDevice());
    updateTransformHint(hw);
}

这里主要就涉及生产者和消费者的BufferQueue的管理了。

2.2.1 createBufferQueue方法

这里关注BufferQueue的createBufferQueue方法,代码如下:

void BufferQueue::createBufferQueue(sp<IGraphicBufferProducer>* outProducer,
        sp<IGraphicBufferConsumer>* outConsumer,
        const sp<IGraphicBufferAlloc>& allocator) {
    sp<BufferQueueCore> core(new BufferQueueCore(allocator));
    sp<IGraphicBufferProducer> producer(new BufferQueueProducer(core));
    sp<IGraphicBufferConsumer> consumer(new BufferQueueConsumer(core));
    *outProducer = producer;
    *outConsumer = consumer;
}

每个Layer都有一个生产者producer和消费者consumer并指向同一个BufferQueueCore,关键成员变量BufferQueueDefs::SlotsType mSlots;SlotsType类型是一个数量为64的数组。即生产者producer和消费者consumer最终指向的同一个核心数组 mSlots(一个64元素的数组)。

2.2.2 MonitoredProducer类分析

MonitoredProducer(producer, mFlinger)中 producer 和SF的关系 主要是在析构时 SF 将producer从mGraphicBufferProducerList (gbp链表)中移除,对应代码如下:

//构造函数
MonitoredProducer::MonitoredProducer(const sp<IGraphicBufferProducer>& producer,
        const sp<SurfaceFlinger>& flinger) :
    mProducer(producer),
    mFlinger(flinger) {}
//析构函数
MonitoredProducer::~MonitoredProducer() {
    class MessageCleanUpList : public MessageBase {
    public:
        MessageCleanUpList(const sp<SurfaceFlinger>& flinger,
                const wp<IBinder>& producer)
            : mFlinger(flinger), mProducer(producer) {}
        virtual ~MessageCleanUpList() {}
        virtual bool handler() {
            Mutex::Autolock _l(mFlinger->mStateLock);
            mFlinger->mGraphicBufferProducerList.remove(mProducer);
            return true;
        }
    private:
        sp<SurfaceFlinger> mFlinger;
        wp<IBinder> mProducer;
    };

    mFlinger->postMessageAsync(new MessageCleanUpList(mFlinger, asBinder()));
}

其他的方法主要依赖于传入的producer对象。本质上就是套壳调用而以。

2.3 获取Surface

这里关注 上面代码中的第二句,surfaceControl->getSurface()的实现代码如下:

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.
        //这里的mGraphicBufferProducer就是之前传递进来的gbp
        mSurfaceData = new Surface(mGraphicBufferProducer, false);
    }
    return mSurfaceData;
}

这里创建了一个新的Surface并把gbp参数传递给Surface,最后返回。可以理解为 客户端创建Surface,最终由SurfaceFlinger将返回,而返回再最主要参数就是gbp生产者。

2.4 总结

每个APP对应一个client,一个SurfaceControl对应创建一个Layer,每个SurfaceControl中的 gbp(BpGraphicBufferProducer)对应 Layer中的mProducer(BnGraphicBufferProducer),它们均遵守同一个接口IGraphicBufferProducer,相关类的关系如下所示:

2.5 思考

在这里我们思考一个问题,就是为什么要设计成SurfaceControl和Surface两个类呢?本质上是可以直接设计成通过SurfaceComposerClient来直接获取Surface的,那么为什么一定要先拿到SurfaceControl,然后再通过SurfaceControl来获取Surface呢?

这是因为在Android中,SurfaceControl和Surface它们在不同的层面上提供了不同的功能和控制。SurfaceControl更强调Surface的控制和处理,比如:创建、删除、属性控制、支持硬件加速等,而Surface更强调图层内容本身的处理和显示。

SurfaceControl类提供了对屏幕上图层的底层控制,它允许应用程序创建、管理和操作图层。SurfaceControl可以用于以下方面:

  • 创建和管理多个Surface对象:SurfaceControl允许应用程序创建多个Surface对象,并对它们进行管理。这对于实现复杂的UI效果、多窗口显示以及多个应用程序之间的交互非常有用。
  • 提供对图层属性的控制:SurfaceControl提供了对图层属性(如位置、大小、透明度等)的控制,使应用程序能够动态地更改图层的外观和行为。
  • 可以跨进程使用:SurfaceControl可以在不同的进程之间共享和传递,使应用程序能够在不同的组件之间进行图层的传递和共享。
  • 支持硬件加速和显示:SurfaceControl与底层图形系统交互,可以利用硬件加速和显示功能,提高图层的性能和效果。

Surface类是对图层内容的抽象表示,它包含了要在屏幕上绘制的像素数据。Surface可以用于以下方面:

  • 绘制和渲染图形内容:Surface允许应用程序将图形内容绘制到其上,并在屏幕上显示。应用程序可以使用Canvas或OpenGL等图形库来绘制图形。
  • 接收用户输入事件:Surface可以接收用户的触摸事件或手势,以便应用程序能够对用户输入做出响应。
  • 提供与媒体处理相关的功能:Surface可以用于媒体播放、视频渲染和相机预览等场景,以提供更高效的媒体处理能力。

尽管Surface可以用于很多图形操作和显示需求,但SurfaceControl提供了更底层的控制和灵活性,使应用程序能够更好地管理和操作图层。SurfaceControl和Surface两者结合使用,可以满足不同应用场景下的需求,提供更强大的图形控制和显示能力。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

图王大胜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值