2018年1月9日 星期二

從 BootAnimation 探索 SurfaceFlinger (一) 世界的建構子們

前情提要

SurfaceFlinger 的架構十分龐大且複雜, 新手進入不易
我們先從 BootAnimation 的實例分析來對 SurfaceFlinger 進行初步的了解  (「・ω・)「

bootanimation 做為一個可執行檔, 是在 init.rc 裡作為一個 service 帶起來的:
    service bootanim /system/bin/bootanimation
查看bootanimation_main.cpp, 你可以發現它會察看一個 property (debug.sf.nobootanimation)來決定是否要執行 boot animation.
如果需要執行的話, 它會生成一個 BootAnimation 物件, 這就是真正運行起開機動畫的 class 了.

那麼, 我們首先從建構子開始下手!
BootAnimation::BootAnimation() : Thread(false), mZip(NULL)
{
    mSession = new SurfaceComposerClient();
}

void BootAnimation::onFirstRef() {
    status_t err = mSession->linkToComposerDeath(this);
    ALOGE_IF(err, "linkToComposerDeath failed (%s) ", strerror(-err));
    if (err == NO_ERROR) {
        run("BootAnimation", PRIORITY_DISPLAY);
    }
}

一開始生成了一個 SurfaceComposeClient 對象, 名為 mSession
可以想見的是要跟 SurfaceFlinger 溝通就是透過這個 mSession 來負責

我們看一下 SurfaceComposeClient 的建構子:
SurfaceComposerClient::SurfaceComposerClient()
    : mStatus(NO_INIT), mComposer(Composer::getInstance())
{
}

void SurfaceComposerClient::onFirstRef() {
    sp<ISurfaceComposer> sm(ComposerService::getComposerService());
    if (sm != 0) {
        sp<ISurfaceComposerClient> conn = sm->createConnection();
        if (conn != 0) {
            mClient = conn;
            mStatus = NO_ERROR;
        }
    }
}

這邊可以看到 Composer 跟 ComposerService 都是一個 singleton 的模式
雖然大家透過不同的 SurfaceComoserClient 來跟 SurfaceFlinger 溝通, 但是一次只有一個人可以使用服務

mComposer
這裡的 mComposer 並不是真正意義上去負責做 Compose 的那個 Composer, 而是比較接近讓 SurfaceComoserClient 有了一個上鎖的機制, 並且跟 ComposerService 來溝通

sm(ComposerService::getComposerSerivce())
這個 getComposerService() 會去取得 SurfaceFlinger 這個 service
(又一個前情提要, SurfaceFlinger 的服務是由 main_surfaceflinger.cpp 加入的, 它也是從 init.rc 帶起來的一個 service)

這裡呼叫了 sm->createConnection(),
在 SurfaceFlinger中會創建一個 ISurfaceComposerClient 對象回來, 並記為 mClient
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;
}

簡單的初始化結束後, 目前 BootAnimation 已經透過了 SurfaceComposerClient 與 SurfaceFlinger 建立起關係

接下來回到 BootAnimation
因為 onFirstRef 呼叫了 run(), 所以這邊會依序執行 readyToRun() 跟 threadLoop()

status_t BootAnimation::readyToRun() {
    // create the native surface
    sp<SurfaceControl> control = session()->createSurface(String8("BootAnimation"),
            dinfo.w, dinfo.h, PIXEL_FORMAT_RGB_565);

    ...
}

首先透過 SurfaceComposerClient 呼叫 createSurface, 並帶入了 Display 的寬高資訊
在這裡一定就是透過 mClient 對象去呼叫 SurfaceFlinger,
不過可以注意到這邊出現了一些新人物, 分別是:
handle, gbp, 以及 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;
}

先記得有這幾位新人, 我們看一下 createSurface 做了甚麼

status_t Client::createSurface(
        const String8& name,
        uint32_t w, uint32_t h, PixelFormat format, uint32_t flags,
        sp<IBinder>* handle,
        sp<IGraphicBufferProducer>* gbp)
{
    /*
     * createSurface must be called from the GL thread so that it can
     * have access to the GL context.
     */
    // 定義一個 Message +++
    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() {
            result = flinger->createLayer(name, client, w, h, format, flags,
                    handle, gbp);
            return true;
        }
    };
    // 定義一個 Message ---

    // 生成 Message
    sp<MessageBase> msg = new MessageCreateLayer(mFlinger.get(),
            name, this, w, h, format, flags, handle, gbp);
    // 將 Message 放入 Queue, 並等待回傳
    mFlinger->postMessageSync(msg);
    return static_cast<MessageCreateLayer*>( msg.get() )->getResult();
}

這是在 SurfaceFlinger 裡面一個很經典的呼叫, 這整段可以分成
1.) 定義一個 Message, 他用來呼叫 CreateLayer, 所以是 MessageCreateLayer
2.) 生成這個 Message, 並丟入 MessageQueue 中
3.) 等待 Message 處理完 (postMessageSync), 並回傳處理完的 Result

從這個 Message 的定義來看, 你會發現輪到處理它時, 就是執行這個 Message 的 handler
在這裡就是 SurfaceFlinger::createLayer();

各位的 SAN 值, 現在感覺如何呀?
 (」・ω・)」SAN値!(/・ω・)/ピンチ!

初次看這段的同學應該會覺得東西怎麼又多又亂,
我的建議是先大略看過一次了解每個部件的關鍵是甚麼, 再回頭熟讀.

那麼, 下面繼續展開 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)
{
    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;
    }

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

    setTransactionFlags(eTransactionNeeded);
    return result;
}

這裡因為預設的 flags 是 0, 所以會走 createNormalLayer

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

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

前面的format不會影響 (我們帶入的是 PIXEL_FORMAT_RGB_565)
因此這邊就是再生成了一個 Layer 對象, 並且把前面的 handle 跟 gbp 也一併賦址了
見到老朋友的感覺真好  (ノ∀`*)

讓我們看看 Layer 的建構子吧:

Layer::Layer(SurfaceFlinger* flinger, const sp<Client>& client,
        const String8& name, uint32_t w, uint32_t h, uint32_t flags)
    :   contentDirty(false),
        sequence(uint32_t(android_atomic_inc(&sSequence))),
        mFlinger(flinger),
        mTextureName(-1U),
        mPremultipliedAlpha(true),
        mName("unnamed"),
        mFormat(PIXEL_FORMAT_NONE),
        mTransactionFlags(0),
        mQueuedFrames(0),
        mSidebandStreamChanged(false),
        mCurrentTransform(0),
        mCurrentScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE),
        mCurrentOpacity(true),
        mRefreshPending(false),
        mFrameLatencyNeeded(false),
        mFiltering(false),
        mNeedsFiltering(false),
        mMesh(Mesh::TRIANGLE_FAN, 4, 2, 2),
        mProtectedByApp(false),
        mHasSurface(false),
        mClientRef(client),
        mPotentialCursor(false),
        mQueueItemLock(),
        mQueueItemCondition(),
        mQueueItems(),
        mLastFrameNumberReceived(0),
        mUpdateTexImageFailed(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::eSecure)
        layerFlags |= layer_state_t::eLayerSecure;

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

    mName = name;

    mCurrentState.active.w = w;
    mCurrentState.active.h = h;
    mCurrentState.active.crop.makeInvalid();
    mCurrentState.z = 0;
    mCurrentState.alpha = 0xFF;
    mCurrentState.layerStack = 0;
    mCurrentState.flags = layerFlags;
    mCurrentState.sequence = 0;
    mCurrentState.transform.set(0, 0);
    mCurrentState.requested = mCurrentState.active;

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

    nsecs_t displayPeriod =
            flinger->getHwComposer().getRefreshPeriod(HWC_DISPLAY_PRIMARY);
    mFrameTracker.setDisplayRefreshPeriod(displayPeriod);
}
這麼一長串的參數, 有沒有一種花惹發的感覺呢?
好在我們甚麼 flags 都沒有帶進來呢~
這邊看起來比較重要的人是 mDrawingState, 不過現在還不知道它能做甚麼

這種時候呢...
(ㆆᴗㆆ)

就是先不管它

姑且先看一下 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);

    mSurfaceFlingerConsumer->setDefaultMaxBufferCount(3);

    const sp<const DisplayDevice> hw(mFlinger->getDefaultDisplayDevice());
    updateTransformHint(hw);
}

野生的 BOSS 出現啦 (((゚Д゚;)))
這個 Producer 跟 Consumer 非常重要, 我建議各位在這裡先存個檔
然後播放激昂的戰鬥配樂 (像是Granblue Fantasy マグナ戦 BGM)
我們, 下一篇見!

沒有留言:

張貼留言

不定參數印 log

From the UNIXProcess_md.c #ifdef DEBUG_PROCESS   /* Debugging process code is difficult; where to write debug output? */ static void deb...