4

关于Gfx.WaitForPresent的耗时问题

 2 years ago
source link: https://blog.uwa4d.com/archives/TechSharing_284.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

1)关于Gfx.WaitForPresent的耗时问题
​2)关于Spine Shader冗余问题
3)Unity添加了ARR插件后导出Android错误
4)对压缩格式的纹理调用GetPixels方法的疑问


这是第284篇UWA技术知识分享的推送。今天我们继续为大家精选了若干和开发、优化相关的问题,建议阅读时间10分钟,认真读完必有收获。

UWA 问答社区:answer.uwa4d.com
UWA QQ群2:793972859(原群已满员)

SpriteAtlas

Q:Profiler里看手机上的CPU、GPU耗时,发现有时候CPU上Gfx.WaitForPresentOnGfxThread的时间是GPU耗时的几倍。可以看出GPU耗时只有9毫秒,但是CPU等待了29毫秒,是GPU耗时的3倍多,请问这是什么原因导致的?

1.png

A:一般WaitForPresent出现一段耗时表示CPU在等待GPU渲染,一般是GPU压力大,渲染线程会有一段Gfx.PresentFrame(Vulkan的话子堆栈还有GfxDeviceVK.Present),最常见的情况如下:

2.png

若同时CPU开销也比较高,这段等待也会被代码耗时所覆盖,如下(主线程Sleep 4ms):

3.png

从题主的截图来看是开启了Profiler的GPU Mode,该模式对GL接口打点会性能更低,渲染线程可以看到GPUProfiler.Begin/EndQueries打点的耗时,体现在主线程就是Wait的耗时高,如下(建议关闭GPU Mode再进行测试):

4.jpg

对于题主描述的在主线程WaitForPresent存在一定的开销的情况下,渲染线程几乎没有统计到任何开销情况,不知道大家有没有遇到过类似的问题。

感谢羽飞@UWA问答社区提供了回答,欢迎大家转至社区交流:
https://answer.uwa4d.com/question/61e6c397d8413e18eb87c10a


AssetBundle

Q:如下图所示,做一个预制体放到AssetBundle包中,预制体只包含一个Spine对象,但每次打AssetBundle包都会把Spine的5个Shader打包到AssetBundle包里面,这种AssetBundle极为冗余。

5.png

并且如下图所示,Spine的五个Shader已经添加到Always Included Shaders中。请问是否有什么方法可以解决Spine AssetBundle包中的Shader冗余?

6.jpg

A1:把Spine的资源也打包,反正就几个Shader和材质球。

感谢1 9 7 3-311135@UWA问答社区提供了回答

A2:像Spine这种第三方插件的Shader,不属于Unity内置的Shader,放入Always Included Shaders设置项中是没有任何用处的。需要自己对它们主动打包进AssetBundle中,否则其他AssetBundle中用到了它们的引用,就会被动将其拉进AssetBundle中。主动打包后,其他用到这个Spine Shader的AssetBundle只是会依赖Spine Shader打的AssetBundle。

感谢Xuan@UWA问答社区提供了回答

A3:像这样的需求,需要自己在打包策略上做处理,可以把资源引用都关联,自己单独处理每个包的依赖,自己在Shader列表里加入一些黑名单,或者在打包依赖里自己处理,这就看自己想怎么设计关联与依赖了。

感谢廖武兴@UWA问答社区提供了回答,欢迎大家转至社区交流:
https://answer.uwa4d.com/question/61dc086ad8413e18eb7bf4c9


Android

Q:Unity升级到版本2021.2.8。之前可以直接把res目录放在Plugins/Android/res,但是现在好像改了,详情可以参考以下网址:https://docs.unity3d.com/2022.1/Documentation/Manual/UpgradeGuide20212.html

7.png

否则错误提示:
OBSOLETE - Providing Android resources in Assets/Plugins/Android/res is deprecated...

现在我从Android Studio中生成AAR导入到Unity中打包,还是报错:

8.png

9.png

10.png

A:之前用Unity 2019的AAR包中我都把Androidmainfest.xml删除了,但是升级到了Untiy 2021.2.8版本就出问题了,解决方案就是保留AAR中的AndroidMainfest.xml,自己手动合并。

感谢题主zerolj@UWA问答社区提供了回答,欢迎大家转至社区交流:
https://answer.uwa4d.com/question/61ebd465d8413e18eb8e5195


Texture

Q:看官方文档,如果纹理设置开关R/W Enabled启用时,可以通过Texture.GetPixels/SetPixels读写纹理数据。

请问,压缩格式的纹理(比如ETC)在内存中的形式应该是未解压的,那么在调用GetPixels时会在CPU端解压吗?

A:在Unity 2019.4.10f1上做了一个测试,代码如下:

11.png

结果如下:

12.png

左边是ETC2 8Bits,右边是代码生成的,2是原图,n/a是代码生成的,从手机截图上看,肉眼似乎分辨不出区别。

13.png

又做了一个额外的测试,让不压缩的图GetPixels,和ETC2的图GetPixels的值作差。

14.png

结果如下图,得到的是一个全黑的图,左边是ETC2格式的图,右边是生成的图。

15.png

由上面的测试可知,GetPixels得到的值是和RGBA32格式的数值是一致的。猜测底层在操作GetPixels时,应该做了解压。

感谢Xuan@UWA问答社区提供了回答,欢迎大家转至社区交流:
https://answer.uwa4d.com/question/61e1877ad8413e18eb822160

封面图来源于网络


今天的分享就到这里。当然,生有涯而知无涯。在漫漫的开发周期中,您看到的这些问题也许都只是冰山一角,我们早已在UWA问答网站上准备了更多的技术话题等你一起来探索和分享。欢迎热爱进步的你加入,也许你的方法恰能解别人的燃眉之急;而他山之“石”,也能攻你之“玉”。

官网:www.uwa4d.com
官方技术博客:blog.uwa4d.com
官方问答社区:answer.uwa4d.com
UWA学堂:edu.uwa4d.com
官方技术QQ群:793972859(原群已满员)


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK