必读:

Android 12(S) 图像显示系统 - 开篇


接口定义

源码位置:/hardware/interfaces/graphics/composer/

在源码目录下可以看到4个版本的HIDL Interface定义,最新版本是2.4,也是目前我的测试平台在用的,不同版本使用带有版本号的包名来区分,例如 :package android.hardware.graphics.composer@2.4
各版本中均有相同的接口,并且具有继承关系,新版本继承旧版接口并扩展了新方法。

/frameworks/native/services/surfaceflinger/DisplayHardware/ 中 android::Hwc2::impl::Composer 相当于HIDL的客户端,framework通过impl::Composer中的方法看跨进程和 hwc hal 互动。

各个版本接口的继承关系

Composer HIDL Service

代码位置
/hardware/interfaces/graphics/composer/2.4/default/service.cpp
/hardware/interfaces/graphics/composer/2.4/default/android.hardware.graphics.composer@2.4-service.rc

开机启动时,init进程解析rc文件带起服务进程,在service.cpp的main函数中,注册服务

int main() {
...
android::sp<IComposer> composer = HwcLoader::load();
if (composer == nullptr) {
return 1;
}
if (composer->registerAsService() != android::NO_ERROR) {
ALOGE("failed to register service");
return 1;
}
...
}

可以看到其中调用了一个非常重要的方法HwcLoader::load(),看其代码:

[/hardware/interfaces/graphics/composer/2.4/utils/passthrough/include/composer-passthrough/2.4/HwcLoader.h]
static IComposer* load() {
const hw_module_t* module = loadModule();
if (!module) {
return nullptr;
}
auto hal = createHalWithAdapter(module);
if (!hal) {
return nullptr;
}
return createComposer(std::move(hal)).release();
}

再看loadModule的定义,去找HAL library中定义的HAL_MODULE_INFO_SYM结构体变量

[/hardware/interfaces/graphics/composer/2.1/utils/passthrough/include/composer-passthrough/2.1/HwcLoader.h]
static const hw_module_t* loadModule() {
const hw_module_t* module;
int error = hw_get_module(HWC_HARDWARE_MODULE_ID, &module);
if (error) {
ALOGI("falling back to gralloc module");
error = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module);
}
if (error) {
ALOGE("failed to get hwcomposer or gralloc module");
return nullptr;
}
return module;
}

可以看到基本的调用流程:
开机启动 ==> HwcLoader::load() ==> HwcLoader::loadModule() ==> hw_get_module

hw_get_module就是去打开Vendor厂商实现的HWC HAL模块,这个流程本质上还是旧有的HAL打开方式,只是外包装了一层HIDL。
最终得到一个指向HWC module的hw_module_t指针

再回到HwcLoader::load()方法中,接下来就是  createHalWithAdapter ==>  createComposer

先看 createHalWithAdapter 做了哪些工作

[/hardware/interfaces/graphics/composer/2.4/utils/passthrough/include/composer-passthrough/2.4/HwcLoader.h]
// create a ComposerHal instance, insert an adapter if necessary
static std::unique_ptr<hal::ComposerHal> createHalWithAdapter(const hw_module_t* module) {
bool adapted;
hwc2_device_t* device = openDeviceWithAdapter(module, &adapted);
if (!device) {
return nullptr;
}
auto hal = std::make_unique<HwcHal>();
return hal->initWithDevice(std::move(device), !adapted) ? std::move(hal) : nullptr;
}

其中调用了openDeviceWithAdapter去打开 hwc2_device_t

[/hardware/interfaces/graphics/composer/2.1/utils/passthrough/include/composer-passthrough/2.1/HwcLoader.h]
// open hwcomposer2 device, install an adapter if necessary
static hwc2_device_t* openDeviceWithAdapter(const hw_module_t* module, bool* outAdapted) {
if (module->id && std::string(module->id) == GRALLOC_HARDWARE_MODULE_ID) {
*outAdapted = true;
return adaptGrallocModule(module);
}
hw_device_t* device;
int error = module->methods->open(module, HWC_HARDWARE_COMPOSER, &device);
if (error) {
ALOGE("failed to open hwcomposer device: %s", strerror(-error));
return nullptr;
}
int major = (device->version >> 24) & 0xf;
if (major != 2) {
*outAdapted = true;
return adaptHwc1Device(std::move(reinterpret_cast<hwc_composer_device_1*>(device)));
}
*outAdapted = false;
return reinterpret_cast<hwc2_device_t*>(device);
}

openDeviceWithAdapter中调用了open方法

hw_device_t* device;
int error = module->methods->open(module, HWC_HARDWARE_COMPOSER, &device);

这样就获取到了 hwc2_device

typedef struct hwc2_device {
struct hw_device_t common;
void (*getCapabilities)(struct hwc2_device* device, uint32_t* outCount,
int32_t* /*hwc2_capability_t*/outCapabilities);
hwc2_function_pointer_t (*getFunction)(struct hwc2_device* device,
int32_t /*hwc2_function_descriptor_t*/descriptor);
} hwc2_device_t;

回到createHalWithAdapter中再调用initWithDevice及保存到了HwcHal中的mDevice这个变量中

bool initWithDevice(hwc2_device_t* device, bool requireReliablePresentFence) {
// we own the device from this point on
mDevice = device;
….
}

getFunction函数关联到了 vendor 厂商实现的hwc hal中具体实现,这个函数通过函数描述符来获取对应的函数指针。

initDispatch的作用介绍

initDispatch()来初始化HWC通用的函数指针

2.4 <---2.3<---2.2<---2.1 版本的initDispatch()会被调用到来初始化函数指针

在这里就是把mDispatch函数指针和HWC HAL具体实现的方法一一对应起来

注意一下继承关系:
V2_1
class HwcHalImpl : public Hal

V2_2 
class HwcHalImpl : public V2_1::passthrough::detail::HwcHalImpl<Hal>

V2_3
class HwcHalImpl : public V2_2::passthrough::detail::HwcHalImpl<Hal>

V2_4
class HwcHalImpl : public V2_3::passthrough::detail::HwcHalImpl<Hal>

各个版本的HwcHalImpl类中都有定义一个结构体变量mDispatch,这个结构体的成员变量均为函数指针,是以 HWC2_PFN_* 开头的函数指针类型。

struct {
HWC2_PFN_ACCEPT_DISPLAY_CHANGES acceptDisplayChanges;
HWC2_PFN_CREATE_LAYER createLayer;
……
HWC2_PFN_VALIDATE_DISPLAY validateDisplay;
} mDispatch = {};

initDispatch通过调用vendor厂商实现的hwc hal中的getFunction方法获取到descriptor对应的函数指针,并保存到mDispatch的成员中

template <typename T>
bool initDispatch(hwc2_function_descriptor_t desc, T* outPfn) {
auto pfn = mDevice->getFunction(mDevice, desc);
if (pfn) {
*outPfn = reinterpret_cast<T>(pfn);
return true;
} else {
ALOGE("failed to get hwcomposer2 function %d", desc);
return false;
}
}

简单总结下上述的分析内容

1. 开机后启动了一个名字为android.hardware.graphics.composer@2.4-service的服务进程,用于 framework 和 hwc hal 的通信;
    2. 这个composer service启动时,进行了必要的初始化工作,主要就是loadModule和openDevice,在这一过程中获取到hal层实现的函数的指针,
    并保存在了mDispatch中
    3. 之后运行时,framework 呼叫功能时,本质就是通过mDispatch持有的函数指针调用到 hwc hal 的具体实现

Framework 与 hwc hal通信的流程

直接打印调用栈信息来展示这一流程,以其中的setClientTarget这个方法的调用过程为例:

SurfaceFlinger进程的调用栈信息

11-13 00:47:20.455   224   224 E HwcComposer: stackdump:#00 pc 00086f8f  /system/bin/surfaceflinger (android::Hwc2::impl::Composer::setClientTarget(unsigned long long, unsigned int, android::sp<android::GraphicBuffer> const&, int, android::hardware::graphics::common::V1_2::Dataspace, std::__1::vector<android::hardware::graphics::composer::V2_1::IComposerClient::Rect, std::__1::allocator<android::hardware::graphics::composer::V2_1::IComposerClient::Rect> > const&)+182)
11-13 00:47:20.455 224 224 E HwcComposer: stackdump:#01 pc 00096791 /system/bin/surfaceflinger (android::impl::HWComposer::setClientTarget(android::HalDisplayId, unsigned int, android::sp<android::Fence> const&, android::sp<android::GraphicBuffer> const&, android::hardware::graphics::common::V1_2::Dataspace)+408)
11-13 00:47:20.455 224 224 E HwcComposer: stackdump:#02 pc 0008e881 /system/bin/surfaceflinger (android::FramebufferSurface::advanceFrame()+332)
11-13 00:47:20.455 224 224 E HwcComposer: stackdump:#03 pc 00122a55 /system/bin/surfaceflinger (android::compositionengine::impl::RenderSurface::queueBuffer(android::base::unique_fd_impl<android::base::DefaultCloser>)+436)
11-13 00:47:20.455 224 224 E HwcComposer: stackdump:#04 pc 001069ed /system/bin/surfaceflinger (android::compositionengine::impl::Output::finishFrame(android::compositionengine::CompositionRefreshArgs const&)+168)
11-13 00:47:20.455 224 224 E HwcComposer: stackdump:#05 pc 00100c89 /system/bin/surfaceflinger (android::compositionengine::impl::Display::finishFrame(android::compositionengine::CompositionRefreshArgs const&)+76)
11-13 00:47:20.455 224 224 E HwcComposer: stackdump:#06 pc 001054ef /system/bin/surfaceflinger (android::compositionengine::impl::Output::present(android::compositionengine::CompositionRefreshArgs const&)+114)
11-13 00:47:20.455 224 224 E HwcComposer: stackdump:#07 pc 000ff727 /system/bin/surfaceflinger (android::compositionengine::impl::CompositionEngine::present(android::compositionengine::CompositionRefreshArgs&)+146)
11-13 00:47:20.455 224 224 E HwcComposer: stackdump:#08 pc 000d600b /system/bin/surfaceflinger (android::SurfaceFlinger::onMessageRefresh()+1530)
11-13 00:47:20.455 224 224 E HwcComposer: stackdump:#09 pc 000d570d /system/bin/surfaceflinger (android::SurfaceFlinger::onMessageInvalidate(long long, long long)+8784)
11-13 00:47:20.455 224 224 E HwcComposer: stackdump:#10 pc 000b9907 /system/bin/surfaceflinger (android::impl::MessageQueue::Handler::handleMessage(android::Message const&)+94)
11-13 00:47:20.456 224 224 E HwcComposer: stackdump:#11 pc 00010179 /system/lib/libutils.so (android::Looper::pollInner(int)+288)
11-13 00:47:20.456 224 224 E HwcComposer: stackdump:#12 pc 0000ffff /system/lib/libutils.so (android::Looper::pollOnce(int, int*, int*, void**)+62)
11-13 00:47:20.456 224 224 E HwcComposer: stackdump:#13 pc 000b9dd1 /system/bin/surfaceflinger (android::impl::MessageQueue::waitMessage()+56)
11-13 00:47:20.456 224 224 E HwcComposer: stackdump:#14 pc 000cc50d /system/bin/surfaceflinger (android::SurfaceFlinger::run()+6)
11-13 00:47:20.456 224 224 E HwcComposer: stackdump:#15 pc 000ff253 /system/bin/surfaceflinger (main+1182)
11-13 00:47:20.456 224 224 E HwcComposer: stackdump:#16 pc 0003253b /apex/com.android.runtime/lib/bionic/libc.so (__libc_init+54)

HWC HAL端的调用栈信息 

11-08 06:04:30.920   339   339 E hwc_display: stackdump:#00 pc 000287cb  /vendor/lib/hw/hwcomposer.stark.so (Display::setClientTarget(native_handle const*, int, int, hwc_region)+90)
11-08 06:04:30.920 339 339 E hwc_display: stackdump:#01 pc 00023255 /vendor/lib/hw/hwcomposer.stark.so (hwc_setClientTarget(hwc2_device*, unsigned long long, native_handle const*, int, int, hwc_region)+56)
11-08 06:04:30.920 339 339 E hwc_display: stackdump:#02 pc 00007d93 /vendor/bin/hw/android.hardware.graphics.composer@2.4-service (android::hardware::graphics::composer::V2_1::passthrough::detail::HwcHalImpl<android::hardware::graphics::composer::V2_4::hal::ComposerHal>::setClientTarget(unsigned long long, native_handle const*, int, int, std::__1::vector<hwc_rect, std::__1::allocator<hwc_rect> > const&)+40)
11-08 06:04:30.920 339 339 E hwc_display: stackdump:#03 pc 00010b11 /vendor/bin/hw/android.hardware.graphics.composer@2.4-service (android::hardware::graphics::composer::V2_1::hal::ComposerCommandEngine::executeSetClientTarget(unsigned short)+244)
11-08 06:04:30.920 339 339 E hwc_display: stackdump:#04 pc 0000ed3f /vendor/bin/hw/android.hardware.graphics.composer@2.4-service (android::hardware::graphics::composer::V2_1::hal::ComposerCommandEngine::execute(unsigned int, android::hardware::hidl_vec<android::hardware::hidl_handle> const&, bool*, unsigned int*, android::hardware::hidl_vec<android::hardware::hidl_handle>*)+86)
11-08 06:04:30.920 339 339 E hwc_display: stackdump:#05 pc 0000d0a1 /vendor/bin/hw/android.hardware.graphics.composer@2.4-service (android::hardware::graphics::composer::V2_1::hal::detail::ComposerClientImpl<android::hardware::graphics::composer::V2_3::IComposerClient, android::hardware::graphics::composer::V2_3::hal::ComposerHal>::executeCommands(unsigned int, android::hardware::hidl_vec<android::hardware::hidl_handle> const&, std::__1::function<void (android::hardware::graphics::composer::V2_1::Error, bool, unsigned int, android::hardware::hidl_vec<android::hardware::hidl_handle> const&)>)+84)
11-08 06:04:30.920 339 339 E hwc_display: stackdump:#06 pc 0001df97 /vendor/lib/android.hardware.graphics.composer@2.2.so (android::hardware::graphics::composer::V2_2::BnHwComposerClient::_hidl_executeCommands_2_2(android::hidl::base::V1_0::BnHwBase*, android::hardware::Parcel const&, android::hardware::Parcel*, std::__1::function<void (android::hardware::Parcel&)>)+294)
11-08 06:04:30.920 339 339 E hwc_display: stackdump:#07 pc 0003182f /vendor/lib/android.hardware.graphics.composer@2.4.so (android::hardware::graphics::composer::V2_4::BnHwComposerClient::onTransact(unsigned int, android::hardware::Parcel const&, android::hardware::Parcel*, unsigned int, std::__1::function<void (android::hardware::Parcel&)>)+1198)
11-08 06:04:30.920 339 339 E hwc_display: stackdump:#08 pc 000546d9 /apex/com.android.vndk.v31/lib/libhidlbase.so (android::hardware::BHwBinder::transact(unsigned int, android::hardware::Parcel const&, android::hardware::Parcel*, unsigned int, std::__1::function<void (android::hardware::Parcel&)>)+96)
11-08 06:04:30.920 339 339 E hwc_display: stackdump:#09 pc 000536a7 /apex/com.android.vndk.v31/lib/libhidlbase.so (android::hardware::IPCThreadState::getAndExecuteCommand()+974)
11-08 06:04:30.920 339 339 E hwc_display: stackdump:#10 pc 00053239 /apex/com.android.vndk.v31/lib/libhidlbase.so (android::hardware::IPCThreadState::joinThreadPool(bool)+56)
11-08 06:04:30.920 339 339 E hwc_display: stackdump:#11 pc 000070fb /vendor/bin/hw/android.hardware.graphics.composer@2.4-service (main+270)
11-08 06:04:30.920 339 339 E hwc_display: stackdump:#12 pc 0003253b /apex/com.android.runtime/lib/bionic/libc.so (__libc_init+54)

发起端:

[/frameworks/native/services/surfaceflinger/DisplayHardware/ComposerHal.cpp]
Error Composer::setClientTarget(Display display, uint32_t slot,
const sp<GraphicBuffer>& target,
int acquireFence, Dataspace dataspace,
const std::vector<IComposerClient::Rect>& damage)
{
mWriter.selectDisplay(display);
const native_handle_t* handle = nullptr;
if (target.get()) {
handle = target->getNativeBuffer()->handle;
}
mWriter.setClientTarget(slot, handle, acquireFence, dataspace, damage);
return Error::NONE;
}

中转站:

[/hardware/interfaces/graphics/composer/2.1/utils/command-buffer/include/composer-command-buffer/2.1/ComposerCommandBuffer.h]
void setClientTargetInternal(...) {
beginCommand(IComposerClient::Command::SET_CLIENT_TARGET, length);
...
endCommand();
}
跨进程了
[/hardware/interfaces/graphics/composer/2.1/utils/hal/include/composer-hal/2.1/ComposerCommandEngine.h]
virtual bool executeCommand(IComposerClient::Command command, uint16_t length) {
switch (command) {
...
case IComposerClient::Command::SET_CLIENT_TARGET:
return executeSetClientTarget(length);
}
} bool executeSetClientTarget(uint16_t length) {
...
err = mHal->setClientTarget(mCurrentDisplay, clientTarget, fence, dataspace, damage);
...
}

处理终端:

Vendor厂商实现的HAL,具体实现setClientTarget的功能



Android 12(S) 图像显示系统 - HWC HAL 初始化与调用流程的更多相关文章

  1. Android 12(S) 图像显示系统 - SurfaceFlinger之VSync-上篇(十六)

    必读: Android 12(S) 图像显示系统 - 开篇 一.前言 为了提高Android系统的UI交互速度和操作的流畅度,在Android 4.1中,引入了Project Butter,即&quo ...

  2. Android 12(S) 图像显示系统 - SurfaceFlinger GPU合成/CLIENT合成方式 - 随笔1

    必读: Android 12(S) 图像显示系统 - 开篇 一.前言 SurfaceFlinger中的图层选择GPU合成(CLIENT合成方式)时,会把待合成的图层Layers通过renderengi ...

  3. Android 12(S) 图像显示系统 - drm_hwcomposer 简析(上)

    必读: Android 12(S) 图像显示系统 - 开篇 前言 Android源码中有包含drm_hwcomposer:/external/drm_hwcomposer/ drm_hwcompose ...

  4. Android 12(S) 图像显示系统 - GraphicBuffer同步机制 - Fence

    必读: Android 12(S) 图像显示系统 - 开篇 一.前言 前面的文章中讲解Android BufferQueue的机制时,有遇到过Fence,但没有具体讲解.这篇文章,就针对Fence这种 ...

  5. Android 12(S) 图像显示系统 - drm_hwcomposer 简析(下)

    必读: Android 12(S) 图像显示系统 - 开篇 合成方式 合成类型的定义:/hardware/interfaces/graphics/composer/2.1/IComposerClien ...

  6. Android 12(S) 图像显示系统 - 基础知识之 BitTube

    必读: Android 12(S) 图像显示系统 - 开篇 一.基本概念 在Android显示子系统中,我们会看到有使用BitTube来进行跨进程数据传递.BitTube的实现很简洁,就是一对&quo ...

  7. Android 12(S) 图像显示系统 - SurfaceFlinger 之 VSync - 中篇(十七)

    必读: Android 12(S) 图像显示系统 - 开篇 1 前言 这一篇文章,将继续讲解有关VSync的知识,前一篇文章 Android 12(S) 图像显示系统 - SurfaceFlinger ...

  8. Android 12(S) 图形显示系统 - 解读Gralloc架构及GraphicBuffer创建/传递/释放(十四)

    必读: Android 12(S) 图形显示系统 - 开篇 一.前言 在前面的文章中,已经出现过 GraphicBuffer 的身影,GraphicBuffer 是Android图形显示系统中的一个重 ...

  9. Android 12(S) 图形显示系统 - 示例应用(二)

    1 前言 为了更深刻的理解Android图形系统抽象的概念和BufferQueue的工作机制,这篇文章我们将从Native Level入手,基于Android图形系统API写作一个简单的图形处理小程序 ...

随机推荐

  1. python基础练习题(题目 求s=a+aa+aaa+aaaa+aa…a的值,其中a是一个数字。例如2+22+222+2222+22222(此时共有5个数相加),几个数相加由键盘控制)

    day11 --------------------------------------------------------------- 实例018:复读机相加 题目 求s=a+aa+aaa+aaa ...

  2. Day 005:PAT练习--1047. 编程团体赛(20)

    编程团体赛的规则为:每个参赛队由若干队员组成:所有队员独立比赛:参赛队的成绩为所有队员的成绩和:成绩最高的队获胜.现给定所有队员的比赛成绩,请你编写程序找出冠军队. 输入格式: 输入第一行给出一个正整 ...

  3. nacos 详细介绍(一)

    一.Nacos介绍 Nacos是SpringCloudAlibaba架构中最重要的组件. Nacos 是一个更易于帮助构建云原生应用的动态服务发现.配置和服务管理平台,提供注册中心.配置中心和动态 D ...

  4. celery介绍、架构、快速使用、包结构,celery执行异步、延迟、定时任务,django中使用celery,定时更新首页轮播图效果实现,数据加入redis缓存的坑及解决

    今日内容概要 celery介绍,架构 celery 快速使用 celery包结构 celery执行异步任务 celery执行延迟任务 celery执行定时任务 django中使用celery 定时更新 ...

  5. 如何对用户的绑定的身份证真实性进行实名认证(java)

    现在随着对用户实名制的要求,因此用户提交的身份证信息经查需要检查是否为真实信息,我们需要对用户提交的身份证信息进行核验,具体操作步骤如下: 第一步 到认证平台注册账号:云亿互通--实名认证服务 (yu ...

  6. ucore lab7 同步互斥机制 学习笔记

    管程的设计实在是精妙,初看的时候觉得非常奇怪,这混乱的进程切换怎么能保证同一时刻只有一个进程访问管程?理清之后大为赞叹,函数中途把前一个进程唤醒后立刻把自己挂起,完美切换.后一个进程又在巧妙的时机将自 ...

  7. Linux-编译安装http-实验

    准备工作 1.关闭防火墙和SELinux 2.基础安装的系统,安装以下命令 yum install gcc make autoconf gcc-c++ glibc glibc-devel pcre p ...

  8. ONNX Runtime 源码阅读:Graph::SetGraphInputsOutputs() 函数

    目录 前言 正文 总结 前言 为了深入理解ONNX Runtime的底层机制,本文将对 Graph::SetGraphInputsOutputs() 的代码逐行分析. 正文 首先判断Graph是否从O ...

  9. 2.SSH协议常见问题排错

    一.SSH登录linux服务器密码验证很慢 现象:ssh登录服务器后,输入密码时,验证要等10秒左右,很慢.登录上去后速度正常,这种情况主要有两种可能的原因: 1. DNS反向解析的问题 OpenSS ...

  10. 红旗 Linux 桌面操作系统11来了:支持国产自主CPU,全新UI风格设计,兼容面广...

    链接:https://reurl.cc/g8ke9X 红旗Linux桌面操作系统11将于1月10日开放预览版的下载,新版本具有良好的硬件兼容,支持多款国产自主CPU品牌,同时还具有丰富的外设支持及海量 ...