privatestaticfinalclassCallbackRecord{ public CallbackRecord next; // 指向下一个对象; publiclong dueTime; public Object action; // Runnable or FrameCallback public Object token;
static jlong nativeInit(JNIEnv* env, jclass clazz, jobject receiverObj, jobject messageQueueObj){ //【1】获取 NativeMessageQueue 实例; sp<MessageQueue> messageQueue = android_os_MessageQueue_getMessageQueue(env, messageQueueObj); if (messageQueue == NULL) { jniThrowRuntimeException(env, "MessageQueue is not initialized."); return0; }
//【-->5.1】创建 NativeDisplayEventReceiver 实例; sp<NativeDisplayEventReceiver> receiver = new NativeDisplayEventReceiver(env, receiverObj, messageQueue); //【-->5.2】初始化 receiver; status_t status = receiver->initialize(); if (status) { String8 message; message.appendFormat("Failed to initialize display event receiver. status=%d", status); jniThrowRuntimeException(env, message.string()); return0; }
//【2】增加强引用计数; receiver->incStrong(gDisplayEventReceiverClassInfo.clazz); // retain a reference for the object return reinterpret_cast<jlong>(receiver.get()); }
4.2 scheduleVsync
请求一个 Vsync 信号,父类方法:
1 2 3 4 5 6 7 8 9
publicvoidscheduleVsync(){ if (mReceiverPtr == 0) { Log.w(TAG, "Attempted to schedule a vertical sync pulse but the display event " + "receiver has already been disposed."); } else { //【-->4.2.1】进入 native 层; nativeScheduleVsync(mReceiverPtr); } }
staticvoidnativeScheduleVsync(JNIEnv* env, jclass clazz, jlong receiverPtr){ sp<NativeDisplayEventReceiver> receiver = reinterpret_cast<NativeDisplayEventReceiver*>(receiverPtr); //【-->5.3】进入 native 的 DisplayEventReceiver 请求 Vsync 信号; 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()); } }
4.3 dispatchVsync
这个方法是在父类里面:
1 2 3 4 5 6
// Called from native code. @SuppressWarnings("unused") privatevoiddispatchVsync(long timestampNanos, int builtInDisplayId, int frame){ //【-->4.4】处理 Vsync 信号 onVsync(timestampNanos, builtInDisplayId, frame); }
@Override publicvoidonVsync(long timestampNanos, int builtInDisplayId, int frame){ //【1】忽略来自第二显示屏的 Vsync 信号; if (builtInDisplayId != SurfaceControl.BUILT_IN_DISPLAY_ID_MAIN) { Log.d(TAG, "Received vsync from secondary display, but we don't support " + "this case yet. Choreographer needs a way to explicitly request " + "vsync for a specific display to ensure it doesn't lose track " + "of its scheduled vsync."); //【-->5.3】请求下一个 Vsync; scheduleVsync(); return; }
// Post the vsync event to the Handler. // The idea is to prevent incoming vsync events from completely starving // the message queue. If there are no messages in the queue with timestamps // earlier than the frame time, then the vsync event will be processed immediately. // Otherwise, messages that predate the vsync event will be handled first. //【1】调整 Vsync 时间; long now = System.nanoTime(); if (timestampNanos > now) { Log.w(TAG, "Frame time is " + ((timestampNanos - now) * 0.000001f) + " ms in the future! Check that graphics HAL is generating vsync " + "timestamps using the correct timebase."); timestampNanos = now; }
//【2】设置 mHavePendingVsync 为 ture,表示正在有一个处理中的 Vsync 信号; if (mHavePendingVsync) { Log.w(TAG, "Already have a pending vsync event. There should only be " + "one at a time."); } else { mHavePendingVsync = true; } //【-->6.X】发送一个消息给 FrameHandler,该消息的 callback 为当前对象 FrameDisplayEventReceiver; mTimestampNanos = timestampNanos; mFrame = frame; Message msg = Message.obtain(mHandler, this); msg.setAsynchronous(true); // 注意:这是异步消息; mHandler.sendMessageAtTime(msg, timestampNanos / TimeUtils.NANOS_PER_MS); }
int DisplayEventDispatcher::handleEvent(int, int events, void*) { if (events & (Looper::EVENT_ERROR | Looper::EVENT_HANGUP)) { ALOGE("Display event receiver pipe was closed or an error occurred. " "events=0x%x", events); return0; // remove the callback }
if (!(events & Looper::EVENT_INPUT)) { ALOGW("Received spurious callback for unhandled poll event. " "events=0x%x", events); return1; // keep the callback }
long intendedFrameTimeNanos = frameTimeNanos; // 预期帧时间 startNanos = System.nanoTime(); //【2】计算时间差值:当前时间 - 帧触发的时间; finallong jitterNanos = startNanos - frameTimeNanos; //【3】判断时间差值是否超过 mFrameIntervalNanos,说明此时已经不满足 16ms 一帧了; if (jitterNanos >= mFrameIntervalNanos) { //【3.1】计算下跳过了多少帧。 finallong skippedFrames = jitterNanos / mFrameIntervalNanos; if (skippedFrames >= SKIPPED_FRAME_WARNING_LIMIT) { Log.i(TAG, "Skipped " + skippedFrames + " frames! " + "The application may be doing too much work on its main thread."); } //【3.2】余下的偏移量; finallong lastFrameOffset = jitterNanos % mFrameIntervalNanos; if (DEBUG_JANK) { Log.d(TAG, "Missed vsync by " + (jitterNanos * 0.000001f) + " ms " + "which is more than the frame interval of " + (mFrameIntervalNanos * 0.000001f) + " ms! " + "Skipping " + skippedFrames + " frames and setting frame " + "time to " + (lastFrameOffset * 0.000001f) + " ms in the past."); } //【3.3】当前时间 - 余下的偏移量,作为本帧的实际时间; frameTimeNanos = startNanos - lastFrameOffset; } //【4】如果帧触发时间比上一帧的时间早,那就要重新请求 Vsync 信号; if (frameTimeNanos < mLastFrameTimeNanos) { if (DEBUG_JANK) { Log.d(TAG, "Frame time appears to be going backwards. May be due to a " + "previously skipped frame. Waiting for next vsync."); } //【-->3.4.1】重新请求 Vsync 信号; scheduleVsyncLocked(); return; }
voiddoCallbacks(int callbackType, long frameTimeNanos){ CallbackRecord callbacks; synchronized (mLock) { // We use "now" to determine when callbacks become due because it's possible // for earlier processing phases in a frame to post callbacks that should run // in a following phase, such as an input event that causes an animation to start. finallong now = System.nanoTime(); //【-->3.3.1】返回指定类型 callbackType 对应的 CallbackRecord, // 通过 last/next 两个指针,找到 CallbackRecord 所有执行时间早于 now 的(也就是已经到执行时间的) // CallbackRecord, 以链表形式返回(头结点,断开链表) callbacks = mCallbackQueues[callbackType].extractDueCallbacksLocked( now / TimeUtils.NANOS_PER_MS); if (callbacks == null) { return; } //【1】讲 mCallbacksRunning 设置为 true; mCallbacksRunning = true;
// Update the frame time if necessary when committing the frame. // We only update the frame time if we are more than 2 frames late reaching // the commit phase. This ensures that the frame time which is observed by the // callbacks will always increase from one frame to the next and never repeat. // We never want the next frame's starting frame time to end up being less than // or equal to the previous frame's commit frame time. Keep in mind that the // next frame has most likely already been scheduled by now so we play it // safe by ensuring the commit time is always at least one frame behind. //【2】针对于最后一种类型 CALLBACK_COMMIT;会重新调整一次 mLastFrameTimeNanos。 // CALLBACK_COMMIT 没有对应的 CallbackQueues; if (callbackType == Choreographer.CALLBACK_COMMIT) { finallong jitterNanos = now - frameTimeNanos; Trace.traceCounter(Trace.TRACE_TAG_VIEW, "jitterNanos", (int) jitterNanos); if (jitterNanos >= 2 * mFrameIntervalNanos) { finallong lastFrameOffset = jitterNanos % mFrameIntervalNanos + mFrameIntervalNanos; if (DEBUG_JANK) { Log.d(TAG, "Commit callback delayed by " + (jitterNanos * 0.000001f) + " ms which is more than twice the frame interval of " + (mFrameIntervalNanos * 0.000001f) + " ms! " + "Setting frame time to " + (lastFrameOffset * 0.000001f) + " ms in the past."); mDebugPrintNextFrameTimeDelta = true; } frameTimeNanos = now - lastFrameOffset; //【2.1】更新 mLastFrameTimeNanos; mLastFrameTimeNanos; = frameTimeNanos; } } } try { Trace.traceBegin(Trace.TRACE_TAG_VIEW, CALLBACK_TRACE_TITLES[callbackType]); //【-->3.3.2】遍历要执行的 CallbackRecord 链表,执行 run 方法; for (CallbackRecord c = callbacks; c != null; c = c.next) { if (DEBUG_FRAMES) { Log.d(TAG, "RunCallback: type=" + callbackType + ", action=" + c.action + ", token=" + c.token + ", latencyMillis=" + (SystemClock.uptimeMillis() - c.dueTime)); } c.run(frameTimeNanos); // run } } finally { synchronized (mLock) { mCallbacksRunning = false; //【3】回收子链表中的节点,其实就是逐个断开链接,置空属性,在 recycleCallbackLocked 方法中; do { final CallbackRecord next = callbacks.next; recycleCallbackLocked(callbacks); callbacks = next; } while (callbacks != null); } Trace.traceEnd(Trace.TRACE_TAG_VIEW); } }
bool EventThread::threadLoop() { DisplayEventReceiver::Event event; Vector< sp<EventThread::Connection> > signalConnections; //【1】等待 Vsync 事件,waitForEvent 内部是一个 do while 循环,但是,并不是无限循环下去; signalConnections = waitForEvent(&event);
//【2】分发 Vsync 事件给监听器: constsize_t count = signalConnections.size(); for (size_t i=0 ; i<count ; i++) { const sp<Connection>& conn(signalConnections[i]); //【1】分发 Vsync 事件,这里 status_t err = conn->postEvent(event); if (err == -EAGAIN || err == -EWOULDBLOCK) { // The destination doesn't accept events anymore, it's probably // full. For now, we just drop the events on the floor. // FIXME: Note that some events cannot be dropped and would have // to be re-sent later. // Right-now we don't have the ability to do this. ALOGW("EventThread: dropping event (%08x) for connection %p", event.header.type, conn.get()); } elseif (err < 0) { // handle any other error on the pipe as fatal. the only // reasonable thing to do is to clean-up this connection. // The most common error we'll get here is -EPIPE. removeDisplayEventConnection(signalConnections[i]); } } returntrue; }
// This will return when (1) a vsync event has been received, and (2) there was // at least one connection interested in receiving it when we started waiting. Vector< sp<EventThread::Connection> > EventThread::waitForEvent( DisplayEventReceiver::Event* event) { Mutex::Autolock _l(mLock); Vector< sp<EventThread::Connection> > signalConnxections; //【1】这里是一个 do whidle 循环,条件是 signalConnections 为空; do { bool eventPending = false; bool waitForVSync = false;
size_t vsyncCount = 0; nsecs_t timestamp = 0; for (int32_t i=0 ; i<DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES ; i++) { timestamp = mVSyncEvent[i].header.timestamp; if (timestamp) { // we have a vsync event to dispatch *event = mVSyncEvent[i]; mVSyncEvent[i].header.timestamp = 0; vsyncCount = mVSyncEvent[i].vsync.count; break; } }
if (!timestamp) { // no vsync event, see if there are some other event eventPending = !mPendingEvents.isEmpty(); if (eventPending) { // we have some other event to dispatch *event = mPendingEvents[0]; mPendingEvents.removeAt(0); } }
//【1】找到所有的监听 Vsync 事件的 connections 对象,实际上这里就是我们前面 DisplayEventReceiver 创建的链接对象; size_t count = mDisplayEventConnections.size(); for (size_t i=0 ; i<count ; i++) { sp<Connection> connection(mDisplayEventConnections[i].promote()); if (connection != NULL) { bool added = false; if (connection->count >= 0) { //【1.1】将其设置为 true,表示有 connection 在等待 Vsync 信号; waitForVSync = true; if (timestamp) { // we consume the event only if it's time // (ie: we received a vsync event) if (connection->count == 0) { // fired this time around connection->count = -1; signalConnections.add(connection); added = true; } elseif (connection->count == 1 || (vsyncCount % connection->count) == 0) { // continuous event, and time to report it signalConnections.add(connection); added = true; } } }
if (eventPending && !timestamp && !added) { // we don't have a vsync event to process // (timestamp==0), but we have some pending // messages. signalConnections.add(connection); } } else { // we couldn't promote this reference, the connection has // died, so clean-up! mDisplayEventConnections.removeAt(i); --i; --count; } }
// Here we figure out if we need to enable or disable vsyncs if (timestamp && !waitForVSync) { // we received a VSYNC but we have no clients // don't report it, and disable VSYNC events disableVSyncLocked(); } elseif (!timestamp && waitForVSync) { // we have at least one client, so we want vsync enabled // (TODO: this function is called right after we finish // notifying clients of a vsync, so this call will be made // at the vsync rate, e.g. 60fps. If we can accurately // track the current state we could avoid making this call // so often.) enableVSyncLocked(); }
// note: !timestamp implies signalConnections.isEmpty(), because we // don't populate signalConnections if there's no vsync pending if (!timestamp && !eventPending) { // wait for something to happen if (waitForVSync) { // This is where we spend most of our time, waiting // for vsync events and new client registrations. // // If the screen is off, we can't use h/w vsync, so we // use a 16ms timeout instead. It doesn't need to be // precise, we just need to keep feeding our clients. // // We don't want to stall if there's a driver bug, so we // use a (long) timeout when waiting for h/w vsync, and // generate fake events when necessary. bool softwareSync = mUseSoftwareVSync; nsecs_t timeout = softwareSync ? ms2ns(16) : ms2ns(1000); if (mCondition.waitRelative(mLock, timeout) == TIMED_OUT) { if (!softwareSync) { ALOGW("Timed out waiting for hw vsync; faking it"); } // FIXME: how do we decide which display id the fake // vsync came from ? mVSyncEvent[0].header.type = DisplayEventReceiver::DISPLAY_EVENT_VSYNC; mVSyncEvent[0].header.id = DisplayDevice::DISPLAY_PRIMARY; mVSyncEvent[0].header.timestamp = systemTime(SYSTEM_TIME_MONOTONIC); mVSyncEvent[0].vsync.count++; } } else { // 没有人对 vsync 感兴趣,所以我们只想睡觉。h/w vsync 会被禁用,线程会进入等待状态,直到我们 // 获取新连接,或现有连接变为有兴趣再次接收 vsync。 mCondition.wait(mLock); } } } while (signalConnections.isEmpty());
// here we're guaranteed to have a timestamp and some connections to signal // (The connections might have dropped out of mDisplayEventConnections // while we were asleep, but we'll still have strong references to them.) return signalConnections; }
可以看到,当没有 vsync 信号的时候,EventThread 是进入等待队列的,而不是无限的 while 循环下去;
// should never happen because of SOCK_SEQPACKET LOG_ALWAYS_FATAL_IF((size >= 0) && (size % static_cast<ssize_t>(objSize)), "BitTube::sendObjects(count=%zu, size=%zu), res=%zd (partial events were sent!)", count, objSize, size);
// should never happen because of SOCK_SEQPACKET LOG_ALWAYS_FATAL_IF((size >= 0) && (size % static_cast<ssize_t>(objSize)), "BitTube::recvObjects(count=%zu, size=%zu), res=%zd (partial events were received!)", count, objSize, size);