@
mayli #25
现代操作系统的显示逻辑是 C/S 架构的,应用程序也就是客户端会申请一块显示区域作为 client area 用于显示(相对应的 host area 一般是标题栏、边框这些)。
没有硬件加速的情况下,客户端区域就是各种界面库 API 或者文字 API 绘制,直接把绘制结果以像素的形式填充到客户端区域。操作系统的窗口合成器( compositor )把桌面上所有应用的显示区域做叠加合成,交给显卡完成最终显示。
有硬件加速的情况下,比如窗口中部分区域播放视频,客户端依旧会声明一块显示区域,但中间挖出一部分,并表示这部分不由客户端负责。窗口合成器也会忽略这一部分(但是还会判断遮挡关系),此时显卡的 framebuffer 就是两部分,一部分是窗口合成器给的去掉视频区域的显示数据,另一部分是视频解码单元给的视频数据。
上个回复里说 3D 其实不准确,因为所有最终的渲染都是走的 3D 单元。在显卡看来,3D 单元就是渲染单元。这个语境下的 2D 一般是指无加速,就是客户端把结果绘制完了,合成器直接拿像素数据,而 3D 有加速就是绘制 API 直接在显示区域上进行操作。这里细节我不是很确定,但大致思路就是浏览器把所有绘制 API 后端都用 3D 指令来实现了,整个浏览器内部就是一个巨大的 3D 显示,skia 文字渲染引擎也是 3D 指令在页面上显示文字。
我上个回复里描述的 3D 渲染行为,是根据风扇狂转推测的浏览器的行为。因为我是 Linux 用户,所以对硬件加速感知很深。每个浏览器都有自己如何用显卡硬件单元完成加速的实现逻辑,最终效率和性能也差别很大。目前 bili 的弹幕功能是基于 css3 的,之前有过基于 canvas 的版本但可能是因为效率问题弃用了。
目前 Firefox/Chrome/Chromium 三个浏览器的表现都是不一样的:
- Firefox 就是我上个帖子里说的模式,会调用视频解码单元,但对于 css3 的加速就很弱。从显卡资源占用上说,比较大可能就是没有优化,直接在透明层上叠加。
- Chrome 官方打包版本对于硬件加速支持很不稳定,有些版本正常有些版本就没了。
- Chromium 主要看发行版适配,官方源会打针对自己发行版的补丁。在解码器和补丁都正常的情况下,效果是最好的。首先视频本身还会走硬件解码,但是 css3 特效并非 3D 透明层,而是调用 video enhance 硬件单元。这个硬件单元的作用原本是用作视频播放去噪点、锐化等功能的,Chromium 的实现里 css3 相当于实时调整原视频,所以大幅降低了 3D 渲染单元的负载。