android surfaceflinger(2)-HWComposer初始化

本文详细解析了SurfaceFlinger中HWComposer的初始化过程,包括通过HAL层加载显示屏模块、初始化帧缓冲设备以及硬件合成器模块等关键步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  上一篇文章介绍了init进程去启动surfaceflinger的过程;本文将继承上篇文章继续往下分析,上文分析到SurfaceFlinger::init();本文将主要分析init()里面的HWComposer初始化。
时序图如下:
这里写图片描述

1、HWComposer创建

void SurfaceFlinger::init() {
     // Initialize the H/W composer object.  There may or may not be an
    // actual hardware composer underneath.
    mHwc = new HWComposer(this,
            *static_cast<HWComposer::EventHandler *>(this));//调用构造函数
 }

2、HWComposer构造函数

HWComposer::HWComposer(
        const sp<SurfaceFlinger>& flinger,EventHandler& handler)
    : mFlinger(flinger),mFbDev(0), mHwc(0), mNumDisplays(1),mCBContext(new cb_context), mEventHandler(handler), mDebugForceFakeVSync(false)
{
    // Note: some devices may insist that the FB HAL be opened before HWC.
    int fberr = loadFbHalModule();//详见第3节
    loadHwcModule();//详见第4节
    。。。。。。
    if (mFbDev) {
    。。。。。。
    } else if (mHwc) {
        // here we're guaranteed to have at least HWC 1.1
        for (size_t i =0 ; i<NUM_BUILTIN_DISPLAYS ; i++) {
            queryDisplayProperties(i);//详见第5节
        }
    }
}

3、loadFbHalModule

  这个函数的作用是通过GRALLOC_HARDWARE_MODULE_ID去加载对应的显示屏HAL层模块,并初始化。

int HWComposer::loadFbHalModule()
{
    hw_module_t const* module;
    int err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module);//详见3.1节
    if (err != 0) {
        ALOGE("%s module not found", GRALLOC_HARDWARE_MODULE_ID);
        return err;
    }

    return framebuffer_open(module, &mFbDev);//详见3.2节
}

3.1、加载模块

通过GRALLOC_HARDWARE_MODULE_ID找到对应的模块,并将HAL_MODULE_INFO_SYM结构体的地址赋给指针module。

struct private_module_t HAL_MODULE_INFO_SYM = {
    base: {
        common: {
            tag: HARDWARE_MODULE_TAG,
            version_major: 1,
            version_minor: 0,
            id: ***GRALLOC_HARDWARE_MODULE_ID***,
            name: "Graphics Memory Allocator Module",
            author: "The Android Open Source Project",
            methods: &gralloc_module_methods,
        },
        registerBuffer: BufferManager::gralloc_register_buffer,
        unregisterBuffer: BufferManager::gralloc_unregister_buffer,
        lock: BufferManager::gralloc_lock,
        unlock: BufferManager::gralloc_unlock,
    },
};

3.2、调用模块open方法

static inline int framebuffer_open(const struct hw_module_t* module,
        struct framebuffer_device_t** device) {
    return module->methods->open(module,
            GRALLOC_HARDWARE_FB0, (struct hw_device_t**)device);
}

由上面可知,module指向的是HMI;那么module->methods->open调用的就是该模块中gralloc_module_methods的open方法。

static struct hw_module_methods_t gralloc_module_methods = {
        open: BufferManager::gralloc_device_open//见3.3节
};

3.3 BufferManager中open方法

int BufferManager::gralloc_device_open(const hw_module_t* module, const char* name,
        hw_device_t** device)
{
    BufferManager* m = BufferManager::getInstance();

    if (!strcmp(name, GRALLOC_HARDWARE_GPU0)) {
      ......
    }
    else {//前面传入的参数为GRALLOC_HARDWARE_FB0
        status = fb_device_open(module, name, device);//见3.4节
    }

    return status;
}

3.4 打开fb设备

int BufferManager::fb_device_open(hw_module_t const* module, const char* name,
        hw_device_t** device)
{
    int status = 0;
    char value[PROPERTY_VALUE_MAX];
    if (!strncmp(name, GRALLOC_HARDWARE_FB, 2)) {
        framebuffer_device_t *fbdev;
        nr_framebuffers = NUM_BUFFERS;

        /* initialize our state here */
        fb_context_t *dev = (fb_context_t*)malloc(sizeof(*dev));
        memset(dev, 0, sizeof(*dev));

        /* initialize the procs */
        dev->device.common.tag = HARDWARE_DEVICE_TAG;
        dev->device.common.version = 0;
        dev->device.common.module = const_cast<hw_module_t*>(module);
        dev->device.common.close = Display::closeDevice;
        dev->device.setSwapInterval = Display::setSwapInterval;
        dev->device.post            = Display::postBuffer;
        dev->device.setUpdateRect = 0;
        dev->device.compositionComplete = Display::compositionComplete;
        dev->device.common.module = const_cast<hw_module_t*>(module);
        BufferManager* pBufferManager = BufferManager::getInstance();

        int fbid = atoi(name+2);//将Fb0中的0转化为数字赋值给fbid
        if (fbid < 0 || fbid > 5) {
            ALOGE("%s invalid fb num %d", __FUNCTION__, fbid);
            ::free(dev);
            return -EINVAL;
        }

        int dispid = 0;
        dev->isMainDisp = 1;

        ALOGI("fb_device_open dispid:%d, fb:%d", dispid, fbid);
        Display* display = pBufferManager->getDisplay(dispid);//通过dispid获取数组对应下标的Display
        if (display == NULL) {
            ALOGE("%s can't get valid display", __FUNCTION__);
            ::free(dev);
            return -EINVAL;
        }

        status = display->initialize(fbid);//详见3.5节
        if (status >= 0) {
            display->setContext(dev);
        }
        dev->display = display;

        *device = &dev->device.common;
        fbdev = (framebuffer_device_t*)(*device);
        fbdev->reserved[0] = nr_framebuffers;
    }

    return status;
}

3.5、初始化Fb设备

int Display::initialize(int fb)
{
    Mutex::Autolock _l(mLock);
    fb_num = fb;
    int fbid = fb_num;
    char const * const device_template[] = {//设备节点路径
            "/dev/graphics/fb%u",
            "/dev/fb%u",
            0 };

    int fd = -1;
    int i=0;
    char name[64];

    while ((fd==-1) && device_template[i]) {
        snprintf(name, 64, device_template[i], fbid);
        fd = open(name, O_RDWR, 0);//打开设备节点,默认是/dev/graphics/fb0
        i++;
    }

    //获取屏幕固定参数
    struct fb_fix_screeninfo finfo;
    if (ioctl(fd, FBIOGET_FSCREENINFO, &finfo) == -1) {
        ALOGE("<%s,%d> FBIOGET_FSCREENINFO failed", __FUNCTION__, __LINE__);
        close(fd);
        return -errno;
    }

    //获取屏幕可变参数
    struct fb_var_screeninfo info;
    if (ioctl(fd, FBIOGET_VSCREENINFO, &info) == -1) {
        ALOGE("<%s,%d> FBIOGET_VSCREENINFO failed", __FUNCTION__, __LINE__);
        close(fd);
        return -errno;
    }

    //显存地址映射
    void* vaddr = mmap(0, fbSize, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
    if (vaddr == MAP_FAILED) {
        ALOGE("Error mapping the framebuffer (%s)", strerror(errno));
        close(fd);
        return -errno;
    }
    mFramebuffer->base = intptr_t(vaddr);
    mFramebuffer->phys = intptr_t(finfo.smem_start);
    memset(vaddr, 0, fbSize);
    close(fd);
    return 0;
}

4、loadHwcModule

  这个函数的作用是通过HWC_HARDWARE_MODULE_ID去加载硬件合成器

void HWComposer::loadHwcModule()
{
    hw_module_t const* module;

    if (hw_get_module(HWC_HARDWARE_MODULE_ID, &module) != 0) {
        ALOGE("%s module not found", HWC_HARDWARE_MODULE_ID);
        return;
    }

    int err = hwc_open_1(module, &mHwc);
    if (err) {
        ALOGE("%s device failed to initialize (%s)",
              HWC_HARDWARE_COMPOSER, strerror(-err));
        return;
    }
}

4.1 加载模块



hwc_module_t HAL_MODULE_INFO_SYM = {
    common: {
        tag: HARDWARE_MODULE_TAG,
        version_major: 2,
        version_minor: 0,
        id: HWC_HARDWARE_MODULE_ID,
        name: "Freescale i.MX hwcomposer module",
        author: "Freescale Semiconductor, Inc.",
        methods: &hwc_module_methods,
        dso: NULL,
        reserved: {0}
    }
};

4.2 调用模块open方法

static inline int hwc_open_1(const struct hw_module_t* module,
        hwc_composer_device_1_t** device) {
    return module->methods->open(module,
            HWC_HARDWARE_COMPOSER, (struct hw_device_t**)device);
}

由上面可知,module指向的是HMI;那么module->methods->open调用的就是该模块中hwc_module_methods的open方法。

static struct hw_module_methods_t hwc_module_methods = {
    open: hwc_device_open
};

4.3 打开硬件合成器

static int hwc_device_open(const struct hw_module_t* module, const char* name,
        struct hw_device_t** device)
{
    int status = -EINVAL;
    struct hwc_context_t *dev = NULL;
    if (!strcmp(name, HWC_HARDWARE_COMPOSER)) {
        //struct hwc_context_t *dev;
        dev = (hwc_context_t*)malloc(sizeof(*dev));

        /* initialize our state here */
        memset(dev, 0, sizeof(*dev));

        /* initialize the procs */
        dev->device.common.tag = HARDWARE_DEVICE_TAG;
        dev->device.common.module = const_cast<hw_module_t*>(module);
        dev->device.common.close = hwc_device_close;

        dev->device.prepare = hwc_prepare;
        dev->device.set = hwc_set;
        dev->device.common.version = HWC_DEVICE_API_VERSION_1_3;
        dev->device.registerProcs = hwc_registerProcs;
        dev->device.eventControl = hwc_eventControl;
        dev->device.query = hwc_query;

        dev->device.blank = hwc_blank;
        dev->device.getDisplayConfigs = hwc_getDisplayConfigs;
        dev->device.getDisplayAttributes = hwc_getDisplayAttributes;

        /* our private state goes below here */
        dev->m_vsync_thread = new VSyncThread(dev);
        dev->m_uevent_thread = new UeventThread(dev);

        bool using_fsl_hwc = false;
        const hw_module_t *hwc_module;

        hwc_get_display_info(dev);//获取显示信息
        hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &dev->m_gralloc_module);
        struct private_module_t *priv_m =
                         (struct private_module_t *)dev->m_gralloc_module;

        for(int dispid=0; dispid<HWC_NUM_PHYSICAL_DISPLAY_TYPES; dispid++) {
            if(dev->mDispInfo[dispid].connected && dev->m_gralloc_module != NULL) {
                int fbid = dev->mDispInfo[dispid].fb_num;
                char fbname[HWC_STRING_LENGTH];
                memset(fbname, 0, sizeof(fbname));
                sprintf(fbname, "fb%d", fbid);
                ALOGI("hwcomposer: open framebuffer %s", fbname);
                dev->mFbDev[dispid] = (framebuffer_device_t*)dispid;
                dev->m_gralloc_module->methods->open(dev->m_gralloc_module, fbname,
                           (struct hw_device_t**)&dev->mFbDev[dispid]);
            }
        }

        *device = &dev->device.common;
    ALOGI("%s,%d", __FUNCTION__, __LINE__);
        return 0;
    }

    /****************************************/
    return status;
}

5、查询显示属性

status_t HWComposer::queryDisplayProperties(int disp) {

    // use zero as default value for unspecified attributes
    int32_t values[NUM_DISPLAY_ATTRIBUTES - 1];
    memset(values, 0, sizeof(values));

    const size_t MAX_NUM_CONFIGS = 128;
    uint32_t configs[MAX_NUM_CONFIGS] = {0};
    size_t numConfigs = MAX_NUM_CONFIGS;
    status_t err = mHwc->getDisplayConfigs(mHwc, disp, configs, &numConfigs);
    if (err != NO_ERROR) {
        // this can happen if an unpluggable display is not connected
        mDisplayData[disp].connected = false;
        return err;
    }

    mDisplayData[disp].currentConfig = 0;
    for (size_t c = 0; c < numConfigs; ++c) {
        err = mHwc->getDisplayAttributes(mHwc, disp, configs[c],
                DISPLAY_ATTRIBUTES, values);
        // If this is a pre-1.5 HWC, it may not know about color transform, so
        // try again with a smaller set of attributes
        if (err != NO_ERROR) {
            err = mHwc->getDisplayAttributes(mHwc, disp, configs[c],
                    PRE_HWC15_DISPLAY_ATTRIBUTES, values);
        }

        DisplayConfig config = DisplayConfig();

        if (config.xdpi == 0.0f || config.ydpi == 0.0f) {
            float dpi = getDefaultDensity(config.width, config.height);
            config.xdpi = dpi;
            config.ydpi = dpi;
        }

        mDisplayData[disp].configs.push_back(config);//显示数据数组管理
    }


    mDisplayData[disp].connected = true;
    return NO_ERROR;
}

到此,HWComposer初始化分析介绍;接下来分析根据HWComposer来构造DisplayDevice对象;从而达到分层的效果。未完待续。。。。。

<think>我们正在分析SurfaceFlinger的`run`函数的初始化和执行流程。根据之前提供的崩溃日志,我们可以看到崩溃发生在`Scheduler::run`函数中(backtrace中的第#08帧)。因此,我们将重点分析`Scheduler::run`方法及其在SurfaceFlinger中的作用。 ### 一、SurfaceFlinger中`run`函数的背景 在Android显示系统中,`SurfaceFlinger`作为系统服务运行,负责接收所有窗口的图形数据,进行合成,并将结果发送到显示设备。`Scheduler`是SurfaceFlinger中负责调度合成的核心模块,其`run`方法是主循环的入口。 ### 二、`Scheduler::run`的初始化流程 1. **创建消息队列** SurfaceFlinger初始化过程中会创建`MessageQueue`对象,该队列用于处理来自`EventThread`(VSync信号源)的事件: ```cpp // SurfaceFlinger.cpp void SurfaceFlinger::init() { // ... 其他初始化 mScheduler = std::make_unique<scheduler::Scheduler>(...); mEventQueue = std::make_unique<impl::MessageQueue>(); // 将Scheduler与MessageQueue关联 mScheduler->setEventQueue(mEventQueue.get()); } ``` 2. **启动调度线程** 在`SurfaceFlinger`主函数中,通过调用`Scheduler::run`启动调度循环: ```cpp // main_surfaceflinger.cpp int main(int, char**) { // ... 初始化 flinger->run(); // 内部调用Scheduler::run() return 0; } ``` 实际执行的是`Scheduler::run`方法,该方法会进入一个无限循环,等待和处理消息。 ### 三、`Scheduler::run`的执行流程 `Scheduler::run`方法的核心是一个消息循环,其处理流程如下: 1. **等待消息** 通过`MessageQueue::waitMessage()`阻塞等待新消息(主要是VSync信号触发的合成事件): ```cpp // Scheduler.cpp void Scheduler::run() { while (true) { auto message = mMessageQueue->waitMessage(); // 阻塞等待 if (message.type == MessageQueue::REFRESH) { onFrameSignal(...); // 处理合成帧 } } } ``` 2. **处理VSync信号** 当`EventThread`分发VSync信号时,会向`MessageQueue`推送`REFRESH`消息: ```cpp // MessageQueue.cpp void MessageQueue::Handler::dispatchRefresh() { mQueue.mHandler->handleMessage(Message(MessageQueue::REFRESH)); } ``` 3. **执行合成操作** `Scheduler`收到`REFRESH`消息后,调用`onFrameSignal`方法,最终触发`SurfaceFlinger::composite`: ```cpp // Scheduler.cpp void Scheduler::onFrameSignal(ICompositor& compositor, VsyncId vsyncId, TimePoint expectedVsyncTime) { compositor.composite(vsyncId, expectedVsyncTime); // 调用SurfaceFlinger的composite } ``` 4. **合成流程** `SurfaceFlinger::composite`执行以下关键步骤: - **准备帧**:收集所有图层的状态和缓冲区。 - **调用HWC**:通过`HWComposer`进行硬件合成或回退到GPU合成。 - **提交帧**:将最终帧提交给显示设备。 $$ \text{Frame}_{n} = \text{HWC} \left( \bigoplus_{i=1}^{k} \text{Layer}_{i} \right) $$ ### 四、关键对象交互 ```mermaid sequenceDiagram participant EventThread as VSync事件线程 participant MessageQueue as 消息队列 participant Scheduler as 调度器(Scheduler) participant SF as SurfaceFlinger EventThread->>MessageQueue: VSync信号到达 MessageQueue->>Scheduler: 发送REFRESH消息 Scheduler->>SF: 调用composite() SF->>SF: 合成所有图层 SF->>HWComposer: 提交帧 ``` ### 五、崩溃日志分析 在用户提供的崩溃日志中,崩溃发生在`Scheduler::run`的调用栈中(#08帧),具体是在等待消息后执行到`onFrameSignal`的过程中。崩溃点位于`FrameTargeter::setPresentFence`(#00帧),这通常与显示设备的栅栏(Fence)同步异常有关。可能的原因包括: - 无效的栅栏指针(如已关闭的文件描述符) - 硬件合成器(HWC)驱动异常 --- ### 六、调试建议 1. **检查HWC状态** 通过`dumpsys SurfaceFlinger`查看`HWComposer`是否报告错误: ``` HWComposer state: Display 0: ERROR (timeout) ``` 2. **启用详细日志** 在`SurfaceFlinger`启动参数中添加`-v`选项: ```bash setprop debug.sf.log_redirector stdout ``` 3. **捕获崩溃现场** 使用`gdb`附加到`surfaceflinger`进程,在崩溃时检查寄存器`r0`的值(`0xb7b7b7bb`)是否为无效地址。 --- §§相关问题§§ 1. SurfaceFlinger如何处理多显示器的合成调度? 2. VSync信号的分发机制在Android 12及更高版本中有哪些变化? 3. 如何调试`HWComposer`的硬件合成失败问题? 4. `MessageQueue`在SurfaceFlinger中如何避免消息积压?</think>### SurfaceFlinger中`run`函数的初始化和执行流程 `run()`函数是SurfaceFlinger的主事件循环核心,负责协调整个显示合成流程。以下是其完整的初始化和执行流程(基于Android U代码分析): #### 一、初始化阶段 1. **主线程启动** 在`main()`函数中完成基础初始化后,调用`Scheduler::run()`启动主循环: ```cpp // main_surfaceflinger.cpp int main() { sp<SurfaceFlinger> flinger = new SurfaceFlinger(); flinger->init(); // 初始化HWC、EventThread等 flinger->run(); // 进入主循环 } ``` 2. **消息队列创建** 在`SurfaceFlinger`构造函数中创建消息队列: ```cpp // SurfaceFlinger.cpp SurfaceFlinger::SurfaceFlinger() { mEventQueue = std::make_unique<impl::MessageQueue>(); mScheduler = std::make_unique<Scheduler>(mEventQueue.get()); } ``` 3. **VSync信号源配置** 通过`EventThread`建立VSync监听: ```mermaid sequenceDiagram HWComposer->>+EventThread: VSync信号 EventThread->>+MessageQueue: VSync消息 MessageQueue->>+Scheduler: 唤醒处理 ``` #### 二、`run()`核心执行流程 ```cpp // Scheduler.cpp void Scheduler::run() { while (true) { auto message = mMessageQueue->waitMessage(); // 阻塞等待消息 switch (message.type) { case MessageQueue::REFRESH: onFrameSignal(message.compositor, message.vsyncId, message.timestamp); break; case MessageQueue::INVALIDATE: // 处理图层更新 break; } } } ``` #### 三、关键处理流程解析 1. **帧信号处理** (`onFrameSignal`) - 调用`SurfaceFlinger::composite()`进行合成 - 通过`FrameTargeter`设置显示栅栏: ```cpp // FrameTargeter.cpp void FrameTargeter::setPresentFence(sp<Fence> fence) { mPresentFence = fence; // 此处是崩溃点 } ``` 2. **合成引擎工作流** $$ \text{Frame}_{n} = \sum_{i=1}^{k} \text{Layer}_i \oplus \text{HWC}_\text{strategy} $$ - 收集所有可见图层 - 通过`HWComposer`生成合成策略 - 提交到显示驱动 3. **同步机制** - 使用`Fence`同步GPU/显示操作 - 通过`BufferQueue`管理缓冲区生命周期: ```cpp // BufferQueueProducer.cpp status_t dequeueBuffer(int* slot, sp<Fence>* fence) { // 确保缓冲区可用 } ``` #### 四、崩溃点分析 在您提供的日志中: ``` #00 pc 004710a8 /system/bin/surfaceflinger (FrameTargeter::setPresentFence(...)+72) ``` 表明在设置显示栅栏时发生`SIGBUS`总线错误。可能原因: 1. **内存对齐问题**:指针`0xb7b7b7bb`不符合ARM对齐要求 2. **栅栏对象失效**:`sp<Fence>`指向已释放内存 3. **并发修改**:多个线程同时操作`FrameTargeter` #### 五、性能优化机制 1. **动态调度策略** 根据负载切换合成模式: ```cpp if (layers > MAX_OVERLAY) { useGpuComposition(); // 回退到GPU合成 } else { useHwcComposition(); // 硬件合成 } ``` 2. **VSync自适应** 根据帧率需求动态调整`EventThread`的分发策略 ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值