void DrawRecommendationFoldout(ProblemDescriptor problemDescriptor) { EditorGUILayout.BeginVertical(GUI.skin.box, GUILayout.Width(LayoutSize.FoldoutWidth)); m_Preferences.recommendation = BoldFoldout(m_Preferences.recommendation, Styles.RecommendationFoldout); if (m_Preferences.recommendation) { if (problemDescriptor != null) { EditorStyles.textField.wordWrap = true; GUILayout.TextArea(problemDescriptor.solution, GUILayout.MaxHeight(LayoutSize.FoldoutMaxHeight)); } else { EditorGUILayout.LabelField(k_NoIssueSelectedText); } } EditorGUILayout.EndVertical(); }
public static List <ProblemDescriptor> LoadFromJson(string path, string name) { var fullPath = Path.GetFullPath(Path.Combine(path, name + ".json")); var json = File.ReadAllText(fullPath); var rawDescriptors = Json.From <ProblemDescriptor>(json); var descriptors = new List <ProblemDescriptor>(rawDescriptors.Length); foreach (var rawDescriptor in rawDescriptors) { if (!IsVersionCompatible(rawDescriptor)) { continue; } var desc = new ProblemDescriptor(rawDescriptor.id, rawDescriptor.description, rawDescriptor.area) { customevaluator = rawDescriptor.customevaluator, type = rawDescriptor.type, method = rawDescriptor.method, value = rawDescriptor.value, critical = rawDescriptor.critical, problem = rawDescriptor.problem, solution = rawDescriptor.solution }; if (string.IsNullOrEmpty(desc.description)) { if (string.IsNullOrEmpty(desc.type) || string.IsNullOrEmpty(desc.method)) { desc.description = string.Empty; } else { desc.description = desc.type + "." + desc.method; } } descriptors.Add(desc); } return(descriptors); }
private void DrawDetailsFoldout(ProblemDescriptor problemDescriptor) { EditorGUILayout.BeginVertical(GUI.skin.box, GUILayout.Width(LayoutSize.FoldoutWidth), GUILayout.MinHeight(LayoutSize.FoldoutMinHeight)); m_ShowDetails = BoldFoldout(m_ShowDetails, Styles.DetailsFoldout); if (m_ShowDetails) { if (problemDescriptor != null) { EditorStyles.textField.wordWrap = true; GUILayout.TextArea(problemDescriptor.problem, GUILayout.MaxHeight(LayoutSize.FoldoutMaxHeight)); } else { EditorGUILayout.LabelField(NoIssueSelectedText); } } EditorGUILayout.EndVertical(); }
void AddVariants(Shader shader, string assetPath, int id, List <ShaderVariantData> shaderVariants, Action <ProjectIssue> onIssueFound) { var shaderName = shader.name; var descriptor = new ProblemDescriptor ( id++, shaderName, Area.BuildSize, string.Empty, string.Empty ); foreach (var shaderVariantData in shaderVariants) { var compilerData = shaderVariantData.compilerData; var shaderKeywordSet = compilerData.shaderKeywordSet.GetShaderKeywords().ToArray(); #if UNITY_2019_3_OR_NEWER var keywords = shaderKeywordSet.Select(keyword => ShaderKeyword.IsKeywordLocal(keyword) ? ShaderKeyword.GetKeywordName(shader, keyword) : ShaderKeyword.GetGlobalKeywordName(keyword)).ToArray(); #else var keywords = shaderKeywordSet.Select(keyword => keyword.GetKeywordName()).ToArray(); #endif var keywordString = String.Join(", ", keywords); if (string.IsNullOrEmpty(keywordString)) { keywordString = "<no keywords>"; } var issue = new ProjectIssue(descriptor, shaderName, IssueCategory.ShaderVariants, new Location(assetPath)); issue.SetCustomProperties(new[] { compilerData.shaderCompilerPlatform.ToString(), shaderVariantData.passName, keywordString, }); onIssueFound(issue); } }
private void DrawFoldouts() { ProblemDescriptor problemDescriptor = null; var selectedItems = m_ActiveIssueTable.GetSelectedItems(); var selectedDescriptors = selectedItems.Select(i => i.ProblemDescriptor); var selectedIssues = selectedItems.Select(i => i.ProjectIssue); // find out if all descriptors are the same var firstDescriptor = selectedDescriptors.FirstOrDefault(); if (selectedDescriptors.Count() == selectedDescriptors.Count(d => d.id == firstDescriptor.id)) { problemDescriptor = firstDescriptor; } DrawDetailsFoldout(problemDescriptor); DrawRecommendationFoldout(problemDescriptor); if (m_ActiveAnalysisView.desc.showInvertedCallTree) { CallTreeNode callTree = null; if (selectedIssues.Count() == 1) { var issue = selectedIssues.First(); if (issue != null) { // get caller sub-tree callTree = issue.callTree.GetChild(); } } if (m_CurrentCallTree != callTree) { m_CallHierarchyView.SetCallTree(callTree); m_CallHierarchyView.Reload(); m_CurrentCallTree = callTree; } DrawCallHierarchy(callTree); } }
public void IssueIsAddedToReport() { var projectReport = new ProjectReport(); var p = new ProblemDescriptor ( 102001, "test", Area.CPU, "this is not actually a problem", "do nothing" ); projectReport.AddIssue(new ProjectIssue ( p, "dummy issue", IssueCategory.Code ) ); Assert.AreEqual(1, projectReport.NumTotalIssues); Assert.AreEqual(1, projectReport.GetNumIssues(IssueCategory.Code)); Assert.AreEqual(0, projectReport.GetNumIssues(IssueCategory.ProjectSettings)); }
void AddShader(Shader shader, string assetPath, int id, Action <ProjectIssue> onIssueFound) { // set initial state (-1: info not available) var variantCount = s_ShaderVariantData.Count > 0 ? 0 : -1; #if UNITY_2018_2_OR_NEWER // add variants first if (s_ShaderVariantData.ContainsKey(shader)) { var variants = s_ShaderVariantData[shader]; variantCount = variants.Count; AddVariants(shader, assetPath, id++, variants, onIssueFound); } #endif var shaderName = shader.name; var shaderHasError = false; #if UNITY_2019_4_OR_NEWER shaderHasError = ShaderUtil.ShaderHasError(shader); #endif if (shaderHasError) { shaderName = Path.GetFileNameWithoutExtension(assetPath) + ": Parse Error"; var issueWithError = new ProjectIssue(k_ParseErrorDescriptor, shaderName, IssueCategory.Shaders, new Location(assetPath)); issueWithError.SetCustomProperties((int)ShaderProperty.Num, k_NotAvailable); onIssueFound(issueWithError); return; } var descriptor = new ProblemDescriptor ( id++, shaderName ); /* * var usedBySceneOnly = false; * if (m_GetShaderVariantCountMethod != null) * { * var value = (ulong)m_GetShaderVariantCountMethod.Invoke(null, new object[] { shader, usedBySceneOnly}); * variantCount = value.ToString(); * } */ var passCount = -1; var globalKeywords = ShaderUtilProxy.GetShaderGlobalKeywords(shader); var localKeywords = ShaderUtilProxy.GetShaderLocalKeywords(shader); var hasInstancing = ShaderUtilProxy.HasInstancing(shader); var subShaderIndex = ShaderUtilProxy.GetShaderActiveSubshaderIndex(shader); var isSrpBatcherCompatible = ShaderUtilProxy.GetSRPBatcherCompatibilityCode(shader, subShaderIndex) == 0; #if UNITY_2019_1_OR_NEWER passCount = shader.passCount; #endif var issue = new ProjectIssue(descriptor, shaderName, IssueCategory.Shaders, new Location(assetPath)); issue.SetCustomProperties(new string[(int)ShaderProperty.Num] { variantCount == -1 ? k_NotAvailable : variantCount.ToString(), passCount == -1 ? k_NotAvailable : passCount.ToString(), (globalKeywords == null || localKeywords == null) ? k_NotAvailable : (globalKeywords.Length + localKeywords.Length).ToString(), shader.renderQueue.ToString(), hasInstancing.ToString(), isSrpBatcherCompatible.ToString() }); onIssueFound(issue); }
public void RegisterDescriptor(ProblemDescriptor descriptor) { m_ProblemDescriptors.Add(descriptor); }
void DrawFoldouts(ProblemDescriptor problemDescriptor) { DrawDetailsFoldout(problemDescriptor); DrawRecommendationFoldout(problemDescriptor); }
public PackageProblemRenderer(ProblemDescriptor descriptor) { this.descriptor = descriptor; InitializeComponent(); this.Render(this.descriptor); }
public void RegisterDescriptor(ProblemDescriptor descriptor) { throw new NotImplementedException(); }
public IssueTableItem(int id, int depth, string displayName, ProblemDescriptor problemDescriptor, ProjectIssue projectIssue) : base(id, depth, displayName) { ProblemDescriptor = problemDescriptor; ProjectIssue = projectIssue; }
void AddShader(Shader shader, string assetPath, int id, Action <ProjectIssue> onIssueFound) { var variantCount = k_NotAvailable; #if UNITY_2018_2_OR_NEWER // add variants first if (s_ShaderVariantData != null) { if (s_ShaderVariantData.ContainsKey(shader)) { var variants = s_ShaderVariantData[shader]; variantCount = variants.Count.ToString(); AddVariants(shader, assetPath, id++, variants, onIssueFound); } else { variantCount = "0"; } } #endif var shaderName = shader.name; var shaderHasError = false; #if UNITY_2019_4_OR_NEWER shaderHasError = ShaderUtil.ShaderHasError(shader); #endif if (shaderHasError) { shaderName = Path.GetFileNameWithoutExtension(assetPath) + ": Parse Error"; var issueWithError = new ProjectIssue(k_ParseErrorDescriptor, shaderName, IssueCategory.Shaders, new Location(assetPath)); issueWithError.SetCustomProperties(new[] { k_NotAvailable, k_NotAvailable, k_NotAvailable, k_NotAvailable, k_NotAvailable, k_NotAvailable }); onIssueFound(issueWithError); return; } var descriptor = new ProblemDescriptor ( id++, shaderName, Area.BuildSize ); var passCount = k_NotAvailable; var keywordCount = k_NotAvailable; var hasInstancing = k_NotAvailable; /* * var usedBySceneOnly = false; * if (m_GetShaderVariantCountMethod != null) * { * var value = (ulong)m_GetShaderVariantCountMethod.Invoke(null, new object[] { shader, usedBySceneOnly}); * variantCount = value.ToString(); * } */ if (m_GetShaderGlobalKeywordsMethod != null && m_GetShaderLocalKeywordsMethod != null) { var globalKeywords = (string[])m_GetShaderGlobalKeywordsMethod.Invoke(null, new object[] { shader }); var localKeywords = (string[])m_GetShaderLocalKeywordsMethod.Invoke(null, new object[] { shader }); keywordCount = (globalKeywords.Length + localKeywords.Length).ToString(); } if (m_HasInstancingMethod != null) { var value = (bool)m_HasInstancingMethod.Invoke(null, new object[] { shader }); hasInstancing = value.ToString(); } // srp batcher var isSrpBatcherCompatible = false; if (m_GetShaderGlobalKeywordsMethod != null && m_GetShaderLocalKeywordsMethod != null) { #if UNITY_2019_1_OR_NEWER if (RenderPipelineManager.currentPipeline != null) { int subShader = (int)m_GetShaderActiveSubshaderIndex.Invoke(null, new object[] { shader }); int SRPErrCode = (int)m_GetSRPBatcherCompatibilityCode.Invoke(null, new object[] { shader, subShader }); isSrpBatcherCompatible = (0 == SRPErrCode); } #endif } #if UNITY_2019_1_OR_NEWER passCount = shader.passCount.ToString(); #endif var issue = new ProjectIssue(descriptor, shaderName, IssueCategory.Shaders, new Location(assetPath)); issue.SetCustomProperties(new[] { variantCount, passCount, keywordCount, shader.renderQueue.ToString(), hasInstancing, isSrpBatcherCompatible.ToString() }); onIssueFound(issue); }
public void RegisterDescriptor(ProblemDescriptor descriptor) { }
public void Audit(Action <ProjectIssue> onIssueFound, Action onComplete, IProgressBar progressBar = null) { var shaderPathMap = new Dictionary <Shader, string>(); var shaderGuids = AssetDatabase.FindAssets("t:shader"); foreach (var guid in shaderGuids) { var assetPath = AssetDatabase.GUIDToAssetPath(guid); // skip editor shaders if (assetPath.IndexOf("/editor/", StringComparison.OrdinalIgnoreCase) != -1) { continue; } // vfx shaders are not currently supported if (Path.HasExtension(assetPath) && Path.GetExtension(assetPath).Equals(".vfx")) { continue; } var shader = AssetDatabase.LoadMainAssetAtPath(assetPath) as Shader; shaderPathMap.Add(shader, assetPath); } var id = k_ShaderVariantFirstId; if (s_ShaderVariantData == null) { var descriptor = new ProblemDescriptor ( id++, "Shader Variants analysis incomplete", Area.BuildSize, string.Empty, string.Empty ); var message = "Build the project to view the Shader Variants"; #if !UNITY_2018_2_OR_NEWER message = "This feature requires Unity 2018.2 or newer"; #endif var issue = new ProjectIssue(descriptor, message, IssueCategory.ShaderVariants); issue.SetCustomProperties(new[] { string.Empty, string.Empty, string.Empty }); onIssueFound(issue); } else { #if UNITY_2018_2_OR_NEWER // find hidden shaders var shadersInBuild = s_ShaderVariantData.Select(variant => variant.Key); foreach (var shader in shadersInBuild) { // skip shader if it's been removed since the last build if (shader == null) { continue; } if (!shaderPathMap.ContainsKey(shader)) { var assetPath = AssetDatabase.GetAssetPath(shader); shaderPathMap.Add(shader, assetPath); } } #endif } var sortedShaders = shaderPathMap.Keys.ToList().OrderBy(shader => shader.name); foreach (var shader in sortedShaders) { var assetPath = shaderPathMap[shader]; AddShader(shader, assetPath, id++, onIssueFound); } onComplete(); }
void AddShader(Shader shader, string assetPath, int id, Action <ProjectIssue> onIssueFound) { const string NotAvailable = "N/A"; var variantCount = NotAvailable; #if UNITY_2018_2_OR_NEWER // add variants first if (s_ShaderVariantData != null) { if (s_ShaderVariantData.ContainsKey(shader)) { var variants = s_ShaderVariantData[shader]; variantCount = variants.Count.ToString(); AddVariants(shader, assetPath, id++, variants, onIssueFound); } else { variantCount = "0"; } } #endif var shaderName = shader.name; var descriptor = new ProblemDescriptor ( id++, shaderName, Area.BuildSize, string.Empty, string.Empty ); var passCount = NotAvailable; var keywordCount = NotAvailable; var hasInstancing = NotAvailable; /* * var usedBySceneOnly = false; * if (m_GetShaderVariantCountMethod != null) * { * var value = (ulong)m_GetShaderVariantCountMethod.Invoke(null, new object[] { shader, usedBySceneOnly}); * variantCount = value.ToString(); * } */ if (m_GetShaderGlobalKeywordsMethod != null && m_GetShaderLocalKeywordsMethod != null) { var globalKeywords = (string[])m_GetShaderGlobalKeywordsMethod.Invoke(null, new object[] { shader }); var localKeywords = (string[])m_GetShaderLocalKeywordsMethod.Invoke(null, new object[] { shader }); keywordCount = (globalKeywords.Length + localKeywords.Length).ToString(); } if (m_HasInstancingMethod != null) { var value = (bool)m_HasInstancingMethod.Invoke(null, new object[] { shader }); hasInstancing = value ? "Yes" : "No"; } #if UNITY_2019_1_OR_NEWER passCount = shader.passCount.ToString(); #endif var issue = new ProjectIssue(descriptor, shader.name, IssueCategory.Shaders, new Location(assetPath)); issue.SetCustomProperties(new[] { variantCount, passCount, keywordCount, shader.renderQueue.ToString(), hasInstancing, }); onIssueFound(issue); }
public void Audit(Action <ProjectIssue> onIssueFound, Action onComplete, IProgressBar progressBar = null) { var id = k_ShaderVariantFirstId; if (s_ShaderCompilerData == null) { var descriptor = new ProblemDescriptor ( id, "Shader analysis incomplete", Area.BuildSize, string.Empty, string.Empty ); var message = "Build the project and run Project Auditor analysis"; #if !UNITY_2018_2_OR_NEWER message = "This feature requires Unity 2018"; #endif var issue = new ProjectIssue(descriptor, message, IssueCategory.Shaders); issue.SetCustomProperties(new[] { string.Empty, string.Empty }); onIssueFound(issue); onComplete(); return; } var shaderGuids = AssetDatabase.FindAssets("t:shader"); foreach (var guid in shaderGuids) { var assetPath = AssetDatabase.GUIDToAssetPath(guid); var shader = AssetDatabase.LoadMainAssetAtPath(assetPath) as Shader; List <ShaderCompilerData> shaderCompilerDataContainer; s_ShaderCompilerData.TryGetValue(shader.name, out shaderCompilerDataContainer); if (shaderCompilerDataContainer != null) { var descriptor = new ProblemDescriptor ( id++, shader.name, Area.BuildSize, string.Empty, string.Empty ); foreach (var shaderCompilerData in shaderCompilerDataContainer) { var shaderKeywordSet = shaderCompilerData.shaderKeywordSet.GetShaderKeywords().ToArray(); #if UNITY_2019_3_OR_NEWER var keywords = shaderKeywordSet.Select(keyword => ShaderKeyword.IsKeywordLocal(keyword) ? ShaderKeyword.GetKeywordName(shader, keyword) : ShaderKeyword.GetGlobalKeywordName(keyword)).ToArray(); #else var keywords = shaderKeywordSet.Select(keyword => keyword.GetKeywordName()).ToArray(); #endif var keywordString = String.Join(", ", keywords); if (string.IsNullOrEmpty(keywordString)) { keywordString = "<no keywords>"; } var issue = new ProjectIssue(descriptor, shader.name, IssueCategory.Shaders, new Location(assetPath)); issue.SetCustomProperties(new[] { shaderCompilerData.shaderCompilerPlatform.ToString(), keywordString, }); onIssueFound(issue); } } } onComplete(); }
public void RegisterDescriptor(ProblemDescriptor descriptor) { // TODO: check for id conflict m_ProblemDescriptors.Add(descriptor); }
public IssueTableItem(int id, int depth, ProblemDescriptor problemDescriptor) : base(id, depth) { ProblemDescriptor = problemDescriptor; }