[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 的界面顯示中的作用。