SurfaceFlinger11-ITransactionCompletedListener事件监听

前言

Transaction用于业务进程和surfaceflinger进程进行图层数据的传递,这是单向的传递过程,没有任何返回结果。因此,如果业务侧需要获取传递的图层数据在sf进程的处理情况时,就可以借助于提供的几个监听接口进行。业务进程对Transaction或SurfaceControl设置对应的监听,sf中处理完成后,通过监听接口发起回调给业务进程。

Transaction上支持2个Listener监听接口,并通过这两个Listener实现了多个事件监听:

  1. IWindowInfosReportedListener:用于监听Transaction上操作时surfaceflinger和inputflinger中窗口和触控信息的更新状态,通知业务侧sf中已完成一个Transaction上携带Layer的窗口触控信息处理;

  2. ITransactionCompletedListener:用于监听Transaction在surfaceflinger进程的提交和完成情况,通过该接口实现以下多个事件的监听:

    1. TransactionCommittedCallback:用于向监听端发送sf进程完成commit操作;

    2. TransactionCompletedCallback:用于向监听端发送sf进程完成composite操作;

    3. ReleaseBufferCallback:用于sf进程完成GraphicBuffer使用后,通知业务进程释放GraphicBuffer;

    4. QueueStallListener:用于向监听端发送sf进程中Transaction队列阻塞时的回调;

    5. TrustedPresentationCallback:用于向监听端发送指定SurfaceControl可信度状态的变化情况;

    6. OnJankDataListener:用于向监听端发送指定图层的"Jank"状态;

    7. SurfaceStatsListener:用于向监听端发送指定SurfaceControl的合成状态。

本篇文章中,将对ITransactionCompletedListener接口的实现和事件处理流程进行汇总, 其中重点将放在TransactionCommittedCallbackTransactionCompletedCallback监听事件上。

一、TransactionCompleteListener的实现

ITransactionCompletedListener接口用于sf进程向业务进程传递Transaction提交后的提交、合成等各种状态。ITransactionCompletedListener作为监听事件的总接口,在业务进程和sf进程间进行回调事件的传递。业务进程将事件监听注册到ITransactionCompletedListener中,sf端完成操作后发起回调,ITransactionCompletedListener收到来自sf的回调后,再进行归类、筛选,最后触发业务进程中对应的回调方法。

ITransactionCompletedListener中定义了4个回调方法:

cpp 复制代码
// frameworks/native/libs/gui/include/gui/ITransactionCompletedListener.h

class ITransactionCompletedListener : public IInterface {
public:
    // sf中完成提交(或合成)操作时回调
    virtual void onTransactionCompleted(ListenerStats stats) = 0;
    // sf中完成buffer释放时时回调
    virtual void onReleaseBuffer(ReleaseCallbackId callbackId, sp<Fence> releaseFence,
                                 uint32_t currentMaxAcquiredBufferCount) = 0;
    // Transaction队列阻塞时回调
    virtual void onTransactionQueueStalled(const String8& name) = 0;
    // 指定Layer可信度状态变化时回调
    virtual void onTrustedPresentationChanged(int id, bool inTrustedPresentationState) = 0;
};

ITransactionCompletedListener的实际实现类是TransactionCompletedListener,在SurfaceComposerClient中进行实现,除了重写ITransactionCompletedListener中的方法之外,还新定义了多个方法和内部类,来支撑不同回调事件的派发。

TransactionCompletedListener既作为IPC的接口,也是众多事件回调的管理者。当业务进程端收到回调后,又根据携带的参数,分别依次触发不同的回调方法。

该类定义如下:

cpp 复制代码
// frameworks/native/libs/gui/include/gui/SurfaceComposerClient.h

class TransactionCompletedListener : public BnTransactionCompletedListener {
......
protected:
    ......
    // 键为CallbackId、值为CallbackTranslation的映射表,保存所有接收onTransactionCompleted()的事件监听
    std::unordered_map<CallbackId, CallbackTranslation, CallbackIdHash> mCallbacks
            GUARDED_BY(mMutex);
    // 键为layerId、值为JankDataListener,保存所有的JankDataListener监听
    std::multimap<int32_t, sp<JankDataListener>> mJankListeners GUARDED_BY(mMutex);
    // 键为ReleaseCallbackId、值为ReleaseBufferCallback,保存所有的ReleaseBufferCallback监听
    std::unordered_map<ReleaseCallbackId, ReleaseBufferCallback, ReleaseBufferCallbackIdHash>
            mReleaseBufferCallbacks GUARDED_BY(mMutex);

    // 键为layerId、值为SurfaceStatsCallbackEntry,保存所有的SurfaceStatsCallback监听
    std::multimap<int32_t, SurfaceStatsCallbackEntry> mSurfaceStatsListeners;
    // 键为任意类型、值为addQueueStallListener函数,保存所有的addQueueStallListener监听
    std::unordered_map<void*, std::function<void(const std::string&)>> mQueueStallListeners;
    // 键为layerId、值为TrustedPresentationCallback,保存所有的TrustedPresentationCallback监听
    std::unordered_map<int, std::tuple<TrustedPresentationCallback, void*>>
            mTrustedPresentationCallbacks;

public:
    // 获取TransactionCompletedListener实例的方法
    static sp<TransactionCompletedListener> getInstance();
    // 获取ITransactionCompletedListener实例的方法,一般用于作为Key值使用
    static sp<ITransactionCompletedListener> getIInstance();

    // 向TCL中添加TransactionCompletedCallback类型监听
    CallbackId addCallbackFunction(
            const TransactionCompletedCallback& callbackFunction,
            const std::unordered_set<sp<SurfaceControl>, SurfaceComposerClient::SCHash>&
                    surfaceControls,
            CallbackId::Type callbackType);

    // 将sc添加到mCallbacks列表中的所有事件回调中
    void addSurfaceControlToCallbacks(SurfaceComposerClient::CallbackInfo& callbackInfo,
                                      const sp<SurfaceControl>& surfaceControl);
    // 注册QueueStallListener监听
    void addQueueStallListener(std::function<void(const std::string&)> stallListener, void* id);
    // 移除QueueStallListener监听
    void removeQueueStallListener(void *id);
    // 注册TrustedPresentationCallback监听
    sp<SurfaceComposerClient::PresentationCallbackRAII> addTrustedPresentationCallback(
            TrustedPresentationCallback tpc, int id, void* context);
    // 清除TrustedPresentationCallback监听
    void clearTrustedPresentationCallback(int id);

    // 注册JankListener监听
    void addJankListener(const sp<JankDataListener>& listener, sp<SurfaceControl> surfaceControl);

    // 移除JankListener监听
    void removeJankListener(const sp<JankDataListener>& listener);
    // 注册SurfaceStatsListener监听
    void addSurfaceStatsListener(void* context, void* cookie, sp<SurfaceControl> surfaceControl,
                SurfaceStatsCallback listener);
    // 移除SurfaceStatsListener监听
    void removeSurfaceStatsListener(void* context, void* cookie);
    // 设置ReleaseBufferCallback监听
    void setReleaseBufferCallback(const ReleaseCallbackId&, ReleaseBufferCallback);

    // sf中完成提交(或合成)操作时回调
    void onTransactionCompleted(ListenerStats stats) override;
    // sf中完成buffer释放时时回调
    void onReleaseBuffer(ReleaseCallbackId, sp<Fence> releaseFence,
                         uint32_t currentMaxAcquiredBufferCount) override;

    void removeReleaseBufferCallback(const ReleaseCallbackId& callbackId);
    // Transaction队列阻塞时回调
    void onTransactionQueueStalled(const String8& reason) override;
    // 指定Layer可信度状态变化时回调
    void onTrustedPresentationChanged(int id, bool presentedWithinThresholds) override;
    ......
};

通过4个支持跨进程调用的回调方法,实现了7类事件回调。

1.1、TransactionCompleteListener初始化

TransactionCompletedListener通过单例的方式进行初始化,因此一个进程只有一个TransactionCompletedListener对象。

TransactionCompletedListener实例创建方法如下:

cpp 复制代码
// frameworks/native/libs/gui/SurfaceComposerClient.cpp

// 获取TransactionCompletedListener实例
sp<TransactionCompletedListener> TransactionCompletedListener::getInstance() {
    std::lock_guard<std::mutex> lock(sListenerInstanceMutex);
    if (sInstance == nullptr) {
        sInstance = new TransactionCompletedListener;
    }
    return sInstance;
}

// 获取sp<ITransactionCompletedListener>类型实例
sp<ITransactionCompletedListener> TransactionCompletedListener::getIInstance() {
    return static_cast<sp<ITransactionCompletedListener>>(getInstance());
}

其他类中就可以通过以上两方法来获取TransactionCompletedListener实例,如在BBQ中设置监听时:

cpp 复制代码
// frameworks/native/libs/gui/BLASTBufferQueue.cpp

BLASTBufferQueue::BLASTBufferQueue(const std::string& name, bool updateDestinationFrame)
      : mSurfaceControl(nullptr),
        mSize(1, 1),
        mRequestedSize(mSize),
        mFormat(PIXEL_FORMAT_RGBA_8888),
        mTransactionReadyCallback(nullptr),
        mSyncTransaction(nullptr),
        mUpdateDestinationFrame(updateDestinationFrame) {
    ......
    // 设置QueueStallListener监听,sf中Transaction队列阻塞时回调
    TransactionCompletedListener::getInstance()->addQueueStallListener(
            [&](const std::string& reason) {
                std::function<void(const std::string&)> callbackCopy;
                {
                    std::unique_lock _lock{mMutex};
                    callbackCopy = mTransactionHangCallback;
                }
                if (callbackCopy) callbackCopy(reason);
            },
            this);
    ......
}

1.2、SurfaceControl、Transaction、TCL之间的关系

TransactionCompleteListenerSurfaceComposerClient类内部以单例的方式创建,因此业务进程可以不用关心何时创建TCL实例,而是直接通过暴露的方法接口将所需事件监听设置给Transaction即可,Transaction内部会将这些监听信息传递给TCL中。

TCL监听的最小单位是图层,也就是对SurfaceControl或Layer的信息监听。

SurfaceControl和Transaction是多对多的关系,一个Transaction上可以携带多个SurfaceControl,一个SurfaceControl也可以设置给不同的Transaction对象;

Transaction和TCL也是多对多关系,这是因为:

虽然TCL通过单例实现,但是由于Transaction支持跨进程传递以及合并操作,因此在Transaction内部,可以有多个进程的TCL实例。

1.3、注册TransactionCompleteListener事件监听的方式

TransactionCompleteListener类中共定义了六类监听事件,各类监听事件都可以通过提供的方法,在获取到TransactionCompleteListener实例后进行注册。

在注册监听事件时,可以在其他类中获取到TransactionCompleteListener实例后直接进行注册。比如不依赖具体Transaction的监听事件QueueStallListenerSurfaceStatsListener

其余监听事件,并不是拿到TransactionCompleteListener实例直接进行注册,而是通过Transaction完成监听事件的注册。这些监听事件要么是和Transaction间有依赖关系,要么是在代码架构设计上需要借助于Transaction进行过渡。

比如Java层要注册JankListener时,那就需要依赖Transaction类,通过JNI向Native进行传递。

再比如ReleaseBufferCallback接口的注册跟随GraphicBuffer的设置流程,会在Transaction::setBuffer()时,由Transaction向TCL中注册ReleaseBufferCallback监听。

二、TransactionCallback的管理和注册

在sf进程中,当Transaction完成commitcomposite操作后,都会触发回调方法ITransactionCompletedListener::onTransactionCompleted()的执行。TransactionCompletedListener中收到onTransactionCompleted()方法调用后,根据携带参数确定下一步触发TransactionCommittedCallback还是TransactionCompeltedCallback回调。

TransactionCommittedCallback用于监听Transaction的commit操作,TransactionCompeltedCallback用于监听Transaction的composite操作,

因此我们把TransactionCommittedCallbackTransactionCompeltedCallback监听事件统称为TransactionCallback

这个监听事件是作用于具体Transaction对象,因此在注册时是通过Transaction进行注册。

2.1、TransactionCallback的管理

在Transaction内部,对该Transaction上关联的各个TransactionCompletedListener实例以及注册的所有TransactionCallback以[sp<ITransactionCompletedListener>, CallbackInfo]的方式保存在mListenerCallbacks映射表中:

cpp 复制代码
// frameworks/native/libs/gui/include/gui/SurfaceComposerClient.h

// Key为sp<IBinder>形式TCL实例,值为CallbackInfo
std::unordered_map<sp<ITransactionCompletedListener>, CallbackInfo, TCLHash>
        mListenerCallbacks;

CallbackInfo代表一个TransactionCompletedListener实例上所有监听事件的信息,它由CallbackId列表和涉及SurfaceControl列表组成:

cpp 复制代码
// frameworks/native/libs/gui/include/gui/SurfaceComposerClient.h

struct CallbackInfo {
    // 表示当前TransactionCompletedListener接口上的所有事件监听的序号列表
    std::unordered_set<CallbackId, CallbackIdHash> callbackIds;
    // 表示当前TransactionCompletedListener接口上的事件监听所涉及的SurfaceControl
    std::unordered_set<sp<SurfaceControl>, SCHash> surfaceControls;
};

CallbackId是代表TransactionCallback的ID的一个封装类:

cpp 复制代码
// frameworks/native/libs/gui/include/gui/ITransactionCompletedListener.h

class CallbackId : public Parcelable {
public:
    // 整型序列号
    int64_t id;
    // 类型
    enum class Type : int32_t {
        ON_COMPLETE = 0,    // 表示该callback为TransactionCompletedCallback
        ON_COMMIT = 1,      // 表示该callback为TransactionCommittedCallback
        /*reserved for serialization = 2*/
    } type;
    // 是否包含JankData
    bool includeJankData; // Only respected for ON_COMPLETE callbacks.

    ......
};

而在TransactionCompletedListener内部,是将所有的TransactionCallback[CallbackId, CallbackTranslation]的方式保存在mCallbacks映射表中:

cpp 复制代码
// frameworks/native/libs/gui/include/gui/SurfaceComposerClient.h

std::unordered_map<CallbackId, CallbackTranslation, CallbackIdHash> mCallbacks
        GUARDED_BY(mMutex);

CallbackTranslation是TCL中TransactionCompletedCallback监听事件和监听范围所涉及SurfaceControl列表的组合:

cpp 复制代码
// frameworks/native/libs/gui/include/gui/SurfaceComposerClient.h

struct CallbackTranslation {
    // 回调函数接口
    TransactionCompletedCallback callbackFunction;
    // surfaceControls列表
    std::unordered_map<sp<IBinder>, sp<SurfaceControl>, SurfaceComposerClient::IBinderHash>
            surfaceControls;
};

TransactionCompletedCallback是TransactionCallback的回调函数接口:

cpp 复制代码
// frameworks/native/libs/gui/include/gui/SurfaceComposerClient.h

using TransactionCompletedCallback =
        std::function<void(nsecs_t /*latchTime*/, const sp<Fence>& /*presentFence*/,
                           const std::vector<SurfaceControlStats>& /*stats*/)>;

2.2、TransactionCallback的注册流程

Transaction类中提供了两个方法分别用来注册TransactionCommittedCallbackTransactionCompeltedCallback

cpp 复制代码
// frameworks/native/libs/gui/SurfaceComposerClient.cpp

// 注册TransactionCompletedCallback
SurfaceComposerClient::Transaction&
SurfaceComposerClient::Transaction::addTransactionCompletedCallback(
        TransactionCompletedCallbackTakesContext callback, void* callbackContext) {
    return addTransactionCallback(callback, callbackContext, CallbackId::Type::ON_COMPLETE);
}

// 注册TransactionCommittedCallback
SurfaceComposerClient::Transaction&
SurfaceComposerClient::Transaction::addTransactionCommittedCallback(
        TransactionCompletedCallbackTakesContext callback, void* callbackContext) {
    return addTransactionCallback(callback, callbackContext, CallbackId::Type::ON_COMMIT);
}

以上方法中,TransactionCompletedCallbackTakesContext代表来自业务侧添加的回调方法的函数接口:

cpp 复制代码
// frameworks/native/libs/gui/include/gui/SurfaceComposerClient.h

using TransactionCompletedCallbackTakesContext =
        std::function<void(void* /*context*/, nsecs_t /*latchTime*/,
                           const sp<Fence>& /*presentFence*/,
                           const std::vector<SurfaceControlStats>& /*stats*/)>;

然后将函数接口传递给Transaction::addTransactionCallback()方法做进一步注册:

cpp 复制代码
// frameworks/native/libs/gui/SurfaceComposerClient.cpp

SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::addTransactionCallback(
        TransactionCompletedCallbackTakesContext callback, void* callbackContext,
        CallbackId::Type callbackType) {
    // 获取TCL实例
    auto listener = TransactionCompletedListener::getInstance();
    
    // 生成可调用对象
    // callbackContext作为回调函数的上下文,通常是一个对象或指针,
    // 用于提供回调函数执行时所需的环境或数据。
    auto callbackWithContext = std::bind(callback, callbackContext, std::placeholders::_1,
                                         std::placeholders::_2, std::placeholders::_3);
    
    // 获取该Transaction对象mListenerCallbacks列表中的对应TCL的surfaceControls列表
    const auto& surfaceControls =
            mListenerCallbacks[TransactionCompletedListener::getIInstance()].surfaceControls;
    // 向TCL中添加回调函数,并返回CallbackId
    CallbackId callbackId =
            listener->addCallbackFunction(callbackWithContext, surfaceControls, callbackType);
    // 将CallbackId添加到TCL对应的CallbackInfo中
    mListenerCallbacks[TransactionCompletedListener::getIInstance()].callbackIds.emplace(
            callbackId);
    return *this;
}

以上方法中:

  1. 会将TransactionCompletedCallbackTakesContext函数接口和Context上下文对象重新绑定生成一个新的函数接口callbackWithContext;

  2. 调用TransactionCompletedListener::addCallbackFunction()方法向TCL中进行注册,并返回一个CallbackId;

  3. 将CallbackId保存在Transaction::mListenerCallbacks列表中。

进入TransactionCompletedListener中的注册方法如下:

cpp 复制代码
// frameworks/native/libs/gui/SurfaceComposerClient.cpp

CallbackId TransactionCompletedListener::addCallbackFunctionLocked(
        const TransactionCompletedCallback& callbackFunction,
        const std::unordered_set<sp<SurfaceControl>, SurfaceComposerClient::SCHash>&
                surfaceControls,
        CallbackId::Type callbackType) {
    startListeningLocked();
    // 创建CallbackId对象
    CallbackId callbackId(getNextIdLocked(), callbackType);
    // 将callbackFunction赋值给CallbackTranslation.callbackFunction
    mCallbacks[callbackId].callbackFunction = callbackFunction;
    // 更新CallbackTranslation.surfaceControls列表
    auto& callbackSurfaceControls = mCallbacks[callbackId].surfaceControls;
    for (const auto& surfaceControl : surfaceControls) {
        callbackSurfaceControls[surfaceControl->getHandle()] = surfaceControl;

        if (callbackType == CallbackId::Type::ON_COMPLETE &&
            mJankListeners.count(surfaceControl->getLayerId()) != 0) {
            callbackId.includeJankData = true;
        }
    }
    // 返回CallbackId
    return callbackId;
}

以上方法中,首先创建了一个CallbackId,然后将callbackFunction函数接口设置给CallbackTranslation,并以CallbackId为键保存在了TransactionCompletedListener::mCallbacks中,最后返回CallbackId给Transaction对象。

执行完以上方法,向TransactionCompletedListener注册TransactionCallback监听事件的流程完成。

可以看到最终TransactionCallback监听保存在了CallbackTranslation::callbackFunction中。

此外,在Java层也定义了对应的方法设置TransactionCallback监听:

java 复制代码
// frameworks/base/core/java/android/view/SurfaceControl.java

// 注册TransactionCommittedListener
public Transaction addTransactionCommittedListener(
        @NonNull @CallbackExecutor Executor executor,
        @NonNull TransactionCommittedListener listener) {
    TransactionCommittedListener listenerInner =
            () -> executor.execute(listener::onTransactionCommitted);
    nativeAddTransactionCommittedListener(mNativeObject, listenerInner);
    return this;
}

// 注册TransactionCompletedListener
public Transaction addTransactionCompletedListener(
        @NonNull @CallbackExecutor Executor executor,
        @NonNull Consumer<TransactionStats> listener) {
    ......
    Consumer<TransactionStats> listenerInner = stats -> executor.execute(
                            () -> listener.andThen(TransactionStats::close).accept(stats));
    nativeAddTransactionCompletedListener(mNativeObject, listenerInner);
    return this;
}

进入Native层后,会将其包装成一个函数接口,传递给ITransactionCompletedListener保存:

cpp 复制代码
// frameworks/base/core/jni/android_view_SurfaceControl.cpp

static void nativeAddTransactionCommittedListener(JNIEnv* env, jclass clazz, jlong transactionObj,
                                                  jobject transactionCommittedListenerObject) {
    auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
    // 将Java类型回调信息包装在TransactionCommittedListenerWrapper中
    void* context =
            new TransactionCommittedListenerWrapper(env, transactionCommittedListenerObject);
    // 设置TransactionCommittedCallback回调
    transaction->addTransactionCommittedCallback(TransactionCommittedListenerWrapper::
                                                         transactionCallbackThunk,
                                                 context);
}

2.3、向sf中传递TransactionCallback监听事件

当执行Transaction::apply()时,会将当前Transaction::mListenerCallbacks列表中保存的TransactionCallback传递给sf进程。

传递时将监听事件信息封装在ListenerCallbacks中传递给surfaceflinger。

ListenerCallbacks代表当前Transaction对象中一个TCL对象上注册的所有TransactionCallback回调的列表,包括两个参数:

cpp 复制代码
// frameworks/native/include/gui/ITransactionCompletedListener.h

class ListenerCallbacks {
public:
    ......
    // Returns a new ListenerCallbacks filtered by type
    ListenerCallbacks filter(CallbackId::Type type) const;
    // sp<IBinder>形式的TCL对象
    sp<IBinder> transactionCompletedListener;
    // TCL对象对应的CallbackId列表
    std::vector<CallbackId> callbackIds;
};

Transaction::apply()中处理TranscationCallback事件的逻辑如下:

cpp 复制代码
// frameworks/native/libs/gui/SurfaceComposerClient.cpp

status_t SurfaceComposerClient::Transaction::apply(bool synchronous, bool oneWay) {
    ......
    // 是否存在TranscationCallback监听
    bool hasListenerCallbacks = !mListenerCallbacks.empty();
    // 创建一个用于给SF侧同步的ListenerCallbacks列表
    std::vector<ListenerCallbacks> listenerCallbacks;
    // 遍历mListenerCallbacks
    for (const auto& [listener, callbackInfo] : mListenerCallbacks) {
        auto& [callbackIds, surfaceControls] = callbackInfo;
        if (callbackIds.empty()) {
            continue;
        }
        // 如果surfaceControls为空,则只将TranscationCallback中的信息全部放入
        // 到listenerCallbacks列表中
        if (surfaceControls.empty()) {
            listenerCallbacks.emplace_back(IInterface::asBinder(listener), std::move(callbackIds));
        } else {
            // 如果存在SC,则将TranscationCallback设置给每个SC上
            for (const auto& surfaceControl : surfaceControls) {
                layer_state_t* s = getLayerState(surfaceControl);
                ......
                std::vector<CallbackId> callbacks(callbackIds.begin(), callbackIds.end());
                s->what |= layer_state_t::eHasListenerCallbacksChanged;
                // 将CallbackIds全部放入到layer_state_t中的ListenerCallbacks列表中
                s->listeners.emplace_back(IInterface::asBinder(listener), callbacks);
            }
        }
    }
    .......
    
    // 向sf中发起调用
    sp<ISurfaceComposer> sf(ComposerService::getComposerService());
    sf->setTransactionState(mFrameTimelineInfo, composerStates, displayStates, flags, applyToken,
                            mInputWindowCommands, mDesiredPresentTime, mIsAutoTimestamp,
                            mUncacheBuffers, hasListenerCallbacks, listenerCallbacks, mId,
                            mMergedTransactionIds);
    ......
    return NO_ERROR;
}

以上方法中,将TransactionCallback监听事件相关的sp和CallbackIds获取到并创建ListenerCallbacks对象,然后将ListenerCallbacks列表传递给sf。并且在传递时分两种情况:

  1. 如果TransactionCallback事件中不存在具体的SurfaceControl,则会将ListenerCallbacks列表直接传递给sf进程;
  2. 如果TransactionCallback事件中存在SurfaceControl,则会将ListenerCallbacks列表设置给每个SurfaceControl对应的layer_state_t中传递给sf,也就是给每个Layer设置TransactionCallback监听。

sf进程中根据TransactionCallback传递方式的不同,也会做不同的处理。

此时,业务进程的注册监听事件的操作全部完成。

三、sf中对TransactionCallback的处理

sf进程中收到来自业务进程的调用后,在下一次主线程执行commit操作时开始处理。

3.1、sf对TransactionCallback的管理

sf进程中将ITransactionCompletedListener监听接口的所有事件以<ITCL, std::deque<TransactionStats>>的形式保存在TransactionCallbackInvoker::mCompletedTransactions映射表中:

cpp 复制代码
// frameworks/native/services/surfaceflinger/TransactionCallbackInvoker.h

std::unordered_map<sp<IBinder>, std::deque<TransactionStats>, IListenerHash>
    mCompletedTransactions;

管理TransactionCallback监听事件的主要有三个类:TransactionStatsTransactionCallbackInvokerCallbackHandle

3.1.1、TransactionStats类

TransactionStats类代表一个ITransactionCompletedListener接口注册的所有TransactionCallback的封装类:

cpp 复制代码
// frameworks/native/libs/gui/include/gui/ITransactionCompletedListener.h

class TransactionStats : public Parcelable {
public:
    ......
    // 该Transaction设置的事件监听的CallbackId列表
    std::vector<CallbackId> callbackIds;
    // latch time时间戳
    nsecs_t latchTime = -1;
    // presentFence
    sp<Fence> presentFence = nullptr;
    // 涉及到的SurfaceStats
    std::vector<SurfaceStats> surfaceStats;
};

3.1.2、TransactionCallbackInvoker类

TransactionCallbackInvoker是专门用于管理TransactionCallback监听事件的类,业务进程设置的TransactionCallback监听事件会以TransactionStats的形式保存在该类中,并在完成提交或合成操作后,由它触发onTransactionCompleted()方法回调。

该类定义如下:

cpp 复制代码
// frameworks/native/services/surfaceflinger/TransactionCallbackInvoker.h

class TransactionCallbackInvoker {
public:
    // 将CallbackHandle中的信息封装到TransactionStats对象中,
    // 并添加到mCompletedTransactions列表保存
    status_t addCallbackHandles(const std::deque<sp<CallbackHandle>>& handles,
                                const std::vector<JankData>& jankData);
    // 将CallbackHandle中监听commit操作的回调事件信息封装到TransactionStats对象中,
    // 并添加到mCompletedTransactions列表保存
    status_t addOnCommitCallbackHandles(const std::deque<sp<CallbackHandle>>& handles,
                                             std::deque<sp<CallbackHandle>>& outRemainingHandles);
    // 将ListenerCallbacks列表中的CallbackId封装到TransactionStats对象中,
    // 并添加到mCompletedTransactions中
    void addEmptyTransaction(const ListenerCallbacks& listenerCallbacks);
    // 添加present Fence
    void addPresentFence(sp<Fence>);
    // 触发回调方法
    void sendCallbacks(bool onCommitOnly);
    ......
private:
    // 创建或获取TransactionStats对象
    status_t findOrCreateTransactionStats(const sp<IBinder>& listener,
                                          const std::vector<CallbackId>& callbackIds,
                                          TransactionStats** outTransactionStats);
    
    // key为IBinder、Value为TransactionStats对象队列的map
    std::unordered_map<sp<IBinder>, std::deque<TransactionStats>, IListenerHash>
        mCompletedTransactions;
    // Present Fence
    sp<Fence> mPresentFence;
};

3.1.3、CallbackHandle类

CallbackHandle表示TransactionCallback的"句柄",用于对Layer中图形缓冲数据相关状态记录、管理,并和TransactionCallback进行关联。在触发TransactionCallback回调事件前,对Layer中GraphicBuffer相关信息的收集会分布在多个步骤中,因此通过CallbackHandle对这些数据进行记录,最后统一传递给TransactionCallbackInvoker保存。

cpp 复制代码
// frameworks/native/services/surfaceflinger/TransactionCallbackInvoker.h

class CallbackHandle : public RefBase {
public:
    // ITransactionCompletedListender的sp<IBinder>形式对象
    sp<IBinder> listener;
    // CallbackId列表
    std::vector<CallbackId> callbackIds;
    // surfaceControl的wp<IBinder>形式对象
    wp<IBinder> surfaceControl;
    // 用于Buffer释放流程,表示是否释放前一帧Buffer
    bool releasePreviousBuffer = false;
    std::string name;
    // 前一帧Buffer的releaseFence
    sp<Fence> previousReleaseFence;
    // 前一帧Buffer的releaseFence集合,会全部merge生成全新的previousReleaseFence
    std::vector<ftl::SharedFuture<FenceResult>> previousReleaseFences;
    // 最近一次AcquireFence Signal的时间戳或AcquireFence本身
    std::variant<nsecs_t, sp<Fence>> acquireTimeOrFence = -1;
    // Latch buffer时间
    nsecs_t latchTime = -1;
    std::optional<uint32_t> transformHint = std::nullopt;
    // BBQ中可申请的最大buffer数
    uint32_t currentMaxAcquiredBufferCount = 0;
    std::shared_ptr<FenceTime> gpuCompositionDoneFence{FenceTime::NO_FENCE};
    CompositorTiming compositorTiming;
    nsecs_t refreshStartTime = 0;
    // 该Transaction开始present时间
    nsecs_t dequeueReadyTime = 0;
    // 当前帧的序列号
    uint64_t frameNumber = 0;
    // ReleaseCallbackId对象,releaseBuffer标识
    ReleaseCallbackId previousReleaseCallbackId = ReleaseCallbackId::INVALID_ID;
};

进入sf进程后的TransactionCallback保存关系图示如下:

3.2、向TransactionCallbackInvoker中的添加过程

由于业务进程向sf中传递TransactionCallback事件监听时,根据是否指定SurfaceControl分为两种方式,对应地

sf进程中收到调用后,也根据ListenerCallbacks的传递方式分两种方式处理:

  1. 如果是直接以参数形式传递的ListenerCallbacks列表,说明监听事件不针对任何Layer,则会将ListenerCallbacks直接读取保存;
  2. 如果是在layer_state_t中传递的ListenerCallbacks列表,说明监听事件还需要监听该Layer的状态,则会在对应的Layer中进行处理。

下面分别来看这两条流程。

3.2.1、直接传递ListenerCallbacks列表

这种方式不需要监听任何Layer的GraphicBuffer状态,因此会直接添加到TransactionCallbackInvoker中进行保存:

cpp 复制代码
// frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp

bool SurfaceFlinger::applyTransactionState(const FrameTimelineInfo& frameTimelineInfo,
                                           std::vector<ResolvedComposerState>& states,
                                           Vector<DisplayState>& displays, uint32_t flags,
                                           const InputWindowCommands& inputWindowCommands,
                                           const int64_t desiredPresentTime, bool isAutoTimestamp,
                                           const std::vector<uint64_t>& uncacheBufferIds,
                                           const int64_t postTime, bool hasListenerCallbacks,
                                           const std::vector<ListenerCallbacks>& listenerCallbacks,
                                           int originPid, int originUid, uint64_t transactionId) {
    ......
    
    // 这里将ListenerCallbacks类型的listener全部添加到mTransactionCallbackInvoker中
    for (const auto& listener : listenerCallbacks) {
        mTransactionCallbackInvoker.addEmptyTransaction(listener);
    }
    
}

在TransactionCallbackInvoker中,会根据ListenerCallbacks对象携带参数,创建TransactionStats对象,并放入到mCompletedTransactions映射表中的transactionStatsDeque队列中:

cpp 复制代码
// frameworks/native/services/surfaceflinger/TransactionCallbackInvoker.cpp

void TransactionCallbackInvoker::addEmptyTransaction(const ListenerCallbacks& listenerCallbacks) {
    auto& [listener, callbackIds] = listenerCallbacks;
    // 通过listener,从mCompletedTransactions中获取transactionStatsDeque
    auto& transactionStatsDeque = mCompletedTransactions[listener];
    // 根据callbackIds创建transactionStats并添加到transactionStatsDeque中
    transactionStatsDeque.emplace_back(callbackIds);
}

3.2.2、layer_state_t传递ListenerCallbacks列表

当ListenCallbacks通过layer_state_t传递时,说明TransactionCallback还会对对应的Layer信息进行收集,因此还需要进行状态收集的操作,Layer中借助于CallbackHandle,将ListenCallbacks和其他所需状态完成关联:

cpp 复制代码
// frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp

uint32_t SurfaceFlinger::setClientStateLocked(const FrameTimelineInfo& frameTimelineInfo,
                                              ResolvedComposerState& composerState,
                                              int64_t desiredPresentTime, bool isAutoTimestamp,
                                              int64_t postTime, uint64_t transactionId) {
    layer_state_t& s = composerState.state;

    std::vector<ListenerCallbacks> filteredListeners;
    // 遍历layer_state_t.listeners, 并将Callback类型为Commit和Complete的Callback保存
    for (auto& listener : s.listeners) {
        // 过滤回调事件类型为Commit的Callback
        ListenerCallbacks onCommitCallbacks = listener.filter(CallbackId::Type::ON_COMMIT);
        if (!onCommitCallbacks.callbackIds.empty()) {
            filteredListeners.push_back(onCommitCallbacks);
        }
        // 过滤回调事件类型为Complete的Callback
        ListenerCallbacks onCompleteCallbacks = listener.filter(CallbackId::Type::ON_COMPLETE);
        if (!onCompleteCallbacks.callbackIds.empty()) {
            filteredListeners.push_back(onCompleteCallbacks);
        }
    }
    ......
    // 根据LayerHandle的sp<IBinder>获得对应Layer
    sp<Layer> layer = nullptr;
    if (s.surface) {
        layer = LayerHandle::getLayer(s.surface);
    } else {
        // The client may provide us a null handle. Treat it as if the layer was removed.
        ALOGW("Attempt to set client state with a null layer handle");
    }
    
    // 根据过滤后得到的ListenCallbacks列表,以每个ListenCallbacks对象中的
    // transactionCompletedListener、callbackIds,结合当前LayerHandle创建CallbackHandle对象 
    std::vector<sp<CallbackHandle>> callbackHandles;
    if ((what & layer_state_t::eHasListenerCallbacksChanged) && (!filteredListeners.empty())) {
        for (auto& [listener, callbackIds] : filteredListeners) {
            callbackHandles.emplace_back(
                    sp<CallbackHandle>::make(listener, callbackIds, s.surface));
        }
    }
    ......
    // 将callbackHandles列表传递给Layer中
    if (layer->setTransactionCompletedListeners(callbackHandles,
                                                layer->willPresentCurrentTransaction() ||
                                                        layer->willReleaseBufferOnLatch())) {
        flags |= eTraversalNeeded;
    }
    ......
}

以上方法中,会根据ListenerCallbacks中的信息创建CallbackHandle对象,并执行Layer::setTransactionCompletedListeners()方法将CallbackHandle传递给Layer做进一步处理:

cpp 复制代码
// frameworks/native/services/surfaceflinger/Layer.cpp

bool Layer::setTransactionCompletedListeners(const std::vector<sp<CallbackHandle>>& handles,
                                             bool willPresent) {
    // 如果没有为当前Layer设置CallbackHandle,则将mReleasePreviousBuffer设置为false后直接返回
    // mReleasePreviousBuffer用于标记在触发回调后是否进行释放buffer操作
    if (handles.empty()) {
        mReleasePreviousBuffer = false;
        return false;
    }

    std::deque<sp<CallbackHandle>> remainingHandles;
    for (const auto& handle : handles) {
        // 是否需要释放上一帧Buffer
        handle->releasePreviousBuffer = mReleasePreviousBuffer;

        // 如果该Layer需要在当前该帧参与合成时, 那么还需要收集其他信息,
        // 此时会将CallbackHandle暂时保存在mDrawingState.callbackHandles中,
        // 等待完成合成后再传递给TransactionCallbackInvoker
        if (willPresent) {
            // 更新CallbackHandle的acquireTimeOrFence和framenumber属性
            handle->acquireTimeOrFence = mCallbackHandleAcquireTimeOrFence;
            handle->frameNumber = mDrawingState.frameNumber;

            // Store so latched time and release fence can be set
            mDrawingState.callbackHandles.push_back(handle);
        } else { 
            // 否则说明该Layer并不会在该帧合成显示,那么也不需要再收集其他信息
            // 则将CallbackHandle放在remainingHandles列表中,并直接添加到Invoker中,
            // 等待完成commit后回调
            remainingHandles.push_back(handle);
        }
    }
    // 将remainingHandles添加到TransactionCallbackInvoker中,等待完成commit后进行回调
    if (!remainingHandles.empty()) {
        std::vector<JankData> jankData;
        transferAvailableJankData(remainingHandles, jankData);
        mFlinger->getTransactionCallbackInvoker().addCallbackHandles(remainingHandles, jankData);
    }
    // 重置
    mReleasePreviousBuffer = false;
    mCallbackHandleAcquireTimeOrFence = -1;

    return willPresent;
}

以上方法中,会根据Layer是否参与此次合成过程,分情况处理:

  • 如果该Layer在该帧需要参与合成过程(willPresent为true),则会等待完成全部合成流程后再添加到TransactionCallbackInvoker中;

  • 否则,直接添加到TransactionCallbackInvoker中,完成commit操作时就会进行回调。

TransactionCallbackInvoker::addCallbackHandle()方法如下:

cpp 复制代码
// frameworks/native/services/surfaceflinger/TransactionCallbackInvoker.cpp

status_t TransactionCallbackInvoker::addCallbackHandle(const sp<CallbackHandle>& handle,
        const std::vector<JankData>& jankData) {

    TransactionStats* transactionStats;
    // 创建或获取TransactionStats对象
    status_t err =
            findOrCreateTransactionStats(handle->listener, handle->callbackIds, &transactionStats);
    // releaseFence相关合并操作,略去
    ......
    transactionStats->latchTime = handle->latchTime;

    sp<IBinder> surfaceControl = handle->surfaceControl.promote();
    if (surfaceControl) {
        ......
        // 创建FrameEventHistoryStats
        FrameEventHistoryStats eventStats(handle->frameNumber,
                                          handle->gpuCompositionDoneFence->getSnapshot().fence,
                                          handle->compositorTiming, handle->refreshStartTime,
                                          handle->dequeueReadyTime);
        // 创建SurfaceStats对象
        transactionStats->surfaceStats.emplace_back(surfaceControl, handle->acquireTimeOrFence,
                                                    handle->previousReleaseFence,
                                                    handle->transformHint,
                                                    handle->currentMaxAcquiredBufferCount,
                                                    eventStats, jankData,
                                                    handle->previousReleaseCallbackId);
    }
    return NO_ERROR;
}

以上方法中,会根据CallbackId创建或获取一个TransactionStats对象,然后将CallbackHandle中的属性更新给TransactionStats

3.3、TransactionCallback回调的触发

sf进程在完成commitcomposite后,会通过TransactionCallbackInvoker::sendCallbacks()发起回调方法的执行:

cpp 复制代码
// frameworks/native/services/surfaceflinger/TransactionCallbackInvoker.cpp

// onCommitOnly: 表示是否仅仅callback Commit类型的回调
void TransactionCallbackInvoker::sendCallbacks(bool onCommitOnly) {
    // 遍历mCompletedTransactions映射表
    auto completedTransactionsItr = mCompletedTransactions.begin();
    BackgroundExecutor::Callbacks callbacks;
    while (completedTransactionsItr != mCompletedTransactions.end()) {
        auto& [listener, transactionStatsDeque] = *completedTransactionsItr;
        // 创建一个ListenerStats对象
        ListenerStats listenerStats;
        // 将ITransactionCompletedListener对象赋值给listenerStats.listener
        listenerStats.listener = listener;

        // 遍历TransactionStats队列
        auto transactionStatsItr = transactionStatsDeque.begin();
        while (transactionStatsItr != transactionStatsDeque.end()) {
            // 获取TransactionStats对象
            auto& transactionStats = *transactionStatsItr;
            // 仅处理Comit类型的callback
            if (onCommitOnly && !containsOnCommitCallbacks(transactionStats.callbackIds)) {
                transactionStatsItr++;
                continue;
            }

            // 设置transactionStats.presentFence
            if (transactionStats.latchTime >= 0 &&
                !containsOnCommitCallbacks(transactionStats.callbackIds)) {
                transactionStats.presentFence = mPresentFence;
            }

            // 将transactionStats添加到listenerStats.transactionStats列表中
            listenerStats.transactionStats.push_back(std::move(transactionStats));
            // 从transactionStatsDeque队列中移除
            transactionStatsItr = transactionStatsDeque.erase(transactionStatsItr);
        }

        if (!listenerStats.transactionStats.empty()) {
            // If the listener is still alive
            if (listener->isBinderAlive()) {
                // 将Callback函数添加到Bg线程任务列表中
                callbacks.emplace_back([stats = std::move(listenerStats)]() {
                    interface_cast<ITransactionCompletedListener>(stats.listener)
                            ->onTransactionCompleted(stats);
                });
            }
        }
        completedTransactionsItr++;
    }
    // 清除mPresentFence
    if (mPresentFence) {
        mPresentFence.clear();
    }
    // Bg线程执行任务
    BackgroundExecutor::getInstance().sendCallbacks(std::move(callbacks));
}

在触发回调事件时,又将以TransactionStats形式保存在TransactionCallbackInvoker::mCompletedTranactions映射表中的监听事件以ListenerStats形式发送。

ListenerStats作为onTransactionCompleted()的方法参数,是sf进程向业务进程回调方法中传递的对象。也就是说,SF中的回调信息是封装在了ListenerStats中返回的:

arduino 复制代码
// frameworks/native/libs/gui/include/gui/ITransactionCompletedListener.h

class ListenerStats : public Parcelable {
public:
    ......
    // sp<IBinder>形式的TransactionCompletedListener对象
    sp<IBinder> listener;
    // transactionStats列表
    std::vector<TransactionStats> transactionStats;
};

四、业务进程接收回调

sf中触发回调方法后,TransactionCompletedListener::onTransactionCompleted()将收到调用并开始执行。

在这个方法中也会对携带参数ListenerStats进行分类和分发。

TransactionCompletedListener::onTransactionCompleted()方法如下:

cpp 复制代码
// frameworks/native/libs/gui/SurfaceComposerClient.cpp

void TransactionCompletedListener::onTransactionCompleted(ListenerStats listenerStats) {
    // 初始化一个map,用于暂存mCallbacks中的元素
    std::unordered_map<CallbackId, CallbackTranslation, CallbackIdHash> callbacksMap;
    // 初始化一个map,用于暂存mJankListeners中的元素
    std::multimap<int32_t, sp<JankDataListener>> jankListenersMap;
    {
        std::lock_guard<std::mutex> lock(mMutex);
        // 暂存mCallbacks中的元素
        callbacksMap = mCallbacks;
        // 暂存mJankListeners中的元素
        jankListenersMap = mJankListeners;
        // 从mCallbacks中移除此次回调返回ListenerStats中包括的callbackId
        for (const auto& transactionStats : listenerStats.transactionStats) {
            for (auto& callbackId : transactionStats.callbackIds) {
                mCallbacks.erase(callbackId);
            }
        }
    }
    
    for (const auto& transactionStats : listenerStats.transactionStats) {
        // 首先处理Transaction commit事件回调
        for (auto callbackId : transactionStats.callbackIds) {
            if (callbackId.type != CallbackId::Type::ON_COMMIT) {
                continue;
            }
            ......
            // 从callbacksMap中根据CallbackId获取对应的值CallbackTranslation对象
            // 并获取CallbackTranslation对象中的callbackFunction和surfaceControls映射表
            auto& [callbackFunction, callbackSurfaceControls] = callbacksMap[callbackId];
            ......
            
            // 将transactionStats.surfaceStats中的SurfaceStats添加到surfaceControlStats列表
            std::vector<SurfaceControlStats> surfaceControlStats;
            for (const auto& surfaceStats : transactionStats.surfaceStats) {
                surfaceControlStats
                        .emplace_back(callbacksMap[callbackId]
                                              .surfaceControls[surfaceStats.surfaceControl],
                                      transactionStats.latchTime, surfaceStats.acquireTimeOrFence,
                                      transactionStats.presentFence,
                                      surfaceStats.previousReleaseFence, surfaceStats.transformHint,
                                      surfaceStats.eventStats,
                                      surfaceStats.currentMaxAcquiredBufferCount);
            }
            // 执行TransactionCommittedCallback回调函数
            callbackFunction(transactionStats.latchTime, transactionStats.presentFence,
                             surfaceControlStats);
        }

        // 处理Transaction complete事件
        for (auto callbackId : transactionStats.callbackIds) {            
            if (callbackId.type != CallbackId::Type::ON_COMPLETE) {
                continue;
            }
            auto& [callbackFunction, callbackSurfaceControls] = callbacksMap[callbackId];
            ......
            // 将transactionStats.surfaceStats中的SurfaceStats添加到surfaceControlStats列表
            std::vector<SurfaceControlStats> surfaceControlStats;
            for (const auto& surfaceStats : transactionStats.surfaceStats) {
                surfaceControlStats
                        .emplace_back(callbacksMap[callbackId]
                                              .surfaceControls[surfaceStats.surfaceControl],
                                      transactionStats.latchTime, surfaceStats.acquireTimeOrFence,
                                      transactionStats.presentFence,
                                      surfaceStats.previousReleaseFence, surfaceStats.transformHint,
                                      surfaceStats.eventStats,
                                      surfaceStats.currentMaxAcquiredBufferCount);
                // 给SurfaceControl设置TransformHint
                if (callbacksMap[callbackId].surfaceControls[surfaceStats.surfaceControl] &&
                    surfaceStats.transformHint.has_value()) {
                    callbacksMap[callbackId]
                            .surfaceControls[surfaceStats.surfaceControl]
                            ->setTransformHint(*surfaceStats.transformHint);
                }
                // 处理Release Callback回调
                if (surfaceStats.previousReleaseCallbackId != ReleaseCallbackId::INVALID_ID) {
                    ReleaseBufferCallback callback;
                    {
                        std::scoped_lock<std::mutex> lock(mMutex);
                        // 从mReleaseBufferCallbacks映射表中找到对应的ReleaseBuffer Callback
                        callback = popReleaseBufferCallbackLocked(
                                surfaceStats.previousReleaseCallbackId);
                    }
                    // 触发Release buffer callback
                    if (callback) {
                        callback(surfaceStats.previousReleaseCallbackId,
                                 surfaceStats.previousReleaseFence
                                         ? surfaceStats.previousReleaseFence
                                         : Fence::NO_FENCE,
                                 surfaceStats.currentMaxAcquiredBufferCount);
                    }
                }
            }
            // 触发TransactionCompletedCallback事件
            callbackFunction(transactionStats.latchTime, transactionStats.presentFence,
                             surfaceControlStats);
        }

        // 处理SurfaceStats回调和onJankDataAvailable回调
        for (const auto& surfaceStats : transactionStats.surfaceStats) {
            ......
        }
    }
}

以上方法中,将依次执行TransactionCommittedCallback、ReleaseBufferCallback、TransactionCompletedCallback等事件的回调方法。

五、其他回调事件方法介绍

5.1、OnJankDataListener

OnJankDataListener用于监听指定图层的"Jank"状态。

当识别到有"Jank"发生时,会触发其onJankDataAvailable()方法回调。

"Jank"是指在渲染-合成-显示过程中,由于CPU/GPU处理Buffer耗时而导致的屏幕显示内容出现卡顿的现象。

设置JankDataListener方法如下:

cpp 复制代码
// 为SurfaceControl设置OnJankDataListener监听

public static void addJankDataListener(OnJankDataListener listener, SurfaceControl surface) {
    nativeAddJankDataListener(listener.mNativePtr.get(), surface.mNativeObject);
}

进入native层后,会将JankListener添加到TransactionCompletedListener中:

cpp 复制代码
// frameworks/base/core/jni/android_view_SurfaceControl.cpp

static void nativeAddJankDataListener(JNIEnv* env, jclass clazz,
                                       jlong jankDataCallbackListenerPtr,
                                       jlong nativeSurfaceControl) {

    // 将JankListener添加到TransactionCompletedListener中
    sp<JankDataListenerWrapper> wrapper =
            reinterpret_cast<JankDataListenerWrapper*>(jankDataCallbackListenerPtr);
    TransactionCompletedListener::getInstance()->addJankListener(wrapper, surface);
}


void TransactionCompletedListener::addJankListener(const sp<JankDataListener>& listener,
                                                   sp<SurfaceControl> surfaceControl) {
    std::lock_guard<std::mutex> lock(mMutex);
    // 将JankDataListener保存到mJankListeners列表中
    mJankListeners.insert({surfaceControl->getLayerId(), listener});
}

5.2、SurfaceStatsListener

SurfaceStatsListener接口用于统计SurfaceControl的合成状态。

在surfaceflinger合成过程中,会统计对应Layer的各个状态并封装在SurfaceStats中,完成合成后,会先通过TransactionCompletedListener::onTransactionCompleted()方法返回给业务进程,之后在TransactionCompletedListener中触发其SurfaceStatsCallback回调函数。

注册SurfaceStatsListener接口方法如下:

cpp 复制代码
// frameworks/native/libs/gui/SurfaceComposerClient.cpp

// 注册SurfaceStatsListener接口
void TransactionCompletedListener::addSurfaceStatsListener(void* context, void* cookie,
        sp<SurfaceControl> surfaceControl, SurfaceStatsCallback listener) {
    std::scoped_lock<std::recursive_mutex> lock(mSurfaceStatsListenerMutex);
    // 将监听接口放在mSurfaceStatsListeners列表中
    mSurfaceStatsListeners.insert(
            {surfaceControl->getLayerId(), SurfaceStatsCallbackEntry(context, cookie, listener)});
}

回调方法SurfaceStatsCallback是一个接受4个参数的函数,定义如下:

cpp 复制代码
// frameworks/native/libs/gui/include/gui/SurfaceComposerClient.h

using SurfaceStatsCallback =
        std::function<void(void* /*context*/, nsecs_t /*latchTime*/,
                           const sp<Fence>& /*presentFence*/,
                           const SurfaceStats& /*stats*/)>;

这个接口目前仅应用于surfaceflinger和HWUI中的数据同步,使用场景不多,但还是比较重要,在分析性能问题时,trace中的一些数据就是通过它进行传递(如GPU_Completion)。

在CanvasContext中,会在设置 的时候注册一个SurfaceStatsCallback:

cpp 复制代码
// frameworks/base/libs/hwui/renderthread/CanvasContext.cpp

void CanvasContext::setSurfaceControl(ASurfaceControl* surfaceControl) {
    if (surfaceControl == mSurfaceControl) return;

    auto funcs = mRenderThread.getASurfaceControlFunctions();

    ......
    mExpectSurfaceStats = surfaceControl != nullptr;
    if (mExpectSurfaceStats) {
        funcs.acquireFunc(mSurfaceControl);
        // 注册SurfaceStatsListener监听
        funcs.registerListenerFunc(surfaceControl, mSurfaceControlGenerationId, this,
                                   &onSurfaceStatsAvailable);
    }
}

当收到callback后,触发onSurfaceStatsAvailable(),然后向FrameInfo中填充gpuCompleteTime:

cpp 复制代码
// frameworks/base/libs/hwui/renderthread/CanvasContext.cpp

void CanvasContext::onSurfaceStatsAvailable(void* context, int32_t surfaceControlId,
                                            ASurfaceControlStats* stats) {
    auto* instance = static_cast<CanvasContext*>(context);
    // 获取gpuCompleteTime时间戳
    nsecs_t gpuCompleteTime = functions.getAcquireTimeFunc(stats);

    FrameInfo* frameInfo = instance->getFrameInfoFromLast4(frameNumber, surfaceControlId);

    // 填充FrameInfo信息
    if (frameInfo != nullptr) {
        std::scoped_lock lock(instance->mFrameMetricsReporterMutex);
        frameInfo->set(FrameInfoIndex::FrameCompleted) = std::max(gpuCompleteTime,
                frameInfo->get(FrameInfoIndex::SwapBuffersCompleted));
        frameInfo->set(FrameInfoIndex::GpuCompleted) = std::max(
                gpuCompleteTime, frameInfo->get(FrameInfoIndex::CommandSubmissionCompleted));
        instance->mJankTracker.finishFrame(*frameInfo, instance->mFrameMetricsReporter, frameNumber,
                                           surfaceControlId);
    }
}

SurfaceStats用于封装合成过程中的Layer相关状态的属性值:

cpp 复制代码
// frameworks/native/include/gui/ITransactionCompletedListener.h

class SurfaceStats : public Parcelable {
public:
    ......
    // LayerHandle对象
    sp<IBinder> surfaceControl;                                
    // 当前Layer在当前帧的Buffer的acquireFence signal的时间,或者acquireFence本身(未Unsignal时)
    std::variant<nsecs_t, sp<Fence>> acquireTimeOrFence = -1;  
    // 当前Layer在当前帧的Buffer releaseFence
    sp<Fence> previousReleaseFence;
    // transformHint用于提示client端BBQ中是否进行Buffer size的变更
    std::optional<uint32_t> transformHint = 0;
    // client端BBQ中变更最大acquire buffer数
    uint32_t currentMaxAcquiredBufferCount = 0;
    // 帧信息
    FrameEventHistoryStats eventStats;
    // Jank信息
    std::vector<JankData> jankData;
    // 释放上一帧Buffer的回调ID,用于进行releaseBuffer
    ReleaseCallbackId previousReleaseCallbackId;
};

5.3、TrustedPresentationCallback

TrustedPresentationCallback用于sf进程向业务进程传递指定SurfaceControl可信度状态的变化情况。

设置监听时,会传入一个可信度阈值TrustedPresentationThresholds,包括最小显示范围、最小渲染比例、保持时间。当满足阈值条件或发生变化后,sf进程中将触发ITransactionCompletedListener::onTrustedPresentationChanged()方法回调。

通过这个监听可以允许业务侧结合显示内容更精细的控制对应图层的显示参数。

Java层设置TrustedPresentationCallback方式如下:

java 复制代码
// frameworks/base/core/java/android/view/SurfaceControl.java

public Transaction setTrustedPresentationCallback(@NonNull SurfaceControl sc,
        @NonNull TrustedPresentationThresholds thresholds, @NonNull Executor executor,
        @NonNull Consumer<Boolean> listener) {
    checkPreconditions(sc);
    // 创建TrustedPresentationCallback
    TrustedPresentationCallback tpc = new TrustedPresentationCallback() {
        @Override
        public void onTrustedPresentationChanged(boolean inTrustedPresentationState) {
            executor.execute(
                    () -> listener.accept(inTrustedPresentationState));
        }
    };
    .....
    
    // 将TrustedPresentationCallback的本地对象注册给对应sc,并传递给surfaceflinger
    nativeSetTrustedPresentationCallback(mNativeObject, sc.mNativeObject,
            tpc.mNativeObject, thresholds);
    sc.mTrustedPresentationCallback = tpc;
    return this;
}

TrustedPresentationThresholds表示满足可信状态的阈值,包括三个属性:

java 复制代码
// frameworks/base/core/java/android/view/SurfaceControl.java

public static final class TrustedPresentationThresholds {
    private final float mMinAlpha;              // 最小图层透明度
    private final float mMinFractionRendered;   // 最小图层渲染比例
    private final int mStabilityRequirementMs;  // 满足透明度和渲染比例后保持的最小时长
 }

进入Native层后,会将回调对象包装成一个函数接口,保存在ITransactionCompletedListener的对应列表中:

cpp 复制代码
// frameworks/native/libs/gui/SurfaceComposerClient.cpp

// 代表Java层传递过来的监听的函数接口
using TrustedPresentationCallback = std::function<void(void*, bool)>;

sp<SurfaceComposerClient::PresentationCallbackRAII>
TransactionCompletedListener::addTrustedPresentationCallback(TrustedPresentationCallback tpc,
                                                             int id, void* context) {
    std::scoped_lock<std::mutex> lock(mMutex);
    // 将监听接口的回调函数接口保存在mTrustedPresentationCallbacks中
    mTrustedPresentationCallbacks[id] =
            std::tuple<TrustedPresentationCallback, void*>(tpc, context);
    return new SurfaceComposerClient::PresentationCallbackRAII(this, id);
}

5.4、ReleaseBufferCallback

ReleaseBufferCallback用于sf进程完成GraphicBuffer的使用后,通知业务进程进行释放GraphicBuffer。

当sf进程完成或者丢弃某一帧的GraphicBuffer时,会触发ITransactionCompletedListener::onReleaseBuffer()方法回调,之后在TransactionCompletedListener中触发其对应的ReleaseBufferCallback监听。

在每次Transaction::setBuffer()时,就会向TransactionCompletedListener中设置ReleaseBufferCallback监听:

cpp 复制代码
// frameworks/native/libs/gui/SurfaceComposerClient.cpp

void SurfaceComposerClient::Transaction::setReleaseBufferCallback(BufferData* bufferData,
                                                                  ReleaseBufferCallback callback) {
    
    bufferData->releaseBufferListener = TransactionCompletedListener::getIInstance();
    // 获取TCL实例
    auto listener = TransactionCompletedListener::getInstance();
    // 将ReleaseBufferCallback添加到TCL中
    listener->setReleaseBufferCallback(bufferData->generateReleaseCallbackId(), callback);
}

ReleaseBufferCallback也是一个函数接口:

cpp 复制代码
// frameworks/native/libs/gui/include/gui/SurfaceComposerClient.h

using ReleaseBufferCallback =
        std::function<void(const ReleaseCallbackId&, const sp<Fence>& /*releaseFence*/,
                           std::optional<uint32_t> currentMaxAcquiredBufferCount)>;

5.5、QueueStallListener

QueueStallListener监听用于向监听端发送sf进程中Transaction队列阻塞时的回调。当sf进程中Transaction队列出现阻塞时,可以通过触发ITransactionCompletedListener::onTransactionQueueStalled()方法回调通知业务进程,业务进程收到调用后,将继续触发已注册的QueueStallListener回调:

cpp 复制代码
// frameworks/native/libs/gui/SurfaceComposerClient.cpp

void TransactionCompletedListener::onTransactionQueueStalled(const String8& reason) {
    std::unordered_map<void*, std::function<void(const std::string&)>> callbackCopy;
    {
        std::scoped_lock<std::mutex> lock(mMutex);
        callbackCopy = mQueueStallListeners;
    }
    for (auto const& it : callbackCopy) {
        it.second(reason.c_str());
    }
}

QueueStallListener监听的注册非常简单,只是将接口保存在对应的监听列表TransactionCompletedListener::mQueueStallListeners中:

cpp 复制代码
// frameworks/native/libs/gui/SurfaceComposerClient.cpp

void TransactionCompletedListener::addQueueStallListener(
        std::function<void(const std::string&)> stallListener, void* id) {
    std::scoped_lock<std::mutex> lock(mMutex);
    mQueueStallListeners[id] = stallListener;
}
相关推荐
二流小码农1 小时前
鸿蒙开发:权限管理之授权方式
android·ios·harmonyos
每次的天空1 小时前
kotlin中的行为组件
android·开发语言·kotlin
wangz761 小时前
Kotlin,jetpack compose,Android,MPAndroidChart,折线图示例
android·kotlin·mpandroidchart
二流小码农1 小时前
鸿蒙开发:申请授权权限
android·ios·harmonyos
锋风2 小时前
音视频缓存数学模型
android
_一条咸鱼_2 小时前
深入剖析 Android Dagger 2 框架的注解模块(一)
android
小白马丶2 小时前
Jetpack源码解读(二)——LiveData
android·android jetpack
TDengine (老段)2 小时前
TDengine 特色查询
android·大数据·数据库·物联网·时序数据库·tdengine·iotdb
锋风2 小时前
安卓屏保调试
android
程序员江同学3 小时前
如何给 Kotlin 新增一个 target?
android·kotlin