Android-Choreographer工作原理(1)

本文详细解释了Android系统中NativeDisplayEventReceiver如何处理Vsync信号,涉及JNI接口、DisplayEventDispatcher初始化、Choreographer的调度以及SurfaceFlinger的工作流程。重点在于Vsync信号的请求和处理机制。
摘要由CSDN通过智能技术生成

nativeInit是一个native方法,其实现在frameworks/base/core/jni/android_view_DisplayEventReceiver.cpp中:

static jlong nativeInit(JNIEnv* env, jclass clazz, jobject receiverWeak,
jobject messageQueueObj, jint vsyncSource) {
sp messageQueue = android_os_MessageQueue_getMessageQueue(env, messageQueueObj);
sp receiver = new NativeDisplayEventReceiver(env, receiverWeak, messageQueue, vsyncSource);
status_t status = receiver->initialize();
receiver->incStrong(gDisplayEventReceiverClassInfo.clazz); // retain a reference for the object
return reinterpret_cast(receiver.get());
}


NativeDisplayEventReceiver 继承自 DisplayEventDispatcher:

DisplayEventReceiver::DisplayEventReceiver(ISurfaceComposer::VsyncSource vsyncSource) {
sp sf(ComposerService::getComposerService());
if (sf != NULL) {
mEventConnection = sf->createDisplayEventConnection(vsyncSource);
if (mEventConnection != NULL) {
mDataChannel = std::make_unique();
mEventConnection->stealReceiveChannel(mDataChannel.get());
}
}
}

sp SurfaceFlinger::createDisplayEventConnection(
ISurfaceComposer::VsyncSource vsyncSource) {
if (vsyncSource == eVsyncSourceSurfaceFlinger) {
return mSFEventThread->createEventConnection();
} else {
// vsyncSource 是 APP
return mEventThread->createEventConnection();
}
}


从 SurfaceFlinger 启动与工作流程 可以知道 EventThread.createEventConnection 创建了一个对 Vsync 信号感兴趣的连接,具体逻辑可以阅读这篇文章。initialize 方法如下:

// frameworks/base/libs/androidfw/DisplayEventDispatcher.cpp
status_t DisplayEventDispatcher::initialize() {
// DisplayEventReceiver mReceiver;
status_t result = mReceiver.initCheck();
int rc = mLooper->addFd(mReceiver.getFd(), 0, Looper::EVENT_INPUT, this, NULL);
if (rc < 0) {
return UNKNOWN_ERROR;
}
return OK;
}

mReceiver 是 DisplayEventReceiver 类型实例,位于frameworks/native/libs/gui/DisplayEventReceiver.cpp。mLooper->addFd(mReceiver.getFd(), 0, Looper::EVENT_INPUT, this, NULL) 用来监听 mReceiver 所获取的文件句柄,当**有存在对 Vsync 信号感兴趣的连接**且**接收到了 Vsync 信号**时,会发送数据到 mReceiver, 然后回调到 DisplayEventDispatcher 中的 handleEvent 方法,具体源码参考 SurfaceFlinger 启动与工作流程 中 addFd 的解析。

# 请求Vsync信号

上面已经注册了一个对 Vsync 信号感兴趣的连接,在 Vsync 信号到来后,会回调到 DisplayEventDispatcher.handleEvent 方法。于是接下来我们需要请求 Vsync 信号。看一下上面调用的代码:mChoreographer.postCallback(Choreographer.CALLBACK_TRAVERSAL, mTraversalRunnable, null),它的调用链是: Choreographer.postCallback -> Choreographer.postCallbackDelayedInternal -> Choreographer.scheduleFrameLocked -> Choreographer.scheduleVsyncLocked 方法,节省篇幅,具体代码不贴出了:

private void postCallbackDelayedInternal(int callbackType, Object action, Object token, long delayMillis) {
synchronized (mLock) {
final long now = SystemClock.uptimeMillis();
final long dueTime = now + delayMillis;
// 对应类型的 CallbackQueue 添加 Callback
mCallbackQueues[callbackType].addCallbackLocked(dueTime, action, token);
// ...
}
}

private void scheduleVsyncLocked() {
mDisplayEventReceiver.scheduleVsync();
}

// DisplayEventReceiver
public void scheduleVsync() {
if (mReceiverPtr == 0) {
// ...
} else {
nativeScheduleVsync(mReceiverPtr);
}
}


接着就到了 native 层代码:

// frameworks/base/core/jni/android_view_DisplayEventReceiver.cpp
static void nativeScheduleVsync(JNIEnv* env, jclass clazz, jlong receiverPtr) {
sp receiver = reinterpret_cast
  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值