如果你是一个电脑游戏玩家,那么你可能最需要的就是不断更新你的GPU驱动程序,无论你是AMD还是NVIDIA的GPU。更新图形驱动程序可以带来更好的性能和与新游戏的兼容性,因此没有真正的理由不更新它们。此外,在Windows上更新图形驱动程序非常容易,可以通过设备管理器手动更新,也可以通过GPU供应商提供的程序自动更新。
另一方面,Android并没有提供一种简单的方式来更新手机或平板电脑的图形驱动程序。事实上,除了获得根访问权限,在大多数设备上几乎不可能自己更新图形驱动程序。在本周的《安卓甜点点评》中,我将深入探讨GPU驱动程序是如何分发的,谷歌和硅厂商是如何试图让它们更容易更新的,以及第三方开发者是如何克服安卓的局限性的。
感谢您注册安卓Edge通讯。每周,我的安卓甜点点评专栏都会分享有关安卓平台的最新消息,这对系统工程师、应用程序开发人员和超级用户都很重要。
与AMD和NVIDIA不同,安卓设备中最受欢迎的两款GPU的制造商高通和Arm与消费者没有直接关系。你不能像制造个人电脑那样制造自己的智能手机,所以你永远不会直接给高通公司或花钱购买GPU。相反,高通公司将其GPU作为片上系统(SoC)的一部分出售给智能手机原始设备制造商,而Arm则将其GPU设计许可给联发科等硅供应商,后者反过来使用这些GPU设计SoC。因此,高通公司距离最终掌握在消费者手中的智能手机只有一步之遥,而Arm则只有两步之遥。
由于与消费者没有直接关系,这些移动GPU制造商几乎没有动力向公众提供更新的图形驱动程序包。相反,GPU驱动程序仅作为主板支持包(BSP)的一部分直接分发给智能手机OEM。正如我之前在关于Google Requirements Freeze程序的文章中所解释的,BSP是一个包含源代码和预构建二进制文件的包,这些代码和二进制文件是在特定芯片组平台上安装和运行Android(或其他操作系统)所需的。BSP包含硬件抽象层(HAL)和驱动程序,Android操作系统需要与设备硬件(包括GPU)通信。此BSP代码包含在设备的只读供应商分区中,并且只能由OEM在SoC供应商的支持下进行更新。
SoC供应商在芯片组的生命周期内更新BSP,芯片组由SoC供应商设置,但可以通过付费软件支持许可证进行扩展。并非每个BSP更新都会包含更新的GPU驱动程序,但当它们包含更新的GPU驱动程序时,OEM可以从更新的BSP中提取它们,然后通过OTA更新将它们发送到设备上。不过,如果你知道Android更新是如何工作的,那么你可能会在这里发现问题。Android的更新是零碎的,这意味着图形驱动程序也是零碎的。
首先,图形驱动程序通常不是特定于SoC的。例如,高通公司的图形驱动程序支持多个Adreno GPU。这意味着一个芯片组的BSP中包含的图形驱动程序可能与另一个芯片组中的GPU兼容。然而,一个BSP可能拥有这些图形驱动程序的更新版本,而其他BSP则没有,这可能会让其他芯片组上的设备使用旧版本的驱动程序。例如,Snapdragon 8 Gen 1的图形驱动程序直接支持Snapdragon 845和更高版本的平台,或者更准确地说,支持任何Adreno 6xx或7XX GPU。
下一个大问题是,原始设备制造商必须将BSP中更新的图形驱动程序合并到他们的项目中,进行测试,然后通过OTA更新将其发送到设备上。你的特定安卓设备是否真的会从原始设备制造商那里得到更新,更不用说包括更新的图形驱动程序的更新了,这还不是一个确定的事实。这意味着,即使是具有相同芯片组的设备也可能具有不同的图形驱动程序。
最后,由于大多数安卓设备出厂时没有超级用户访问权限,因此无法自行更新GPU驱动程序,这意味着你完全依赖于购买设备的OEM。如果您获得了root访问权限,那么就可以手动更新供应商分区中的图形驱动程序,前提是您能够获得必要的文件。通常,这意味着从另一台设备的固件中提取驱动程序,XDA开发者社区的一些修补者就是这么做的。这就是为什么我能够更新我生命终结的Pixel 3 XL上的图形驱动程序,显著提高了手机的图形性能。
这些驱动程序来自Snapdragon 8 Gen 1的设备,并通过其Snapdragon 845在my Pixel 3 XL上可闪存,这要归功于开发者细则,开发者细则创建了一个垫片,用于转换较新的Adreno图形驱动程序使用的QtiMapper API和较旧的Adrenos上可用的gralloc API之间的调用。
如果你的设备没有最新的图形驱动程序,这并不是世界末日,但它肯定会让用户和游戏开发者感到恼火。正如我之前提到的,更新的图形驱动程序可以带来更好的性能,我的Pixel 3 XL上的3DMark分数提升就证明了这一点。更重要的是,较新的图形驱动程序可能会修复一些图形API功能如何实现的错误。对于游戏开发者来说,针对安卓系统已经是一个挑战,因为每个GPU在功能支持方面都有很大的不同。再加上使用相同GPU的设备之间不一致的驱动程序版本,你就会明白为什么Android是一个具有挑战性的平台,从游戏开发的角度来看。开发人员要么需要维护一系列令人眼花缭乱的解决驱动程序错误的方法,要么限制设备兼容性,这两种方法都不是好的选择。谷歌正在制作一个基准配置文件,这样游戏开发者就可以更容易地确定一台设备是否支持一组常见的Vulkan功能,但这仍然不能解决碎片问题。
然而,减少碎片的方法是使图形驱动程序更容易更新。谷歌在几年前就意识到了这一点,多亏了Treble项目引入的系统供应商分离,他们能够将更新的图形驱动程序作为标准Android应用程序包的一部分发布。高通公司意识到了这一点的潜力,因此该公司开始营销其最新芯片组支持通过应用商店更新GPU驱动程序。然而,这最终无助于改善情况。
由于Project Treble标准化了HALs和OS框架之间的接口,因此在不破坏与后者兼容性的情况下更新前者变得更加容易。因此,Treble使独立更新图形驱动程序变得更容易,无需将图形驱动程序更新与整体固件更新联系起来。然而,面临的挑战是如何准确地在标准OTA更新之外提供这些图形驱动程序更新。
答案是Android应用程序包(.APK文件)。APK可以包含共享库(.so文件),它们也是每个Android应用商店(包括Google Play)的首选交付格式。因此,选择APK作为交付更新图形驱动程序的机制并不奇怪,即使是在ProjectMainline引入的APEX文件格式之上。毕竟,如果你有一个APK,你可以在Google Play上为你的可交付图形驱动程序创建一个列表。
从市场营销的角度来看,这很好。想象一个用户打开Google Play,看到手机GPU驱动程序的更新。他们中的一些人会想,“酷,就像我的电脑!干得好,X!”我相信这是高通和Arm希望看到的反应,这也是为什么小米、OPPO和三星等几家原始设备制造商开始通过应用商店提供GPU驱动程序更新的原因。
不过,从安全角度来看,这种交付机制提出了一些问题。您如何确保仅向用户交付带有经过验证和测试的图形驱动程序的经批准的APK?如果任何随机的APK可以更新你手机上的图形驱动程序,那么你的手机可能会因为不正确的驱动程序而无法运行,或者面临安全问题的风险。那么,原始设备制造商如何使用应用商店安全地提供图形驱动程序更新呢?
首先,OEM需要创建并签署一个空的可更新驱动程序APK。如果OEM希望在应用商店中发布应用程序,则此APK应具有自己的唯一软件包名称。此APK应安装在供应商分区下的/vendor/app路径中的设备上,预安装的图形驱动程序位于该分区。
接下来,OEM需要创建并签署一个非空的可更新驱动程序APK。这个APK实际上应该包含要交付的更新的图形驱动程序,并且它应该与空的可更新驱动程序APK具有相同的包名和签名。由于签名验证,如果没有OEM签名,Android将拒绝任何与驱动程序APK同名的应用程序,从而确保只有OEM可以更新驱动程序APK。
由于供应商分区是只读的,因此在更新驱动程序APK时不会直接覆盖预安装的图形驱动程序(对于/vendor/app中的空的可更新驱动程序APK也是如此)。覆盖这些文件的唯一方法是更新供应商映像,这意味着要经过标准的OTA更新过程。
为了解决这个问题,谷歌对Android进行了修改,添加了对从三个不同来源加载图形驱动程序库的支持:APK中包含的可更新生产驱动程序、APK中包含的可更新预发布驱动程序,或者预安装在供应商分区中的系统图形驱动程序。生产驱动程序打算在消费类设备上发货,并包含在APK中,该APK的包名在系统属性ro中定义。gfx。驾驶员0.同时,预发布驱动程序用于在将驱动程序推送到消费者之前对其进行测试,它包含在APK中,该APK具有在prop ro中定义的包名。gfx。驾驶员1.
Android根据白名单系统决定加载哪些驱动程序。驱动程序APK本身可能包含OEM希望自动选择使用驱动程序的软件包白名单,但开发人员也可以转到设置>;开发商选项>;Graphics Driver Preferences可选择所有应用应使用的图形驱动程序,或根据每个应用选择要使用的图形驱动程序。
不过,为了尽量减少错误驱动程序更新带来的危害,特权或系统应用程序永远不会加载可更新的驱动程序。出于同样的原因,SoC供应商自己也不会使用此方案向图形驱动程序推送更新。想象一下,如果高通推出的驱动程序更新破坏了OEM产品与一系列游戏的兼容性;可以理解,OEM会对高通公司非常不满,这可能就是为什么该硅供应商只提供预发布驱动程序APK,并要求OEM解包、压力测试、重新打包、签名,然后将驱动程序更新推送到生产部门。
如果硅供应商选择为其驱动程序APK设置应用商店列表,他们可以自行解决GPU驱动程序碎片问题,因为他们已经在BSP中包含了自己的空签名预发布驱动程序APK。所有原始设备制造商需要做的就是不移除由硅供应商提供的空的签名预发布驱动程序APK。然而,硅供应商希望避免因运送有缺陷的驱动程序更新而承担责任,这是合理的,最终破坏了整个可更新GPU驱动程序计划。唯一改变的是提供GPU驱动程序更新的机制——OEM仍然负责实际推动更新,这意味着更新的驱动程序不会统一推出。大多数原始设备制造商将默认使用固件OTA发布驱动程序更新,因为这样他们只需测试驱动程序和固件的一个组合,而不是多个组合。因此,我们回到了原点。
由于对Android上GPU驱动程序的不一致性感到不满,天际线(Skyline)的两名开发人员决定自行解决这一问题。天际线是一款面向Android的开放源码任天堂交换机模拟器,正在开发中。虽然任何Android游戏开发人员都很讨厌处理许多不同的GPU及其不同的功能,但对于模拟器开发人员来说,更令人讨厌的是,他们被迫实施大量的黑客解决方案,以解决他们几乎无法控制的游戏的兼容性问题。
例如,天际线开发人员Mark‘Pixelylon’最近告诉我,该团队正在努力克服一个与驱动程序相关的主要限制。据他说,很多开关游戏使用一种叫做BCn的纹理压缩格式。虽然Adreno GPU显然多年来一直支持BCn纹理,但据报道,高通公司直到Snapdragon 865时代才在其驱动程序中公开对BCn的支持。Mark推测这是由于BCn的专利(现已过期),但无论如何,这对Skyline开发者来说是一个问题,因为使用较旧的Adreno GPU的用户与使用BCn的游戏存在兼容性问题。
我在本文前面提到的Skyline开发者细则的同事提出了一个解决方案。他开发了一个名为BCeNabler的库,该库修补了Adreno GPU驱动程序,以公开对BCn纹理的支持。虽然这确实有效,但对于Skyline开发者来说,这并不是一个可行的长期解决方案,因为很难修补高通公司专有的Adreno GPU驱动程序,以添加任何超出基本功能的内容。
在头脑风暴下一步该怎么做的时候,马克开玩笑说要更换Skyline加载的图形驱动程序,而不是修补。加载一个不同的图形驱动程序并不是一个可笑的想法——我花了大量时间讨论了实现这一点的方法。然而,Skyline开发人员希望在没有谷歌、OEM或SoC供应商支持的情况下完成这项工作,并且不需要根用户访问。换句话说,他们希望注入一个与系统提供的驱动程序完全不同的驱动程序,并且他们希望这样做不需要任何特权。
在一次天才之旅中,开发者细则想出了如何替换应用程序加载的用户空间驱动程序,前提是用户空间驱动程序与内核驱动程序兼容,马克说内核驱动程序“通常相当稳定,不会经常以中断的方式更改”Bylaws扩展了BCeNabler以创建Adreno工具,这是一个无根库,用于应用Adreno GPU驱动程序修改或替换。该库支持加载自定义GPU驱动程序、启用BCn纹理和重定向文件操作,以访问着色器转储并修改驱动程序配置文件。
Adreno工具的工作方式相当复杂,但基本上,它利用了Android应用程序本身不加载图形驱动程序这一事实。相反,他们使用Android驱动程序(libvulkan.so)加载实际的驱动程序(libvulkan.adreno.so)。Adreno工具通过向系统库中注入钩子,然后交换新的驱动程序来拦截这个过程。
有了Adreno工具,Skyline应用程序可以加载Turnip,这是Adreno GPU的开源Vulkan驱动程序,而无需root访问。这是Android仿真领域的一个重大突破,因为任何处理Adreno GPU驱动程序问题的项目都可以通过加载Turnip绕过这些问题。Turnip是由一个开发团队在Mesa项目下的Freedreno项目上公开开发的。由于Turnip的开放性,它更容易与开发人员交谈、报告错误或提交补丁,这使得Turnip成为模拟器开发人员面临的所有驱动程序相关问题的一个有吸引力的解决方案。
例如,Android的PlayStation 2模拟器AetherSX2的开发者塔勒雷思已经在利用Adreno工具。据开发者称,使用Turnip修复了Adreno 660 GPU驱动程序中出现的仿真问题,但与供应商驱动程序相比,使用它确实会降低性能。尽管如此,Tahlreth还是提供了内置Turnip驱动程序的AetherSX2版本,供那些因设备驱动程序而存在仿真问题的用户使用。虽然开发者说这些版本无法上传到Google Play,但Skyline项目的马克告诉我,他们最近收到了谷歌的许可,同意用Turnip发布他们的应用程序。因此,Tahlreth很可能也可以为AetherSX2做同样的事情,这样用户就不必在该项目的网站上寻找特殊版本的模拟器。
如果你浏览仿真爱好者聚集的社区,你可能以前听过这样一条建议:买一台带有Adreno GPU的设备,因为它们更适合仿真。这个建议源于这样一个信念:Adreno GPU提供更好的性能,更少的驱动程序错误,支持更多的功能。多年来,基于我自己的经验和我从模拟器开发人员那里听到的情况似乎都是这样,但Mark告诉我,Arm的Mali GPU在驱动程序质量方面已经显著缩小了差距。在过去的几年里,只有高通公司的“Vulkan”支持的“Turn2”扩展才真正得到了支持。与此同时,Galaxy S22中三星新Xclipse 920 GPU的驱动程序支持比最新的Mali和Adreno GPU驱动程序更多的扩展,尽管Mark告诉我Skyline项目实际上不需要这些附加功能。
不过,说到高通GPU,马克告诉我,他们需要的大部分功能都由Adreno GPU硬件支持,所以只需更新驱动程序即可。Adreno工具和Turnip使这成为可能,因此试图在Android上处理驱动程序问题的模拟器开发人员可能想看看规章制度和Mark编造了什么。一旦用于Mali GPU的开源Vulkan驱动程序PanVK的开发取得进展,那么开发人员将看到Adreno工具是否可以扩展以支持Mali设备。希望不会有任何障碍阻止这种情况发生,但不管怎样,这是一个令人兴奋的项目。
感谢阅读本周的安卓甜点点滴。我要感谢Skyline项目的Mark和bylaws在起草本文时提供的广泛帮助。
如果你喜欢这篇文章,那么请订阅安卓Edge时事通讯,获取我的安卓甜点点评专栏未来版本的链接。你可以在这个页面上找到以前的版本。