[Android禪修之路] 解讀Layer

語言: CN / TW / HK

theme: channing-cyan

[Android禪修之路] 解讀Layer

Android禪修之路

一 前言

Layer(我看網上一些部落格翻譯為圖元,所以後續我也用圖元稱呼), 它是 SurfaceFlinger 中一個非常重要的角色。從 SurfaceFlinger 合成前的準備開始,就一直通過 Layer 的一些函式來完成一些操作SurfaceFlinger合成前的預處理。 例如 rebuildLayerStacks 。

並且在合成中也是有頻繁的呼叫,所以本文會詳細的介紹一下圖元和它內部的工作原理。

例如: cpp // 重建Layer集合,並計算每個Layer的可見區域的髒資料 rebuildLayerStacks();

二 Layer

2.1 Layer 的定義

首先看 Layer.h 標頭檔案, 這個類非常長, 這裡就簡單看一下它的定義

```c class Layer; class Layer : public virtual compositionengine::LayerFE { ... void onFirstRef() override; }

class LayerFE : public virtual RefBase { } ```

Layer 繼承自 LayerFE,而 LayerFE 則繼承自 Android 的智慧指標 RefBase,對於 RefBase,當系統第一次將它的弱指標轉換為強指標的時候會呼叫 onFirstRef,不過我們看到 Layer 對這個函式是一個空實現,說明具體的工作,還是通過子類實現的。

2.2 Layer 的實現

關於 Layer 的程式碼實現, 這裡先簡單介紹一些比較重要的類。

2.2.1 State

首先要說的就是這個結構體 State,同名的 State 還有一個是 SurfaceFlinger.h 中定義的內部類,雖然都叫 State,但是它們還是不同的,這裡我們看一下 Layer 中的 State

```c [/frameworks/native/services/surfaceflinger/Layer.h] struct State { Geometry active_legacy; Geometry requested_legacy; // z 座標軸的值 int32_t z;

// 此圖元所屬的圖元堆疊的識別符號。一個圖元只能關聯到一個圖元堆疊。
// 圖元堆疊是一組按 z 軸排序的圖元,可與一個或多個顯示器關聯。在不同的顯示器上使用相同的 layerStack 是實現映象的一種方法
uint32_t layerStack;

uint8_t flags;
uint8_t reserved[2];
// 該圖元的序列號,每次圖元的屬性發生改變時,這個序列號都需要自增
int32_t sequence;
bool modified;

...

// 資料空間,僅 BufferStateLayer 和 ColorLayer 使用
ui::Dataspace dataspace;

// 此點下方的欄位僅由 BufferStateLayer 使用
Geometry active;


std::list<std::shared_ptr<SyncPoint>> mLocalSyncPoints;
...

}; ```

關於 State,這裡列舉出來一些經常用到的,比如決定圖元順序的Z軸座標,決定圖元顯示在哪個顯示器的 layerStack 等等。

再看一下 Layer 中的兩個 State 變數

  • mCurrentState:當前圖元的 State
  • mDrawingState:上次繪製圖元時的 State

這兩個變數代表了圖元的兩個狀態,一個是當前的狀態,一個是上次繪製的狀態,因為圖元的狀態是可以更改的,如果當前的狀態和上次繪製的狀態不一致,那麼就說明狀態發生了改變

2.2.1 Layer 的建構函式

```cpp [/frameworks/native/services/surfaceflinger/Layer.h] Layer::Layer(const LayerCreationArgs& args) : mFlinger(args.flinger), mName(args.name), mClientRef(args.client), mWindowType(args.metadata.getInt32(METADATA_WINDOW_TYPE, 0)) { mCurrentCrop.makeInvalid();

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

mTransactionName = String8("TX - ") + mName;

// 給 mCurrentState 成員變數的賦值
mCurrentState.active_legacy.w = args.w;
mCurrentState.active_legacy.h = args.h;
mCurrentState.flags = layerFlags;

...

//將當前狀態賦值給繪製狀態
mDrawingState = mCurrentState;

CompositorTiming compositorTiming;
args.flinger->getCompositorTiming(&compositorTiming);
mFrameEventHistory.initializeCompositorTiming(compositorTiming);
mFrameTracker.setDisplayRefreshPeriod(compositorTiming.interval);

mSchedulerLayerHandle = mFlinger->mScheduler->registerLayer(mName.c_str(), mWindowType);
    // 然後回撥 SurfaceFlinger 的 onLayerCreated
mFlinger->onLayerCreated();

} ```

Layer 的建構函式的引數是 LayerCreationArgs,這是一個封裝好的結構體,它裡面儲存的是建構函式真正需要的引數。

在建構函式中,會做一些變數的初始化,然後給 mCurrentState 裡的一些屬性賦值,並將 mCurrentState 賦值給 mDrawingState,也就是說到目前位置,圖元當前的狀態就是繪製狀態。之後如果再對圖元進行修改,就會修改到 mCurrentState 中,這樣兩者就產生了差異,直到下次繪製,又讓兩者達到一致

2.2.2 LayerCreationArgs

接下來再看一下 LayerCreationArgs 這個類, 看名字也知道它是圖元建立時使用到的引數, 它將圖元建立時需要的引數進行的封裝

```c [/frameworks/native/services/surfaceflinger/Layer.h] struct LayerCreationArgs { LayerCreationArgs(SurfaceFlinger* flinger, const sp& client, const String8& name, uint32_t w, uint32_t h, uint32_t flags, LayerMetadata metadata) : flinger(flinger), client(client), name(name), w(w), h(h), flags(flags), metadata(std::move(metadata)) {}

SurfaceFlinger* flinger;
const sp<Client>& client;
const String8& name;
uint32_t w;
uint32_t h;
uint32_t flags;
LayerMetadata metadata;

}; ```

這裡面的引數都比較簡單,唯一一個需要注意的是這個 Client,它是定義在frameworks/native/services/surfaceflinger/Client.h,這個 Client 在 SurfaceFlinger 中代表應用端(App端)。

2.2.3 SyncPoint

SyncPoint 是定義在 Layer.h 標頭檔案中的一個內部類,翻譯過來就是同步點

```c class SyncPoint { public: explicit SyncPoint(uint64_t frameNumber, wp requestedSyncLayer) : mFrameNumber(frameNumber), mFrameIsAvailable(false), mTransactionIsApplied(false), mRequestedSyncLayer(requestedSyncLayer) {}

uint64_t getFrameNumber() const { return mFrameNumber; }

bool frameIsAvailable() const { return mFrameIsAvailable; }

void setFrameAvailable() { mFrameIsAvailable = true; }

bool transactionIsApplied() const { return mTransactionIsApplied; }

void setTransactionApplied() { mTransactionIsApplied = true; }

// wp 是 Android native 中的智慧弱指標,sp 是Android native 中的智慧強指標
// promote 其實就是將智慧弱指標轉換未智慧強指標
sp<Layer> getRequestedSyncLayer() { return mRequestedSyncLayer.promote(); }

private: const uint64_t mFrameNumber; std::atomic mFrameIsAvailable; std::atomic mTransactionIsApplied; wp mRequestedSyncLayer; };

// 定義在 Layer.h 中的關於 SyncPoint 個物件 Mutex mLocalSyncPointMutex; //鎖 // 一個 SyncPoint 的列表 std::list> mLocalSyncPoints;

// 應用事務時將發出訊號然後移除的同步點 std::list> mRemoteSyncPoints; ```

同步點,當正確的幀位於佇列的頭部時將發出訊號,並在幀被鎖定後丟棄。受mLocalSyncPointMutex保護

2.3 LayerFE

接下來再看 LayerFE 的定義,

```c [frameworks/native/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFE.h]

class LayerFE : public virtual RefBase { public: // 更新與顯示無關的合成狀態。如果 includeGeometry 為 false ,則可以跳過 geometry 狀態 virtual void latchCompositionState(LayerFECompositionState&, bool includeGeometry) const = 0; // 在 Layer 顯示後呼叫以更新 Fence virtual void onLayerDisplayed(const sp&) = 0;

// debug name
virtual const char* getDebugName() const = 0;

}; ```

對於 LayerFE , 根據官方的說法, 它是一個介面,這個介面定義了 CompositionEngine 合成引擎向前端層發出請求的函式。

三 合成前的Layer

接下來我們先按照之前 SurfaceFlinger 的合成流程,來看 Layer 的工作原理,首先是合成前 Layer 做了什麼。具體的 SurfaceFlinger 的合成流程可以檢視SurfaceFlinger的合成總覽

3.1 notifyAvailableFrames

首先是 handleTransactionLocked 中的 notifyAvailableFrames,這個函式在 Layer.h 中是一個空實現,看來又是由它的子類處理的。但是根據我的檢視,真正實現了這個函式的子類只有 BufferLayer。

c [frameworks/native/services/surfaceflinger/Layer.h] virtual void notifyAvailableFrames() {}

3.1.1 BufferLayer::notifyAvailableFrames

```cpp [/frameworks/native/services/surfaceflinger/BufferLayer.cpp] void BufferLayer::notifyAvailableFrames() { const auto headFrameNumber = getHeadFrameNumber(); const bool headFenceSignaled = fenceHasSignaled(); const bool presentTimeIsCurrent = framePresentTimeIsCurrent(); Mutex::Autolock lock(mLocalSyncPointMutex);

// 遍歷 mLocalSyncPoints,這個是一個同步點的集合[2.2.3]
for (auto& point : mLocalSyncPoints) {

    // 如果頭部幀的序號大於同步點中幀的序號,並且頭部幀已經發送過Fence訊號
    // Fence 訊號是用於軟硬體間同步的
    if (headFrameNumber >= point->getFrameNumber() && headFenceSignaled &&
        presentTimeIsCurrent) {
        // 通知同步點,將同步點中的 mFrameIsAvailable 設定為 true,見 [2.2.3]
        point->setFrameAvailable();
        // 從同步點獲取需要同步的圖元,並更新它的事務標誌
        sp<Layer> requestedSyncLayer = point->getRequestedSyncLayer();
        if (requestedSyncLayer) {
            // 更新事務標誌以確保應用層的掛起事務,實現在 Layer.cpp 中
            requestedSyncLayer->setTransactionFlags(eTransactionNeeded);
        }
    }
}

}

```

3.2 getTransactionFlags

接下來是 handleTransactionLocked 中的 getTransactionFlags,它直接返回了 Layer 中的 mTransactionFlags 。忘記 handleTransactionLocked 可以看SurfaceFlinger合成前的預處理

c [frameworks/native/services/surfaceflinger/Layer.h] uint32_t getTransactionFlags() const { return mTransactionFlags; }

3.3 doTransaction

doTransaction 就是處理事務,Layer 會依據當前的圖元哪些屬性發生了改變,來決定具體應該怎麼做,在介紹之前Layer 中 State 結構體的時候,看到了一個成員變數 sequence,這個序列號就是用來記錄圖元屬性發生改變的。

```c [frameworks/native/services/surfaceflinger/Layer.cpp] uint32_t Layer::doTransaction(uint32_t flags) {

... // 前面會進行一些屬性判斷
    State c = getCurrentState();

// doTransactionResize 判斷當前圖元的 size 是否發生了改變
flags = doTransactionResize(flags, &c);

// 獲取繪製時的狀態
const State& s(getDrawingState());

// 如果當前的的狀態和繪製時的狀態的活動區域不相同,那麼就需要重新計算可見區域
if (getActiveGeometry(c) != getActiveGeometry(s)) {
    // 需要重新計算可見區域,如果活動區域 active_legacy 不一致,則需要重新計算可見區域
    flags |= Layer::eVisibleRegion;
}

// 如果當前狀態的序列號和繪製時的序列號不一致,那麼當前的圖元屬性肯定發生了變化
if (c.sequence != s.sequence) {
    // 重新計算可見區域
    flags |= eVisibleRegion;
    // 內容髒了,即當前圖元存在髒區域,需要重新合成繪製等操作
    this->contentDirty = true;

    ...
}

...

// 提交事務
commitTransaction(c);
mCurrentState.callbackHandles = {};
return flags;

} ```

doTransaction 這個函式的邏輯很簡單

  • 先判斷活動區域是否發生了變化
  • 再判斷圖元的屬性是否發生了變化
  • 最後提交事務

3.3.1 commitTransaction

再來看一下提交事務的邏輯,原來就是將當前的圖元的狀態賦值給繪製圖元的狀態,這樣狀態就同步了,然後等到下一輪狀態發生改變時,再重複之前的動作即可。

c void Layer::commitTransaction(const State& stateToCommit) { mDrawingState = stateToCommit; }

關於序列號 sequence 的改變,這裡就不再擴充套件了,簡單來說,就是當呼叫圖元 Layer 的 set 之類的方法時,sequence 就會自增。

最後關於 doTransaction 需要說一點的是,它的函式傳入的是一個 int 值 flag,返回的也是一個 int 值,當前這個值在之前判斷圖元屬性時已經發生了改變,而它的返回值也決定了後續 SurfaceFlinger 合成的一些操作。這裡可以回顧一下SurfaceFlinger合成前的預處理

四 Layer 的子類

Layer 表示的是 Android 系統中的圖元, 那麼對於 Layer 的子類, 則是具體的圖元操作的封裝。Layer 的子類主要有三個

  • ColorLayer
  • BufferLayer
  • BufferStateLayer

3.1 ColorLayer

ColorLayer 即顏色圖元, 它算是 Layer 的幾個子類中最簡單的一個子類了, 不過麻雀雖小, 五臟俱全. 通過檢視 ColorLayer , 我們基本能夠看到圖元的一些基礎操作

3.1.1 ColorLayer 的定義

首先還是先看 ColorLayer.h 標頭檔案

```c [frameworks/native/services/surfaceflinger/ColorLayer.h] class ColorLayer : public Layer { public: // 建構函式和解構函式 explicit ColorLayer(const LayerCreationArgs&); ~ColorLayer() override;

// 
std::shared_ptr<compositionengine::Layer> getCompositionLayer() const override;

// Layer 的型別: ColorLayer
virtual const char* getTypeId() const { return "ColorLayer"; }
// 可見狀態
bool isVisible() const override;

// 顏色
bool setColor(const half3& color) override;
// 資料空間
bool setDataspace(ui::Dataspace dataspace) override;
// 將幀資料設定到 HWComposer 中
void setPerFrameData(const sp<const DisplayDevice>& display, const ui::Transform& transform,
                     const Rect& viewport, int32_t supportedPerFrameMetadata,
                     const ui::Dataspace targetDataspace) override;

// 提交操作
void commitTransaction(const State& stateToCommit) override;

// 合成前的預處理
// 在 ColorLayer 中直接返回了 fasle , 沒有做任何邏輯, 因為 ColorLayer 沒有合成前預處理
bool onPreComposition(nsecs_t /*refreshStartTime*/) override { return false; }

protected:

virtual bool prepareClientLayer(const RenderArea& renderArea, const Region& clip,
                                bool useIdentityTransform, Region& clearRegion,
                                const bool supportProtectedContent,
                                renderengine::LayerSettings& layer);

private:

std::shared_ptr<compositionengine::Layer> mCompositionLayer;

};

```

3.1.2 ColorLayer 的實現

3.1.2.1 建構函式

cpp ColorLayer::ColorLayer(const LayerCreationArgs& args) : Layer(args), mCompositionLayer{mFlinger->getCompositionEngine().createLayer( compositionengine::LayerCreationArgs{this})} {}

ColorLayer 中構造時, 呼叫了父類 Layer 的建構函式, 然後還建立了一個 mCompositionLayer 物件

3.1.2.2 commitTransaction

最後再來看一下 commitTransaction 的 ,它其實呼叫的也是 Layer 的 commitTransaction (見3.3.1)。

cpp void ColorLayer::commitTransaction(const State& stateToCommit) { Layer::commitTransaction(stateToCommit); mCurrentDataSpace = mDrawingState.dataspace; }

3.1.2.3 prepareClientLayer

再來說說 prepareClientLayer 這個函式,它會在 SurfaceFlinger 的合成中呼叫,詳情可以檢視 SurfaceFlinger合成中的工作 中的 3.2 doComposeSurfaces 的第二部分。

cpp bool ColorLayer::prepareClientLayer(const RenderArea& renderArea, const Region& clip, bool useIdentityTransform, Region& clearRegion, const bool supportProtectedContent, renderengine::LayerSettings& layer) { Layer::prepareClientLayer(renderArea, clip, useIdentityTransform, clearRegion, supportProtectedContent, layer); half4 color(getColor()); half3 solidColor(color.r, color.g, color.b); layer.source.solidColor = solidColor; return true; }

3.1.2.3 setPerFrameData

setPerFrameData 的作用是為每一層圖元設定需要顯示的資料。所以它做的大致是如下幾件事情 1. 設定可見區域 2. 設定輸出圖元 3. 設定圖元的合成方式為顏色圖元 4. 設定資料空間 5. 設定資料(即顏色)

```cpp

void ColorLayer::setPerFrameData(const sp& display, const ui::Transform& transform, const Rect& viewport, int32_t / supportedPerFrameMetadata /, const ui::Dataspace targetDataspace) {

// 處理可見區域
Region visible = transform.transform(visibleRegion.intersect(viewport));
// 找到需要輸出的顯示圖元
const auto outputLayer = findOutputLayerForDisplay(display);

// hwcLayer
auto& hwcLayer = (*outputLayer->getState().hwc).hwcLayer;

//
auto error = hwcLayer->setVisibleRegion(visible);
if (error != HWC2::Error::None) {
    visible.dump(LOG_TAG);
}
outputLayer->editState().visibleRegion = visible;

// 設定合成方式為顏色圖元
setCompositionType(display, Hwc2::IComposerClient::Composition::SOLID_COLOR);

const ui::Dataspace dataspace =
        isColorSpaceAgnostic() && targetDataspace != ui::Dataspace::UNKNOWN ? targetDataspace

// 設定資料空間
error = hwcLayer->setDataspace(dataspace);

auto& layerCompositionState = getCompositionLayer()->editState().frontEnd;
layerCompositionState.dataspace = mCurrentDataSpace;

half4 color = getColor();
error = hwcLayer->setColor({static_cast<uint8_t>(std::round(255.0f * color.r)),
                            static_cast<uint8_t>(std::round(255.0f * color.g)),
                            static_cast<uint8_t>(std::round(255.0f * color.b)), 255});

layerCompositionState.color = {static_cast<uint8_t>(std::round(255.0f * color.r)),
                               static_cast<uint8_t>(std::round(255.0f * color.g)),
                               static_cast<uint8_t>(std::round(255.0f * color.b)), 255};

// Clear out the transform, because it doesn't make sense absent a source buffer
error = hwcLayer->setTransform(HWC2::Transform::None);

outputLayer->editState().bufferTransform = static_cast<Hwc2::Transform>(0);

error = hwcLayer->setColorTransform(getColorTransform());

layerCompositionState.colorTransform = getColorTransform();

error = hwcLayer->setSurfaceDamage(surfaceDamageRegion);

layerCompositionState.surfaceDamage = surfaceDamageRegion;

} ```

3.2 BufferLayer

3.2.1 BufferLayer 的定義

相比於 ColorLayer , BufferLayer 中包含的函式多了許多, 這也是因為 BufferLayer 的處理比簡單顏色圖元的處理要複雜許多, 不過後續我們需要關注的, 還是從父類中繼承來的那些公共的函式

```c class BufferLayer : public Layer { public: explicit BufferLayer(const LayerCreationArgs& args); ~BufferLayer() override;

public: std::shared_ptr getCompositionLayer() const override;

// 如果我們在這個幀中收到一個新的緩衝區,我們將把它的表髒區域傳遞給 hardware composer (後續簡稱hwc)
// 否則,我們必須傳送一個包含一個空 rect 的區域
void useSurfaceDamage() override;
void useEmptyDamage() override;

// 圖元的型別: BufferLayer
const char* getTypeId() const override { return "BufferLayer"; }

// 是否是不透明的
bool isOpaque(const Layer::State& s) const override;

// 是否可見
bool isVisible() const override;

// isProtected - true if the layer may contain protected content in the
// GRALLOC_USAGE_PROTECTED sense.
// 是否包含受保護的內容(在 GRALLOC_USAGE_PROTECTED 區域), true 表示包含
bool isProtected() const override;

// 內容是否是固定大小, true 表示是的
bool isFixedSize() const override;

bool usesSourceCrop() const override;

bool isHdrY410() const override;

// 設定幀資料
void setPerFrameData(const sp<const DisplayDevice>& display, const ui::Transform& transform,
                     const Rect& viewport, int32_t supportedPerFrameMetadata,
                     const ui::Dataspace targetDataspace) override;

// 合成前預處理
bool onPreComposition(nsecs_t refreshStartTime) override;

// 合成後的處理
bool onPostComposition(const std::optional<DisplayId>& displayId,
                       const std::shared_ptr<FenceTime>& glDoneFence,
                       const std::shared_ptr<FenceTime>& presentFence,
                       const CompositorTiming& compositorTiming) override;


// latchBuffer-每次重新繪製螢幕時呼叫,並返回是否需要重新計算可見區域。
// 這是一個相當重的操作,所以只在需要時才設定)。
// 通常,這用於確定 Surface 的內容或大小是否已更改
bool latchBuffer(bool& recomputeVisibleRegions, nsecs_t latchTime) override;

bool isBufferLatched() const override { return mRefreshPending; }

void notifyAvailableFrames() override;

bool hasReadyFrame() const override;

// 返回當前縮放模式, 如果設定了mOverrideScalingMode 則返回 mOverrideScalingMode
uint32_t getEffectiveScalingMode() const override;


// -----------------------------------------------------------------------
// 必須由派生類實現的函式
// -----------------------------------------------------------------------
...

} ```

3.2.2 BufferLayer 的實現

3.2.2.1 prepareClientLayer

同樣,我們也看下 BufferLayer 的 prepareClientLayer 是如何實現的。它和 ColorLayer 一樣,會在 SurfaceFlinger 的合成中呼叫,詳情可以檢視 SurfaceFlinger合成中的工作 中的 3.2 doComposeSurfaces 的第二部分。

```cpp bool BufferLayer::prepareClientLayer(const RenderArea& renderArea, const Region& clip, bool useIdentityTransform, Region& clearRegion, const bool supportProtectedContent, renderengine::LayerSettings& layer) {

Layer::prepareClientLayer(renderArea, clip, useIdentityTransform, clearRegion,
                          supportProtectedContent, layer);
if (CC_UNLIKELY(mActiveBuffer == 0)) {
    //紋理還沒有被建立,這個圖元實際上從來沒有被繪製。這在SurfaceView中經常發生,因為WindowManager不知道客戶端什麼時候第一次繪製
    // 如下下層沒有任何東西, 就把螢幕繪製成黑色, 否則就跳過這個更新

    // 遍歷底層
    Region under;
    bool finished = false;
    mFlinger->mDrawingState.traverseInZOrder([&](Layer* layer) {
        if (finished || layer == static_cast<BufferLayer const*>(this)) {
            finished = true;
            return;
        }
        under.orSelf(layer->visibleRegion);
    });
    // 如果沒有Layer在這個圖元的底部, 就忽略這個圖元的空隙
    Region holes(clip.subtract(under));
    if (!holes.isEmpty()) {
        clearRegion.orSelf(holes);
    }
    return false;
}

// DRM處理, 如果圖元是安全記憶體就直接繪製一塊黑色. 主要是針對數字版權
bool blackOutLayer =
        (isProtected() && !supportProtectedContent) || (isSecure() && !renderArea.isSecure());
const State& s(getDrawingState());
if (!blackOutLayer) {
    layer.source.buffer.buffer = mActiveBuffer;
    layer.source.buffer.isOpaque = isOpaque(s);
    layer.source.buffer.fence = mActiveBufferFence;
    layer.source.buffer.textureName = mTextureName;
    layer.source.buffer.usePremultipliedAlpha = getPremultipledAlpha();
    layer.source.buffer.isY410BT2020 = isHdrY410();
    // TODO: we could be more subtle with isFixedSize()
    const bool useFiltering = needsFiltering(renderArea.getDisplayDevice()) ||
            renderArea.needsFiltering() || isFixedSize();

    // 查詢我們當前過濾模式下的紋理矩陣
    float textureMatrix[16];
    setFilteringEnabled(useFiltering);
    getDrawingTransformMatrix(textureMatrix);

    // 顯示器的橫豎屏切換, 保證緩衝區和本機的顯示方向一致
    if (getTransformToDisplayInverse()) {
        // 下面的程式碼將主顯示的反變換應用到紋理變換
        uint32_t transform = DisplayDevice::getPrimaryDisplayOrientationTransform();
        mat4 tr = inverseOrientation(transform);

        // 確保無論父轉換如何,這個緩衝區總是從本機顯示方向轉換為顯示方向。
        // 例如,在一個相機的情況下,緩衝區保持在本機方向,我們希望畫素總是垂直的
        sp<Layer> p = mDrawingParent.promote();
        if (p != nullptr) {
            const auto parentTransform = p->getTransform();
            tr = tr * inverseOrientation(parentTransform.getOrientation());
        }

        // 最後將變換應用到原始紋理矩陣中
        const mat4 texTransform(mat4(static_cast<const float*>(textureMatrix)) * tr);
        memcpy(textureMatrix, texTransform.asArray(), sizeof(textureMatrix));
    }

    const Rect win{getBounds()};
    float bufferWidth = getBufferSize(s).getWidth();
    float bufferHeight = getBufferSize(s).getHeight();

    // 如果緩衝區沒有設定幀, 就設定一個尺寸為[0,0,-1,-1], 並忽略這個緩衝區
    if (!getBufferSize(s).isValid()) {
        bufferWidth = float(win.right) - float(win.left);
        bufferHeight = float(win.bottom) - float(win.top);
    }

    const float scaleHeight = (float(win.bottom) - float(win.top)) / bufferHeight;
    const float scaleWidth = (float(win.right) - float(win.left)) / bufferWidth;
    const float translateY = float(win.top) / bufferHeight;
    const float translateX = float(win.left) / bufferWidth;

    //因為GLConsumer和OpenGL的約定, 翻轉y座標,
    mat4 tr = mat4::translate(vec4(.5, .5, 0, 1)) * mat4::scale(vec4(1, -1, 1, 1)) *
            mat4::translate(vec4(-.5, -.5, 0, 1)) *
            mat4::translate(vec4(translateX, translateY, 0, 1)) *
            mat4::scale(vec4(scaleWidth, scaleHeight, 1.0, 1.0));

    layer.source.buffer.useTextureFiltering = useFiltering;
    layer.source.buffer.textureTransform = mat4(static_cast<const float*>(textureMatrix)) * tr;
} else {
    // 如果圖元被塗黑,強制alpha值為1,這樣我們就可以畫一個黑色圖元
    layer.source.buffer.buffer = nullptr;
    layer.alpha = 1.0;
}

return true;

} ```

3.2.2.1 onPreComposition

在 ColorLayer 中, 合成前的預處理沒有任何工作. 但是對於 BufferLayer , 則會預先做一些事情,onPreComposition 是 合成前的預處理工作,它會在SurfaceFlinger的合成前呼叫,具體的位置可以檢視SurfaceFlinger合成前的預處理 中的二 preComposition。

cpp bool BufferLayer::onPreComposition(nsecs_t refreshStartTime) { if (mBufferLatched) { Mutex::Autolock lock(mFrameEventHistoryMutex); // 將當前的幀數新增到 mFrameEventHistory mFrameEventHistory.addPreComposition(mCurrentFrameNumber, refreshStartTime); } mRefreshPending = false; // 判斷當前是否還有已經準備好的幀需要處理 return hasReadyFrame(); }

hasReadyFrame

cpp bool BufferLayer::hasReadyFrame() const { // 在這三種情況下是需要繼續處理的 // 1. hasFrameUpdate 為 true , 即當前狀態發生了改變, 並且還有提交來的 buffer // 2. SidebandStream 發生了改變 // 3. 當前是自動重新整理模式 return hasFrameUpdate() || getSidebandStreamChanged() || getAutoRefresh(); }

3.2.2.2 setPerFrameData

cpp compositionengine::OutputLayer* Layer::findOutputLayerForDisplay( const sp<const DisplayDevice>& display) const { // DisplayDevice 的 getCompositionDisplay 獲取到它的成員變數 mCompositionDisplay // const std::shared_ptr<compositionengine::Display> mCompositionDisplay; // getOutputLayerForLayer 拿到的是一個 return display->getCompositionDisplay()->getOutputLayerForLayer(getCompositionLayer().get()); }

到此,關於 Layer 的介紹已經算是完成了一半了。

為什麼我要說是一半呢?因為現在還只是粗略的介紹了 Layer 合成的相關操作,而它是怎麼來的,整體上的流程是怎樣的還沒有說明,下面,我就通過 Activity 開始,結合此篇 Layer 具體的函式,來詳細說明 Layer 的介面顯示中的作用。