Android 12(S) 圖形顯示系統 - createSurface的流程(五)

二的次方發表於2022-02-08

題外話

剛剛開始著筆寫作這篇文章時,正好看電視在採訪一位92歲的考古學家,在他的日記中有這樣一句話,寫在這裡與君共勉“不要等待幸運的降臨,要去努力的掌握知識”。如此樸實的一句話,此時此刻,正適合我們。


1 前言

回到前面的文章:Android 12(S) 圖形顯示系統 - 示例應用(二)  ,在上一篇文章中已經講解了應用如何與SurfaceFlinger建立連線和通訊,接下來就要去建立Surface了,當然在此之前,還有獲取螢幕Display資訊的操作,這不是關注的重點,先不展開講解。
// create the native surface
sp<SurfaceControl> surfaceControl = surfaceComposerClient->createSurface(mName, 
                                                            resolution.getWidth(), 
                                                            resolution.getHeight(), PIXEL_FORMAT_RGBA_8888,
                                                            ISurfaceComposerClient::eFXSurfaceBufferState,
                                                            /*parent*/ nullptr);

注:本片涉及的程式碼

/frameworks/native/libs/gui/SurfaceComposerClient.cpp

/frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp

/frameworks/native/services/surfaceflinger/Client.cpp

/frameworks/native/libs/gui/ISurfaceComposer.cpp


 

2 createSurface的流程

先把類圖貼這裡,待會分析流程便於檢視資料的流向
 

SurfaceComposerClient::createSurface

程式碼如下,比較簡單,使用時需要傳遞一個名字(name),指定寬高資訊,指定格式(format)等,返回一個SurfaceControl的指標,這個方法中呼叫了createSurfaceChecked

* /frameworks/native/libs/gui/SurfaceComposerClient.cpp

sp<SurfaceControl> SurfaceComposerClient::createSurface(const String8& name, uint32_t w, uint32_t h,
                                                        PixelFormat format, uint32_t flags,
                                                        const sp<IBinder>& parentHandle,
                                                        LayerMetadata metadata,
                                                        uint32_t* outTransformHint) {
    sp<SurfaceControl> s;
    createSurfaceChecked(name, w, h, format, &s, flags, parentHandle, std::move(metadata),
                         outTransformHint);
    return s;
}

SurfaceComposerClient::createSurfaceChecked

這個方法的核心是 mClient->createSurface ,前面講過(sp<ISurfaceComposerClient>  mClient)是Client的代理客戶端,最終呼叫到服務端 Client::createSurface

這個方法中還有兩個變數:

sp<IBinder> handle  == 這個代表什麼? ==> SurfaceFlinger中建立的Layer的控制程式碼或標識

sp<IGraphicBufferProducer> gbp == 他又是誰?==>這個gbp貌似已經沒有實際用途了,BLASTBufferQueue分擔了任務

* /frameworks/native/libs/gui/SurfaceComposerClient.cpp

status_t SurfaceComposerClient::createSurfaceChecked(const String8& name, uint32_t w, uint32_t h,
                                                     PixelFormat format,
                                                     sp<SurfaceControl>* outSurface, uint32_t flags,
                                                     const sp<IBinder>& parentHandle,
                                                     LayerMetadata metadata,
                                                     uint32_t* outTransformHint) {
    sp<SurfaceControl> sur;
    status_t err = mStatus;

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

        uint32_t transformHint = 0;
        int32_t id = -1;
        err = mClient->createSurface(name, w, h, format, flags, parentHandle, std::move(metadata),
                                     &handle, &gbp, &id, &transformHint);

        if (outTransformHint) {
            *outTransformHint = transformHint;
        }
        ALOGE_IF(err, "SurfaceComposerClient::createSurface error %s", strerror(-err));
        if (err == NO_ERROR) {
            *outSurface =
                    new SurfaceControl(this, handle, gbp, id, w, h, format, transformHint, flags);
        }
    }
    return err;
}
 

Client::createSurface

Binder IPC 跨程式,一路飛奔,直接執行到了Client::createSurface函式中,先看程式碼:
*  /frameworks/native/services/surfaceflinger/Client.cpp

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, int32_t* outLayerId,
                               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, outLayerId, nullptr, outTransformHint);
}
上面這段程式碼是不是很簡單,前面文章中也有提到Client物件中持有執行SurfaceFlinger的指標 sp<SurfaceFlinger> mFlinger
SurfaceFlinger隆重登場,呼叫 mFlinger->createLayer 。

SurfaceFlinger::createLayer

瞅瞅createLayer中都幹了哪些事情呢?
* /frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp

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, int32_t* outLayerId,
                                     const sp<Layer>& parentLayer, uint32_t* outTransformHint) {
    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;
    }

    ALOG_ASSERT(parentLayer == nullptr || parentHandle == nullptr,
            "Expected only one of parentLayer or parentHandle to be non-null. "
            "Programmer error?");

    status_t result = NO_ERROR;

    sp<Layer> layer;

    std::string uniqueName = getUniqueLayerName(name.string());

    switch (flags & ISurfaceComposerClient::eFXSurfaceMask) {
        case ISurfaceComposerClient::eFXSurfaceBufferQueue:
        case ISurfaceComposerClient::eFXSurfaceBufferState: {
            result = createBufferStateLayer(client, std::move(uniqueName), w, h, flags,
                                            std::move(metadata), handle, &layer);
            std::atomic<int32_t>* pendingBufferCounter = layer->getPendingBufferCounter();
            if (pendingBufferCounter) {
                std::string counterName = layer->getPendingBufferCounterName();
                mBufferCountTracker.add((*handle)->localBinder(), counterName,
                                        pendingBufferCounter);
            }
        } 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;
    }

    if (result != NO_ERROR) {
        return result;
    }

    bool addToRoot = callingThreadHasUnscopedSurfaceFlingerAccess();
    result = addClientLayer(client, *handle, *gbp, layer, parentHandle, parentLayer, addToRoot,
                            outTransformHint);
    if (result != NO_ERROR) {
        return result;
    }
    mInterceptor->saveSurfaceCreation(layer);

    setTransactionFlags(eTransactionNeeded);
    *outLayerId = layer->sequence;
    return result;
}

1. 檢查寬高數值是否合法,寬/高不應為負值;

2. 檢查parentLayer/parentHandle,對於我們的應用來說,沒有parent,兩者都為 null;

3. 獲取一個獨一無二的Layer name,即不能有重名的Layer;

4. 根據flags去建立對應型別的Layer ⇒ createBufferStateLayer or createEffectLayer or createContainerLayer

Surface建立標誌 SurfaceFlinger方法 Layer例項 簡單說明
eFXSurfaceBufferQueue createBufferStateLayer BufferStateLayer

Creates a normal surface.

標準的Surface

eFXSurfaceBufferState
eFXSurfaceEffect createEffectLayer EffectLayer

Creates a effect surface which represents a solid color and or shadows.

純色或陰影的顯示效果的Surface

eFXSurfaceContainer createContainerLayer ContainerLayer

Creates a container surface. This surface will have no buffers and will only be used as a container for other surfaces, or for its InputInfo.

建立surface容器。此surface沒有緩衝區,僅用作其他surfaces或InputInfo的容器。

 
Layer的詳細知識我們之後再介紹,目前先以熟悉流程為主。
 

Tips:

有意思的一點是 BufferQueueLayer 貌似不再有實際用途了


 
5. 呼叫SurfaceFlinger::addClientLayer方法:
> 將新建立的Layer加入到 mCreatedLayers 這個列表中;
> client->attachLayer(handle, lbc)將新建立的Layer加入到對應的Client的 mLayers;
> setTransactionState 為後續SurfaceFlinger去做一些更新設定狀態資訊
 
6. Layer建立完成後,呼叫setTransactionFlags函式,告訴SurfaceFlinger,新增加了Layer,有新的顯示,有很多顯示資料需要去更新。SurfaceFlinger根據flag,決定是否需要換醒服務。
    比如addClientLayer時設定一些Transaction State
> 因為有設定 composerState.state.what = layer_state_t::eLayerCreated;  所以最終會call到 SurfaceFlinger::setClientStateLocked ==> SurfaceFlinger::handleLayerCreatedLocked
> SurfaceFlinger::handleLayerCreatedLocked中將新建立的Layer新增到mCurrentState的layer列表中,按照Z-order排序 , mGraphicBufferProducerList儲存了當前的所有Layer內容的生產者

 

感覺這裡講解的還是迷迷糊糊,雲裡霧裡,其實我自己也很多疑惑

 

Surface or Layer建立完成,應用得到了什麼?

回過頭再瞅一眼 SurfaceComposerClient::createSurfaceChecked 這個函式的程式碼,客戶端主要獲取到以下幾個資訊:

sp<IBinder> handle;
sp<IGraphicBufferProducer> gbp;
uint32_t transformHint = 0;
int32_t id = -1;
 

Layer handle

這個handle是在建立Layer時賦值的

status_t SurfaceFlinger::createBufferStateLayer(const sp<Client>& client, std::string name,
                                                uint32_t w, uint32_t h, uint32_t flags,
                                                LayerMetadata metadata, sp<IBinder>* handle,
                                                sp<Layer>* outLayer) {
    LayerCreationArgs args(this, client, std::move(name), w, h, flags, std::move(metadata));
    args.textureName = getNewTexture();
    sp<BufferStateLayer> layer = getFactory().createBufferStateLayer(args);
    *handle = layer->getHandle();
    *outLayer = layer;

    return NO_ERROR;
}
 
其中呼叫了Layer::getHandle()
sp<IBinder> Layer::getHandle() {
    Mutex::Autolock _l(mLock);
    if (mGetHandleCalled) {
        ALOGE("Get handle called twice" );
        return nullptr;
    }
    mGetHandleCalled = true;
    return new Handle(mFlinger, this);
}
 
再來看看Handle的定義,它就是一個BBinder物件,可以通過Binder IPC機制傳遞給客戶端
    /*
     * The layer handle is just a BBinder object passed to the client
     * (remote process) -- we don't keep any reference on our side such that
     * the dtor is called when the remote side let go of its reference.
     *
     * LayerCleaner ensures that mFlinger->onLayerDestroyed() is called for
     * this layer when the handle is destroyed.
     */
    class Handle : public BBinder, public LayerCleaner {
    public:
        Handle(const sp<SurfaceFlinger>& flinger, const sp<Layer>& layer)
              : LayerCleaner(flinger, layer), owner(layer) {}

        wp<Layer> owner;
    };
 
我把它暫且理解為 sp<IBinder> handle  ==  SurfaceFlinger中建立的Layer的控制程式碼或標識
 
最後所有在客戶端獲取到的Layer資訊都被封裝到一個SurfaceControl物件中,並返回給應用來使用。
if (err == NO_ERROR) {
   *outSurface =
       new SurfaceControl(this, handle, gbp, id, w, h, format, transformHint, flags);
}
 
 

3 事務處理

再返回檢視應用的程式碼,執行完 surfaceComposerClient->createSurface 建立好一個Layer圖層後,便去設定Layer的一些狀態:
SurfaceComposerClient::Transaction{}
           .setLayer(surfaceControl, std::numeric_limits<int32_t>::max())
           .show(surfaceControl)
           .apply();
 
這裡利用了Transaction類來完成狀態資訊的傳遞,那它是如何通知到SurfaceFlinger的呢?
先看一下Transaction類中都定義了哪些內容和功能:下面類圖並沒有把全部方法都列出
 
Android 12(S) 圖形顯示系統 - createSurface的流程(五)
可以看到Transaction中提供大量方法,用於設定影像顯示的屬性等狀態,比如show/hide/setPosition
 
你應該已經注意到了,Transaction中有兩個非常重要的成員:mComposerStates和mDisplayStates,這兩個成員分別用於處理兩種不同型別的事務:合成相關事務 和 螢幕相關事務
 
 
ComposerState
* /frameworks/native/libs/gui/include/gui/LayerState.h

struct ComposerState {
    layer_state_t state;
    status_t write(Parcel& output) const;
    status_t read(const Parcel& input);
};
ComposerState中主要包含成員 layer_state_t ,read/write函式用於BinderIPC 通訊時封裝和解析資料
 
layer_state_t
Used to communicate layer information between SurfaceFlinger and its clients.
用於在SurfaceFlinger和客戶端之間傳遞layer資訊。其定義可以參見   /frameworks/native/libs/gui/include/gui/LayerState.h
 
其中成員 what 用於標記layer的哪些狀態/屬性發生了變化,可能的變化有:
    enum {
        ePositionChanged = 0x00000001,
        eLayerChanged = 0x00000002,
        eSizeChanged = 0x00000004,
        eAlphaChanged = 0x00000008,
        eMatrixChanged = 0x00000010,
        eTransparentRegionChanged = 0x00000020,
        eFlagsChanged = 0x00000040,
        eLayerStackChanged = 0x00000080,
        eReleaseBufferListenerChanged = 0x00000400,
        eShadowRadiusChanged = 0x00000800,
        eLayerCreated = 0x00001000,
        eBufferCropChanged = 0x00002000,
        eRelativeLayerChanged = 0x00004000,
        eReparent = 0x00008000,
        eColorChanged = 0x00010000,
        eDestroySurface = 0x00020000,
        eTransformChanged = 0x00040000,
        eTransformToDisplayInverseChanged = 0x00080000,
        eCropChanged = 0x00100000,
        eBufferChanged = 0x00200000,
        eAcquireFenceChanged = 0x00400000,
        eDataspaceChanged = 0x00800000,
        eHdrMetadataChanged = 0x01000000,
        eSurfaceDamageRegionChanged = 0x02000000,
        eApiChanged = 0x04000000,
        eSidebandStreamChanged = 0x08000000,
        eColorTransformChanged = 0x10000000,
        eHasListenerCallbacksChanged = 0x20000000,
        eInputInfoChanged = 0x40000000,
        eCornerRadiusChanged = 0x80000000,
        eDestinationFrameChanged = 0x1'00000000,
        eCachedBufferChanged = 0x2'00000000,
        eBackgroundColorChanged = 0x4'00000000,
        eMetadataChanged = 0x8'00000000,
        eColorSpaceAgnosticChanged = 0x10'00000000,
        eFrameRateSelectionPriority = 0x20'00000000,
        eFrameRateChanged = 0x40'00000000,
        eBackgroundBlurRadiusChanged = 0x80'00000000,
        eProducerDisconnect = 0x100'00000000,
        eFixedTransformHintChanged = 0x200'00000000,
        eFrameNumberChanged = 0x400'00000000,
        eBlurRegionsChanged = 0x800'00000000,
        eAutoRefreshChanged = 0x1000'00000000,
        eStretchChanged = 0x2000'00000000,
        eTrustedOverlayChanged = 0x4000'00000000,
    };
 
比如setBuffer時設定eBufferChanged標記位
SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setBuffer(...) {
    layer_state_t* s = getLayerState(sc);
    ...
    s->what |= layer_state_t::eBufferChanged;
    ...
}
 
 
DisplayState

struct DisplayState {
    enum {
        eSurfaceChanged = 0x01,
        eLayerStackChanged = 0x02,
        eDisplayProjectionChanged = 0x04,
        eDisplaySizeChanged = 0x08
    };

    DisplayState();
    void merge(const DisplayState& other);

    uint32_t what;
    sp<IBinder> token;
    sp<IGraphicBufferProducer> surface;
    uint32_t layerStack;

    // These states define how layers are projected onto the physical display.
    //
    // Layers are first clipped to `layerStackSpaceRect'.  They are then translated and
    // scaled from `layerStackSpaceRect' to `orientedDisplaySpaceRect'.  Finally, they are rotated
    // according to `orientation', `width', and `height'.
    //
    // For example, assume layerStackSpaceRect is Rect(0, 0, 200, 100), orientedDisplaySpaceRect is
    // Rect(20, 10, 420, 210), and the size of the display is WxH.  When orientation is 0, layers
    // will be scaled by a factor of 2 and translated by (20, 10). When orientation is 1, layers
    // will be additionally rotated by 90 degrees around the origin clockwise and translated by (W,
    // 0).
    ui::Rotation orientation = ui::ROTATION_0;
    Rect layerStackSpaceRect;
    Rect orientedDisplaySpaceRect;

    uint32_t width, height;

    status_t write(Parcel& output) const;
    status_t read(const Parcel& input);
};
 
Display的狀態有4個,也就是
    enum {
        eSurfaceChanged = 0x01,            // surface改變了
        eLayerStackChanged = 0x02,         // layer stack改變了
        eDisplayProjectionChanged = 0x04,  // display projecttion改變了
        eDisplaySizeChanged = 0x08         // display size改變了
    };
 
其中成員 DispalyState::what,就是用以標記哪些屬性改變了,有多個屬性改變的時候,加上對應的mark標記位即可。
比如setDisplaySize時設定eDisplaySizeChanged標記位
void SurfaceComposerClient::Transaction::setDisplaySize(const sp<IBinder>& token, uint32_t width, uint32_t height) {
    DisplayState& s(getDisplayState(token));
    s.width = width;
    s.height = height;
    s.what |= DisplayState::eDisplaySizeChanged;
}

 

在我們的應用中,呼叫了setLayer/show/apply,我們看看Transaction是如何把狀態/屬性資訊傳遞給SurfaceFlinger的.

setLayer,設定Layer的z-order

SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setLayer(
        const sp<SurfaceControl>& sc, int32_t z) {
    layer_state_t* s = getLayerState(sc);
    if (!s) {
        mStatus = BAD_INDEX;
        return *this;
    }
    s->what |= layer_state_t::eLayerChanged;
    s->what &= ~layer_state_t::eRelativeLayerChanged;
    s->z = z;

    registerSurfaceControlForCallback(sc);
    return *this;
}

getLayerState,就是根據SurfaceCotrol物件去找對應的layer_state_t。

layer_state_t* SurfaceComposerClient::Transaction::getLayerState(const sp<SurfaceControl>& sc) {
    auto handle = sc->getLayerStateHandle();

    if (mComposerStates.count(handle) == 0) {
        // we don't have it, add an initialized layer_state to our list
        ComposerState s;

        s.state.surface = handle;
        s.state.layerId = sc->getLayerId();

        mComposerStates[handle] = s;
    }

    return &(mComposerStates[handle].state);
}

文章前面講解SurfaceComposerClient::createSurface時,我們知曉SurfaceFlinger建立好Layer後返回給客戶端Layer handle和id,這些Layer資訊都被封裝到一個SurfaceControl物件,SurfaceControl::getLayerStateHandle返回的就是這個Layer handle

sp<IBinder> SurfaceControl::getLayerStateHandle() const
{
    return mHandle;
}

然後判斷這個layer hanlde是否在mComposerStates中,如果沒有則建立對應的ComposerState並加入

我們看,setLayer時,增加標識what是layer_state_t::eLayerChanged,而對應的值儲存到layer_state_t 中。你應該注意到了設定看起來沒有立即生效,

同樣,show時,也是將對應的標識加到what中,而是否顯示的標識存放在layer_state_t的flag中。

SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::show(
        const sp<SurfaceControl>& sc) {
    return setFlags(sc, 0, layer_state_t::eLayerHidden);
}

SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setFlags(
        const sp<SurfaceControl>& sc, uint32_t flags,
        uint32_t mask) {
    layer_state_t* s = getLayerState(sc);
    if (!s) {
        mStatus = BAD_INDEX;
        return *this;
    }
    if ((mask & layer_state_t::eLayerOpaque) || (mask & layer_state_t::eLayerHidden) ||
        (mask & layer_state_t::eLayerSecure) || (mask & layer_state_t::eLayerSkipScreenshot) ||
        (mask & layer_state_t::eEnableBackpressure)) {
        s->what |= layer_state_t::eFlagsChanged;
    }
    s->flags &= ~mask;
    s->flags |= (flags & mask);
    s->mask |= mask;

    registerSurfaceControlForCallback(sc);
    return *this;
}

 

最後呼叫apply,使得設定生效

status_t SurfaceComposerClient::Transaction::apply(bool synchronous) {
    ...
    sp<ISurfaceComposer> sf(ComposerService::getComposerService());

    ...
    cacheBuffers();

    Vector<ComposerState> composerStates;
    Vector<DisplayState> displayStates;

    for (auto const& kv : mComposerStates){
        composerStates.add(kv.second);
    }

    displayStates = std::move(mDisplayStates);


    ...
    sf->setTransactionState(mFrameTimelineInfo, composerStates, displayStates, flags, applyToken,
                            mInputWindowCommands, mDesiredPresentTime, mIsAutoTimestamp,
                            {} /*uncacheBuffer - only set in doUncacheBufferTransaction*/,
                            hasListenerCallbacks, listenerCallbacks, mId);
    mId = generateId();

    // Clear the current states and flags
    clear();
    ...
}

 

apply時,最重要的就是呼叫sf->setTransactionState,Binder IPC一路飛奔到了SurfaceFlinger::setTransactionState

status_t SurfaceFlinger::setTransactionState(...) {
    ATRACE_CALL();
    ......
    IPCThreadState* ipc = IPCThreadState::self();
    const int originPid = ipc->getCallingPid();
    const int originUid = ipc->getCallingUid();
    TransactionState state{frameTimelineInfo,  states,
                           displays,           flags,
                           applyToken,         inputWindowCommands,
                           desiredPresentTime, isAutoTimestamp,
                           uncacheBuffer,      postTime,
                           permissions,        hasListenerCallbacks,
                           listenerCallbacks,  originPid,
                           originUid,          transactionId};

    // Check for incoming buffer updates and increment the pending buffer count.
    state.traverseStatesWithBuffers([&](const layer_state_t& state) {
        mBufferCountTracker.increment(state.surface->localBinder());
    });
    queueTransaction(state);

    // Check the pending state to make sure the transaction is synchronous.
    if (state.transactionCommittedSignal) {
        waitForSynchronousTransaction(*state.transactionCommittedSignal);
    }

    return NO_ERROR;
}

SurfaceFlinger把資訊封裝到一個TransactionState變數中:

    TransactionState state{frameTimelineInfo,  states,
                           displays,           flags,
                           applyToken,         inputWindowCommands,
                           desiredPresentTime, isAutoTimestamp,
                           uncacheBuffer,      postTime,
                           permissions,        hasListenerCallbacks,
                           listenerCallbacks,  originPid,
                           originUid,          transactionId};

然後放置到待處理的Transaction佇列中: SurfaceFlinger::queueTransaction

void SurfaceFlinger::queueTransaction(TransactionState& state) {
    Mutex::Autolock _l(mQueueLock);

    ...

    mTransactionQueue.emplace(state);
    ATRACE_INT("TransactionQueue", mTransactionQueue.size());


    setTransactionFlags(eTransactionFlushNeeded, schedule, state.applyToken);
}

SurfaceFlinger::setTransactionFlags中在 滿足一定條件時 呼叫signalTransaction觸發執行 invalidate 操作

uint32_t SurfaceFlinger::setTransactionFlags(uint32_t flags, TransactionSchedule schedule,
                                             const sp<IBinder>& token) {
    uint32_t old = mTransactionFlags.fetch_or(flags);
    modulateVsync(&VsyncModulator::setTransactionSchedule, schedule, token);
    if ((old & flags) == 0) signalTransaction();
    return old;
}

void SurfaceFlinger::signalTransaction() {
    mScheduler->resetIdleTimer();
    mPowerAdvisor.notifyDisplayUpdateImminent();
    mEventQueue->invalidate();
}

上一篇文章 Android 12(S) 圖形顯示系統 - SurfaceFlinger的啟動和訊息佇列處理機制(四)

我們分析訊息處理機制時對 invalidate 的執行介紹過

// 第一步

void SurfaceFlinger::onMessageReceived(int32_t what, int64_t vsyncId, nsecs_t expectedVSyncTime) {
    switch (what) {
        case MessageQueue::INVALIDATE: {
            onMessageInvalidate(vsyncId, expectedVSyncTime);
            break;
        }
    }
}

// 第二步
void SurfaceFlinger::onMessageInvalidate(int64_t vsyncId, nsecs_t expectedVSyncTime) {
  ...
    refreshNeeded = handleMessageTransaction();
  ...
}

// 第三步
bool SurfaceFlinger::handleMessageTransaction() {
    ATRACE_CALL();

    if (getTransactionFlags(eTransactionFlushNeeded)) {
        flushTransactionQueues();
    }
    ...
}

// 第四步
void SurfaceFlinger::flushTransactionQueues() {
  ...
        // Now apply all transactions.
        for (const auto& transaction : transactions) {
            applyTransactionState(transaction.frameTimelineInfo, transaction.states,
                                  transaction.displays, transaction.flags,
                                  transaction.inputWindowCommands, transaction.desiredPresentTime,
                                  transaction.isAutoTimestamp, transaction.buffer,
                                  transaction.postTime, transaction.permissions,
                                  transaction.hasListenerCallbacks, transaction.listenerCallbacks,
                                  transaction.originPid, transaction.originUid, transaction.id);
            if (transaction.transactionCommittedSignal) {
                mTransactionCommittedSignals.emplace_back(
                        std::move(transaction.transactionCommittedSignal));
            }
        }
  ...
}

// 第五步
void SurfaceFlinger::applyTransactionState(...) {
    ...
    for (const DisplayState& display : displays) {
        transactionFlags |= setDisplayStateLocked(display);
    }
  
      for (const ComposerState& state : states) {
        clientStateFlags |=
                setClientStateLocked(frameTimelineInfo, state, desiredPresentTime, isAutoTimestamp,
                                     postTime, permissions, listenerCallbacksWithSurfaces);
    }
      
    ...
}

// 第六步  

uint32_t SurfaceFlinger::setDisplayStateLocked(const DisplayState& s) {}
uint32_t SurfaceFlinger::setClientStateLocked(){}

跋山涉水,走到了setClientStateLocked/setDisplayStateLocked

setDisplayStateLocked

uint32_t SurfaceFlinger::setDisplayStateLocked(const DisplayState& s) {
    const ssize_t index = mCurrentState.displays.indexOfKey(s.token);
    if (index < 0) return 0;

    uint32_t flags = 0;
    DisplayDeviceState& state = mCurrentState.displays.editValueAt(index);

    const uint32_t what = s.what;
    if (what & DisplayState::eSurfaceChanged) {
        if (IInterface::asBinder(state.surface) != IInterface::asBinder(s.surface)) {
            state.surface = s.surface;
            flags |= eDisplayTransactionNeeded;
        }
    }
    ....
}

setDisplayStateLocked中會把我們在客戶端設定的標誌為資訊解析出來儲存到mCurrentState中

 

setClientStateLocked

uint32_t SurfaceFlinger::setClientStateLocked(){
    ....
    
    if (what & layer_state_t::eLayerChanged) {
        // NOTE: index needs to be calculated before we update the state
        const auto& p = layer->getParent();
        if (p == nullptr) {
            ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer);
            if (layer->setLayer(s.z) && idx >= 0) { // setLayer
                mCurrentState.layersSortedByZ.removeAt(idx);
                mCurrentState.layersSortedByZ.add(layer);
                // we need traversal (state changed)
                // AND transaction (list changed)
                flags |= eTransactionNeeded|eTraversalNeeded;
            }
        } else {
            if (p->setChildLayer(layer, s.z)) {
                flags |= eTransactionNeeded|eTraversalNeeded;
            }
        }
    }
    
    ....

}

setClientStateLocked中同樣會把我們在客戶端設定的標誌為資訊解析出來,然後設定到對應的Layer中去,這裡就是呼叫了layer->setLayer,z-order資訊儲存到了layer的mDrawingState中

bool Layer::setLayer(int32_t z) {
    if (mDrawingState.z == z && !usingRelativeZ(LayerVector::StateSet::Current)) return false;
    mDrawingState.sequence++;
    mDrawingState.z = z;
    mDrawingState.modified = true;

    mFlinger->mSomeChildrenChanged = true;

    // Discard all relative layering.
    if (mDrawingState.zOrderRelativeOf != nullptr) {
        sp<Layer> strongRelative = mDrawingState.zOrderRelativeOf.promote();
        if (strongRelative != nullptr) {
            strongRelative->removeZOrderRelative(this);
        }
        setZOrderRelativeOf(nullptr);
    }
    setTransactionFlags(eTransactionNeeded);
    return true;
}

 

至此createSurface的流程基本就講完了。


隱隱約約,迷迷糊糊感覺還是很多事情沒講透徹,比如設定下來的資訊 儲存到 mDrawingState or mCurrentState 後,這些資訊又是什麼時候確實被利用的呢?走了怎麼樣的流程?

哈哈,我現在只能說下次繪製圖形時就會用了(嘻嘻)

4 總結

本文結合NativeSurface應用,講解了建立Surface的流程,SurfaceFlinger中顯示的資料都是通過Layer進行封裝,介紹了建立Layer的過程。最後,介紹了事務處理的流程,客戶端設定的引數資訊怎麼從Client端傳到SurfaceFlinger的。
 
 

 
 
 

 
保持一份好心情

 
 
 

相關文章