• iOS和android游戏纹理优化和内存优化(cocos2dx)


    (未完成)

    1、2d游戏最占内存的无疑是图片资源。

    2、cocos2d-x不同平台读取纹理的机制不同。ios下面使用CGImage,android和windows下是直接调用png库。我测试了下,使用png库直接读取png会比CGImage还要节约1mb左右内存(图片所占内存4mb)但是速度要比CGImage慢一倍。时间和空间如何取舍就看实际情况了。不过最佳的选择似乎是pvr(即使android版本,即使不使用pvrtc4)。

    3、一般来说,我们可以直接使用  w * h * bpp得到一张纹理所占的内存,比如一张1024*1024格式为argb8888,那么他所占的内存就是1024*1024*4=4mb。之前看到有博客提到jpg会开辟3倍与此的内存(先转换为png,然后解析png),但是新的ios系统似乎没有这个问题。jpg与png所消耗的内存几乎相同,并且jpg解析速度更快(几乎都是4mb解析+4mb纹理数据,而jpg解析时间是png的一半),但是这样反而很怪异,因为jpg是没有透明色的,一个像素最多3字节,而png一个像素4字节,jpg纹理应该占用内存更小才对,后来看了下cocos2d的ios加载图片的代码,它把所有纹理转换成rgba8888格式,所以无论是jpg还是png,占用的都是4字节。正因cocos2d对其他纹理支持不够好,pvr才会显得那么高效。

    4、pvr格式可以被显卡所认可,而不需要开辟临时内存来读取,所以即便同为argb8888格式的图片,pvr也会比png有效率,虽然不会节约程序稳定运行时的内存,但是会避免加载大量图片时的内存暴涨。  并且如果是ios设备的话,可以使用pvrtc4格式的图片,这个格式相当于windows下的dds图片,是可以被显卡直接支持的。它是有损压缩,一个像素只占4位,不过如果不是有渐变半透明色的话,一般效果可以接受,而其节约的内存和cpu时间非常非常显著。

    5、pvr也不是万金油。android设备下虽然可以使用pvr格式,但是不能使用pvrtc4,希望通过pvr像ios设备上一样真正减少游戏内存是不太可行的。

    6、pvr.ccz其实就是pvr图片zip打包下,程序读的时候还是先解压出pvr资源,然后再读取pvr。不过由于压缩下可以极大的减小图片体积,所以虽然多了解压过程也不会有特别多的cpu消耗。

    7、一张jpg图片实际加载过程内存消耗,以一张1024*1024 argb8888 500k的jpg图片为例: a.读取图片文件(消耗图片大小内存,500k)     b、解析jpg数据(cgimage, 4mb) c、释放500k的图片内存    d、opengl纹理数据(4mb)    e、释放cgimage的4mb内存。      注意,这个过程不是必然的顺序执行,释放cgimage内存的实际是有系统决定的,会很快,但是不一定是立即执行。  所以内存会瞬间飙升9mb左右,然后减少5mb,稳定到4mb左右

           png图片的加载过程与此相同

           pvr图片可以节约解析图片数据到纹理这一步的消耗。也就是说读取pvr图片资源(等价于解压pvr.ccz到内存,如果是1024*1024 argb8888格式的话,那么图片大小就是4mb,ccz压缩后图片1mb左右)消耗4mb,将pvr图片数据提交给显卡消耗4mb。然后释放文件数据4mb。这么看似乎跟Png从内存占用上相比也不是非常有优势。(注意这里说的pvr是指pvr封装的argb8888,与pvrtc4的性能有天壤之别)

    8、由于最终消耗内存的都是纹理数据,所以只要纹理数据格式是一定的,无论图片是什么格式消耗的内存都是一样的。比如使用Png8图片,体积会减少70%,但是内存占用与png24/png32是等价的(读取的时候会内部把调色板还原成真彩色,也就是说,虽然png8是一个像素只占8位,但是读取到内存中的时候会将调色板颜色还原,依然需要开辟1024*1024*4字节的空间存放纹理数据)。 当然有无透明色,cocos2d的处理还是有区别的。如果是无透明色,可以使用png24,那么所需开辟的纹理空间就是3mb。

           这里还有一点需要说明,一般我们处理windows下的dds纹理的时候,都习惯将其按2的整次幂对其,虽然图片内容只有900*900,但是图片大小却是1024*1024。那我们读取这个图片所消耗的内存就是4mb,按2的整次幂对其是有助于提高运行效率的,但是不是非常必须的。ios和android的设备都支持非2的整次幂的纹理。所以如果是png图片,那么它该多大就多大。此时消耗的内存就只有900*900*4=3mb。

    9、不要过于迷信所谓的去除alpha通道以节约内存。这个还要实际分析下具体结果。  我测试过(分别用cocos2d-x和鬼火3d引擎),rgba8888和rgb888格式的png图片显示所消耗的内存是一样的。24位图片虽然读取的时候开辟的内存只有3mb(1024*1024*3,注意如果是用CGImage读取的话,那这个值就是4mb),但是glTexImage2D提交给显卡后依然会增加4mb内存。可能跟显卡的数据对齐有关。

         这里我测试还有一个诡异的地方,如果是用pvr的npot图片的话,rgb888要比rgba8888所消耗的内存要小,但是pot图片两者又是一样的(png图片两种情况都是一样的)。可能是powervr显卡有特殊处理。

    10、rgb565和rgb5551的图片所消耗的内存是rgba8888的一半,如果没有透明渐变的话,视觉上也看不出什么区别。一些大的背景图可以优先选择这种格式。

    11、pvr图片加载速度要比png和jpg快3~5倍(同样1024*1024 argb8888),png消耗的时间可能是700ms左右,但是pvr只需要100ms左右。如果是pvr.ccz压缩下,消耗的时间是200ms左右。可见pvr在加载速度上还是有非常大的优势的。这个应该是因为png和jpg需要把图片数据还原为rgba,但是pvr可以直接把图片数据传递给显卡。pvrtc4的图片是可以被powervr显卡直接支持的。

    总结下:

    1、最终决定图片占用内存的是它的像素格式和大小,与其扩展名无关。png8  png32 jpg pvr只要其像素格式都是argb8888,那么最终图片占用的内存是一样的。

    2、如果不是pvrtc4的格式,那么不要扩展成2的整次幂,因为图片越小,占用内存越小

    3、单单去除透明通道不会减少图片所消耗的内存,png和jpg图片也无法减少图片体积,所以不推荐rgb888的格式。替代选择rgb565和rgb5551。

    5、小心加载图片时临时开辟的纹理数据造成的内存飙高,可以考虑加入内存池,及时的开辟和释放缓冲区。

    6、如果是为了减少图片体积可以选择:1、jpg--压缩比最高,质量较好,但是不支持半透明    2、png8--同样图片会比jpg略大一些,使用ImageAlpha进行转换,视觉上几乎看不出差别。    这两种图片格式都可以极大的减少图片体积(减少70%~80%),但是无助于减少内存

    7、如果是为了减少内存可以选择:1、没有透明色的图片统一转换为rgb565格式,这个时候无法使用png8了,所以png和pvr.ccz图片大小几乎相同,pvr.ccz速度更快,所以推荐pvr.ccz的rgb565格式    2、如果透明色仅仅是进行关键色标注,而没有渐变混合,那么推荐rgb5551 (r5_a1)的pvr.ccz格式

    8、可以考虑写个打包系统,统一把资源文件打包,而不是单个文件用pvr.ccz进行zip压缩,这样可以获得更高的效率。(比如我封装了下暴雪的mpq打包,其读取速度与本地文件读取速度相当,这样就可以获得最佳的读取效率)

    最后附上我测试的数据日志,图片是一张1024*1024的图片,实际图片内容大小为960*700。测试设备iphone4,png jpg等图片加载代码修改为windows版本。tex后面是图片的加载时间。 over后面的括号里面是图片加载所消耗的内存。

    1. 2012-12-27 14:28:54.614 HelloCpp[4939:707] cocos2d: surface size: 960x640 
    2. Cocos2d: cocos2d: cocos2d-2.1beta3-x-2.1.0 
    3. Cocos2d: cocos2d: GL_VENDOR:     Imagination Technologies 
    4. Cocos2d: cocos2d: GL_RENDERER:   PowerVR SGX 535 
    5. Cocos2d: cocos2d: GL_VERSION:    OpenGL ES 2.0 IMGSGX535-63.24 
    6. Cocos2d: cocos2d: GL_MAX_TEXTURE_SIZE: 2048 
    7. Cocos2d: cocos2d: GL_MAX_TEXTURE_UNITS: 8 
    8. Cocos2d: cocos2d: GL supports PVRTC: YES 
    9. Cocos2d: cocos2d: GL supports BGRA8888 textures: NO 
    10. Cocos2d: cocos2d: GL supports NPOT textures: YES 
    11. Cocos2d: cocos2d: GL supports discard_framebuffer: YES 
    12. Cocos2d: cocos2d: GL supports shareable VAO: YES 
    13. Cocos2d: cocos2d: compiled with Profiling Support: NO 
    14. tex   195    map_001_BG.pvr 
    15. map_001_BG.pvr   
    16.         ---over   proess:11.0mb (4.0mb)   free:274.6mb 
    17. tex   159    map_001_BG_rgb.pvr 
    18. map_001_BG_rgb.pvr   
    19.         ---over   proess:15.0mb (4.0mb)   free:270.6mb 
    20. tex   711    map_001_BG.jpg 
    21. map_001_BG.jpg   
    22.         ---over   proess:19.1mb (4.1mb)   free:266.7mb 
    23. tex   653    map_001_BG_rgb.jpg 
    24. map_001_BG_rgb.jpg   
    25.         ---over   proess:23.1mb (4.0mb)   free:262.6mb 
    26. tex   670    map_001_BG.png 
    27. map_001_BG.png   
    28.         ---over   proess:27.1mb (4.1mb)   free:258.7mb 
    29. tex   739    map_001_BG_rgb.png 
    30. map_001_BG_rgb.png   
    31.         ---over   proess:31.1mb (4.0mb)   free:254.3mb 
    32. tex   240    map_001_BG.pvr.ccz 
    33. map_001_BG.pvr.ccz   
    34.         ---over   proess:35.1mb (4.0mb)   free:250.4mb 
    35. tex   204    map_001_BG_rgb.pvr.ccz 
    36. map_001_BG_rgb.pvr.ccz   
    37.         ---over   proess:39.2mb (4.0mb)   free:246.5mb 
    38. tex   97    map_001_BG_rgb565.pvr 
    39. map_001_BG_rgb565.pvr   
    40.         ---over   proess:41.2mb (2.0mb)   free:244.6mb 
    41. tex   710    map_001_BG_rgb565.png 
    42. map_001_BG_rgb565.png   
    43.         ---over   proess:45.2mb (4.0mb)   free:241.1mb 
    44. tex   591    map_001_BG_rgba8888f.png 
    45. map_001_BG_rgba8888f.png   
    46.         ---over   proess:47.8mb (2.6mb)   free:238.3mb 
    47. tex   484    map_001_BG_rgba8888f.jpg 
    48. map_001_BG_rgba8888f.jpg   
    49.         ---over   proess:49.7mb (1.9mb)   free:236.5mb 
    50. tex   123    map_001_BG_rgba8888f.pvr 
    51. map_001_BG_rgba8888f.pvr   
    52.         ---over   proess:52.4mb (2.7mb)   free:234.1mb 
    53. tex   589    map_001_BG_rgb888f.png 
    54. map_001_BG_rgb888f.png   
    55.         ---over   proess:55.1mb (2.7mb)   free:231.2mb 
    56. tex   478    map_001_BG_rgb888f.jpg 
    57. map_001_BG_rgb888f.jpg   
    58.         ---over   proess:57.0mb (1.9mb)   free:229.4mb 
    59. tex   92    map_001_BG_rgb888f.pvr 
    60. map_001_BG_rgb888f.pvr   
    61.         ---over   proess:59.0mb (2.0mb)   free:227.8mb 
    62. (lldb)  
    2012-12-27 14:28:54.614 HelloCpp[4939:707] cocos2d: surface size: 960x640
    Cocos2d: cocos2d: cocos2d-2.1beta3-x-2.1.0
    Cocos2d: cocos2d: GL_VENDOR:     Imagination Technologies
    Cocos2d: cocos2d: GL_RENDERER:   PowerVR SGX 535
    Cocos2d: cocos2d: GL_VERSION:    OpenGL ES 2.0 IMGSGX535-63.24
    Cocos2d: cocos2d: GL_MAX_TEXTURE_SIZE: 2048
    Cocos2d: cocos2d: GL_MAX_TEXTURE_UNITS: 8
    Cocos2d: cocos2d: GL supports PVRTC: YES
    Cocos2d: cocos2d: GL supports BGRA8888 textures: NO
    Cocos2d: cocos2d: GL supports NPOT textures: YES
    Cocos2d: cocos2d: GL supports discard_framebuffer: YES
    Cocos2d: cocos2d: GL supports shareable VAO: YES
    Cocos2d: cocos2d: compiled with Profiling Support: NO
    tex   195    map_001_BG.pvr
    map_001_BG.pvr  
    		---over   proess:11.0mb (4.0mb)   free:274.6mb
    tex   159    map_001_BG_rgb.pvr
    map_001_BG_rgb.pvr  
    		---over   proess:15.0mb (4.0mb)   free:270.6mb
    tex   711    map_001_BG.jpg
    map_001_BG.jpg  
    		---over   proess:19.1mb (4.1mb)   free:266.7mb
    tex   653    map_001_BG_rgb.jpg
    map_001_BG_rgb.jpg  
    		---over   proess:23.1mb (4.0mb)   free:262.6mb
    tex   670    map_001_BG.png
    map_001_BG.png  
    		---over   proess:27.1mb (4.1mb)   free:258.7mb
    tex   739    map_001_BG_rgb.png
    map_001_BG_rgb.png  
    		---over   proess:31.1mb (4.0mb)   free:254.3mb
    tex   240    map_001_BG.pvr.ccz
    map_001_BG.pvr.ccz  
    		---over   proess:35.1mb (4.0mb)   free:250.4mb
    tex   204    map_001_BG_rgb.pvr.ccz
    map_001_BG_rgb.pvr.ccz  
    		---over   proess:39.2mb (4.0mb)   free:246.5mb
    tex   97    map_001_BG_rgb565.pvr
    map_001_BG_rgb565.pvr  
    		---over   proess:41.2mb (2.0mb)   free:244.6mb
    tex   710    map_001_BG_rgb565.png
    map_001_BG_rgb565.png  
    		---over   proess:45.2mb (4.0mb)   free:241.1mb
    tex   591    map_001_BG_rgba8888f.png
    map_001_BG_rgba8888f.png  
    		---over   proess:47.8mb (2.6mb)   free:238.3mb
    tex   484    map_001_BG_rgba8888f.jpg
    map_001_BG_rgba8888f.jpg  
    		---over   proess:49.7mb (1.9mb)   free:236.5mb
    tex   123    map_001_BG_rgba8888f.pvr
    map_001_BG_rgba8888f.pvr  
    		---over   proess:52.4mb (2.7mb)   free:234.1mb
    tex   589    map_001_BG_rgb888f.png
    map_001_BG_rgb888f.png  
    		---over   proess:55.1mb (2.7mb)   free:231.2mb
    tex   478    map_001_BG_rgb888f.jpg
    map_001_BG_rgb888f.jpg  
    		---over   proess:57.0mb (1.9mb)   free:229.4mb
    tex   92    map_001_BG_rgb888f.pvr
    map_001_BG_rgb888f.pvr  
    		---over   proess:59.0mb (2.0mb)   free:227.8mb
    (lldb) 

    第二个日志是ios版本的图片加载,其他与上一个相同,可以看到速度要比windows版本的png加载快一倍,但是内存消耗更高

    1. 2012-12-27 15:36:10.330 HelloCpp[4979:707] cocos2d: surface size: 960x640 
    2. Cocos2d: cocos2d: cocos2d-2.1beta3-x-2.1.0 
    3. Cocos2d: cocos2d: GL_VENDOR:     Imagination Technologies 
    4. Cocos2d: cocos2d: GL_RENDERER:   PowerVR SGX 535 
    5. Cocos2d: cocos2d: GL_VERSION:    OpenGL ES 2.0 IMGSGX535-63.24 
    6. Cocos2d: cocos2d: GL_MAX_TEXTURE_SIZE: 2048 
    7. Cocos2d: cocos2d: GL_MAX_TEXTURE_UNITS: 8 
    8. Cocos2d: cocos2d: GL supports PVRTC: YES 
    9. Cocos2d: cocos2d: GL supports BGRA8888 textures: NO 
    10. Cocos2d: cocos2d: GL supports NPOT textures: YES 
    11. Cocos2d: cocos2d: GL supports discard_framebuffer: YES 
    12. Cocos2d: cocos2d: GL supports shareable VAO: YES 
    13. Cocos2d: cocos2d: compiled with Profiling Support: NO 
    14. tex   196    map_001_BG.pvr 
    15. map_001_BG.pvr   
    16.         ---over   proess:11.0mb (4.0mb)   free:275.8mb 
    17. tex   160    map_001_BG_rgb.pvr 
    18. map_001_BG_rgb.pvr   
    19.         ---over   proess:15.0mb (4.0mb)   free:271.9mb 
    20. tex   130    map_001_BG.jpg 
    21. map_001_BG.jpg   
    22.         ---over   proess:19.3mb (4.3mb)   free:267.6mb 
    23. tex   151    map_001_BG_rgb.jpg 
    24. map_001_BG_rgb.jpg   
    25.         ---over   proess:23.5mb (4.2mb)   free:263.8mb 
    26. tex   344    map_001_BG.png 
    27. map_001_BG.png   
    28.         ---over   proess:28.7mb (5.3mb)   free:258.7mb 
    29. tex   328    map_001_BG_rgb.png 
    30. map_001_BG_rgb.png   
    31.         ---over   proess:34.0mb (5.3mb)   free:253.6mb 
    32. tex   237    map_001_BG.pvr.ccz 
    33. map_001_BG.pvr.ccz   
    34.         ---over   proess:38.0mb (4.0mb)   free:249.6mb 
    35. tex   221    map_001_BG_rgb.pvr.ccz 
    36. map_001_BG_rgb.pvr.ccz   
    37.         ---over   proess:42.0mb (4.0mb)   free:245.2mb 
    38. tex   98    map_001_BG_rgb565.pvr 
    39. map_001_BG_rgb565.pvr   
    40.         ---over   proess:44.0mb (2.0mb)   free:243.2mb 
    41. tex   300    map_001_BG_rgb565.png 
    42. map_001_BG_rgb565.png   
    43.         ---over   proess:48.9mb (4.9mb)   free:238.2mb 
    44. tex   293    map_001_BG_rgba8888f.png 
    45. map_001_BG_rgba8888f.png   
    46.         ---over   proess:52.8mb (3.9mb)   free:234.2mb 
    47. tex   87    map_001_BG_rgba8888f.jpg 
    48. map_001_BG_rgba8888f.jpg   
    49.         ---over   proess:55.7mb (2.9mb)   free:231.7mb 
    50. tex   143    map_001_BG_rgba8888f.pvr 
    51. map_001_BG_rgba8888f.pvr   
    52.         ---over   proess:58.3mb (2.7mb)   free:228.8mb 
    53. tex   300    map_001_BG_rgb888f.png 
    54. map_001_BG_rgb888f.png   
    55.         ---over   proess:62.2mb (3.9mb)   free:225.3mb 
    56. tex   87    map_001_BG_rgb888f.jpg 
    57. map_001_BG_rgb888f.jpg   
    58.         ---over   proess:65.1mb (2.9mb)   free:222.7mb 
    59. tex   91    map_001_BG_rgb888f.pvr 
    60. map_001_BG_rgb888f.pvr   
    61.         ---over   proess:67.0mb (1.9mb)   free:220.7mb 
    62. (lldb) 
  • 相关阅读:
    Android API之android.provider.ContactsContract.Data
    Android API之android.provider.ContactsContract
    Android API之android.provider.ContactsContract.Contacts
    Android API之android.os.Parcelable
    Android网络开发之基本介绍
    wpf小技巧——datagrid 滚动条问题
    C# List去重的三种方法(转)
    spring jwt springboot RESTful API认证方式
    Springboot 实现api校验和登录验证
    SpringBoot系列
  • 原文地址:https://www.cnblogs.com/lancidie/p/3019510.html
Copyright © 2020-2023  润新知