SurfaceFlinger启动-Android12

Posted xhBruce

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SurfaceFlinger启动-Android12相关的知识,希望对你有一定的参考价值。

SurfaceFlinger启动-android12

android12-release


1. surfaceflinger.rc文件

init进程所启动的守护进程,在init.rc中该服务如下surfaceflinger.rc文件

SurfaceFlinger进程名:surfaceflinger,
bin文件:/system/bin/surfaceflinger
对应启动入口:frameworks/native/services/surfaceflinger/main_surfaceflinger.cpp

frameworks/native/services/surfaceflinger/surfaceflinger.rc

service surfaceflinger /system/bin/surfaceflinger
    class core animation
    user system
    group graphics drmrpc readproc
    capabilities SYS_NICE
    onrestart restart zygote
    task_profiles HighPerformance
    socket pdx/system/vr/display/client     stream 0666 system graphics u:object_r:pdx_display_client_endpoint_socket:s0
    socket pdx/system/vr/display/manager    stream 0666 system graphics u:object_r:pdx_display_manager_endpoint_socket:s0
    socket pdx/system/vr/display/vsync      stream 0666 system graphics u:object_r:pdx_display_vsync_endpoint_socket:s0

main_surfaceflinger.cpp启动入口代码:

  • hardware::configureRpcThreadpool(1, false) 设置当前进程用于hwbinder通信的最大线程数(#include <hidl/HidlTransportSupport.h>)
  • 启动 Gralloc 服务startGraphicsAllocatorService();HIDL直通式hardware::registerPassthroughServiceImplementation<android::hardware::graphics::allocator::V2_0::IAllocator>()
  • ProcessState::self()->setThreadPoolMaxThreadCount(4) 设定surfaceflinger进程的binder线程池个数上限为4,并启动binder线程池ps->startThreadPool()
  • surfaceflinger::createSurfaceFlinger()创建SurfaceFlinger对象
  • 设置surfaceflinger进程为高优先级setpriority(PRIO_PROCESS, 0, PRIORITY_URGENT_DISPLAY)以及前台调度策略set_sched_policy(0, SP_FOREGROUND)
  • flinger->init()初始化SurfaceFlinger
  • sm->addService(String16(SurfaceFlinger::getServiceName()), flinger,...)"SurfaceFlinger"服务注册到binder通信的ServiceManager;
  • startDisplayService()启动;HIDL定义接口frameworks/hardware/interfaces/displayservice/1.0/IDisplayService.hal
  • flinger->run() 在当前主线程执行SurfaceFlinger的run方法

frameworks/native/services/surfaceflinger/main_surfaceflinger.cpp

int main(int, char**) 
    signal(SIGPIPE, SIG_IGN);

    hardware::configureRpcThreadpool(1 /* maxThreads */,
            false /* callerWillJoin */);

    startGraphicsAllocatorService();

    // When SF is launched in its own process, limit the number of
    // binder threads to 4.
    ProcessState::self()->setThreadPoolMaxThreadCount(4);

    // Set uclamp.min setting on all threads, maybe an overkill but we want
    // to cover important threads like RenderEngine.
    if (SurfaceFlinger::setSchedAttr(true) != NO_ERROR) 
        ALOGW("Couldn't set uclamp.min: %s\\n", strerror(errno));
    

    // The binder threadpool we start will inherit sched policy and priority
    // of (this) creating thread. We want the binder thread pool to have
    // SCHED_FIFO policy and priority 1 (lowest RT priority)
    // Once the pool is created we reset this thread's priority back to
    // original.
    int newPriority = 0;
    int origPolicy = sched_getscheduler(0);
    struct sched_param origSchedParam;

    int errorInPriorityModification = sched_getparam(0, &origSchedParam);
    if (errorInPriorityModification == 0) 
        int policy = SCHED_FIFO;
        newPriority = sched_get_priority_min(policy);

        struct sched_param param;
        param.sched_priority = newPriority;

        errorInPriorityModification = sched_setscheduler(0, policy, &param);
    

    // start the thread pool
    sp<ProcessState> ps(ProcessState::self());
    ps->startThreadPool();

    // Reset current thread's policy and priority
    if (errorInPriorityModification == 0) 
        errorInPriorityModification = sched_setscheduler(0, origPolicy, &origSchedParam);
     else 
        ALOGE("Failed to set SurfaceFlinger binder threadpool priority to SCHED_FIFO");
    

    // instantiate surfaceflinger
    sp<SurfaceFlinger> flinger = surfaceflinger::createSurfaceFlinger();

    // Set the minimum policy of surfaceflinger node to be SCHED_FIFO.
    // So any thread with policy/priority lower than SCHED_FIFO, 1, will run
    // at least with SCHED_FIFO policy and priority 1.
    if (errorInPriorityModification == 0) 
        flinger->setMinSchedulerPolicy(SCHED_FIFO, newPriority);
    

    setpriority(PRIO_PROCESS, 0, PRIORITY_URGENT_DISPLAY);

    set_sched_policy(0, SP_FOREGROUND);

    // Put most SurfaceFlinger threads in the system-background cpuset
    // Keeps us from unnecessarily using big cores
    // Do this after the binder thread pool init
    if (cpusets_enabled()) set_cpuset_policy(0, SP_SYSTEM);

    // initialize before clients can connect
    flinger->init();

    // publish surface flinger
    sp<IServiceManager> sm(defaultServiceManager());
    sm->addService(String16(SurfaceFlinger::getServiceName()), flinger, false,
                   IServiceManager::DUMP_FLAG_PRIORITY_CRITICAL | IServiceManager::DUMP_FLAG_PROTO);

    startDisplayService(); // dependency on SF getting registered above

    if (SurfaceFlinger::setSchedFifo(true) != NO_ERROR) 
        ALOGW("Couldn't set to SCHED_FIFO: %s", strerror(errno));
    

    // run surface flinger in this thread
    flinger->run();

    return 0;

2. SurfaceFlinger初始化

SurfaceFlinger继承于BnSurfaceComposer,IBinder::DeathRecipient等;new SurfaceFlinger()初始化sp强指针首次被引用时则执行onFirstRef()

  • SurfaceFlingerFactory.cpp/SurfaceFlingerDefaultFactory.cpp 各种创建
  • mSetInputWindowsListener = new SetInputWindowsListener([&]() setInputWindowsFinished(); ) 继承os::BnSetInputWindowsListener,AIDL定义接口frameworks/native/libs/input/android/os/ISetInputWindowsListener.aidl

frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp

SurfaceFlinger::SurfaceFlinger(Factory& factory, SkipInitializationTag)
      : mFactory(factory),
        mInterceptor(mFactory.createSurfaceInterceptor()),
        mTimeStats(std::make_shared<impl::TimeStats>()),
        mFrameTracer(mFactory.createFrameTracer()),
        mFrameTimeline(mFactory.createFrameTimeline(mTimeStats, getpid())),
        mEventQueue(mFactory.createMessageQueue()),
        mCompositionEngine(mFactory.createCompositionEngine()),
        mHwcServiceName(base::GetProperty("debug.sf.hwc_service_name"s, "default"s)),
        mTunnelModeEnabledReporter(new TunnelModeEnabledReporter()),
        mInternalDisplayDensity(getDensityFromProperty("ro.sf.lcd_density", true)),
        mEmulatedDisplayDensity(getDensityFromProperty("qemu.sf.lcd_density", false)),
        mPowerAdvisor(*this) 
    ALOGI("Using HWComposer service: %s", mHwcServiceName.c_str());

    mSetInputWindowsListener = new SetInputWindowsListener([&]()  setInputWindowsFinished(); );


SurfaceFlinger::SurfaceFlinger(Factory& factory) : SurfaceFlinger(factory, SkipInitialization) 
    // ... ...

2.1 onFirstRef 创建Handler并初始化

创建 Handler/Looper 并初始化

void SurfaceFlinger::onFirstRef() 
    mEventQueue->init(this);

/frameworks/native/services/surfaceflinger/Scheduler/MessageQueue.cpp

void MessageQueue::init(const sp<SurfaceFlinger>& flinger) 
    mFlinger = flinger;
    mLooper = new Looper(true);
    mHandler = new Handler(*this);

2.2 SurfaceFlinger::init()

  • renderengine::RenderEngine::create()获取RenderEngine引擎;
  1. 两类引擎GLESRenderEngine、SkiaGLRenderEngineRenderEngineThreaded对应相应异步线程;RenderEngineCreationArgs参数配置,其中默认RenderEngineType::SKIA_GL_THREADED类型,即RenderEngineThreaded::create(SkiaGLRenderEngine::create(skiaArgs),renderEngineType)
  2. SkiaGLRenderEngine创建中EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY)初始化EGL相关
  • getFactory().createHWComposer(mHwcServiceName)创建 HWComposer
  • processDisplayHotplugEventsLocked() 处理任何初始热插拔和显示更改结果
  1. processDisplayChanged()/processDisplayAdded()处理显示更改结果
  2. 其中initScheduler(state)创建app、appsf的链接mAppConnectionHandle、mSfConnectionHandle,并启动对应EventThread线程
  • initializeDisplays()初始化显示设备
  • mStartPropertySetThread->Start() 在线程中设置property_set("ctl.start", "bootanim")启动开机动画
void SurfaceFlinger::init() 
    ALOGI(  "SurfaceFlinger's main thread ready to run. "
            "Initializing graphics H/W...");
    Mutex::Autolock _l(mStateLock);

    // Get a RenderEngine for the given display / config (can't fail)
    // TODO(b/77156734): We need to stop casting and use HAL types when possible.
    // Sending maxFrameBufferAcquiredBuffers as the cache size is tightly tuned to single-display.
    mCompositionEngine->setRenderEngine(renderengine::RenderEngine::create(
            renderengine::RenderEngineCreationArgs::Builder()
                    .setPixelFormat(static_cast<int32_t>(defaultCompositionPixelFormat))
                    .setImageCacheSize(maxFrameBufferAcquiredBuffers)
                    .setUseColorManagerment(useColorManagement)
                    .setEnableProtectedContext(enable_protected_contents(false))
                    .setPrecacheToneMapperShaderOnly(false)
                    .setSupportsBackgroundBlur(mSupportsBlur)
                    .setContextPriority(
                            useContextPriority
                                    ? renderengine::RenderEngine::ContextPriority::REALTIME
                                    : renderengine::RenderEngine::ContextPriority::MEDIUM)
                    .build()));

    // Set SF main policy after initializing RenderEngine which has its own policy.
    if (!SetTaskProfiles(0, "SFMainPolicy")) 
        ALOGW("Failed to set main task profile");
    

    mCompositionEngine->setTimeStats(mTimeStats);
    mCompositionEngine->setHwComposer(getFactory().createHWComposer(mHwcServiceName));
    mCompositionEngine->getHwComposer().setCallback(this);
    ClientCache::getInstance().setRenderEngine(&getRenderEngine());

    if (base::GetBoolProperty("debug.sf.enable_hwc_vds"s, false)) 
        enableHalVirtualDisplays(true);
    

    // Process any initial hotplug and resulting display changes.
    processDisplayHotplugEventsLocked();
    const auto display = getDefaultDisplayDeviceLocked();
    LOG_ALWAYS_FATAL_IF(!display, "Missing internal display after registering composer callback.");
    const auto displayId = display->getPhysicalId();
    LOG_ALWAYS_FATAL_IF(!getHwComposer().isConnected(displayId),
                        "Internal display is disconnected.");

    // initialize our drawing state
    mDrawingState = mCurrentState;

    // set initial conditions (e.g. unblank default device)
    initializeDisplays();

    mPowerAdvisor.init();

    char primeShaderCache[PROPERTY_VALUE_MAX];
    property_get("service.sf.prime_shader_cache", primeShaderCache, "1");
    if (atoi(primeShaderCache)) 
        if (setSchedFifo(false) != NO_ERROR) 
            ALOGW("Can't set SCHED_OTHER for primeCache");
        

        mRenderEnginePrimeCacheFuture = getRenderEngine().primeCache();

        if (setSchedFifo(true) != NO_ERROR) 
            ALOGW("Can't set SCHED_OTHER for primeCache");
        
    

    getRenderEngine().onPrimaryDisplaySizeChanged(display->getSize());

    // Inform native graphics APIs whether the present timestamp is supported:

    const bool presentFenceReliable =
            !getHwComposer().hasCapability(hal::Capability::PRESENT_FENCE_IS_NOT_RELIABLE);
    mStartPropertySetThread = getFactory().createStartPropertySetThread(presentFenceReliable);

    if (mStartPropertySetThread->Start() != NO_ERROR) 
        ALOGE("Run StartPropertySetThread failed!");
    

    ALOGV("Done initializing");

3. SurfaceFlinger::run()

不断循环地等待事件

4. 简要时序图

以上是关于SurfaceFlinger启动-Android12的主要内容,如果未能解决你的问题,请参考以下文章

SurfaceFlinger启动-Android12

SurfaceFlinger启动-Android12

SurfaceFlinger启动-Android12

SurfaceFlinger启动篇

Android 图形架构 之二—— SurfaceFlinger 启动和连接

Android 图形架构 之二—— SurfaceFlinger 启动和连接