硬件混合渲染器 (HWC) HAL 用于合成从 SurfaceFlinger 接收的图层,从而减少 OpenGL ES (GLES) 和 GPU 执行的合成量。

HWC 可以抽象出叠加层和 2D 位块传送器等对象来合成 Surface,并与专门的窗口合成硬件进行通信以合成窗口。使用 HWC 来合成窗口,而不是让 SurfaceFlinger 与 GPU 进行合成。大多数 GPU 都未针对合成进行过优化,当 GPU 合成来自 SurfaceFlinger 的图层时,应用就无法使用 GPU 进行自我渲染。

HWC 实现应该支持:

  • 至少 4 个叠加层:

    • 状态栏
    • 系统栏
    • 应用
    • 壁纸/背景
  • 大于屏幕的图层(例如壁纸)
  • 同时预乘的每像素 Alpha 混合和每平面 Alpha 混合
  • 受保护视频播放的硬件路径
  • RGBA 打包顺序、YUV 格式以及平铺、重排和步幅属性

要实现 HWC,请执行以下操作:

  1. 实现非运行的 HWC,并将所有合成工作发送到 GLES。
  2. 实现一种算法,以逐步将合成委托给 HWC。例如,仅将前 3 个或前 4 个 Surface 委托给 HWC 的叠加硬件。
  3. 优化 HWC。这可能包括以下操作:
    • 选择可以最大限度提高从 GPU 移除的负载的 Surface,并将其发送到 HWC。
    • 检测屏幕是否正在更新。如果不是,则将合成委托给 GLES 而不是 HWC,以节省电量。当屏幕再次更新时,继续将合成分载到 HWC。
    • 为常见用例做准备,例如:
      • 主屏幕,包括状态栏、系统栏、应用窗口和动态壁纸
      • 纵向和横向模式下的全屏游戏
      • 带有字幕和播放控件的全屏视频
      • 受保护的视频播放
      • 分屏多窗口

注意:用例应针对常规可预测的用途而不是边缘用例,以便最大限度地提高优化益处。

HWC 基元

HWC 提供了两个基元(图层和屏幕)来表示合成工作及其与屏幕硬件的交互。此外,HWC 还提供对 VSYNC 的控制,以及对 SurfaceFlinger 的回调,用于通知它何时发生 VSYNC 事件。

HIDL 接口

Android 8.0 及更高版本使用一个名为混合渲染器 HAL 的 HIDL 接口,用于在 HWC 和 SurfaceFlinger 之间绑定 IPC。混合渲染器 HAL 取代了旧版 hwcomposer2.h 接口。如果供应商提供 HWC 的混合渲染器 HAL 实现,则混合渲染器 HAL 将直接接受来自 SurfaceFlinger 的 HIDL 调用。如果供应商提供 HWC 的旧版实现,混合渲染器 HAL 将从 hwcomposer2.h 加载函数指针,从而将 HIDL 调用转发到函数指针调用中。

HWC 提供相应函数来确定给定屏幕的属性;在不同的屏幕配置(例如 4k 或 1080p 分辨率)和颜色模式(例如原生颜色或真正的 sRGB)之间切换;以及打开、关闭屏幕或将其切换到低功率模式(如果支持)。

函数指针

如果供应商直接实现混合渲染器 HAL,则 SurfaceFlinger 会通过 HIDL IPC 调用其函数。例如,要创建图层,SurfaceFlinger 会在混合渲染器 HAL 上调用 createLayer()

如果供应商实现 hwcomposer2.h 接口,则混合渲染器 HAL 会调用 hwcomposer2.h 函数指针。在 hwcomposer2.h 注释中,HWC 接口函数由 lowerCamelCase 名称引用,这些名称并未作为命名的字段存在于接口中。几乎每个函数都是通过使用 hwc2_device_t 提供的 getFunction 请求函数指针来进行加载。例如,函数 createLayer 是一个 HWC2_PFN_CREATE_LAYER 类型的函数指针,当枚举值 HWC2_FUNCTION_CREATE_LAYER 传递到 getFunction 中时便会返回该指针。

有关混合渲染器 HAL 函数和 HWC 直通式函数的详细文档,请参阅 composer。有关 HWC 函数指针的详细文档,请参阅 hwcomposer2.h。

图层和屏幕句柄

图层和屏幕由 HWC 生成的句柄操纵。这些句柄对 SurfaceFlinger 而言是不透明的。

当 SurfaceFlinger 要创建新图层时,它会调用 createLayer,该函数会针对直接实现返回 Layer 类型,或者针对直通式实现返回 hwc2_layer_t 类型。当 SurfaceFlinger 要修改该图层的属性时,它会将该 hwc2_layer_t 值以及进行修改所需的任何其他信息传递给相应的修改函数。hwc2_layer_t 类型的大小足以容纳一个指针或一个索引。

物理屏幕是通过热插拔创建的。在热插拔物理屏幕时,HWC 会创建一个句柄并通过热插拔回调将该句柄传递给 SurfaceFlinger。虚拟屏幕是由通过调用 createVirtualDisplay() 来请求屏幕的 SurfaceFlinger 创建的。如果 HWC 支持虚拟屏幕合成,则会返回一个句柄。然后,SurfaceFlinger 将屏幕的合成工作委托给 HWC。如果 HWC 不支持虚拟屏幕合成,则 SurfaceFlinger 会创建句柄并合成屏幕。

屏幕合成操作

如果 SurfaceFlinger 具有可合成的新内容,则会唤醒,且每个 VSYNC 唤醒一次。该新内容可以是来自应用的新图像缓冲区,也可以是一个或多个图层的属性更改。当 SurfaceFlinger 唤醒时,它将执行以下步骤:

  1. 处理事务(如果存在)。
  2. 如果存在新的图形缓冲区,则将其锁定。
  3. 如果步骤 1 或 2 导致显示内容更改,则执行新的合成。

为了执行新的合成,SurfaceFlinger 会创建和销毁图层或修改图层状态(如适用)。它还会使用 setLayerBuffer 或 setLayerColor 等调用,用图层的当前内容来更新图层。更新所有图层之后,SurfaceFlinger 会调用 validateDisplay,以告诉 HWC 检查各个图层的状态,并确定如何进行合成。尽管在某些情况下,SurfaceFlinger 会通过 GPU 回退来合成图层,但在默认情况下,SurfaceFlinger 会尝试配置每个图层,以使相应图层由 HWC 进行合成。

在调用 validateDisplay 之后,SurfaceFlinger 会调用 getChangedCompositionTypes,以查看 HWC 是否需要在执行合成之前更改任何图层的合成类型。要接受这些更改,SurfaceFlinger 需要调用 acceptDisplayChanges

如果已将任何图层标记为进行 SurfaceFlinger 合成,SurfaceFlinger 会将这些图层合成到目标缓冲区中。然后,SurfaceFlinger 通过调用 setClientTarget 将该缓冲区提供给屏幕,以便缓冲区可以在屏幕上显示,或者进一步与未标记为进行 SurfaceFlinger 合成的图层合成。如果没有将任何图层标记为进行 SurfaceFlinger 合成,则 SurfaceFlinger 会跳过合成步骤。

最后,SurfaceFlinger 会调用 presentDisplay,以告知 HWC 完成合成过程并显示最终结果。

多个屏幕

Android 10 支持多个物理屏幕。在设计要在 Android 7.0 及更高版本上使用的 HWC 实现时,还存在一些 HWC 定义中并不存在的限制:

  • 假设只有一个内部屏幕。内部屏幕是初始热插拔在启动期间报告的屏幕。内部屏幕在热插拔后无法断开连接。
  • 在设备的正常操作期间,除了内部屏幕之外,还可以热插拔任意数量的外部屏幕。该框架假设,在热插拔第一个内部屏幕之后,所有热插拔操作都是在外部屏幕上进行,因此如果添加了更多内部屏幕,它们将被错误地归类为 Display.TYPE_HDMI,而不是 Display.TYPE_BUILT_IN

尽管上述 SurfaceFlinger 操作按屏幕执行,但会对所有活动的屏幕依序执行这些操作,即使只更新了一个屏幕的内容也不例外。

例如,如果更新了外部屏幕,则顺序为:

// In Android 9 and lower:// Update state for internal display
// Update state for external display
validateDisplay(<internal display>)
validateDisplay(<external display>)
presentDisplay(<internal display>)
presentDisplay(<external display>)// In Android 10 and higher:// Update state for internal display
// Update state for external display
validateInternal(<internal display>)
presentInternal(<internal display>)
validateExternal(<external display>)
presentExternal(<external display>)

虚拟屏幕合成

虚拟屏幕合成与外部屏幕合成类似。虚拟屏幕合成与物理屏幕合成之间的区别在于,虚拟屏幕将输出发送到 Gralloc 缓冲区,而不是发送到屏幕。硬件混合渲染器 (HWC) 将输出内容写入缓冲区,提供完成栅栏信号,并将缓冲区发送给使用方(例如视频编码器、GPU、CPU 等)。如果显示通道写入内存,虚拟屏幕便可使用 2D/位块传送器或叠加层。

模式

在 SurfaceFlinger 调用 validateDisplay() HWC 方法之后,每个帧处于以下三种模式之一:

  • GLES - GPU 合成所有图层,直接写入输出缓冲区。HWC 不参与合成。
  • MIXED - GPU 将一些图层合成到帧缓冲区,由 HWC 合成帧缓冲区和剩余的图层,直接写入输出缓冲区。
  • HWC - HWC 合成所有图层并直接写入输出缓冲区。

输出格式

虚拟屏幕的缓冲区输出格式取决于其模式:

  • GLES 模式 - EGL 驱动程序在 dequeueBuffer() 中设置输出缓冲区格式,通常为 RGBA_8888。使用方必须能够接受该驱动程序设置的输出格式,否则便无法读取缓冲区。
  • MIXED 和 HWC 模式 - 如果使用方需要 CPU 访问权限,则由使用方设置格式。否则,格式将为 IMPLEMENTATION_DEFINED,Gralloc 会根据使用标记设置最佳格式。例如,如果使用方是视频编码器,则 Gralloc 会设置 YCbCr 格式,而 HWC 可以高效地写入该格式。

注意:Android 10 取消了有关 eglSwapBuffers() 在渲染开始后将缓冲区移出队列的要求。缓冲区可能会立即退出队列。

同步栅栏

同步栅栏是 Android 图形系统的关键部分。栅栏允许 CPU 工作与并行的 GPU 工作相互独立进行,仅在存在真正的依赖关系时才会阻塞。

例如,当应用提交在 GPU 上生成的缓冲区时,它还将提交一个同步栅栏对象。当 GPU 完成写入缓冲区的操作时,该栅栏会变为有信号状态。

HWC 要求 GPU 在显示缓冲区之前完成写入缓冲区的操作。同步栅栏通过包含缓冲区的图形管道传递,并在缓冲区写入完成时发出信号。在显示缓冲区之前,HWC 会检查同步栅栏是否已发出信号,如果有,则显示缓冲区。

如需详细了解同步栅栏,请参阅硬件混合渲染器集成。

硬件混合渲染器 (HWC)相关推荐

  1. HWC与GPU混合渲染

    硬件混合渲染器 (HWC) HAL 用于确定通过可用硬件来合成缓冲区的最有效方法.作为 HAL,其实现是特定于设备的,而且通常由显示硬件原始设备制造商 (OEM) 完成. 当您考虑使用叠加平面时,很容 ...

  2. HWC与GPU混合渲染概念详解

    硬件混合渲染器 (HWC) HAL 用于确定通过可用硬件来合成缓冲区的最有效方法.作为 HAL,其实现是特定于设备的,而且通常由显示硬件原始设备制造商 (OEM) 完成. 当您考虑使用叠加平面时,很容 ...

  3. 3dsmax动画渲染速度慢,渲染结果高糊的解决,图片渲染清晰,但变成动画就糊(Quicksilver硬件渲染器)

    最近刚学3dmax,渲染方面有很多问题 150帧渲了快6个小时,最后结果还很糊,根本用不了 而且明明在渲染过程中看到的每帧的图片都是清晰的,但到视频里就糊了 最后摸索出了一些解决方法,不知道好不好,就 ...

  4. D5渲染器电脑硬件配置Vol.1——操作系统丨显卡

    D5 有什么电脑配置需求?电脑配置明明够了却带不动D5?显卡好多分类我需要什么显卡?...... 许多刚接触 D5 的用户对 D5 需要的电脑硬件配置疑问较多,这次一个合集解答所有问题,后续会根据内容 ...

  5. c4d支持mac系统渲染器有哪些_C4D常用的4大主流渲染器如何选择与比较 (OC/RS/VR/阿诺德)...

    这里说下支持C4D的几大主流渲染器,我们比较熟悉的octane .阿诺德.Redshift.vray这四大主流渲染器.以及我个人看法便于各位参考选择~ 对于渲染器我是一直觉得除了C4D标准渲染器,一定 ...

  6. C4D的GPU渲染器Octane和Redshift的渲染对比

    对CG圈创作人员来说,除制作软件外渲染器是平时接触最多的一类软件,用渲染器进行渲染的过程,就是把制作软件里的预览效果变到融合材质.光照.物理特性的最终效果的这个过程,这是CG制作中最重要的一步,关乎着 ...

  7. SoftRendererRenderPipeline(从迷你光栅化软渲染器的实现看渲染流水线)

    简介 这是可能一篇没有什么实际作用的文章,因为没有任何shader效果实现,整篇文章到最后,我只实现了一个旋转的立方体(o(╯□╰)o,好弱),和游戏引擎渲染的万紫千红的3D世界显得有很大落差,仿佛一 ...

  8. 非常棒的13款3DMax渲染器插件推荐给大家

    3Ds Max 可能是具有最多可与其集成的外部渲染引擎的 3D 软件包. 今天我们将看看 13 个最好的 3Ds max 渲染插件,我们将从以下列表开始: 13- Radeon ProRender P ...

  9. 实时渲染、离线渲染、实时云渲染、混合渲染是什么?

    渲染,就是将 3D 模型转换成 2D 图像,并最终呈现在屏幕上的过程.虽然这里只有一句话,但是这一句话里面包含了太多的数学.物理和计算机方面的知识,它描述了我们用计算机来虚拟化真实世界的基本逻辑.渲染 ...

最新文章

  1. Servlet,过滤器,监听器,拦截器的区别
  2. java 数组集合转换_Java 实例 – 集合转数组
  3. python读取txt文件第一行-python读取文本文件数据
  4. 【渝粤教育】电大中专测量学 (3)作业 题库
  5. 首次披露!阿里线下智能方案进化史
  6. nginx下部署vue项目概览 - (资源篇)
  7. Mysql过长的Sql语句优化:在循环中调用存储过程运行动态语句
  8. 【工程项目经验】github定位到历史版本(历史commit点)
  9. [Java] 蓝桥杯ALGO-103 算法训练 完数
  10. ajax请求的五个媒体查询,七个高度有效的媒体查询技巧
  11. 计算机系统集成 行业标准,行业标准信息服务平台
  12. 时间序列深度学习:状态 LSTM 模型预测太阳黑子(中)
  13. ubuntu 中安装 Redis
  14. pythonurllib爬虫教学_python爬虫基础教程:urllib库(一)
  15. SSL自签名证书制作方法
  16. java解方程_JAVA解N元一次方程组(矩阵) | 学步园
  17. 简述python的安装过程_安装Python-3.5.2过程中常见的几种错误
  18. Entry name ‘META-INF/MANIFEST.MF‘ collided
  19. 微信群聊小机器人的服务器,微信群里自动聊天的机器人是怎么弄的?有没有操作教程?...
  20. 怎么选择.net培训机构

热门文章

  1. Android DLNA投屏-基本原理
  2. iOS滚动的导航条(仿网易新闻)
  3. Oracle数据库之同义词(SYNONYM)使用
  4. XMLHttpRequest简介
  5. 单点登录、统一认证解决方案(一)
  6. Jetson嵌入式系列模型部署-3
  7. 学习指南者STM32F103第一天——LED控制
  8. 编程参考 - va_list的定义问题
  9. drl 规则语言 语法_C语言基本语法规则
  10. 目前计算机常用的硬盘类型,干货大放送,电脑硬盘分类你知道几个?