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 构造
- 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
- 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()); } - 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(); } - 核心都是通过 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 的服务
- 创建:构造函数中创建
//获取 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());
}
}
- 发送消息
//设置 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 的接口,看看是怎么处理的