EventThread::EventThread(constchar*name,std::shared_ptr<scheduler::VsyncSchedule>vsyncSchedule,android::frametimeline::TokenManager*tokenManager,ThrottleVsyncCallbackthrottleVsyncCallback,GetVsyncPeriodFunctiongetVsyncPeriodFunction,std::chrono::nanosecondsworkDuration,std::chrono::nanosecondsreadyDuration):mThreadName(name),// ATRACE名称
mVsyncTracer(base::StringPrintf("VSYNC-%s",name),0),// VSYNC计算时使用的偏移量
mWorkDuration(base::StringPrintf("VsyncWorkDuration-%s",name),workDuration),// VSYNC计算时使用的偏移量
mReadyDuration(readyDuration),mVsyncSchedule(std::move(vsyncSchedule)),// 一个VSYNC请求者的具体处理类
mVsyncRegistration(mVsyncSchedule->getDispatch(),createDispatchCallback()/*VSync生成后的回调函数*/,name),mTokenManager(tokenManager),mThrottleVsyncCallback(std::move(throttleVsyncCallback)),mGetVsyncPeriodFunction(std::move(getVsyncPeriodFunction)){LOG_ALWAYS_FATAL_IF(getVsyncPeriodFunction==nullptr,"getVsyncPeriodFunction must not be null");mThread=std::thread([this]()NO_THREAD_SAFETY_ANALYSIS{std::unique_lock<std::mutex>lock(mMutex);threadMain(lock);});
platform/frameworks/native/services/surfaceflinger/Scheduler/Scheduler.cppConnectionHandleScheduler::createConnection(std::unique_ptr<EventThread>eventThread){constConnectionHandlehandle=ConnectionHandle{mNextConnectionHandleId++};ALOGV("Creating a connection handle with ID %"PRIuPTR,handle.id);autoconnection=createConnectionInternal(eventThread.get());std::lock_guard<std::mutex>lock(mConnectionsLock);mConnections.emplace(handle,Connection{connection,std::move(eventThread)});returnhandle;}sp<EventThreadConnection>Scheduler::createConnectionInternal(EventThread*eventThread,EventRegistrationFlagseventRegistration,constsp<IBinder>&layerHandle){int32_tlayerId=static_cast<int32_t>(LayerHandle::getLayerId(layerHandle));autoconnection=eventThread->createEventConnection([&]{resync();},eventRegistration);mLayerHistory.attachChoreographer(layerId,connection);returnconnection;}
voidEventThread::threadMain(std::unique_lock<std::mutex>&lock){DisplayEventConsumersconsumers;while(mState!=State::Quit){std::optional<DisplayEventReceiver::Event>event;// Determine next event to dispatch.
if(!mPendingEvents.empty()){event=mPendingEvents.front();mPendingEvents.pop_front();if(event->header.type==DisplayEventReceiver::DISPLAY_EVENT_HOTPLUG){if(event->hotplug.connected&&!mVSyncState){mVSyncState.emplace(event->header.displayId);}elseif(!event->hotplug.connected&&mVSyncState&&mVSyncState->displayId==event->header.displayId){mVSyncState.reset();}}}boolvsyncRequested=false;// Find connections that should consume this event.
autoit=mDisplayEventConnections.begin();while(it!=mDisplayEventConnections.end()){if(constautoconnection=it->promote()){if(event&&shouldConsumeEvent(*event,connection)){consumers.push_back(connection);}vsyncRequested|=connection->vsyncRequest!=VSyncRequest::None;++it;}else{it=mDisplayEventConnections.erase(it);}}if(!consumers.empty()){dispatchEvent(*event,consumers);consumers.clear();}if(mVSyncState&&vsyncRequested){mState=mVSyncState->synthetic?State::SyntheticVSync:State::VSync;}else{ALOGW_IF(!mVSyncState,"Ignoring VSYNC request while display is disconnected");mState=State::Idle;}if(mState==State::VSync){constautoscheduleResult=mVsyncRegistration.schedule({.workDuration=mWorkDuration.get().count(),.readyDuration=mReadyDuration.count(),.earliestVsync=mLastVsyncCallbackTime.ns()});LOG_ALWAYS_FATAL_IF(!scheduleResult,"Error scheduling callback");}else{mVsyncRegistration.cancel();}if(!mPendingEvents.empty()){continue;}// Wait for event or client registration/request.
if(mState==State::Idle){mCondition.wait(lock);}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.
conststd::chrono::nanosecondstimeout=mState==State::SyntheticVSync?16ms:1000ms;if(mCondition.wait_for(lock,timeout)==std::cv_status::timeout){if(mState==State::VSync){ALOGW("Faking VSYNC due to driver stall for thread %s",mThreadName);}LOG_FATAL_IF(!mVSyncState);constautonow=systemTime(SYSTEM_TIME_MONOTONIC);constautodeadlineTimestamp=now+timeout.count();constautoexpectedVSyncTime=deadlineTimestamp+timeout.count();mPendingEvents.push_back(makeVSync(mVSyncState->displayId,now,++mVSyncState->count,expectedVSyncTime,deadlineTimestamp));}}}// cancel any pending vsync event before exiting
mVsyncRegistration.cancel();}
ScheduleResultVSyncDispatchTimerQueue::scheduleLocked(CallbackTokentoken,ScheduleTimingscheduleTiming){autoit=mCallbacks.find(token);if(it==mCallbacks.end()){return{};}auto&callback=it->second;autoconstnow=mTimeKeeper->now();/* If the timer thread will run soon, we'll apply this work update via the callback
* timer recalculation to avoid cancelling a callback that is about to fire. */autoconstrearmImminent=now>mIntendedWakeupTime;if(CC_UNLIKELY(rearmImminent)){callback->addPendingWorkloadUpdate(scheduleTiming);returngetExpectedCallbackTime(*mTracker,now,scheduleTiming);}constScheduleResultresult=callback->schedule(scheduleTiming,*mTracker,now);if(!result.has_value()){return{};}if(callback->wakeupTime()<mIntendedWakeupTime-mTimerSlack){rearmTimerSkippingUpdateFor(now,it);}returnresult;}
voidEventThread::dispatchEvent(constDisplayEventReceiver::Event&event,constDisplayEventConsumers&consumers){for(constauto&consumer:consumers){DisplayEventReceiver::Eventcopy=event;if(event.header.type==DisplayEventReceiver::DISPLAY_EVENT_VSYNC){constint64_tframeInterval=mGetVsyncPeriodFunction(consumer->mOwnerUid);copy.vsync.vsyncData.frameInterval=frameInterval;generateFrameTimeline(copy.vsync.vsyncData,frameInterval,copy.header.timestamp,event.vsync.vsyncData.preferredExpectedPresentationTime(),event.vsync.vsyncData.preferredDeadlineTimestamp());}switch(consumer->postEvent(copy)){caseNO_ERROR:break;case-EAGAIN:// TODO: Try again if pipe is full.
ALOGW("Failed dispatching %s for %s",toString(event).c_str(),toString(*consumer).c_str());break;default:// Treat EPIPE and other errors as fatal.
removeDisplayEventConnectionLocked(consumer);}}}
platform/frameworks/native/services/surfaceflinger/Scheduler/MessageQueue.cppvoidMessageQueue::initVsync(std::shared_ptr<scheduler::VSyncDispatch>dispatch,frametimeline::TokenManager&tokenManager,std::chrono::nanosecondsworkDuration){std::unique_ptr<scheduler::VSyncCallbackRegistration>oldRegistration;{std::lock_guardlock(mVsync.mutex);mVsync.workDuration=workDuration;mVsync.tokenManager=&tokenManager;oldRegistration=onNewVsyncScheduleLocked(std::move(dispatch));}// See comments in onNewVsyncSchedule. Today, oldRegistration should be
// empty, but nothing prevents us from calling initVsync multiple times, so
// go ahead and destruct it outside the lock for safety.
oldRegistration.reset();}