//frameworks/native/services/surfaceflinger/Surfaceflinger.cpp
voidSurfaceFlinger::onComposerHalHotplug(hal::HWDisplayIdhwcDisplayId,hal::Connectionconnection){constboolconnected=connection==hal::Connection::CONNECTED;ALOGI("%s HAL display %"PRIu64,connected?"Connecting":"Disconnecting",hwcDisplayId);// Only lock if we're not on the main thread. This function is normally
// called on a hwbinder thread, but for the primary display it's called on
// the main thread with the state lock already held, so don't attempt to
// acquire it here.
ConditionalLocklock(mStateLock,std::this_thread::get_id()!=mMainThreadId);mPendingHotplugEvents.emplace_back(HotplugEvent{hwcDisplayId,connection});if(std::this_thread::get_id()==mMainThreadId){// Process all pending hot plug events immediately if we are on the main thread.
// 如果我们在主线程上,请立即处理所有待处理的热插拔事件。
processDisplayHotplugEventsLocked();}setTransactionFlags(eDisplayTransactionNeeded);}
//frameworks/native/services/surfaceflinger/Surfaceflinger.cpp
voidSurfaceFlinger::processDisplayHotplugEventsLocked(){for(constauto&event:mPendingHotplugEvents){std::optional<DisplayIdentificationInfo>info=getHwComposer().onHotplug(event.hwcDisplayId,event.connection);if(!info){continue;}constautodisplayId=info->id;constautotoken=mPhysicalDisplayTokens.get(displayId);if(event.connection==hal::Connection::CONNECTED){auto[supportedModes,activeMode]=loadDisplayModes(displayId);if(!token){ALOGV("Creating display %s",to_string(displayId).c_str());DisplayDeviceStatestate;state.physical={.id=displayId,.type=getHwComposer().getDisplayConnectionType(displayId),.hwcDisplayId=event.hwcDisplayId,.deviceProductInfo=std::move(info->deviceProductInfo),.supportedModes=std::move(supportedModes),.activeMode=std::move(activeMode)};state.isSecure=true;// All physical displays are currently considered secure.
state.displayName=std::move(info->name);sp<IBinder>token=newBBinder();mCurrentState.displays.add(token,state);mPhysicalDisplayTokens.try_emplace(displayId,std::move(token));mInterceptor->saveDisplayCreation(state);}else{ALOGV("Recreating display %s",to_string(displayId).c_str());auto&state=mCurrentState.displays.editValueFor(token->get());state.sequenceId=DisplayDeviceState{}.sequenceId;// Generate new sequenceId.
state.physical->supportedModes=std::move(supportedModes);state.physical->activeMode=std::move(activeMode);if(getHwComposer().updatesDeviceProductInfoOnHotplugReconnect()){state.physical->deviceProductInfo=std::move(info->deviceProductInfo);}}}else{ALOGV("Removing display %s",to_string(displayId).c_str());if(constssize_tindex=mCurrentState.displays.indexOfKey(token->get());index>=0){constDisplayDeviceState&state=mCurrentState.displays.valueAt(index);mInterceptor->saveDisplayDeletion(state.sequenceId);mCurrentState.displays.removeItemsAt(index);}mPhysicalDisplayTokens.erase(displayId);}processDisplayChangesLocked();}mPendingHotplugEvents.clear();}
//frameworks/native/services/surfaceflinger/Surfaceflinger.cpp
voidSurfaceFlinger::processDisplayChangesLocked(){// here we take advantage of Vector's copy-on-write semantics to
// improve performance by skipping the transaction entirely when
// know that the lists are identical
constKeyedVector<wp<IBinder>,DisplayDeviceState>&curr(mCurrentState.displays);constKeyedVector<wp<IBinder>,DisplayDeviceState>&draw(mDrawingState.displays);if(!curr.isIdenticalTo(draw)){mVisibleRegionsDirty=true;// find the displays that were removed
// (ie: in drawing state but not in current state)
// also handle displays that changed
// (ie: displays that are in both lists)
for(size_ti=0;i<draw.size();i++){constwp<IBinder>&displayToken=draw.keyAt(i);constssize_tj=curr.indexOfKey(displayToken);if(j<0){// in drawing state but not in current state
processDisplayRemoved(displayToken);}else{// this display is in both lists. see if something changed.
constDisplayDeviceState¤tState=curr[j];constDisplayDeviceState&drawingState=draw[i];processDisplayChanged(displayToken,currentState,drawingState);}}// find displays that were added
// (ie: in current state but not in drawing state)
for(size_ti=0;i<curr.size();i++){constwp<IBinder>&displayToken=curr.keyAt(i);if(draw.indexOfKey(displayToken)<0){processDisplayAdded(displayToken,curr[i]);}}}mDrawingState.displays=mCurrentState.displays;}
//frameworks/native/services/surfaceflinger/Surfaceflinger.cpp
voidSurfaceFlinger::processDisplayRemoved(constwp<IBinder>&displayToken){autodisplay=getDisplayDeviceLocked(displayToken);if(display){display->disconnect();if(display->isVirtual()){releaseVirtualDisplay(display->getVirtualId());}else{dispatchDisplayHotplugEvent(display->getPhysicalId(),false);}}mDisplays.erase(displayToken);if(display&&display->isVirtual()){static_cast<void>(mScheduler->schedule([display=std::move(display)]{// Destroy the display without holding the mStateLock.
// This is a temporary solution until we can manage transaction queues without
// holding the mStateLock.
// With blast, the IGBP that is passed to the VirtualDisplaySurface is owned by the
// client. When the IGBP is disconnected, its buffer cache in SF will be cleared
// via SurfaceComposerClient::doUncacheBufferTransaction. This call from the client
// ends up running on the main thread causing a deadlock since setTransactionstate
// will try to acquire the mStateLock. Instead we extend the lifetime of
// DisplayDevice and destroy it in the main thread without holding the mStateLock.
// The display will be disconnected and removed from the mDisplays list so it will
// not be accessible.
}));}}
//frameworks/native/services/surfaceflinger/Surfaceflinger.cpp
voidSurfaceFlinger::processDisplayChanged(constwp<IBinder>&displayToken,constDisplayDeviceState¤tState,constDisplayDeviceState&drawingState){constsp<IBinder>currentBinder=IInterface::asBinder(currentState.surface);constsp<IBinder>drawingBinder=IInterface::asBinder(drawingState.surface);// Recreate the DisplayDevice if the surface or sequence ID changed.
if(currentBinder!=drawingBinder||currentState.sequenceId!=drawingState.sequenceId){getRenderEngine().cleanFramebufferCache();if(constautodisplay=getDisplayDeviceLocked(displayToken)){display->disconnect();if(display->isVirtual()){releaseVirtualDisplay(display->getVirtualId());}}mDisplays.erase(displayToken);if(constauto&physical=currentState.physical){getHwComposer().allocatePhysicalDisplay(physical->hwcDisplayId,physical->id);}processDisplayAdded(displayToken,currentState);if(currentState.physical){constautodisplay=getDisplayDeviceLocked(displayToken);setPowerModeInternal(display,hal::PowerMode::ON);// TODO(b/175678251) Call a listener instead.
if(currentState.physical->hwcDisplayId==getHwComposer().getPrimaryHwcDisplayId()){updateInternalDisplayVsyncLocked(display);}}return;}if(constautodisplay=getDisplayDeviceLocked(displayToken)){if(currentState.layerStack!=drawingState.layerStack){display->setLayerStack(currentState.layerStack);}if(currentState.flags!=drawingState.flags){display->setFlags(currentState.flags);}if((currentState.orientation!=drawingState.orientation)||(currentState.layerStackSpaceRect!=drawingState.layerStackSpaceRect)||(currentState.orientedDisplaySpaceRect!=drawingState.orientedDisplaySpaceRect)){display->setProjection(currentState.orientation,currentState.layerStackSpaceRect,currentState.orientedDisplaySpaceRect);if(isDisplayActiveLocked(display)){mActiveDisplayTransformHint=display->getTransformHint();}}if(currentState.width!=drawingState.width||currentState.height!=drawingState.height){display->setDisplaySize(currentState.width,currentState.height);if(isDisplayActiveLocked(display)){onActiveDisplaySizeChanged(display);}}}}
/frameworks/native/services/surfaceflinger/Surfaceflinger.cppvoidSurfaceFlinger::processDisplayAdded(constwp<IBinder>&displayToken,constDisplayDeviceState&state){ui::Sizeresolution(0,0);ui::PixelFormatpixelFormat=static_cast<ui::PixelFormat>(PIXEL_FORMAT_UNKNOWN);if(state.physical){resolution=state.physical->activeMode->getResolution();pixelFormat=static_cast<ui::PixelFormat>(PIXEL_FORMAT_RGBA_8888);}elseif(state.surface!=nullptr){intstatus=state.surface->query(NATIVE_WINDOW_WIDTH,&resolution.width);ALOGE_IF(status!=NO_ERROR,"Unable to query width (%d)",status);status=state.surface->query(NATIVE_WINDOW_HEIGHT,&resolution.height);ALOGE_IF(status!=NO_ERROR,"Unable to query height (%d)",status);intformat;status=state.surface->query(NATIVE_WINDOW_FORMAT,&format);ALOGE_IF(status!=NO_ERROR,"Unable to query format (%d)",status);pixelFormat=static_cast<ui::PixelFormat>(format);}else{// Virtual displays without a surface are dormant:
// they have external state (layer stack, projection,
// etc.) but no internal state (i.e. a DisplayDevice).
return;}compositionengine::DisplayCreationArgsBuilderbuilder;if(constauto&physical=state.physical){builder.setId(physical->id);}else{builder.setId(acquireVirtualDisplay(resolution,pixelFormat));}builder.setPixels(resolution);builder.setIsSecure(state.isSecure);builder.setPowerAdvisor(mPowerAdvisor.get());builder.setName(state.displayName);autocompositionDisplay=getCompositionEngine().createDisplay(builder.build());compositionDisplay->setLayerCachingEnabled(mLayerCachingEnabled);sp<compositionengine::DisplaySurface>displaySurface;sp<IGraphicBufferProducer>producer;sp<IGraphicBufferProducer>bqProducer;sp<IGraphicBufferConsumer>bqConsumer;getFactory().createBufferQueue(&bqProducer,&bqConsumer,/*consumerIsSurfaceFlinger =*/false);if(state.isVirtual()){constautodisplayId=VirtualDisplayId::tryCast(compositionDisplay->getId());LOG_FATAL_IF(!displayId);autosurface=sp<VirtualDisplaySurface>::make(getHwComposer(),*displayId,state.surface,bqProducer,bqConsumer,state.displayName);displaySurface=surface;producer=std::move(surface);}else{ALOGE_IF(state.surface!=nullptr,"adding a supported display, but rendering ""surface is provided (%p), ignoring it",state.surface.get());constautodisplayId=PhysicalDisplayId::tryCast(compositionDisplay->getId());LOG_FATAL_IF(!displayId);displaySurface=sp<FramebufferSurface>::make(getHwComposer(),*displayId,bqConsumer,state.physical->activeMode->getResolution(),ui::Size(maxGraphicsWidth,maxGraphicsHeight));producer=bqProducer;}LOG_FATAL_IF(!displaySurface);autodisplay=setupNewDisplayDeviceInternal(displayToken,std::move(compositionDisplay),state,displaySurface,producer);if(display->isPrimary()){initScheduler(display);}if(!state.isVirtual()){dispatchDisplayHotplugEvent(display->getPhysicalId(),true);}mDisplays.try_emplace(displayToken,std::move(display));}
//frameworks/native/services/surfaceflinger/Surfaceflinger.cpp
std::unique_ptr<scheduler::Scheduler>mScheduler;voidSurfaceFlinger::initScheduler(constsp<DisplayDevice>&display){if(mScheduler){// If the scheduler is already initialized, this means that we received
// a hotplug(connected) on the primary display. In that case we should
// update the scheduler with the most recent display information.
ALOGW("Scheduler already initialized, updating instead");mScheduler->setRefreshRateConfigs(display->holdRefreshRateConfigs());return;}constautocurrRefreshRate=display->getActiveMode()->getFps();mRefreshRateStats=std::make_unique<scheduler::RefreshRateStats>(*mTimeStats,currRefreshRate,hal::PowerMode::OFF);mVsyncConfiguration=getFactory().createVsyncConfiguration(currRefreshRate);mVsyncModulator=sp<VsyncModulator>::make(mVsyncConfiguration->getCurrentConfigs());usingFeature=scheduler::Feature;scheduler::FeatureFlagsfeatures;if(sysprop::use_content_detection_for_refresh_rate(false)){features|=Feature::kContentDetection;}if(base::GetBoolProperty("debug.sf.show_predicted_vsync"s,false)){features|=Feature::kTracePredictedVsync;}if(!base::GetBoolProperty("debug.sf.vsync_reactor_ignore_present_fences"s,false)&&!getHwComposer().hasCapability(Capability::PRESENT_FENCE_IS_NOT_RELIABLE)){features|=Feature::kPresentFences;}// 创建Scheduler对象
mScheduler=std::make_unique<scheduler::Scheduler>(static_cast<ICompositor&>(*this),static_cast<ISchedulerCallback&>(*this),features);{autoconfigs=display->holdRefreshRateConfigs();if(configs->kernelIdleTimerController().has_value()){features|=Feature::kKernelIdleTimer;}mScheduler->createVsyncSchedule(features);mScheduler->setRefreshRateConfigs(std::move(configs));}setVsyncEnabled(false);mScheduler->startTimers();constautoconfigs=mVsyncConfiguration->getCurrentConfigs();constnsecs_tvsyncPeriod=currRefreshRate.getPeriodNsecs();mAppConnectionHandle=mScheduler->createConnection("app",mFrameTimeline->getTokenManager(),/*workDuration=*/configs.late.appWorkDuration,/*readyDuration=*/configs.late.sfWorkDuration,impl::EventThread::InterceptVSyncsCallback());mSfConnectionHandle=mScheduler->createConnection("appSf",mFrameTimeline->getTokenManager(),/*workDuration=*/std::chrono::nanoseconds(vsyncPeriod),/*readyDuration=*/configs.late.sfWorkDuration,[this](nsecs_ttimestamp){mInterceptor->saveVSyncEvent(timestamp);});mScheduler->initVsync(mScheduler->getVsyncDispatch(),*mFrameTimeline->getTokenManager(),configs.late.sfWorkDuration);mRegionSamplingThread=newRegionSamplingThread(*this,RegionSamplingThread::EnvironmentTimingTunables());mFpsReporter=newFpsReporter(*mFrameTimeline,*this);// Dispatch a mode change request for the primary display on scheduler
// initialization, so that the EventThreads always contain a reference to a
// prior configuration.
//
// This is a bit hacky, but this avoids a back-pointer into the main SF
// classes from EventThread, and there should be no run-time binder cost
// anyway since there are no connected apps at this point.
mScheduler->onPrimaryDisplayModeChanged(mAppConnectionHandle,display->getActiveMode());}
//frameworks/native/services/surfaceflinger/Scheduler/EventThread.cpp
classEventThread:publicandroid::EventThread,privateVSyncSource::Callback{EventThread::EventThread(std::unique_ptr<VSyncSource>vsyncSource,android::frametimeline::TokenManager*tokenManager,InterceptVSyncsCallbackinterceptVSyncsCallback,ThrottleVsyncCallbackthrottleVsyncCallback,GetVsyncPeriodFunctiongetVsyncPeriodFunction):mVSyncSource(std::move(vsyncSource)),mTokenManager(tokenManager),mInterceptVSyncsCallback(std::move(interceptVSyncsCallback)),mThrottleVsyncCallback(std::move(throttleVsyncCallback)),mGetVsyncPeriodFunction(std::move(getVsyncPeriodFunction)),mThreadName(mVSyncSource->getName()){LOG_ALWAYS_FATAL_IF(getVsyncPeriodFunction==nullptr,"getVsyncPeriodFunction must not be null");mVSyncSource->setCallback(this);//设置VsyncSource回调
mThread=std::thread([this]()NO_THREAD_SAFETY_ANALYSIS{std::unique_lock<std::mutex>lock(mMutex);//创建一个线程
threadMain(lock);//调用threadMain方法,接收回调消息
});pthread_setname_np(mThread.native_handle(),mThreadName);pid_ttid=pthread_gettid_np(mThread.native_handle());// Use SCHED_FIFO to minimize jitter
constexprintEVENT_THREAD_PRIORITY=2;structsched_paramparam={0};param.sched_priority=EVENT_THREAD_PRIORITY;if(pthread_setschedparam(mThread.native_handle(),SCHED_FIFO,¶m)!=0){ALOGE("Couldn't set SCHED_FIFO for EventThread");}set_sched_policy(tid,SP_FOREGROUND);}}