跳至正文

CocosCreator中png和etc纹理所占内存测试

1 PNG和ETC的加载区别

1.1 PNG

PNG是一种图片压缩格式,并不能被GPU直接识别,CPU把PNG图片读取到内存后,还需要在内存中解码,转换成GPU能识别的数据格式,然后传送给GPU渲染。

整个过程所占内存是编码数据*1+解码数据*2,即原始PNG文件占一份,解码后的数据在内存和GPU各占一份。

2.1 ETC

ETC是一种能被GPU直接识别的压缩纹理格式,CPU把ETC压缩纹理读取到内存后,无需解码,直接传送给GPU渲染。
整个过程所占内存是压缩纹理数据*2

2 测试环境

  • CocosCreator 2.4.x
  • 构建Android包在真机上测试
  • 关闭纹理缓存,即 cc.macro.CLEANUP_IMAGE_CACHE = true,使加载后的图片内存及时释放。
  • 4种尺寸的图片:等于2048、小于2048、等于1024、小于1024,各使用4张不同的。

3 内存对比

3.1 加载PNG

3.1.1 长宽等于2048的图片

理论内存是16M。第一次加载完后,内存增加约32M,后面再加载了3张相同大小的不同图片,每次增加约16M。

为什么第一次会增加32M呢?在 cc.macro.CLEANUP_IMAGE_CACHE = true 的情况下,正常应该是只占16M。如果不是引擎BUG的话,推测是因为js的数据内存由gc控制,不是使用完就立即回收的。

3.1.2 长宽小于2048且大于1024的图片

4张图片的详细尺寸稍有区别,具体就不列举了,反正理论内存约12M。第一次加载完后,内存增加约24M,后面3次加载,每次增加约12M。为什么第一次是2倍实际内存即24M呢?推测原因同上。

3.1.3 长宽等于1024的图片

理论内存是4M。第一次加载完后,内存增加约8M,后面3次加载,每次增加约4M。

3.1.4 长宽小于1024的图片

理论内存是1-2M。第一次加载完后,内存增加约4M,后面3次加载,每次增加约1-2M。

3.2 加载ETC1纹理

加载ETC1的表现和PNG类似,就不再详述了,也是第一次加载会占用双倍内存,但后面就不会了。但平均来说,每次增加内存只有PNG的1/4,优势巨大。

4 总结

  • OpenGL ES 2.0开始,GPU纹理支持非2的幂次方。例如,小于2048的图片比2048图片更省内存。目前所有手机都已经是OpenGL ES 2.0及以上了(2021年)。
  • 尽量使用压缩纹理,ETC1的内存占用只相当于PNG的1/4,但文件体积约比PNG大1-2倍,经过zip后比PNG小。
  • ETC2的质量比ETC1好,但需要OpenGL ES 3.0支持,目前(2021年)不是所有Android手机都支持,但iPhone6开始已经是OpenGL ES 3.0了,所以iOS可以考虑用ETC2。
  • 图片长宽比要尽量均匀,例如,一张120*2000的图片,最好转换成480*500
  • PVR纹理要求长宽是正方形且是2的幂次方,如果用PVR格式,则图片大小应该依次限制在256、512、1024、2048内,宁愿用3张1024也比用一张2048好。
标签:

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注