app 进程请求 vsync 信号

116 阅读2分钟

1. 接口调用

Choreography.java:

public void postFrameCallback(FrameCallback callback)public void postVsyncCallback(@NonNull VsyncCallback callback)

二者都会调用下面接口,向系统请求 Vsync 信号
private void scheduleVsyncLocked() {
    try {
        //mDisplayEventReceiver 类型为 FrameDisplayEventReceiver
        mDisplayEventReceiver.scheduleVsync(); 
    } finally {
    }
}

2. 流程

2.1 FrameDisplayEventReceiver.java 类

2.1.1 构造

  1. Choreography 初始化的时候构造
// looper 为Choreography 的 looper,可以认为是主线程 looper
// vsyncSource: 1
// layerHandle:不需要管一直为 0

FrameDisplayEventReceiver(Looper looper, int vsyncSource, long layerHandle) {
    super(looper, vsyncSource, /* eventRegistration */ 0, layerHandle);
}

2. 继承自DisplayEventReceiver

public DisplayEventReceiver(Looper looper, int vsyncSource, int eventRegistration,
    long layerHandle) {
    
    //持有 Looper 的 Queue
    mMessageQueue = looper.getQueue();
    //持有 native 层的 DisplayEventReceiver (NativeDisplayEventReceiver)
    mReceiverPtr = nativeInit(new WeakReference<DisplayEventReceiver>(this),
            new WeakReference<VsyncEventData>(mVsyncEventData),
            mMessageQueue,
            vsyncSource, eventRegistration, layerHandle);
}

3. 请求 VSync 信号

public void scheduleVsync() {
    nativeScheduleVsync(mReceiverPtr);
}

2.2 android_view_DisplayEventReceiver.cpp

  1. nativeInit
    //构造方法 nativeInit 对应的初始化
    // receiverWeak: java 层的 DisplayEventReceiver
    //messageQueueObj: java 层的 MessageQueue
    static jlong nativeInit(JNIEnv* env, jclass clazz, jobject receiverWeak,
        jobject messageQueueObj, jint vsyncSource) {
        //拿到本地的 MessageQueue
        sp<MessageQueue> messageQueue = android_os_MessageQueue_getMessageQueue(env, messageQueueObj);
        
        //创建 NativeDisplayEventReceiver
        sp<NativeDisplayEventReceiver> receiver = new NativeDisplayEventReceiver(env,
            receiverWeak, messageQueue, vsyncSource);
        status_t status = receiver->initialize();
    
        receiver->incStrong(gDisplayEventReceiverClassInfo.clazz); 
        //返回指针
        return reinterpret_cast<jlong>(receiver.get());
    }
    
  2. nativeScheduleVsync
    // receiverPtr native 层的 NativeDisplayEventReceiver
    static void nativeScheduleVsync(JNIEnv* env, jclass clazz, jlong receiverPtr) {
        sp<NativeDisplayEventReceiver> receiver =
            reinterpret_cast<NativeDisplayEventReceiver*>(receiverPtr);
           //核心方法
        status_t status = receiver->scheduleVsync();
    }
    
  3. 核心都是通过 native 的 NativeDisplayEventReceiver 来实现的

2.3 NativeDisplayEventReceiver.cpp

class NativeDisplayEventReceiver : public DisplayEventDispatcher {
public:
    NativeDisplayEventReceiver(JNIEnv* env,
        jobject receiverWeak, const sp<MessageQueue>& messageQueue, jint vsyncSource);

    void dispose();

protected:
    virtual ~NativeDisplayEventReceiver();

private:
    jobject mReceiverWeakGlobal;
    sp<MessageQueue> mMessageQueue;
    DisplayEventReceiver mReceiver;

    virtual void dispatchVsync(nsecs_t timestamp, int32_t id, uint32_t count);
    virtual void dispatchHotplug(nsecs_t timestamp, int32_t id, bool connected);
};

继承自 DisplayEventDispatcher

2.4 DisplayEventDispatcher.cpp

class DisplayEventDispatcher : public LooperCallback {
    public:
        DisplayEventDispatcher(const sp<Looper>& looper,
        ISurfaceComposer::VsyncSource vsyncSource = ISurfaceComposer::eVsyncSourceApp);

        status_t initialize();
        void dispose();
        status_t scheduleVsync();//这是调度 Vsync 接口

    private:
        sp<Looper> mLooper;
        //这个是重点对象
        DisplayEventReceiver mReceiver;
        bool mWaitingForVsync;

};

status_t DisplayEventDispatcher::scheduleVsync() {
    if (!mWaitingForVsync) {
        //核心是通过 mReceiver 进行请求
        status_t status = mReceiver.requestNextVsync();

        mWaitingForVsync = true;
    }
    return OK;
}

2.5 DisplayEventReceiver 重点讲解

2.1 mEventConnection

作为 binder 客户端,调用 SurfaceFlinger 的服务

  1. 创建:构造函数中创建
    //获取 SurfaceFlinger 服务
    sp<ISurfaceComposer> sf(ComposerService::getComposerService());
    if (sf != NULL) {
        //创建与 SurfaceFlinger 通信的桥梁,mEventConnection 主要是发消息给 SurfaceFlinger
        mEventConnection = sf->createDisplayEventConnection(vsyncSource);
        if (mEventConnection != NULL) {
            mDataChannel = std::make_unique<gui::BitTube>();
            mEventConnection->stealReceiveChannel(mDataChannel.get());
        }
    }
  1. 发送消息
//设置 Vsync 的 rate
status_t DisplayEventReceiver::setVsyncRate(uint32_t count) {
    if (int32_t(count) < 0)
        return BAD_VALUE;

    if (mEventConnection != NULL) {
        mEventConnection->setVsyncRate(count);
        return NO_ERROR;
    }
    return NO_INIT;
}
//请求 Vsync 信号
status_t DisplayEventReceiver::requestNextVsync() {
    if (mEventConnection != NULL) {
        mEventConnection->requestNextVsync();
        return NO_ERROR;
    }
    return NO_INIT;
}

对于这两个方法,在 SurfaceFlinger 有相同的方法对应;这里的 mEventConnection 可以理解为一个 binder 客户端,给 SurfaceFlinger 服务发送请求

至此 app 请求 Vsync 信号的流程就结束了,这里说的结束这是应用程序进程端结束,而 mEventConnection 接口没有详细介绍,为什么呢,因为他们是 binder 调用,等到后续我讲到 SurfaceFlinger 部分再来结合 mEventConnection 的接口,看看是怎么处理的