// 分发事件给connection constsize_t count = signalConnections.size(); for (size_t i = 0; i < count; i++) { const sp<Connection>& conn(signalConnections[i]); // 2.5 分发事件 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. removeDisplayEventConnectionLocked(signalConnections[i]); } } } }
// 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::waitForEventLocked( std::unique_lock<std::mutex>* lock, DisplayEventReceiver::Event* event) { Vector<sp<EventThread::Connection> > signalConnections;
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) { // 当timestamp不为0时,说明有事件发生 if (mInterceptVSyncsCallback) { mInterceptVSyncsCallback(timestamp); } *event = mVSyncEvent[i]; // 置timestamp为0,标记为当前事件被消费 mVSyncEvent[i].header.timestamp = 0; vsyncCount = mVSyncEvent[i].vsync.count; break; } }
// mDisplayEventConnections保存的是注册的Connection的, // SF EventThread线程里只有一个Connection, 而这个Connection主要是用来渲染 // 而如果是APP EventThread, 这里会有多个connection size_t count = mDisplayEventConnections.size(); if (!timestamp && count) { // 没有vsync事件, 来看下是否有其它pending的event, 这里主要是hotplug的事件 eventPending = !mPendingEvents.isEmpty(); if (eventPending) { // we have some other event to dispatch *event = mPendingEvents[0]; mPendingEvents.removeAt(0); } }
for (size_t i = 0; i < count;) { sp<Connection> connection(mDisplayEventConnections[i].promote()); if (connection != nullptr) { bool added = false; // Connection->count的值大小含义如下: // 1. >=1: 表示持续接收Vsync信号 // 2. ==0: 只接收一次Vsync信号 // 3. ==-1: 不接收Vsync信号 if (connection->count >= 0) { // 如果有 connection->count >= 0,说明需要Vsync信号 waitForVSync = true; if (timestamp) { // 大于0.说明有事件 // 处理本次事件 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); } ++i; } else { // we couldn't promote this reference, the connection has // died, so clean-up! mDisplayEventConnections.removeAt(i); --count; } }
// Here we figure out if we need to enable or disable vsyncs if (timestamp && !waitForVSync) { // 收到Vsync信号,但是没有Connection监听,所以关闭Vsync disableVSyncLocked(); } elseif (!timestamp && waitForVSync) { // 有Connection监听,但是还没有Vsync信号,所以打开Vsync enableVSyncLocked(); }
// 没有事件发生 if (!timestamp && !eventPending) { if (waitForVSync) { // 如果有connection监听,则需要等待Vsync事件 // 以防止硬件Driver出问题,设置一个超时时间16ms bool softwareSync = mUseSoftwareVSync; auto timeout = softwareSync ? 16ms : 1000ms; if (mCondition.wait_for(*lock, timeout) == std::cv_status::timeout) { 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 { // 没有connection监听,也没有收到事件,则一直等待 mCondition.wait(*lock); } } }
// 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; }
void EventThread::Connection::onFirstRef() { // NOTE: mEventThread doesn't hold a strong reference on us mEventThread->registerDisplayEventConnection(this); }