解决 GNOME 桌面环境下 Chromium 系浏览器全屏时有横线闪烁
大前提
本文假设你使用的是 GNOME (Wayland),且使用 Xwayland 运行 Chromium 系浏览器。
TL;DR
安装 gnome-shell-extension-disable-unredirect 这个 GNOME 插件并启用。如果从 AUR 安装可能需要自己改一下兼容 GNOME 版本号。
分析
经过了数年的努力,Linux 桌面在 Wayland 的环境下,大部分软件都可以正常使用了。Chromium 系浏览器虽然可以通过设 --ozone-platform-hint=auto 来启用 Native Wayland,但硬件加速就没法工作了,大概是因为我用的是 NVIDIA 卡的缘故。
默认情况下,Chromium 系浏览器都是运行在 Xwayland 下,且启用硬件加速。在播放 YouTube 或哔哩哔哩视频时,如果不全屏,视频可以正常播放。如果进入全屏模式,过几秒画面上就会出现闪烁的横线。
互联网上的大部分教程都是让关闭硬件加速或者传入各种奇奇怪怪的 Chromium flags。关闭硬件加速是治标不治本的行为,对于日常网页浏览影响不大,但是会显著增加 CPU 负担,尤其是播放 4K 视频的情况下。各种奇怪的 flags,如 --ignore-gpu-blocklist、--use-gl=egl 以及 Arch Linux Wiki 上有关 Chromium 硬件加速的 flags,还有 VAAPI,测试下来基本没有效果,部分似乎有效果的 flags 都是误打误撞把硬件加速禁用了。
经过众多搜索后,我意识到这似乎是一个垂直同步问题,虽然画面上是跳动的横线,不像 Windows 下的画面撕裂是错位的样子,但应该和垂直同步有关。于是我参考了 How do I enable desktop Vsync on GNOME Wayland with NVIDIA driver?,并尝试了 gnome-shell-extension-disable-unredirect,这是一个 GNOME 扩展,问题解决了。
我的猜测是 GNOME 在浏览器全屏后不再强制对窗口进行画面转发和同步,而是由窗口自己负责,进而导致浏览器出现画面撕裂。Chromium 系浏览器在 Linux 下不会自行垂直同步的问题已经有很长时间了,但一直没有解决过。gnome-shell-extension-disable-unredirect 仅仅是强制 GNOME 继续接管全屏窗口,并没有解决垂直同步问题。
在搜索过程中还发现了 mutter-dynamic-buffering,这个包把 GNOME 混成器 Mutter 替换成开启双重或三重缓冲的版本,但这样对系统包的介入性过强,因此没有尝试。
我用的不是 GNOME!
对于其他桌面环境,解决思路应该类似,都是打开自己的桌面混成器的垂直同步或三重缓冲功能。
遗留问题
虽然在 chrome://gpu 里显示 Hardware accelerated,但播放视频时在 F12 控制台的 Media 选项卡里并没有看到调用显卡解码,依然是 FFmpegVideoDecoder 且 Hardware Decoder 为 false。