Hello Unity Community,
I’m currently testing the performance of my Android build using the Profiler. I set targetFrameRate = 60. Most of the time, it maintains a smooth 60 FPS, but occasionally drops down to 40 FPS. Upon analyzing the frame drops, I noticed that the main difference between the 40 FPS and 60 FPS scenarios is that the Gfx.PresentFrame time increases by about 6 to 7 milliseconds.
From my research, it seems this situation typically indicates high GPU load, causing the CPU to wait on the GPU. However, I’m struggling to fully understand this explanation. The blue bars in the Profiler include most of the draw calls, such as those from the main camera and UI camera, suggesting that the GPU rendering is nearly complete before the PresentFrame. Additionally, I observe significant WaitForGfxCommandsFromMainThread occurrences, indicating the GPU is often idle.
Could you help clarify why there is such a long Gfx.PresentFrame time leading to frame drops? I’ve also come across the idea that Gfx.PresentFrame might be waiting for VSync, which is enforced on Android devices. If the frame rate can’t meet 60 FPS, it drops to 30 FPS, resulting in a sudden frame rate drop. Is this explanation accurate, and are there any solutions to mitigate this issue?
Thank you very much for your assistance!
The timeline view shows you the CPU side of rendering, both on the main thread and on the rendering thread. That’s just the work needed to tell the GPU what to do though. The GPU will then still have to actually do the work, which you can’t see in detail with the CPU Profiler. Depending on the platform and graphics backend, you might be able to use the GPU Profiler Module in the Unity profiler, or a Platform/GPU manufacturer specific profiler (see third part tools here) to get insights into what’s taking long on the GPU.
1 Like
This indicates that the Rendering Thread is idle, not that the GPU is idle. Once you try syncing on the previous frame after issuing the commands for the next one is where you see that the GPU definitely wasn’t idle, as it’s not ready yet.
1 Like
I see. Thank you so much!!
1 Like
As a further explanation:
Some Rendering work has to happen on the main thread because it needs to grab data only reliably available there. The Render Thread is offloading what it can from the main thread in terms of prepping the data to be sent to the GPU.
Something you might be able to do is to actually have the CPU do more of that prep work (culling and other rendering features can help with that) so that the GPU has to do less work.
Wait… So the the green bar with name “DrawSRPBatcher” under RenderThread is actually submitting the commandbuffer and prepare for GPU? Or, all green bars represent for GPU stuff?
Can I understand it this way: in the Timeline view, only Gfx.PresentFrame represents all GPU-related timing, while everything else pertains to CPU side? That still doesn’t make sense to me since CPU and GPU are no more parallel in that case.
No, that sample also represents CPU time, albeit the CPU time that was spent waiting on the GPU. GPU timings are completely absent on the Timeline. They’d have to be shown as their own thread(s).
1 Like
In Unity 6 we have the Highlights Profiler module that shows the total time spend on CPU vs GPU.
It seems to be GPU Bound in this case.
On mobile, it’s tile-base rendering which will split rendering work into tiles in most case.
Try to reduce texture size or render texture will help a lot on mobile.
1 Like
Thanks for your reply! Actually, we use a very restricted rule for textures. Most of textures are no more than 256x256 while only a few buildings are allowed to have 512x512 textures, which I think is quite fair for mobile devices. This frame drop only happens in timeline when vfx are spawning, with Huawei Devices only. Sometimes it drops to 10 fps. Other Android devices won’t drop below 40. However, the vfx themselves, according to renderdoc capture, don’t take that much time to render though. It seems that once the vfx spawns, the time to draw every single mesh in the entire scene double or even triple… So weird.
1 Like
It could be due to the effects transparency and overdraw (try optimizing how much screen space the particle meshes cover and/or the particle counts and/or it’s shader) or that you’re hitting a memory bandwidth bottleneck were the GPU now needs to switch what memory it can have on speed dial in and out as it goes through drawing the frame because there is too much there now to have it all available immediately.
1 Like