350 lines
18 KiB
C#
350 lines
18 KiB
C#
using System.Runtime.InteropServices;
|
|
using System.Text;
|
|
|
|
using Unity.Profiling;
|
|
using LitJson;
|
|
using System.Collections.Generic;
|
|
|
|
using UnityEngine;
|
|
using UnityEngine.Profiling;
|
|
|
|
#if UNITY_WEBGL || WEIXINMINIGAME || UNITY_EDITOR
|
|
using WeChatWASM;
|
|
public class WXProfileStatsScript : MonoBehaviour, WeChatWASM.WXSDKManagerHandler.WXProfileStatsScript
|
|
{
|
|
private string statsText;
|
|
#if UNITY_2021_2_OR_NEWER
|
|
// private ProfilerRecorder m_totalUsedMemoryRecorder;
|
|
// private ProfilerRecorder m_totalReservedMemoryRecorder;
|
|
// private ProfilerRecorder m_gcUsedMemoryRecorder;
|
|
// private ProfilerRecorder m_gcReservedMemoryRecorder;
|
|
// private ProfilerRecorder m_gfxUsedMemoryRecorder;
|
|
// private ProfilerRecorder m_gfxReservedMemoryRecorder;
|
|
|
|
// private ProfilerRecorder m_systemUsedMemoryRecorder;
|
|
// private ProfilerRecorder m_textureCountRecorder;
|
|
// private ProfilerRecorder m_textureMemoryRecorder;
|
|
// private ProfilerRecorder m_meshCountRecorder;
|
|
// private ProfilerRecorder m_meshMemoryRecorder;
|
|
// private ProfilerRecorder m_materialCountRecorder;
|
|
// private ProfilerRecorder m_materialMemoryRecorder;
|
|
// private ProfilerRecorder m_animationClipCountRecorder;
|
|
// private ProfilerRecorder m_animationClipMemoryRecorder;
|
|
|
|
// private ProfilerRecorder m_assetCountRecorder;
|
|
// private ProfilerRecorder m_gameObjectsInScenesRecorder;
|
|
// private ProfilerRecorder m_totalObjectsInScenesRecorder;
|
|
// private ProfilerRecorder m_totalUnityObjectCountRecorder;
|
|
// private ProfilerRecorder m_gcAllocationInFrameCountRecorder;
|
|
// private ProfilerRecorder m_gcAllocatedInFrameRecorder;
|
|
private ProfilerRecorder m_setPassCallsRecorder; //切换用于渲染游戏对象的着色器通道的次数
|
|
private ProfilerRecorder m_drawCallsRecorder; //绘制调用总数
|
|
private ProfilerRecorder m_verticesRecorder; //顶点数
|
|
private ProfilerRecorder m_triangleRecorder; //三角形数
|
|
|
|
private ProfilerRecorder m_renderTexturesCount;
|
|
private ProfilerRecorder m_RenderTexturesBytes;
|
|
private ProfilerRecorder m_BatchesCount;
|
|
private ProfilerRecorder m_ShadowCastersCount;
|
|
private ProfilerRecorder m_VisibleSkinnedMeshesCount;
|
|
private ProfilerRecorder m_RenderTexturesChangesCount;
|
|
private ProfilerRecorder m_UsedBuffersCount;
|
|
private ProfilerRecorder m_UsedBuffersBytes;
|
|
private ProfilerRecorder m_VertexBufferUploadInFrameCount;
|
|
private ProfilerRecorder m_VertexBufferUploadInFrameBytes;
|
|
private ProfilerRecorder m_IndexBufferUploadInFrameCount;
|
|
private ProfilerRecorder m_IndexBufferUploadInFrameBytes;
|
|
|
|
|
|
#endif
|
|
private int m_fpsCount;
|
|
private float m_fpsDeltaTime;
|
|
private int fps;
|
|
private GUIStyle m_bgStyle;
|
|
private bool m_isShow = true;
|
|
private System.Collections.Generic.Dictionary<string, ProfValue> profValues = new System.Collections.Generic.Dictionary<string, ProfValue>();
|
|
|
|
public void Awake()
|
|
{
|
|
m_bgStyle = new GUIStyle();
|
|
m_bgStyle.normal.background = Texture2D.whiteTexture;
|
|
}
|
|
|
|
public void OnEnable()
|
|
{
|
|
#if UNITY_2021_2_OR_NEWER
|
|
// m_totalUsedMemoryRecorder = ProfilerRecorder.StartNew(ProfilerCategory.Memory, "Total Used Memory");
|
|
// m_totalReservedMemoryRecorder = ProfilerRecorder.StartNew(ProfilerCategory.Memory, "Total Reserved Memory");
|
|
// m_gcUsedMemoryRecorder = ProfilerRecorder.StartNew(ProfilerCategory.Memory, "GC Used Memory");
|
|
// m_gcReservedMemoryRecorder = ProfilerRecorder.StartNew(ProfilerCategory.Memory, "GC Reserved Memory");
|
|
// m_gfxUsedMemoryRecorder = ProfilerRecorder.StartNew(ProfilerCategory.Memory, "Gfx Used Memory");
|
|
// m_gfxReservedMemoryRecorder = ProfilerRecorder.StartNew(ProfilerCategory.Memory, "Gfx Reserved Memory");
|
|
// m_systemUsedMemoryRecorder = ProfilerRecorder.StartNew(ProfilerCategory.Memory, "System Used Memory");
|
|
// m_textureCountRecorder = ProfilerRecorder.StartNew(ProfilerCategory.Memory, "Texture Count");
|
|
// m_textureMemoryRecorder = ProfilerRecorder.StartNew(ProfilerCategory.Memory, "Texture Memory");
|
|
// m_meshCountRecorder = ProfilerRecorder.StartNew(ProfilerCategory.Memory, "Mesh Count");
|
|
// m_meshMemoryRecorder = ProfilerRecorder.StartNew(ProfilerCategory.Memory, "Mesh Memory");
|
|
// m_materialCountRecorder = ProfilerRecorder.StartNew(ProfilerCategory.Memory, "Material Count");
|
|
// m_materialMemoryRecorder = ProfilerRecorder.StartNew(ProfilerCategory.Memory, "Material Memory");
|
|
// m_animationClipCountRecorder = ProfilerRecorder.StartNew(ProfilerCategory.Memory, "AnimationClip Count");
|
|
// m_animationClipMemoryRecorder = ProfilerRecorder.StartNew(ProfilerCategory.Memory, "AnimationClip Memory");
|
|
// m_assetCountRecorder = ProfilerRecorder.StartNew(ProfilerCategory.Memory, "Asset Count");
|
|
// m_gameObjectsInScenesRecorder = ProfilerRecorder.StartNew(ProfilerCategory.Memory, "GameObject Count");
|
|
// m_totalObjectsInScenesRecorder = ProfilerRecorder.StartNew(ProfilerCategory.Memory, "Scene Object Count");
|
|
// m_totalUnityObjectCountRecorder = ProfilerRecorder.StartNew(ProfilerCategory.Memory, "Object Count");
|
|
// m_gcAllocationInFrameCountRecorder = ProfilerRecorder.StartNew(ProfilerCategory.Memory, "GC Allocation In Frame Count");
|
|
// m_gcAllocatedInFrameRecorder = ProfilerRecorder.StartNew(ProfilerCategory.Memory, "GC Allocated In Frame");
|
|
m_setPassCallsRecorder = ProfilerRecorder.StartNew(ProfilerCategory.Render, "SetPass Calls Count");
|
|
m_drawCallsRecorder = ProfilerRecorder.StartNew(ProfilerCategory.Render, "Draw Calls Count");
|
|
m_verticesRecorder = ProfilerRecorder.StartNew(ProfilerCategory.Render, "Vertices Count");
|
|
if (WeChatWASM.WXSDKManagerHandler.Instance.IsCloudTest())
|
|
{
|
|
m_triangleRecorder = ProfilerRecorder.StartNew(ProfilerCategory.Render, "Triangles Count");
|
|
|
|
m_renderTexturesCount = ProfilerRecorder.StartNew(ProfilerCategory.Render, "Render Textures Count");
|
|
m_RenderTexturesBytes = ProfilerRecorder.StartNew(ProfilerCategory.Render,"Render Textures Bytes");
|
|
m_BatchesCount = ProfilerRecorder.StartNew(ProfilerCategory.Render, "Batches Count");
|
|
m_ShadowCastersCount = ProfilerRecorder.StartNew(ProfilerCategory.Render, "Shadow Casters Count");
|
|
m_VisibleSkinnedMeshesCount = ProfilerRecorder.StartNew(ProfilerCategory.Render, "Visible Skinned Meshes Count");
|
|
m_RenderTexturesChangesCount = ProfilerRecorder.StartNew(ProfilerCategory.Render, "Render Textures Changes Count");
|
|
m_UsedBuffersCount = ProfilerRecorder.StartNew(ProfilerCategory.Render, "Used Buffers Count");
|
|
m_UsedBuffersBytes = ProfilerRecorder.StartNew(ProfilerCategory.Render, "Used Buffers Bytes");
|
|
m_VertexBufferUploadInFrameCount = ProfilerRecorder.StartNew(ProfilerCategory.Render, "Vertex Buffer Upload In Frame Count");
|
|
m_VertexBufferUploadInFrameBytes = ProfilerRecorder.StartNew(ProfilerCategory.Render, "Vertex Buffer Upload In Frame Bytes");
|
|
m_IndexBufferUploadInFrameCount = ProfilerRecorder.StartNew(ProfilerCategory.Render, "Index Buffer Upload In Frame Count");
|
|
m_IndexBufferUploadInFrameBytes = ProfilerRecorder.StartNew(ProfilerCategory.Render, "Index Buffer Upload In Frame Bytes");
|
|
}
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
public void OnDisable()
|
|
{
|
|
#if UNITY_2021_2_OR_NEWER
|
|
// m_totalUsedMemoryRecorder.Dispose();
|
|
// m_totalReservedMemoryRecorder.Dispose();
|
|
// m_gcUsedMemoryRecorder.Dispose();
|
|
// m_gcReservedMemoryRecorder.Dispose();
|
|
// m_gfxUsedMemoryRecorder.Dispose();
|
|
// m_gfxReservedMemoryRecorder.Dispose();
|
|
// m_systemUsedMemoryRecorder.Dispose();
|
|
// m_textureCountRecorder.Dispose();
|
|
// m_textureMemoryRecorder.Dispose();
|
|
// m_meshCountRecorder.Dispose();
|
|
// m_meshMemoryRecorder.Dispose();
|
|
// m_materialCountRecorder.Dispose();
|
|
// m_materialMemoryRecorder.Dispose();
|
|
// m_animationClipCountRecorder.Dispose();
|
|
// m_animationClipMemoryRecorder.Dispose();
|
|
// m_assetCountRecorder.Dispose();
|
|
// m_gameObjectsInScenesRecorder.Dispose();
|
|
// m_totalObjectsInScenesRecorder.Dispose();
|
|
// m_totalUnityObjectCountRecorder.Dispose();
|
|
// m_gcAllocationInFrameCountRecorder.Dispose();
|
|
// m_gcAllocatedInFrameRecorder.Dispose();
|
|
m_setPassCallsRecorder.Dispose();
|
|
m_drawCallsRecorder.Dispose();
|
|
m_verticesRecorder.Dispose();
|
|
if (WeChatWASM.WXSDKManagerHandler.Instance.IsCloudTest())
|
|
{
|
|
m_triangleRecorder.Dispose();
|
|
m_renderTexturesCount.Dispose();
|
|
m_RenderTexturesBytes.Dispose();
|
|
m_BatchesCount.Dispose();
|
|
m_ShadowCastersCount.Dispose();
|
|
m_VisibleSkinnedMeshesCount.Dispose();
|
|
m_RenderTexturesChangesCount.Dispose();
|
|
m_UsedBuffersCount.Dispose();
|
|
m_UsedBuffersBytes.Dispose();
|
|
m_VertexBufferUploadInFrameCount.Dispose();
|
|
m_VertexBufferUploadInFrameBytes.Dispose();
|
|
m_IndexBufferUploadInFrameCount.Dispose();
|
|
m_IndexBufferUploadInFrameBytes.Dispose();
|
|
}
|
|
#endif
|
|
}
|
|
|
|
public class ProfValue
|
|
{
|
|
public float current;
|
|
public float max = 0;
|
|
public float min = 9999;
|
|
|
|
// public int avrage;
|
|
}
|
|
|
|
public ProfValue UpdateValue(string key, float value, StringBuilder sb, string format = "0")
|
|
{
|
|
ProfValue profValue = null;
|
|
if (!profValues.TryGetValue(key, out profValue))
|
|
{
|
|
profValue = new ProfValue();
|
|
profValues.Add(key, profValue);
|
|
}
|
|
|
|
profValue.current = value;
|
|
profValue.max = value > profValue.max ? value : profValue.max;
|
|
profValue.min = value < profValue.min ? value : profValue.min;
|
|
sb.AppendLine($"{key}:[{profValue.current.ToString(format)}, {profValue.min.ToString(format)}, {profValue.max.ToString(format)}]");
|
|
return profValue;
|
|
}
|
|
|
|
public void Update()
|
|
{
|
|
UpdateFps();
|
|
const uint toMB = 1024 * 1024;
|
|
var sb = new StringBuilder(500);
|
|
sb.AppendLine($"-------------FPS---------------");
|
|
|
|
// var key = "targetFrameRate";
|
|
UpdateValue("TargetFramerate", Application.targetFrameRate, sb);
|
|
UpdateValue("FPS", fps, sb);
|
|
UpdateValue("FrameTime(ms)", WeChatWASM.WXSDKManagerHandler.Instance.GetEXFrameTime(), sb, "0.00");
|
|
|
|
sb.AppendLine($"-------------Profiler------------");
|
|
|
|
UpdateValue("MonoHeapReserved", Profiler.GetMonoHeapSizeLong() / toMB, sb);
|
|
UpdateValue("MonoHeapUsed", Profiler.GetMonoUsedSizeLong() / toMB, sb);
|
|
|
|
// UpdateValue("Graphics", Profiler.GetAllocatedMemoryForGraphicsDriver() / toMB, sb);
|
|
|
|
// UpdateValue("TempAllocator", Profiler.GetTempAllocatorSize() / toMB, sb);
|
|
UpdateValue("NativeReserved", Profiler.GetTotalReservedMemoryLong() / toMB, sb);
|
|
UpdateValue("NativeUnused", Profiler.GetTotalUnusedReservedMemoryLong() / toMB, sb);
|
|
UpdateValue("NativeAllocated", Profiler.GetTotalAllocatedMemoryLong() / toMB, sb);
|
|
|
|
#if UNITY_2021_2_OR_NEWER
|
|
sb.AppendLine("-------------Render------------");
|
|
UpdateValue("SetPass Calls", m_setPassCallsRecorder.LastValue, sb);
|
|
UpdateValue("Draw Calls", m_drawCallsRecorder.LastValue, sb);
|
|
UpdateValue("Vertices", m_verticesRecorder.LastValue, sb);
|
|
#endif
|
|
sb.AppendLine("-------------WebAssembly----------");
|
|
UpdateValue("TotalHeapMemory", WeChatWASM.WXSDKManagerHandler.Instance.GetTotalMemorySize() / toMB, sb);
|
|
UpdateValue("DynamicMemory", WeChatWASM.WXSDKManagerHandler.Instance.GetDynamicMemorySize() / toMB, sb);
|
|
UpdateValue("UsedHeap(ProfilingMemory only)", WeChatWASM.WXSDKManagerHandler.Instance.GetUsedMemorySize() / toMB, sb);
|
|
UpdateValue("UnAllocatedMemory", WeChatWASM.WXSDKManagerHandler.Instance.GetUnAllocatedMemorySize() / toMB, sb);
|
|
|
|
sb.AppendLine("-------------AssetBundle----------");
|
|
UpdateValue("NumberInMemory", WeChatWASM.WXSDKManagerHandler.Instance.GetBundleNumberInMemory(), sb);
|
|
UpdateValue("NumberOnDisk", WeChatWASM.WXSDKManagerHandler.Instance.GetBundleNumberOnDisk(), sb);
|
|
UpdateValue("SizeInMemory", WeChatWASM.WXSDKManagerHandler.Instance.GetBundleSizeInMemory() / toMB, sb);
|
|
UpdateValue("SizeOnDisk", WeChatWASM.WXSDKManagerHandler.Instance.GetBundleSizeOnDisk() / toMB, sb);
|
|
|
|
#if UNITY_2021_2_OR_NEWER
|
|
// sb.AppendLine("-------------MemoryRecorder-----");
|
|
// UpdateValue("Total Used Memory", m_totalUsedMemoryRecorder.LastValue / toMB, sb);
|
|
// UpdateValue("Total Reserved Memory", m_totalReservedMemoryRecorder.LastValue / toMB, sb);
|
|
// UpdateValue("GC Used Memory", m_gcUsedMemoryRecorder.LastValue / toMB, sb);
|
|
// UpdateValue("GC Reserved Memory", m_gcReservedMemoryRecorder.LastValue / toMB, sb);
|
|
// UpdateValue("Gfx Used Memory", m_gfxUsedMemoryRecorder.LastValue / toMB, sb);
|
|
// UpdateValue("Gfx Reserved Memory", m_gfxReservedMemoryRecorder.LastValue / toMB, sb);
|
|
// UpdateValue("System Used Memory", m_systemUsedMemoryRecorder.LastValue / toMB, sb);
|
|
// UpdateValue("Texture Count", m_textureCountRecorder.LastValue, sb);
|
|
// UpdateValue("Texture Memory", m_textureMemoryRecorder.LastValue / toMB, sb);
|
|
// UpdateValue("Mesh Count", m_meshCountRecorder.LastValue, sb);
|
|
// UpdateValue("Mesh Memory", m_meshMemoryRecorder.LastValue / toMB, sb);
|
|
// UpdateValue("Material Count", m_materialCountRecorder.LastValue, sb);
|
|
// UpdateValue("Material Memory", m_materialMemoryRecorder.LastValue / toMB, sb);
|
|
// UpdateValue("AnimationClip Count", m_animationClipCountRecorder.LastValue, sb);
|
|
// UpdateValue("AnimationClip Memory", m_animationClipMemoryRecorder.LastValue / toMB, sb);
|
|
// UpdateValue("Asset Count", m_assetCountRecorder.LastValue, sb);
|
|
// UpdateValue("GameObject Count", m_gameObjectsInScenesRecorder.LastValue, sb);
|
|
// UpdateValue("Scene Object Count", m_totalObjectsInScenesRecorder.LastValue, sb);
|
|
// UpdateValue("Object Count", m_totalUnityObjectCountRecorder.LastValue, sb);
|
|
// UpdateValue("GC Allocation In Frame Count", m_gcAllocationInFrameCountRecorder.LastValue, sb);
|
|
// UpdateValue("GC Allocated In Frame", m_gcAllocatedInFrameRecorder.LastValue / toMB, sb);
|
|
#endif
|
|
statsText = sb.ToString();
|
|
}
|
|
|
|
public void UpdateFps()
|
|
{
|
|
m_fpsCount++;
|
|
m_fpsDeltaTime += Time.deltaTime;
|
|
|
|
if (m_fpsCount % 60 == 0)
|
|
{
|
|
m_fpsCount = 1;
|
|
fps = (int)Mathf.Ceil(60.0f / m_fpsDeltaTime);
|
|
m_fpsDeltaTime = 0;
|
|
}
|
|
}
|
|
|
|
public void OnGUI()
|
|
{
|
|
// 云测环境不展示profile stats的界面
|
|
if(!WeChatWASM.WXSDKManagerHandler.Instance.IsCloudTest()) {
|
|
GUI.backgroundColor = new Color(0, 0, 0, 0.5f);
|
|
#if UNITY_EDITOR
|
|
GUI.skin.button.fontSize = 10;
|
|
GUI.skin.label.fontSize = 10;
|
|
#else
|
|
GUI.skin.button.fontSize = 30;
|
|
GUI.skin.label.fontSize = 30;
|
|
#endif
|
|
if (GUILayout.Button("Performance Stats", GUILayout.ExpandWidth(false)))
|
|
{
|
|
m_isShow = !m_isShow;
|
|
}
|
|
|
|
if (GUILayout.Button("ProfilingMemory Dump", GUILayout.ExpandWidth(false)))
|
|
{
|
|
WeChatWASM.WXSDKManagerHandler.Instance.ProfilingMemoryDump();
|
|
}
|
|
|
|
GUILayout.BeginVertical(m_bgStyle);
|
|
if (m_isShow)
|
|
{
|
|
GUILayout.Label(statsText);
|
|
}
|
|
|
|
GUILayout.EndVertical();
|
|
}
|
|
}
|
|
|
|
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
|
|
private static void OnGameLaunch()
|
|
{
|
|
WeChatWASM.WXSDKManagerHandler.SetProfileStatsScript(typeof(WXProfileStatsScript));
|
|
}
|
|
|
|
public string GetProfileStatsDatas()
|
|
{
|
|
const uint toMB = 1024 * 1024;
|
|
Dictionary<string, long> _profileDatasDic = new Dictionary<string, long>();
|
|
_profileDatasDic.Add("MonoHeapReserved", Profiler.GetMonoHeapSizeLong() / toMB);
|
|
_profileDatasDic.Add("MonoHeapUsed", Profiler.GetMonoUsedSizeLong() / toMB);
|
|
_profileDatasDic.Add("NativeReserved", Profiler.GetTotalReservedMemoryLong() / toMB);
|
|
_profileDatasDic.Add("NativeUnused", Profiler.GetTotalUnusedReservedMemoryLong() / toMB);
|
|
_profileDatasDic.Add("NativeAllocated", Profiler.GetTotalAllocatedMemoryLong() / toMB);
|
|
|
|
#if UNITY_2021_2_OR_NEWER
|
|
_profileDatasDic.Add("SetPassCalls", m_setPassCallsRecorder.LastValue);
|
|
_profileDatasDic.Add("DrawCalls", m_drawCallsRecorder.LastValue);
|
|
_profileDatasDic.Add("Vertices", m_verticesRecorder.LastValue);
|
|
if (WeChatWASM.WXSDKManagerHandler.Instance.IsCloudTest())
|
|
{
|
|
_profileDatasDic.Add("Triangles", m_triangleRecorder.LastValue);
|
|
_profileDatasDic.Add("renderTexturesCount", m_renderTexturesCount.LastValue);
|
|
_profileDatasDic.Add("RenderTexturesBytes", m_RenderTexturesBytes.LastValue);
|
|
_profileDatasDic.Add("BatchesCount", m_BatchesCount.LastValue);
|
|
_profileDatasDic.Add("ShadowCastersCount", m_ShadowCastersCount.LastValue);
|
|
_profileDatasDic.Add("VisibleSkinnedMeshesCount", m_VisibleSkinnedMeshesCount.LastValue);
|
|
_profileDatasDic.Add("RenderTexturesChangesCount", m_RenderTexturesChangesCount.LastValue);
|
|
_profileDatasDic.Add("UsedBuffersCount", m_UsedBuffersCount.LastValue);
|
|
_profileDatasDic.Add("UsedBuffersBytes", m_UsedBuffersBytes.LastValue);
|
|
_profileDatasDic.Add("VertexBufferUploadInFrameCount", m_VertexBufferUploadInFrameCount.LastValue);
|
|
_profileDatasDic.Add("VertexBufferUploadInFrameBytes", m_VertexBufferUploadInFrameBytes.LastValue);
|
|
_profileDatasDic.Add("IndexBufferUploadInFrameCount", m_IndexBufferUploadInFrameCount.LastValue);
|
|
_profileDatasDic.Add("IndexBufferUploadInFrameBytes", m_IndexBufferUploadInFrameBytes.LastValue);
|
|
}
|
|
|
|
#endif
|
|
return JsonMapper.ToJson(_profileDatasDic);;
|
|
}
|
|
|
|
}
|
|
#endif
|