由于之前有过小游戏开发经验,也做过 js 游戏引擎相关的开发,还是蛮相信自己能搞定的。下载了代码,作者也没写注释,只能硬着头皮猜,核心部分就是用 js 模拟了 GBA 的 32 位 CPU,GBA 解包等等这些无关语言和环境的东西,只有最后拿到 ImageData 才涉及到渲染层,看上去还挺简单,要改的东西不多。
于是自己花了一两个小时,把涉及到 DOM 和 BOM 都改了,渲染全部由小游戏 canvas 接管,解决了一系列 BUG 后,终于能在模拟器上看到画面了。内心很激动,感觉要成了!
在模拟器出画面后,用真机调试,发现真机啥画面都没有,于是开始了 debug 之路,非常漫长,由于不知道是平台原因还是小游戏 API 不完善的原因,完全一行一行的 debug,一两个小时后,终于找到原因所在,一个 callback 导致的画面黑屏(为什么 Web 和模拟器都行,就是真机不行,小游戏&小程序的模拟器不靠谱啊)
搞定了上一个问题,更是兴奋,感觉离成功不远了,真机上跑了一下,怎么感觉 fps 有点低呢? drawcall 只有 2,但 fps 一直上不了 20,稳定在 12-15 左右,变成了幻灯片。用模拟器看了一下,模拟器能跑满 60fps,于是我就在想,会不会是渲染效率的原因,于是又开始了漫长的 debug。这次先找渲染层,也是一行行代码的测,因为不确定小游戏的引擎有哪些未知 BUG,所以这样来测比较细,也不会遗漏什么。这一测,就是 3 个多小时,还是完全没有头绪,各种方式都试遍了,依然保持 12fps。
本着不改好 bug 不睡觉的原则,继续刚,终于让我发现了问题所在。在 pc 端和手机浏览器上,能跑满 60fps,但小游戏不行,问题出在模拟 cpu 的核心代码上,用虚拟的 cpu 去运行 GBA 的 rom,pc 和手机浏览器只需要几 ms 的时间就能解析出一帧的画面,而到了小游戏里,则需要 80 多 ms,1000ms/80ms 约等于 12 左右,刚好解释了为什么 fps 在 12 左右波动。完全占据了 90%的性能开销。很奇怪为什么会开销这么大,这部分代码也没用到 polyfill,于是脑瓜更疼了。思来想去,于是想到,会不会是 ios 上小程序的 js 引擎并非系统的 js 引擎,而是自己实现了一套(突然想到了腾讯有自己的 x5 内核,会不会也有自己的"x5js")?带着疑问搜索了一圈,果真搜到了一篇文章,介绍了小程序的 js 引擎,是苹果的 JSC 引擎? WTF ? JSC 不是 Safari 的引擎吗?我明明用 Safari 试过没问题才准备移植的,带着疑问又上路搜关于 JSC 的资料,可算找到一个稍微靠谱的解释。
原来在 Safari 里,JSC 是带有 JIT 的,UIWebview 不带 JIT,也没有 Safari 那么好的优化,但具体是哪部分没有优化好,我继续在代码里找。由于小程序开发工具运行流畅,不好 debug,于是只有用真机打 log 看运行时间,又是花费一两个小时时间,终于找到了,原来是 ARM 的 STM 指令耗时,90%的时间都消耗在 STM 上了,由于鄙人能力有限,对计算机底层不太熟悉,到这一步就放弃了
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.