App Request Vsync
/frameworks/base/core/java/android/view/ViewRootImpl.java
[ViewRootImpl.java–>ViewRootImpl.scheduleTraversals()]
void scheduleTraversals() {
if (!mTraversalScheduled) {
mTraversalScheduled = true;
mTraversalBarrier = mHandler.getLooper().getQueue().postSyncBarrier();
/**
1. 创建一个mTraversalRunnable
2. 将mTraversalRunnable添加到Choreographer中CALLBACK_TRAVERSAL的消息队列中
*/
mChoreographer.postCallback(
Choreographer.CALLBACK_TRAVERSAL, mTraversalRunnable, null);
if (!mUnbufferedInputDispatch) {
scheduleConsumeBatchedInput();
}
notifyRendererOfFramePending();
pokeDrawLockIfNeeded();
}
}
[ViewRootImpl.java–>ViewRootImpl.mTraversalRunnable]
final class TraversalRunnable implements Runnable {
@Override
public void run() {
doTraversal();
}
}
final TraversalRunnable mTraversalRunnable = new TraversalRunnable();
/frameworks/base/core/java/android/view/Choreographer.java
[Choreographer.java–>Choreographer.postCallback()]
/**
参数列表:
1. callbackType = Choreographer.CALLBACK_TRAVERSAL = 2
2. action = mTraversalRunnable
3. token = null
*/
public void postCallback(int callbackType, Runnable action, Object token) {
postCallbackDelayed(callbackType, action, token, 0);
}
/**
delay的时间
* delayMillis = 0
*/
public void postCallbackDelayed(int callbackType,
Runnable action, Object token, long delayMillis) {
if (action == null) {
throw new IllegalArgumentException("action must not be null");
}
/**
CALLBACK_LAST = CALLBACK_COMMIT = 3
*/
if (callbackType < 0 || callbackType > CALLBACK_LAST) {
throw new IllegalArgumentException("callbackType is invalid");
}
postCallbackDelayedInternal(callbackType, action, token, delayMillis);
}
private void postCallbackDelayedInternal(int callbackType,
Object action, Object token, long delayMillis) {
if (DEBUG_FRAMES) {
Log.d(TAG, "PostCallback: type=" + callbackType
+ ", action=" + action + ", token=" + token
+ ", delayMillis=" + delayMillis);
}
/**
1. 将action 添加到mCallbackQueues中Choreographer.CALLBACK_TRAVERSAL的队列中
2. 由于dueTime = now + delayMillis = now,因此会执行scheduleFrameLocked
*/
synchronized (mLock) {
final long now = SystemClock.uptimeMillis();
final long dueTime = now + delayMillis;
mCallbackQueues[callbackType].addCallbackLocked(dueTime, action, token);
if (dueTime <= now) {
scheduleFrameLocked(now);
} else {
Message msg = mHandler.obtainMessage(MSG_DO_SCHEDULE_CALLBACK, action);
msg.arg1 = callbackType;
msg.setAsynchronous(true);
mHandler.sendMessageAtTime(msg, dueTime);
}
}
}
[Choreographer.java–>Choreographer.scheduleFrameLocked()]
private void scheduleFrameLocked(long now) {
if (!mFrameScheduled) {
mFrameScheduled = true;
if (USE_VSYNC) {
if (DEBUG_FRAMES) {
Log.d(TAG, "Scheduling next frame on vsync.");
}
// If running on the Looper thread, then schedule the vsync immediately,
// otherwise post a message to schedule the vsync from the UI thread
// as soon as possible.
if (isRunningOnLooperThreadLocked()) {
scheduleVsyncLocked();
} else {
Message msg = mHandler.obtainMessage(MSG_DO_SCHEDULE_VSYNC);
msg.setAsynchronous(true);
mHandler.sendMessageAtFrontOfQueue(msg);
}
} else {
final long nextFrameTime = Math.max(
mLastFrameTimeNanos / TimeUtils.NANOS_PER_MS + sFrameDelay, now);
if (DEBUG_FRAMES) {
Log.d(TAG, "Scheduling next frame in " + (nextFrameTime - now) + " ms.");
}
Message msg = mHandler.obtainMessage(MSG_DO_FRAME);
msg.setAsynchronous(true);
mHandler.sendMessageAtTime(msg, nextFrameTime);
}
}
}
[Choreographer.java–>Choreographer.scheduleFrameLocked()]
private void scheduleVsyncLocked() {
mDisplayEventReceiver.scheduleVsync();
}
/frameworks/base/core/java/android/view/DisplayEventReceiver.java
[DisplayEventReceiver.java–>DisplayEventReceiver.scheduleVsync()]
/**
* Schedules a single vertical sync pulse to be delivered when the next
* display frame begins.
*/
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);
}
}
/frameworks/base/core/jni/android_view_DisplayEventReceiver.cpp
[android_view_DisplayEventReceiver.cpp–>android_view_DisplayEventReceiver.nativeScheduleVsync()]
static void nativeScheduleVsync(JNIEnv* env, jclass clazz, jlong receiverPtr) {
sp
reinterpret_cast
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());
}
}
/frameworks/base/libs/androidfw/DisplayEventDispatcher.cpp
[DisplayEventDispatcher.cpp–>DisplayEventDispatcher::scheduleVsync()]
status_t DisplayEventDispatcher::scheduleVsync() {
if (!mWaitingForVsync) {
ALOGV("dispatcher %p ~ Scheduling vsync.", this);
// Drain all pending events.
nsecs_t vsyncTimestamp;
int32_t vsyncDisplayId;
uint32_t vsyncCount;
if (processPendingEvents(&vsyncTimestamp, &vsyncDisplayId, &vsyncCount)) {
ALOGE("dispatcher %p ~ last event processed while scheduling was for %" PRId64 "",
this, ns2ms(static_cast
}
status_t status = mReceiver.requestNextVsync();
if (status) {
ALOGW("Failed to request next vsync, status=%d", status);
return status;
}
mWaitingForVsync = true;
}
return OK;
}
/frameworks/native/libs/gui/DisplayEventReceiver.cpp
[DisplayEventReceiver.cpp–>DisplayEventReceiver::requestNextVsync()]
status_t DisplayEventReceiver::requestNextVsync() {
if (mEventConnection != NULL) {
mEventConnection->requestNextVsync();
return NO_ERROR;
}
return NO_INIT;
}
/frameworks/native/libs/gui/IDisplayEventConnection.cpp
[IDisplayEventConnection.cpp–>BpDisplayEventConnection::requestNextVsync()]
virtual void requestNextVsync() {
Parcel data, reply;
data.writeInterfaceToken(IDisplayEventConnection::getInterfaceDescriptor());
remote()->transact(REQUEST_NEXT_VSYNC, data, &reply, IBinder::FLAG_ONEWAY);
}
/frameworks/native/services/surfaceflinger/EventThread.cpp
[EventThread.cpp–>EventThread::Connection::requestNextVsync()]
void EventThread::Connection::requestNextVsync() {
mEventThread->requestNextVsync(this);
}
1
2
3
[EventThread.cpp–>EventThread::requestNextVsync()]
void EventThread::requestNextVsync(
const sp
Mutex::Autolock _l(mLock);
mFlinger.resyncWithRateLimit();
if (connection->count < 0) {
connection->count = 0;
mCondition.broadcast();
}
}
UML图
这里写图片描述
---------------------
作者:LincolnJunior
来源:CSDN
原文:https://blog.csdn.net/lincolnjunior_lj/article/details/79369263
版权声明:本文为博主原创文章,转载请附上博文链接!