[Chrome翻译]Blink如何影响WebGL,第二部分

172 阅读5分钟

原文地址:blog.tojicode.com/2014/02/how…

原文作者:blog.tojicode.com/

发布时间:2014年2月17日

之前的一篇文章中,我详细介绍了迁移到Blink对WebGL流水线的一些影响。简而言之,我们能够在不改变执行的代码的情况下删除一些抽象层,从而清理了我们的依赖关系图。当时我们最终得到的数据流大致是这样的。

image.png

那是8个月前的事了,这段时间我一直很忙!所以我们先来看看目前的状况。

切换到Blink之后,马上对代码进行了初步清理,很快就发现GraphicsContext3D类基本上没有必要了。正如我在第一篇文章中所解释的那样,它的目的是为所有不同的 WebKit 端口提供一个抽象接口,以便与图形硬件进行通信,每个端口都可以用任何最适合自己的方式来实现它。我们能够将抽象接口和 Chrome 的实现整合到 Blink 代码中,但这给我们留下了大量的函数调用,这些函数实际上看起来像这样。

GraphicsContext3D::clear(GC3Duint flags) {  m_webGraphicsContext3D->clear(flags);}

(这不是实际的Blink代码,但它很清楚地传达了发生了什么。)

这个类还提供了一些其他的小功能,但大部分都是像这样的简单传递,因此并不是严格意义上的需要。尽管这样,Blink代码库中的大部分都在使用这个类作为它进行硬件加速绘图调用的主要手段。我相信大多数开发者都会这样想,在代码中加入这样一个明显不必要的层让我很不舒服,所以我开始着手做一些事情。

这最终是一个比预期更大的任务。

你可以查看Chrome浏览器的票据,在那里我跟踪了这项任务的所有进展,以了解其中涉及的内容,以及需要修改多少代码才能最终关闭这个残余的抽象层。简而言之,我花了两个多月的时间和大量的代码来回修改,才把所有的东西都弄好。不过,最终的结果是值得的,并且产生了一些令人惊讶的副作用。

(警告!前面是浏览器实现的琐碎术语!)

我首先要解决的问题之一是,GraphicsContext3D类(以下简称GC3D,因为我很懒)托管了整个代码中使用的图形枚举。像GC3Dint、GC3Dfloat等等,这些都是等价的GL类型的重新声明,因为WebKit不想强迫实现者使用特定版本的OpenGL头文件。然而在Blink中,我们可以直接包含GL(ES)头文件,因此能够在整个代码中把所有的GC3D枚举类型转换为标准的GL等价类型,在我看来,这让事情变得更易读。

然而,我确实需要解决一些与代码中其他部分的冲突,这些部分包含了他们自己的GL类型声明(NaCl和Skia是主要的),以便开始包含Khronos头文件。具体来说,我需要确保整个代码库中64位类型的声明是一致的。

在我让整个代码库使用标准的GL类型之后,下一步就是逐个类地检查代码,并将每个类转换为开始存储和直接调用WebGraphicsContext3D(Chrome的底层3D上下文实现,以下简称WGC3D)。这很机械,并没有出现太多问题。

然而,在进行转换的过程中,我意识到另一个类--Extensions3D对象--处于一个非常类似的位置,即只是将函数调用传递给实际实现(在这种情况下也是WGC3D)。由于它没有被太多其他类使用,我们能够完全消除它,而不需要太多麻烦。

接下来,我必须更新任何获取GC3D的代码,并让它请求一个WGC3D来代替。由于每个类使用的内存跟踪模型不同,这被证明是很棘手的。GC3D类使用Blink的RefPtr来跟踪在任何给定的时间内有多少类持有对它的引用,并且会自动删除这个数字曾经达到零的对象。这很方便,但它要求被跟踪的类必须继承RefCounted类。而WGC3D类,只是Chrome实现的一个接口,保持Blink和Chrome代码的分离。由于我们不能要求Chrome为我们提供一个RefCounted对象,我必须更明确地管理WGC3D对象的寿命。这是可行的,但需要仔细考虑在任何特定时间谁 "拥有 "该对象。

在这一点上,另一个令人高兴的副作用是,我能够在这时摆脱一个叫做SharedGraphicsContext3D的帮助类,因为我们意识到,在这个没有GC3D的新世界里,它所提供的对象跟踪已经不再需要了。奖励!

最后,由于现在大家都直接调用了WGC3D方法,GC3D只剩下几个主要是处理通用图像转换和一些扩展管理助手的静态函数。我将这些功能分解成单独的类(WebGLImageConversion和Extensions3DUtil),并完全放弃了GC3D类。噗! 噗!一层抽象消失了。

作为最后的奖励,在剔除Extensions3DUtil类的时候,我意识到我们在反复检查是否启用了一些Chrome浏览器保证随时可用的扩展,这使得这些检查在Blink中变得没有必要了。小小的优化真好!所以在所有这些之后,我们现在有了一个新的扩展类。

所以,在所有这些之后,我们现在有了一个看起来像这样的数据流。

image.png

这样看的话,其实并不是什么大的变化 但在代码清晰度上的差异是显著的。和之前的重构一样,这里的目标并不是为了提高性能(虽然可能因此好了一点点),而是为了减少不必要的代码层。通过删除那些不适用于Blink代码库的抽象,我们让开发人员更容易开发新功能,跟踪问题,并找到相关的代码片段。反过来,这也将转化为更快的修复和功能的周转时间,这也是您作为开发者所需要的。每个人都是赢家


www.deepl.com 翻译