iOS程序猿

为什么每一帧都清除画布会提高性能?

2019-07-07  本文已影响0人  皮皮Warrior

为什么每一帧都清除画布会提高性能?

是否需要glClear

在绝大多数的渲染代码中,都会在每一帧绘制前去清空画布(OpenGL的glClear,或Metal的MTLLoadActionClear)。今天和一个朋友聊到这里,他就怀疑这是一个冗余操作,实际上他做渲染相关很久了,我没想到他竟然会觉得这是错的。我和他争论的焦点是每一帧都清空画布是否适合所有平台(我是做iOS,他做PC),他的核心论据是他声称以前看过一个论坛的文章,在GPU操作时尽量减少glClear是有益的。说实话他这么一说我就虚了,毕竟PC上的驱动版本繁杂,反而我有主观臆断的嫌疑,我几乎要被他说服。

转念一想,我记得WebKit就会在绘制前清空画布,这种级别的库应该不会犯错吧。休战一天后,我查了大量资料,确认每一帧绘制前清空画布是必要的。

glClear的实现

其实他说的论点也对,只是针对比较老板本的驱动才有效。

早期的实现,名副其实:它会写FBO对应的显存,改成你设定的值,在混合时一来一回显然这是一个比较重的操作。

目前的实现,名不副实:它只是标记对应的显存时clear状态,当后续的操作去读取时,会返回一个on-fly的值,这个值就是你的设定值。这个过程实际上并没有真的占用总线,因为没有什么实质的操作,在GPU上就完成了。

也就是说就算在IMR下,调不调glClear的差别不大,你就算调了,也只是多了一个标记内存的操作,这在硬件层面不算个事。但是在TBR/TBDR上,情况有所不同。

TBR/TBDR

在TBR/TBDR的GPU架构下,tile在每次渲染前会读取FBO的值,再这个基础上做绘制,最后把结果写到屏幕数据(或者是写到新的FBO)上。

这么做的原因是GPU默认你需要上一帧的画面,来完成混合等操作,这部分工作是在tile中完成的。

而glClear会省去tile读取上一帧数据的操作,也就是图中的第2个步骤。这样就少了一次GPU通过总线读显存的操作,这样会提升GPU帧率和减少GPU发热,毕竟移动端的显存带宽小是GPU操作的一大掣肘。

glClear很有必要

由上,在一个渲染模块中,每一帧渲染前都clear都是合理的,因为它在最差的情况下,也只是和不clear性能相当。

虽然我赢了,但我不骄不躁,强行让他请客喝了个奶茶,真是知识变现年代啊……

上一篇下一篇

猜你喜欢

热点阅读