hwc1 surfaceflinger启动流程

本文详细解析了SurfaceFlinger服务的启动流程,包括SurfaceFlinger实例创建、初始化、HWComposer构造函数中的核心操作,如加载模块、注册回调、开启线程等。此外,还介绍了registerProcs、init_uevent_thread、init_vsync_thread、queryDisplayProperties及DisplayDevice的相关功能,阐述了如何判断屏幕的存在并获取其配置信息,为理解HWC2的初始化奠定了基础。
摘要由CSDN通过智能技术生成

先来看看大体的流程图:
在这里插入图片描述
1.SurfaceFlinger作为一个服务被添加到serviceManager上,其服务的添加在main_surfaceflinger.cpp这个文件里面

int main(int, char**) {
   
  ...
    sp<SurfaceFlinger> flinger = new SurfaceFlinger();

    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);

    // publish GpuService
    sp<GpuService> gpuservice = new GpuService();
    sm->addService(String16(GpuService::SERVICE_NAME), gpuservice, false);
....
    flinger->run();

    return 0;
}

上面的代码主要有几点:
1.创建surfaceFlinger的实例
2.调用init初始化
3.将实例添加到ServiceManager上
4.添加RUN开始事件处理
我们这里来看看其MakeFile文件

LOCAL_SRC_FILES := \
    Client.cpp \
    DisplayDevice.cpp \
    DispSync.cpp \
    EventControlThread.cpp \
    StartPropertySetThread.cpp \
    EventThread.cpp \
    FrameTracker.cpp \
    GpuService.cpp \
    Layer.cpp \
    LayerDim.cpp \
    LayerRejecter.cpp \
    LayerVector.cpp \
    MessageQueue.cpp \
    MonitoredProducer.cpp \
    SurfaceFlingerConsumer.cpp \
    SurfaceInterceptor.cpp \
    Transform.cpp \
    DisplayHardware/ComposerHal.cpp \
    DisplayHardware/FramebufferSurface.cpp \
    DisplayHardware/HWC2.cpp \
    DisplayHardware/HWComposerBufferCache.cpp \
    DisplayHardware/PowerHAL.cpp \
    DisplayHardware/VirtualDisplaySurface.cpp \
    Effects/Daltonizer.cpp \
    EventLog/EventLogTags.logtags \
    EventLog/EventLog.cpp \
    RenderEngine/Description.cpp \
    RenderEngine/Mesh.cpp \
    RenderEngine/Program.cpp \
    RenderEngine/ProgramCache.cpp \
    RenderEngine/GLExtensions.cpp \
    RenderEngine/RenderEngine.cpp \
    RenderEngine/Texture.cpp \
    RenderEngine/GLES20RenderEngine.cpp \

LOCAL_MODULE := libsurfaceflinger
LOCAL_C_INCLUDES := \
    frameworks/native/vulkan/include \
    external/vulkan-validation-layers/libs/vkjson \
    system/libhwbinder/fast_msgq/include \

LOCAL_CFLAGS := -DLOG_TAG=\"SurfaceFlinger\"
LOCAL_CFLAGS += -DGL_GLEXT_PROTOTYPES -DEGL_EGLEXT_PROTOTYPES

ifeq ($(TARGET_USES_HWC2),true)
    LOCAL_CFLAGS += -DUSE_HWC2
    LOCAL_SRC_FILES += \
        SurfaceFlinger.cpp \
        DisplayHardware/HWComposer.cpp
else
    LOCAL_SRC_FILES += \
        SurfaceFlinger_hwc1.cpp \
        DisplayHardware/HWComposer_hwc1.cpp
endif

其上就是其参与编译的源文件,这里需要注意的是TARGET_USES_HWC2这个定义,hwc1是之前使用的框架,而hwc2是新的框架。看编译选项使用哪种方式。这里我们先从 hwc1开始分析,因为这个会比HWC2更容易

2.SurfaceFlinger init

void SurfaceFlinger::init() {
   
    ALOGI(  "SurfaceFlinger's main thread ready to run. "
            "Initializing graphics H/W...");

    Mutex::Autolock _l(mStateLock);

    // initialize EGL for the default display
    //调用OpenGL的接口进行初始化
    mEGLDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
    eglInitialize(mEGLDisplay, NULL, NULL);

    // start the EventThread
    //这个主要是用来处理vsync事件的,虚拟场同步事件,这个逻辑有点复杂,这里不讲这个,后面把逻辑搞清楚了。画个流程图再来看看
    sp<VSyncSource> vsyncSrc = new DispSyncSource(&mPrimaryDispSync,
            vsyncPhaseOffsetNs, true, "app");
    mEventThread = new EventThread(vsyncSrc, *this, false);
    sp<VSyncSource> sfVsyncSrc = new DispSyncSource(&mPrimaryDispSync,
            sfVsyncPhaseOffsetNs, true, "sf");
    mSFEventThread = new EventThread(sfVsyncSrc, *this, true);
    mEventQueue.setEventThread(mSFEventThread);

    // set EventThread and SFEventThread to SCHED_FIFO to minimize jitter
    struct sched_param param = {
   0};
    param.sched_priority = 2;
    if (sched_setscheduler(mSFEventThread->getTid(), SCHED_FIFO, &param) != 0) {
   
        ALOGE("Couldn't set SCHED_FIFO for SFEventThread");
    }
    if (sched_setscheduler(mEventThread->getTid(), SCHED_FIFO, &param) != 0) {
   
        ALOGE("Couldn't set SCHED_FIFO for EventThread");
    }

    // Initialize the H/W composer object.  There may or may not be an
    // actual hardware composer underneath.
   //创建 HWcomposer实例
    mHwc = new HWComposer(this,
            *static_cast<HWComposer::EventHandler *>(this));

    // get a RenderEngine for the given display / config (can't fail)
    mRenderEngine = RenderEngine::create(mEGLDisplay,
            mHwc->getVisualID(), 0);

    // retrieve the EGL context that was selected/created
    mEGLContext = mRenderEngine->getEGLContext();

    LOG_ALWAYS_FATAL_IF(mEGLContext == EGL_NO_CONTEXT,
            "couldn't create EGLContext");

    // initialize our non-virtual displays
    //获取当前所有已经存在的display
    for (size_t i=0 ; i<DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES ; i++) {
   
        DisplayDevice::DisplayType type((DisplayDevice::DisplayType)i);
        // set-up the displays that are already connected
        if (mHwc->isConnected(i) || type==DisplayDevice::DISPLAY_PRIMARY) {
   
            // All non-virtual displays are currently considered secure.
            bool isSecure = true;
            createBuiltinDisplayLocked(type);
            wp<IBinder> token = mBuiltinDisplays[i];

            sp<IGraphicBufferProducer> producer;
            sp<IGraphicBufferConsumer> consumer;
            BufferQueue::createBufferQueue(&producer, &consumer);

            sp<FramebufferSurface> fbs = new 
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

bruk_spp

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值