硬核万字长文:我是如何把Skia的体积“缩小”到1/8的?( 三 )


在线端:一般指的就是设备端 , 接收到 AST 的序列化文件后就可以重构 AST 数据结构 , 并进行翻译 。目前主要搞定了 OpenglES 和 Metal 两个主力平台 , Vulkan 正在进行中 。
在开源中找找答案
Bgfx
bgfx 是一套对显卡接口的抽象 , 相对来说比较全面 。它通过内置一个开源的 C 语言宏处理器的方式 , 来利用宏展开的特性把自定义的 Shader 语法实时翻译成目标平台的语法 。我没有选择它的原因是我不喜欢它对 Shader 语法的处理方式 , 就其本身来说是一个非常优秀的项目 。
Spirv
在 Spirv 字节码(Vulkan 支持的 Shader 字节码 , 不是编程语言)慢慢变成显卡跨平台字节码的事实标准后 , 行业也出现了一些利用 Spirv 来进行 Shader 转化的项目 。
【硬核万字长文:我是如何把Skia的体积“缩小”到1/8的?】
硬核万字长文:我是如何把Skia的体积“缩小”到1/8的?
文章图片

文章图片
我有想过把 RSL 的实现换成微软的 HLSL 实现 , 这样我就可以不用维护 RSL 的编译器 。同时还能享受微软 HLSL 编译器强大的优化能力 。
实际上我也确实这么做了 , 但是这样会明显增加包体积(会增加十几 MB , 我实在没有办法忍受把这么一个巨无霸塞进去) 。
所以目前也是只是对内置的 Shader 在离线编译的时候会使用这个编译方案 。如果需要动态下发还是保留 RSL 的方式 , 互相补充 。这也是目前能找到的最好最稳定的办法 , 重点是不增加二进制体积 。
几何
从这一节开始涉及渲染器最为核心的灵魂 , 数学是一切魔法的开始 。
三角形和三角剖分
在图形学中三角形的重要性已经没有必要去描述了 。它的质性简单 , 可以让显卡的插值器更加简单高效的工作 。
试想一下如果显卡支持的不是三角形而是四边形 , 那么有四个顶点很有可能不共面 , 这就会出现很复杂的情况了 , 而三角形则不会出现这个问题 。
如果只能渲染三角形那就太单调啦 , 实际情况中通常需要把多边形剖分成一组三角形的网格 , 我们管这个网格叫 Mesh 。只有得到了 Mesh 后才能提交给 GPU 并行计算 。我们管这个过程叫三角剖分 , 可见三角剖分是联系复杂多边形和三角形之间的桥梁 。
复杂的多边形
如何定义多边形?在计算几何里面也是一个比较麻烦的问题 , 常见的多边形可以是下图这样的 。
硬核万字长文:我是如何把Skia的体积“缩小”到1/8的?
文章图片

文章图片
这些还是多边形家族中一小部分 。当我们说起多边形 , 可能第一印象想起的是矩形 , 矩形是最简单的凸多边形 , 它也存在一些非常重要的性质 。
region 这类数据结构在表示区域的时候 , 会使用多个不相交的矩形来进行数学表达 。如果存在相交的情况可以利用线扫描快速剔除重叠的区域 。这就是利用了他足够简单的特性 , 运算速度可以飞快 。
硬核万字长文:我是如何把Skia的体积“缩小”到1/8的?
文章图片

文章图片
如上图所示 , 看起来杂乱无章实际上也是一个合法的多边形 。这样的多边形也应该被算法正确的处理 , 比如三角化 , 甚至做一些布尔运算 。
多边形规范
在图形学中会使用一些关键点序列来描述一个多边形 。通常认为沿着关键点序列的顺序行走 , 左手边代表多边形的内部 , 相反右手边代表多边形的外部 。
硬核万字长文:我是如何把Skia的体积“缩小”到1/8的?