Android(安卓)应用程序请求Vsync
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 receiver = reinterpret_cast(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()); }}
/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(vsyncTimestamp))); } 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);}
[EventThread.cpp–>EventThread::requestNextVsync()]
void EventThread::requestNextVsync( const sp<EventThread::Connection>& connection) { Mutex::Autolock _l(mLock); mFlinger.resyncWithRateLimit(); if (connection->count < 0) { connection->count = 0; mCondition.broadcast(); }}
UML图
更多相关文章
- Android加载对话框,异步执行代码的封装类
- Android(安卓)UI布局中设置了fill_parenet仍然没有全屏的解决办
- Android面试系列文章2018之Android部分Fragment篇
- Android面试系列文章2018之Android部分Fragment篇
- Android(安卓)UI布局中设置了fill_parenet仍然没有全屏的解决办
- Android(安卓)Studio下添加assets目录
- 【Android】Android(安卓)开机广播的使用
- Android下单元测试
- android安装SDK时遇到的一些问题