app要进行更新,必须先要请求一个vsync,等到下个vsync信号来的时候进行界面的更新。
一、首先先看一下app请求vsync。
我们熟知的TextView.setText 或者ImageView.setImageBitmap,最后都要执行invalidate申请重绘,最后会通过ViewParent递归到ViewRootImpl的invalidate。Choreographer.postCallback进行vsync信号的申请。最终胡通过IDisplayEventConnection.cpp 的requestNextVsync,调用到服务端EventThread的requestNextVsync();
流程图如下:
流程比较简单,最终就是调用了一个 mChoreographer.postCallback
frameworks/base/core/java/android/view/ViewRootImpl.java
@UnsupportedAppUsage
void scheduleTraversals() {
if (!mTraversalScheduled) {
mTraversalScheduled = true;
mTraversalBarrier = mHandler.getLooper().getQueue().postSyncBarrier(); @1
mChoreographer.postCallback(
Choreographer.CALLBACK_TRAVERSAL, mTraversalRunnable, null); @2
notifyRendererOfFramePending();
pokeDrawLockIfNeeded();
}
}
@1 设置同步栅栏,拦截同步消息
@2 来请求请求vnsc垂直同步信号,
二、Choreograhper接下来的流程如下图:
看下几个重要方法
1、
scheduleFrameLocked可以被调用多次,但是mFrameScheduled保证下一个vsync到来之前,不会有新的请求发出,多余的scheduleFrameLocked调用被无效化
frameworks/base/core/java/android/view/Choreographer.java
private void scheduleFrameLocked(long now) {
if (!mFrameScheduled) {
mFrameScheduled = true;
......
if (ScrollOptimizer.shouldUseVsync(USE_VSYNC)) {
......
if (isRunningOnLooperThreadLocked()) {
scheduleVsyncLocked();
} else {
// 设置此message为异步消息,因为之前已经设置了同步屏障,所以异步消息会优先执行。
Message msg = mHandler.obtainMessage(MSG_DO_SCHEDULE_VSYNC);
msg.setAsynchronous(true);
mHandler.sendMessageAtFrontOfQueue(msg);
}
}
}
}
2、
最终要的就是最后一步,在IDisplayEventConnection.cpp中的requestNextVsync方法
framworks/native/libs/gui/IDisplayEventConnection.cpp
void requestNextVsync() override {
callRemoteAsync<decltype(&IDisplayEventConnection::requestNextVsync)>(
Tag::REQUEST_NEXT_VSYNC);
}
};
这块CallRemoteAsync,异步binder调用到服务端,会执行服务端的onTransact方法,这个过程是夸进程的。
status_t BnDisplayEventConnection::onTransact(uint32_t code, const Parcel& data, Parcel* reply,
uint32_t flags) {
if (code < IBinder::FIRST_CALL_TRANSACTION || code > static_cast<uint32_t>(Tag::LAST)) {
return BBinder::onTransact(code, data, reply, flags);
}
auto tag = static_cast<Tag>(code);
switch (tag) {
case Tag::STEAL_RECEIVE_CHANNEL:
return callLocal(data, reply, &IDisplayEventConnection::stealReceiveChannel);
case Tag::SET_VSYNC_RATE:
return callLocal(data, reply, &IDisplayEventConnection::setVsyncRate);
case Tag::REQUEST_NEXT_VSYNC: @1
return callLocalAsync(data, reply, &IDisplayEventConnection::requestNextVsync);
}
}
在@1处会调用到 EventThreadConnection的 requestNextVsync。
很明显,BpDisplayEventConnection 的requestNextVsync 会binder调用到BnDisplayEventConnection的requestNextVsync。也就是夸进程,从app进程到surfaceFlinger进程。
看一下各自的位置
frameworks/native/libs/gui/DisplayEventReceiver.cpp
Client端:
class BpDisplayEventConnection : public SafeBpInterface<IDisplayEventConnection> {
......
} 在frameworks/native/libs/gui/IDisplayEventConnection.cpp 中
server端:
class EventThreadConnection : public BnDisplayEventConnection {
.....
} 在frameworks/native/services/surfaceflinger/scheduler/eventThread.h 中
class BnDisplayEventConnection : public SafeBnInterface<IDisplayEventConnection> {
......
} 在frameworks/native/include/gui/IDisplayEventConnection.h
三、接下来看下服务端(EventThreadConnection)的requestNextVsync
void EventThreadConnection::requestNextVsync() {
ATRACE_NAME("requestNextVsync");
mEventThread->requestNextVsync(this);
}
会调用EventThread的requestNextVsync
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(); @1
}
}
因为 threadMain中的循环在EventThread的构造方法中已经启动,此时@1出的notify_call就会唤醒其 mConditioni.wait(lock),进入下一次循环,这时候就会执行 mVSyncSource->setVsyncEnable(true);
State nextState;
if (mVSyncState && vsyncRequested) {
nextState = mVSyncState->synthetic ? State::SyntheticVSync : State::VSync;
} else {
ALOGW_IF(!mVSyncState, "Ignoring VSYNC request while display is disconnected");
nextState = State::Idle;
}
if (mState != nextState) {
if (mState == State::VSync) {
mVSyncSource->setVSyncEnabled(false);
} else if (nextState == State::VSync) {
mVSyncSource->setVSyncEnabled(true); @2
}
mState = nextState;
}
if (event) {
continue;
}
// Wait for event or client registration/request.
if (mState == State::Idle) {
mCondition.wait(lock); @3
} else {
// Generate a fake VSYNC after a long timeout in case the driver stalls. When the
// display is off, keep feeding clients at 60 Hz.
......
@3处就会等待下一次requestVsync信号过来进行唤醒,会进行下一次循环,经过一系列的操作,会执行 mVSyncSource->setVSyncEnabled(true);
frameworks/native/services/surfaceflinger/scheduler/DispSyncSource.cpp
void DispSyncSource::setVsyncEnabled(bool enable){
std::lock_gurad lock(mVsyncMutex);
If(enable){ @4
status_t err = mDispSync->addEventlistener(mName,mPhaseOffset,static_cast<DispSync::Callback*>(this),mLastCallbackTime); @1
If(err != No_ERROE){
ALOGE(“error registering vsync callback: %s (%d)”,strerror(-err),err);
}
}else{
status_t err = mDispSync->removeEventlistener(mName,mPhaseOffset,static_cast<DispSync::Callback*>(this),mLastCallbackTime);
If(err != No_ERROE){
ALOGE(“error unregistering vsync callback: %s (%d)”,strerror(-err),err);
}
If(mDolphinCheck){
If(mDolphinCheck(mName)){
status_t err = mDispSync->addEventlistener(mName,mPhaseOffset,static_cast<DispSync::Callback*>(this),mLastCallbackTime);
If(err != No_ERROE){
ALOGE(“error registering vsync callback: %s (%d)”,strerror(-err),err);
}
}
}
}
mEnable = enable
}
在@4处 enable 为true的时候,会执行mDispSync->addEventListener注册一个vsync监听
system/native/services/surfaceflinger/scheduler/DispSync.cpp
status_t addEventListener(const char* name, nsecs_t phase, DispSync::Callback* callback,
nsecs_t lastCallbackTime) {
if (mTraceDetailedInfo) ATRACE_CALL();
Mutex::Autolock lock(mMutex);
for (size_t i = 0; i < mEventListeners.size(); i++) {
if (mEventListeners[i].mCallback == callback) {
return BAD_VALUE;
}
}
EventListener listener;
listener.mName = name;
listener.mPhase = phase;
listener.mCallback = callback;
// We want to allow the firstmost future event to fire without
// allowing any past events to fire. To do this extrapolate from
// mReferenceTime the most recent hardware vsync, and pin the
// last event time there.
const nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
if (mPeriod != 0) {
const nsecs_t baseTime = now - mReferenceTime;
const nsecs_t numPeriodsSinceReference = baseTime / mPeriod;
const nsecs_t predictedReference = mReferenceTime + numPeriodsSinceReference * mPeriod;
const nsecs_t phaseCorrection = mPhase + listener.mPhase;
const nsecs_t predictedLastEventTime = predictedReference + phaseCorrection;
if (predictedLastEventTime >= now) {
// Make sure that the last event time does not exceed the current time.
// If it would, then back the last event time by a period.
listener.mLastEventTime = predictedLastEventTime - mPeriod;
} else {
listener.mLastEventTime = predictedLastEventTime;
}
} else {
listener.mLastEventTime = now + mPhase - mWakeupLatency;
}
if (lastCallbackTime <= 0) {
// If there is no prior callback time, try to infer one based on the
// logical last event time.
listener.mLastCallbackTime = listener.mLastEventTime + mWakeupLatency;
} else {
listener.mLastCallbackTime = lastCallbackTime;
}
mEventListeners.push_back(listener);@1
mCond.signal();
return NO_ERROR;
}
传进来的参数name, phase, callback, lastCallbackTime 都会赋值给一个EventListener对象,然后@1处 存入一个vector类型的集合。这样app 的 vsync信号就算注册好了。