Няма описание
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

NoLeaksOnEnterLeavePlaymode.cs 5.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. using NUnit.Framework;
  2. using UnityEditor;
  3. using UnityEngine;
  4. using UnityEngine.Rendering;
  5. using UnityEngine.Rendering.Universal;
  6. using UnityEditor.Rendering.Universal.Internal;
  7. using UnityEngine.Experimental.Rendering.Universal;
  8. using UnityEngine.TestTools;
  9. using UnityEditor.SceneManagement;
  10. using System.Collections;
  11. using System.Linq;
  12. using System.Collections.Generic;
  13. class NoLeaksOnEnterLeavePlaymode
  14. {
  15. // This variable needs to be serialized, as going into play-mode will reload the domain and
  16. // wipe the state of all objects, including the content of this variable
  17. [SerializeField]
  18. string materialNames = "";
  19. [SerializeField]
  20. string meshNames = "";
  21. [SerializeField]
  22. string textureNames = "";
  23. void EnsureUniversalRPIsActivePipeline()
  24. {
  25. Camera.main.Render();
  26. // Skip test if project is not configured to be SRP project
  27. if (RenderPipelineManager.currentPipeline == null)
  28. Assert.Ignore("Test project has no SRP configured, skipping test");
  29. Assert.IsInstanceOf<UniversalRenderPipeline>(RenderPipelineManager.currentPipeline);
  30. }
  31. Dictionary<string, int> CountResources(string[] names)
  32. {
  33. var result = new Dictionary<string, int>();
  34. foreach (string name in names)
  35. {
  36. if (result.TryGetValue(name, out int materialCount))
  37. {
  38. result[name] = materialCount + 1;
  39. }
  40. else
  41. {
  42. result.Add(name, 1);
  43. }
  44. }
  45. return result;
  46. }
  47. void CompareResourceLists(Dictionary<string, int> oldList, Dictionary<string, int> newList, string [] blackList)
  48. {
  49. foreach (var newRes in newList)
  50. {
  51. // Ignore blacklisted materials
  52. if (blackList.Contains(newRes.Key)) continue;
  53. int oldCount = 0;
  54. oldList.TryGetValue(newRes.Key, out oldCount);
  55. if (newRes.Value > oldCount)
  56. {
  57. Debug.LogError("Leaked " + newRes.Key + "(" + (newRes.Value - oldCount) + "x)");
  58. }
  59. }
  60. }
  61. [UnityTest]
  62. public IEnumerator NoResourceLeaks()
  63. {
  64. // Ignoring OpenGL as it has now been deprecated and this test is unstable on that platform.
  65. GraphicsDeviceType gfxAPI = SystemInfo.graphicsDeviceType;
  66. if (gfxAPI == GraphicsDeviceType.OpenGLCore)
  67. yield break;
  68. // give it a chance to warm-up by entering play mode once
  69. // in theory this shouldn't be needed but I hope this avoids the worst instabilities.
  70. yield return new EnterPlayMode();
  71. yield return null;
  72. yield return new ExitPlayMode();
  73. yield return null;
  74. // Grab the list of existing objects
  75. var mats = Resources.FindObjectsOfTypeAll(typeof(Material));
  76. materialNames = string.Join(";", mats.Select(m => m.name));
  77. var meshes = Resources.FindObjectsOfTypeAll(typeof(Mesh));
  78. meshNames = string.Join(";", meshes.Select(m => m.name));
  79. var textures = Resources.FindObjectsOfTypeAll(typeof(Texture));
  80. textureNames = string.Join(";", textures.Select(m => m.name));
  81. yield return new EnterPlayMode();
  82. yield return null;
  83. yield return new ExitPlayMode();
  84. yield return null;
  85. // Grab lists of existing objects.
  86. // Note: resources created from code often reuse the same names so we have to both check the names
  87. // and the counts per name to ensure nothing leaked.
  88. var newMats = Resources.FindObjectsOfTypeAll(typeof(Material));
  89. var newMeshes = Resources.FindObjectsOfTypeAll(typeof(Mesh));
  90. var newTextures = Resources.FindObjectsOfTypeAll(typeof(Texture));
  91. string[] materialBlackList = {
  92. "Hidden/Universal/HDRDebugView",
  93. "Hidden/Universal Render Pipeline/Debug/DebugReplacement",
  94. "Roboto Mono - Regular Material", // Font leaks
  95. "Inter - Regular Material" // https://jira.unity3d.com/browse/UUM-28555
  96. };
  97. var oldMaterialNames = materialNames.Split(";");
  98. var materialsPerNameOld = CountResources(oldMaterialNames);
  99. var newMaterialNames = newMats.Select(m => m.name).ToArray();
  100. var materialsPerNameNew = CountResources(newMaterialNames);
  101. CompareResourceLists(materialsPerNameOld, materialsPerNameNew, materialBlackList);
  102. string[] meshBlackList = {
  103. };
  104. var oldMeshNames = meshNames.Split(";");
  105. var meshesPerNameOld = CountResources(oldMeshNames);
  106. var newMeshNames = newMeshes.Select(m => m.name).ToArray();
  107. var meshesPerNameNew = CountResources(newMeshNames);
  108. CompareResourceLists(meshesPerNameOld, meshesPerNameNew, meshBlackList);
  109. string[] textureBlackList = {
  110. "Inter - Regular Atlas", // more fonts leakage :-\
  111. "Roboto Mono - Regular Atlas", // more fonts leakage :-\
  112. };
  113. var oldTextureNames = textureNames.Split(";");
  114. var texturesPerNameOld = CountResources(oldTextureNames);
  115. var newTextureNames = newTextures.Select(m => m.name).ToArray();
  116. var texturesPerNameNew = CountResources(newTextureNames);
  117. CompareResourceLists(texturesPerNameOld, texturesPerNameNew, textureBlackList);
  118. }
  119. }