上一篇文章中介绍了SurfaceFlinger搭建的Vsync基础设施,它先向HWComposer注册回调,然后开启EventThread 线程无限循环,从pendingEvents中拿事件向消费者分发事件,它会往消费者提供的文件描述符中发送信号,从而通知消费者。当pendingEvents中没有事件时,线程就等待mCondition上的通知。而另一方面,当HWComposer上来Vsync事件时,会往pendingEvents添加一个 Vsync的事件,并调用mCondition.notify_all,唤醒分发线程。 同时也提到如果没有消费者,或者消费者没有发出请求,则不会向App发出Vsync信号。本文将从App的角度继续来分析Vsync的原理。
1.1 App层注册DisplayEventReceiver
首先是App运行时,会在初始化Choreographer的初始化,这时就创建了一个DisplayEventReceiver的子类的对象
private Choreographer(Looper looper, int vsyncSource) {
mLooper = looper;
mHandler = new FrameHandler(looper);
mDisplayEventReceiver = USE_VSYNC
? new FrameDisplayEventReceiver(looper, vsyncSource)
: null;
...
}
构造方法内部调用一个nativeInit方法在JNI层生成一个NativeDisplayEventReceiver对象,并将该对象的指针返回,java层将指针保存到mReceiverPtr
public DisplayEventReceiver(Looper looper, int vsyncSource, int eventRegistration) {
if (looper == null) {
throw new IllegalArgumentException("looper must not be null");
}
mMessageQueue = looper.getQueue();
mReceiverPtr = nativeInit(new WeakReference<DisplayEventReceiver>(this), mMessageQueue,
vsyncSource, eventRegistration);
}
frameworks/base/core/jni/android_view_DisplayEventReceiver.cpp
static jlong nativeInit(JNIEnv* env, jclass clazz, jobject receiverWeak, jobject messageQueueObj, jint vsyncSource, jint eventRegistration) {
sp<NativeDisplayEventReceiver> receiver =
new NativeDisplayEventReceiver(env, receiverWeak, messageQueue, vsyncSource,eventRegistration);
status_t status = receiver->initialize();
receiver->incStrong(gDisplayEventReceiverClassInfo.clazz); // retain a reference for the object
return reinterpret_cast<jlong>(receiver.get());
}
这里的NativeDisplayEventReceiver继承自DisplayEventDispatcher
class NativeDisplayEventReceiver : public DisplayEventDispatcher {
而这个DisplayEventDispatcher来自于
frameworks/native/libs/gui/DisplayEventReceiver.cpp
DisplayEventReceiver::DisplayEventReceiver(
ISurfaceComposer::VsyncSource vsyncSource,
ISurfaceComposer::EventRegistrationFlags eventRegistration) {
sp<ISurfaceComposer> sf(ComposerService::getComposerService());
if (sf != nullptr) {
mEventConnection = sf->createDisplayEventConnection(vsyncSource, eventRegistration);
if (mEventConnection != nullptr) {
mDataChannel = std::make_unique<gui::BitTube>();
mEventConnection->stealReceiveChannel(mDataChannel.get());
}
}
}
创建好层的NativeDisplayEventReceiver,它会获取surfaceFlinger远程服务创建一个mEventConnection,接着调用了mEventConnection->stealReceiveChannel(mDataChannel.get());方法,这个远程服务的流程在后文中再介绍。
frameworks/native/services/surfaceflinger/Scheduler/EventThread.cpp
status_t EventThreadConnection::stealReceiveChannel(gui::BitTube* outChannel) {
outChannel->setReceiveFd(mChannel.moveReceiveFd());
outChannel->setSendFd(base::unique_fd(dup(mChannel.getSendFd())));
return NO_ERROR;
}
这是一个远程调用,它将mEventConnect的mChannel中的moveReceiveFd和getSendFd都拷贝到了outChannel,然后调用initialize进行初始化。
frameworks/native/libs/gui/DisplayEventDispatcher.cpp
status_t DisplayEventDispatcher::initialize() {
...
if (mLooper != nullptr) {
int rc = mLooper->addFd(mReceiver.getFd(), 0, Looper::EVENT_INPUT, this, NULL);
if (rc < 0) {
return UNKNOWN_ERROR;
}
}
return OK;
}
initialize很简单,只是给mLooper添加一个监听的mReceiver的文件描述符FileDescriptor,上面看到这个文件描述符是有从 mEventConnection中”steal“来的,因此实际上监听是注册在mEventConnection上的(上一篇中介绍到,当EventThread分发时Vsync时,是通过send方法向FD中发送数据,所以APP和SurfaceFlinger就是在这里对接起来),于是当产生EVENT_INPUT事件时回调this的handleEvent函数
int DisplayEventDispatcher::handleEvent(int, int events, void*) {
...
// Drain all pending events, keep the last vsync.
nsecs_t vsyncTimestamp;
PhysicalDisplayId vsyncDisplayId;
uint32_t vsyncCount;
VsyncEventData vsyncEventData;
if (processPendingEvents(&vsyncTimestamp, &vsyncDisplayId, &vsyncCount, &vsyncEventData)) {
...
mWaitingForVsync = false;
dispatchVsync(vsyncTimestamp, vsyncDisplayId, vsyncCount, vsyncEventData);
}
return 1; // keep the callback
}
handleEvent的时候会调用processPendingEvents来处理收到的事件数据,其中一种数据的header.type == DISPLAY_EVENT_VSYNC,就表示是sync事件,然后调用dispatchVsync函数,通知app层sync信号产生了。
bool DisplayEventDispatcher::processPendingEvents(nsecs_t* outTimestamp, PhysicalDisplayId* outDisplayId,
uint32_t* outCount, VsyncEventData* outVsyncEventData) {
bool gotVsync = false;
DisplayEventReceiver::Event buf[EVENT_BUFFER_SIZE];
ssize_t n;
while ((n = mReceiver.getEvents(buf, EVENT_BUFFER_SIZE)) > 0) {
ALOGV("dispatcher %p ~ Read %d events.", this, int(n));
mFrameRateOverrides.reserve(n);
for (ssize_t i = 0; i < n; i++) {
const DisplayEventReceiver::Event& ev = buf[i];
switch (ev.header.type) {
case DisplayEventReceiver::DISPLAY_EVENT_VSYNC:
gotVsync = true;
...
break;
...
return gotVsync;
}
dispatchVsyncs是一个虚函数,在NativeDisplayEventReceiver中实现
frameworks/base/core/jni/android_view_DisplayEventReceiver.cpp
void NativeDisplayEventReceiver::dispatchVsync(nsecs_t timestamp, PhysicalDisplayId displayId,
uint32_t count, VsyncEventData vsyncEventData) {
JNIEnv* env = AndroidRuntime::getJNIEnv();
ScopedLocalRef<jobject> receiverObj(env, jniGetReferent(env, mReceiverWeakGlobal));
if (receiverObj.get()) {
env->CallVoidMethod(receiverObj.get(), gDisplayEventReceiverClassInfo.dispatchVsync,
timestamp, displayId.value, count, vsyncEventData.id,
vsyncEventData.deadlineTimestamp, vsyncEventData.frameInterval);
}
mMessageQueue->raiseAndClearException(env, "dispatchVsync");
}
获取到JAVA层DisplayEventReceiver对象的指针,然后调用dispatchVsync方法(偏移量为DisplayEventReceiverClassInfo.dispatchVsync)
android/view/DisplayEventReceiver.java
private void dispatchVsync(long timestampNanos, long physicalDisplayId, int frame,
long frameTimelineVsyncId, long frameDeadline, long frameInterval) {
onVsync(timestampNanos, physicalDisplayId, frame,
new VsyncEventData(frameTimelineVsyncId, frameDeadline, frameInterval));
}
调用onVsync方法,这个时在Choreogragher 的内部类中实现的
public FrameDisplayEventReceiver(Looper looper, int vsyncSource) {
super(looper, vsyncSource, 0);
}
public void onVsync(long timestampNanos, long physicalDisplayId, int frame,
VsyncEventData vsyncEventData) {
...
Message msg = Message.obtain(mHandler, this);
msg.setAsynchronous(true);
mHandler.sendMessageAtTime(msg, timestampNanos / TimeUtils.NANOS_PER_MS);
}
public void run() {
mHavePendingVsync = false;
doFrame(mTimestampNanos, mFrame, mLastVsyncEventData);
}
Vsync就在应用层得到了响应,执行doFrame开始绘制界面。整个的初始化流程以及Vsync信息向上传递的流程就串联起来了。但是中间有一个断层,就是DisplayEventDispatcher的Looper什么时候会收到mReceiver文件描述符上的Looper::EVENT_INPUT事件?前一篇文章中提到Vsync需要App层的通知才会发送,否则EventThread线程将一直等待在mCondition.wait.
3.2 触发Vsync
我们再回到UI层来看看
3.2.1 ViewRootimpl
在ViewRootImpl.setView之后,回去调用requestLayout方法,此时会向Choreographer注册callback:
public void requestLayout() {
if (!mHandlingLayoutInLayoutRequest) {
checkThread();
mLayoutRequested = true;
scheduleTraversals();
}
}
void scheduleTraversals() {
if (!mTraversalScheduled) {
mTraversalScheduled = true;
mTraversalBarrier = mHandler.getLooper().getQueue().postSyncBarrier();
mChoreographer.postCallback(Choreographer.CALLBACK_TRAVERSAL, mTraversalRunnable, null);
notifyRendererOfFramePending();
pokeDrawLockIfNeeded();
}
}
mChoreographer.postCallback将进入到Choreograher,通知安排vsync
3.2.2 Choreographer
Choreograher是一个承上启下的角色,当Vsync到来时通知View进行绘制,同样当画面绘制开始时,它也会通知低层开始可以安排Vsync
public void postCallback(int callbackType, Runnable action, Object token) {
postCallbackDelayed(callbackType, action, token, 0);
}
public void postCallbackDelayed(int callbackType, Runnable action, Object token, long delayMillis) {
...
postCallbackDelayedInternal(callbackType, action, token, delayMillis);
}
private void postCallbackDelayedInternal(int callbackType, Object action, Object token, long delayMillis) {
...
Message msg = mHandler.obtainMessage(MSG_DO_SCHEDULE_CALLBACK, action);
msg.arg1 = callbackType;
msg.setAsynchronous(true);
mHandler.sendMessageAtTime(msg, dueTime);
}
mHandler是FrameHandler的实例,它 是一个内部类,它可以处理三种消息
1,MSG_DO_FRAME。调用doFrame开始新一帧的绘制
2,MSG_DO_SCHEDULE_VSYNC。调用doScheduleVsync通知低层准备VSync
3,MSG_DO_SCHEDULE_CALLBACK。调用doScheduleCallback,如果mFrameScheduled = false,调用scheduleFrameLocked,将mFrameScheduled 设置为true,在USE_VSYNC==true的时候,发送MSG_DO_SCHEDULE_VSYNC消息,消息处理后就会调用到doScheduleVsync。目前USE_VSYNC都是为true的,如果关闭它,则发送直接发送MSG_DO_FRAME消息。
private final class FrameHandler extends Handler {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_DO_FRAME:
doFrame(System.nanoTime(), 0, new DisplayEventReceiver.VsyncEventData());
break;
case MSG_DO_SCHEDULE_VSYNC:
doScheduleVsync();
break;
case MSG_DO_SCHEDULE_CALLBACK:
doScheduleCallback(msg.arg1);
break;
}
}
}
处理MSG_DO_SCHEDULE_VSYNC消息,此时mFrameScheduled = false,调用scheduleFrameLocked方法
void doScheduleCallback(int callbackType) {
if (!mFrameScheduled) {
...
scheduleFrameLocked(now);
}
}
mFrameScheduled 开始为false,进入case之后设置为true,USE_VSYNC是由一个系统属性“debug.choreographer.vsync”控制的,默认为true,然后就发送MSG_DO_SCHEDULE_VSYNC消息。
private void scheduleFrameLocked(long now) {
if (!mFrameScheduled) {
mFrameScheduled = true;
if (USE_VSYNC) {
if (isRunningOnLooperThreadLocked()) {
scheduleVsyncLocked();
} else {
Message msg = mHandler.obtainMessage(MSG_DO_SCHEDULE_VSYNC);
msg.setAsynchronous(true);
mHandler.sendMessageAtFrontOfQueue(msg);
}
} else {
Message msg = mHandler.obtainMessage(MSG_DO_FRAME);
msg.setAsynchronous(true);
mHandler.sendMessageAtTime(msg, nextFrameTime);
}
}
}
处理MSG_DO_SCHEDULE_VSYNC消息,此时mFrameScheduled = true,因此执行scheduleVsyncLocked方法
void doScheduleVsync() {
synchronized (mLock) {
if (mFrameScheduled) {
scheduleVsyncLocked();
}
}
}
调用mDisplayEventReceiver安排sync
private void scheduleVsyncLocked() {
...
mDisplayEventReceiver.scheduleVsync();
...
}
这里有一个mFrameScheduled控制变量很重要,它表示已经通知低层为下一帧排期了,在app收到Vsync,执行doFrame之后,它会再次置为false。
到目前为之,我们可以看到,是因为ViewRootImpl.requestLayout 触发了 mDisplayEventReceiver.scheduleVsync,也就是app需要更新的时候,并不是自己立刻就动手绘制,而且先告知底层框架,我有更新需求了,底层框架得到通知后就检测一下它是不是显示完一帧了,显示完了就发一个Vsync给上层app,app收到之后执行doFrame开始真正的绘制。如果app一直没有更新需求,底层得不到通知,所以就不会发出vsync信号
@UnsupportedAppUsage
public void scheduleVsync() {
if (mReceiverPtr == 0) {
Log.w(TAG, "Attempted to schedule a vertical sync pulse but the display event "
+ "receiver has already been disposed.");
} else {
nativeScheduleVsync(mReceiverPtr);
}
}
调用了一个native方法nativeScheduleVsync函数,传入mReceiverPtr
frameworks/base/core/jni/android_view_DisplayEventReceiver.cpp
static const JNINativeMethod gMethods[] = {
...
{ "nativeScheduleVsync", "(J)V", (void*)nativeScheduleVsync }
};
nativeScheduleVsync映射到nativeScheduleVsync这个函数
static void nativeScheduleVsync(JNIEnv* env, jclass clazz, jlong receiverPtr) {
sp<NativeDisplayEventReceiver> receiver =
reinterpret_cast<NativeDisplayEventReceiver*>(receiverPtr);
status_t status = receiver->scheduleVsync();
if (status) {
String8 message;
message.appendFormat("Failed to schedule next vertical sync pulse. status=%d", status);
jniThrowRuntimeException(env, message.string());
}
}
将receiverPtr转换回NativeDisplayEventReceiver类型的对象,这个对象就是初始化时在JNI生成的,然后再执行它的scheduleVsync函数
status_t DisplayEventDispatcher::scheduleVsync() {
if (!mWaitingForVsync) {
// Drain all pending events.
nsecs_t vsyncTimestamp;
PhysicalDisplayId vsyncDisplayId;
uint32_t vsyncCount;
VsyncEventData vsyncEventData;
if (processPendingEvents(&vsyncTimestamp, &vsyncDisplayId, &vsyncCount, &vsyncEventData)) {
ALOGE("dispatcher %p ~ last event processed while scheduling was for %" PRId64 "", this,
ns2ms(static_cast<nsecs_t>(vsyncTimestamp)));
}
status_t status = mReceiver.requestNextVsync();
if (status) {
ALOGW("Failed to request next vsync, status=%d", status);
return status;
}
mWaitingForVsync = true;
}
return OK;
}
继续调用 mReceiver.requestNextVsync()请求下一次 Vsync,
frameworks/native/libs/gui/include/gui/DisplayEventDispatcher.h
status_t DisplayEventReceiver::requestNextVsync() {
if (mEventConnection != nullptr) {
mEventConnection->requestNextVsync();
return NO_ERROR;
}
return NO_INIT;
}
mEventConnection是初始化DisplayEventReceiver时调用ComposeerService.createDisplayEventConnection就创建好的,它的类型是IDisplayEventConnection,然后在requestNextVsync时,通过调用mEventConnection.requestNextVsync来请求下一次VSync。
需要说明的是到目前为止,我们的代码包括JAVA和JNI,都运行在app的进程。这个里多出来几个新的类型。ComposerService,ISurfaceComposer,IDisplayEventConnection, 现在我们就需要通过Binder进行IPC穿越到surfaceflinger进程中去,IBinder的机制不是本文的范围,这里就不介绍Binder的原理了,直接进入到 SurfaceFlingger
.
3.2.3 连接SurfaceFligger
- ComposerService::getComposerService()
frameworks/native/include/private/gui/ComposerService.h
*frameworks/native/libs/gui/SurfaceComposerClient.cpp
/*static*/ sp<ISurfaceComposer> ComposerService::getComposerService() {
ComposerService& instance = ComposerService::getInstance();
Mutex::Autolock _l(instance.mLock);
if (instance.mComposerService == nullptr) {
if (ComposerService::getInstance().connectLocked()) {
ALOGD("ComposerService reconnected");
}
}
return instance.mComposerService;
}
ComposerService 是通过宏定义的一个单例,
NDROID_SINGLETON_STATIC_INSTANCE(ComposerService);
ComposerService::ComposerService()
: Singleton<ComposerService>() {
Mutex::Autolock _l(mLock);
connectLocked();
}
bool ComposerService::connectLocked() {
const String16 name("SurfaceFlinger");
mComposerService = waitForService<ISurfaceComposer>(name);
if (mComposerService == nullptr) {
return false; // fatal error or permission problem
}
...
}
初始化单例对象的时候,会调用connectLocked方法,内部通过调用ServiceManager的waitForService去获取SurfaceFlinger远程服务的本地接口,所以mComposerService可以和远程的SurfaceFlinger服务进行IPC通信。
这里的第一个通信就是createDisplayEventConnection。
我们知道一个Binder通信由3部分组成,一个就是通信接口,一个服务端的Bn接口和客户端的Bp接口。ISurfaceComposer 是接口,BnSurfaceComposer是服务端,BpSurfaceComposer是客户端。ISurfaceComposer,BnSurfaceComposer的申明是在ISurfaceComposer.h中,
frameworks/native/include/gui/ISurfaceComposer.h
class ISurfaceComposer: public IInterface {
public:
DECLARE_META_INTERFACE(SurfaceComposer)//
static constexpr size_t MAX_LAYERS = 4096;
...
}
这里用到DECLARE_META_INTERFACE这个宏定义,就具有IIIterface的那些模板方法
class BnSurfaceComposer: public BnInterface<ISurfaceComposer> {
public:
enum ISurfaceComposerTag {
}
...
BnSurfaceComposer 是服务端的桩,surfaceflinger服务类需要继承这个类.下面是客户端的BpSurfaceComposer
frameworks/native/libs/gui/ISurfaceComposer.cpp
class BpSurfaceComposer : public BpInterface<ISurfaceComposer>
{
public:
explicit BpSurfaceComposer(const sp<IBinder>& impl)
: BpInterface<ISurfaceComposer>(impl)
{
}
virtual ~BpSurfaceComposer();
virtual sp<ISurfaceComposerClient> createConnection()
我们通过 mComposerService = waitForService<ISurfaceComposer>(“SurfaceFlinger”)得到的mComposerService,就是在Binder驱动中查找到的IBinder,然后用BpSurfaceComposer包装出来的,也就是说mComposerService的类型是BpSurfaceComposer。因此createDisplayEventConnection方法如下:
frameworks/native/libs/gui/ISurfaceComposer.cpp
sp<IDisplayEventConnection> createDisplayEventConnection(
VsyncSource vsyncSource, EventRegistrationFlags eventRegistration) override {
...
err = remote()->transact(
BnSurfaceComposer::CREATE_DISPLAY_EVENT_CONNECTION,
data, &reply);
...
result = interface_cast<IDisplayEventConnection>(reply.readStrongBinder());
return result;
}
remote()->transact就是在进行远程调用,它会IPC到surfaceFlinger进程,执行BnSurfaceComposer.createDisplayEventConnection,而SurfaceFlinger就是BnSurfaceComposer的子类,因此进入到SurfaceFlinger。
frameworks/native/services/surfaceflinger/SurfaceFlinger.h
class SurfaceFlinger : public BnSurfaceComposer,
public PriorityDumper,
private IBinder::DeathRecipient,
private HWC2::ComposerCallback,
private ISchedulerCallback {
...
}
SurfaceFlinger 是继承自BnSurfaceComposer。下面来看看createDisplayEventConnection的实现。
frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
sp<IDisplayEventConnection> SurfaceFlinger::createDisplayEventConnection(
ISurfaceComposer::VsyncSource vsyncSource,
ISurfaceComposer::EventRegistrationFlags eventRegistration) {
const auto& handle =
vsyncSource == eVsyncSourceSurfaceFlinger ? mSfConnectionHandle : mAppConnectionHandle;
return mScheduler->createDisplayEventConnection(handle, eventRegistration);
}
这里通过呼叫mScheduler的createDisplayEventConnection来创建,因为这里是App进来的,因此handle == mAppConnectionHandle。
frameworks/native/services/surfaceflinger/Scheduler/Scheduler.cpp
sp<IDisplayEventConnection> Scheduler::createDisplayEventConnection(
ConnectionHandle handle, ISurfaceComposer::EventRegistrationFlags eventRegistration) {
std::lock_guard<std::mutex> lock(mConnectionsLock);
RETURN_IF_INVALID_HANDLE(handle, nullptr);
return createConnectionInternal(mConnections[handle].thread.get(), eventRegistration);
}
sp<EventThreadConnection> Scheduler::createConnectionInternal(
EventThread* eventThread, ISurfaceComposer::EventRegistrationFlags eventRegistration) {
return eventThread->createEventConnection([&] { resync(); }, eventRegistration);
}
调用eventThread的createEventConnection
frameworks/native/services/surfaceflinger/Scheduler/EventThread.cpp
sp<EventThreadConnection> EventThread::createEventConnection(
ResyncCallback resyncCallback,
ISurfaceComposer::EventRegistrationFlags eventRegistration) const {
return new EventThreadConnection(const_cast<EventThread*>(this),
IPCThreadState::self()->getCallingUid(),
std::move(resyncCallback), eventRegistration);
}
也就是说最后这个EventConnection是一个EventThreadConnection对象这再上一篇文章中也介绍过。这个EventThreadConnection也是一个IBinder,因为这个是一个Binder,当第一引用的时候,会执行onFirstRef,然后调用到mEventThread->registerDisplayEventConnection(this); 于是把这个connect放入到mDisplayEventConnections这个集合中,从而加入Vsync消费者行列。
frameworks/native/services/surfaceflinger/Scheduler/EventThread.h
class EventThreadConnection : public BnDisplayEventConnection {
VSyncRequest vsyncRequest = VSyncRequest::None;
...
}
void EventThreadConnection::onFirstRef() {
// NOTE: mEventThread doesn't hold a strong reference on us
mEventThread->registerDisplayEventConnection(this);
}
status_t EventThread::registerDisplayEventConnection(const sp<EventThreadConnection>& connection) {
...
mDisplayEventConnections.push_back(connection);
mCondition.notify_all();
return NO_ERROR;
}
它对应的BnDisplayEventConnection接口是
frameworks/native/include/gui/IDisplayEventConnection.h
class BnDisplayEventConnection : public SafeBnInterface<IDisplayEventConnection> {
public:
BnDisplayEventConnection()
: SafeBnInterface<IDisplayEventConnection>("BnDisplayEventConnection") {}
status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply,
uint32_t flags = 0) override;
};
因为DisplayEventReceiver在初始化时拿到了surfaceFlinger的客户端,然后调用这个客户端的createDisplayEventConnection方法,返回了一个
EventThreadConnection对象并赋值给mEventConnection,而这个对象又是BnDisplayEventConnection的客户端,所以在DisplayEventReceiver的requestNextVsync方法中,mEventConnection.requestNextVsync将会进入到BnDisplayEventConnection的requestNextVsync方法
status_t DisplayEventReceiver::requestNextVsync() {
if (mEventConnection != nullptr) {
mEventConnection->requestNextVsync();
return NO_ERROR;
}
return NO_INIT;
}
BnDisplayEventConnection作为服务端的桩,由服务者实现。
frameworks/native/services/surfaceflinger/Scheduler/EventThread.h
class EventThreadConnection : public BnDisplayEventConnection {
...
}
所以requestNextVsync将进入这里:
frameworks/native/services/surfaceflinger/Scheduler/EventThread.cpp
void EventThreadConnection::requestNextVsync() {
ATRACE_NAME("requestNextVsync");
mEventThread->requestNextVsync(this);
}
mEventThread是EventThread的实例
void EventThread::requestNextVsync(const sp<EventThreadConnection>& connection) {
if (connection->resyncCallback) {
connection->resyncCallback();
}
std::lock_guard<std::mutex> lock(mMutex);
if (connection->vsyncRequest == VSyncRequest::None) {
connection->vsyncRequest = VSyncRequest::Single;
mCondition.notify_all();
} else if (connection->vsyncRequest == VSyncRequest::SingleSuppressCallback) {
connection->vsyncRequest = VSyncRequest::Single;
}
}
在上面构造EventThreadConnection时,没有为vsyncRequest赋值,所以默认是VSyncRequest::None。因此执行:
connection->vsyncRequest = VSyncRequest::Single;
mCondition.notify_all();
起关键作用的就是mCondition.notify_all()。
4. 总结
- 从UI层注册监听,实质上是建立了一个与SurfaceFlinger建立了EventThreadConnection,然后将其加入到Vsync的消费者集合,
然后复制并监听其消息的文件描述符。 - 从UI层requestLayout触发的scheduleVsync,其路经很长,经由JNI,IPC最终进入到EventThread,
完成唤醒分发线mCondition.notify_all() 的任务