public void OnEnable()
        {
            if (_treeView == null)
            {
                _treeView = new BurstMethodTreeView(new TreeViewState());
            }
            _safetyChecks = BurstCompiler.Options.EnableBurstSafetyChecks;

            var assemblyList = BurstReflection.GetAssemblyList(AssembliesType.Editor, onlyAssembliesThatPossiblyContainJobs: true);

            Task.Run(
                () =>
            {
                // Do this stuff asynchronously.
                var result = BurstReflection.FindExecuteMethods(assemblyList);
                _targets   = result.CompileTargets;
                _targets.Sort((left, right) => string.Compare(left.GetDisplayName(), right.GetDisplayName(), StringComparison.Ordinal));
                return(result);
            })
            .ContinueWith(t =>
            {
                // Do this stuff on the main (UI) thread.
                if (t.Status == TaskStatus.RanToCompletion)
                {
                    foreach (var logMessage in t.Result.LogMessages)
                    {
                        switch (logMessage.LogType)
                        {
                        case BurstReflection.LogType.Warning:
                            Debug.LogWarning(logMessage.Message);
                            break;

                        case BurstReflection.LogType.Exception:
                            Debug.LogException(logMessage.Exception);
                            break;

                        default:
                            throw new InvalidOperationException();
                        }
                    }

                    _treeView.Targets = _targets;
                    _treeView.Reload();

                    if (_selectedItem != null)
                    {
                        _treeView.TrySelectByDisplayName(_selectedItem);
                    }

                    _requiresRepaint = true;
                    _initialized     = true;
                }
                else if (t.Exception != null)
                {
                    Debug.LogError($"Could not load Inspector: {t.Exception}");
                }
            });
        }
示例#2
0
        public void OnGUI()
        {
            // Make sure that editor options are synchronized
            BurstEditorOptions.EnsureSynchronized();

            if (_targets == null)
            {
                _targets = BurstReflection.FindExecuteMethods(AssembliesType.Editor);
                foreach (var target in _targets)
                {
                    // Enable burst compilation by default (override globals for the inspector)
                    // This is not working as expected. This changes indirectly the global options while it shouldn't
                    // Unable to explain how it can happen
                    // so for now, if global enable burst compilation is disabled, then inspector is too
                    //target.Options.EnableBurstCompilation = true;
                }

                // Order targets per name
                _targets.Sort((left, right) => string.Compare(left.GetDisplayName(), right.GetDisplayName(), StringComparison.Ordinal));

                _treeView.Targets = _targets;
                _treeView.Reload();

                if (_selectedItem != null)
                {
                    _treeView.TrySelectByDisplayName(_selectedItem);
                }
            }

            if (_fontSizesText == null)
            {
                _fontSizesText = new string[FontSizes.Length];
                for (var i = 0; i < FontSizes.Length; ++i)
                {
                    _fontSizesText[i] = FontSizes[i].ToString();
                }
            }

            if (_fontSizeIndex == -1)
            {
                _fontSizeIndex = EditorPrefs.GetInt(FontSizeIndexPref, 5);
                _fontSizeIndex = Math.Max(0, _fontSizeIndex);
                _fontSizeIndex = Math.Min(_fontSizeIndex, FontSizes.Length - 1);
            }

            if (_fixedFontStyle == null)
            {
                _fixedFontStyle = new GUIStyle(GUI.skin.label);
                string fontName;
                if (Application.platform == RuntimePlatform.WindowsEditor)
                {
                    fontName = "Consolas";
                }
                else
                {
                    fontName = "Courier";
                }

                CleanupFont();

                _font = Font.CreateDynamicFontFromOSFont(fontName, FontSize);
                _fixedFontStyle.font     = _font;
                _fixedFontStyle.fontSize = FontSize;
            }

            if (_searchField == null)
            {
                _searchField = new SearchField();
            }

            if (_textArea == null)
            {
                _textArea = new LongTextArea();
            }

            GUILayout.BeginHorizontal();

            GUILayout.BeginVertical(GUILayout.Width(position.width / 3));

            GUILayout.Label("Compile Targets", EditorStyles.boldLabel);

            var newFilter = _searchField.OnGUI(_treeView.Filter);

            if (newFilter != _treeView.Filter)
            {
                _treeView.Filter = newFilter;
                _treeView.Reload();
            }

            _treeView.OnGUI(GUILayoutUtility.GetRect(GUIContent.none, GUIStyle.none, GUILayout.ExpandHeight(true),
                                                     GUILayout.ExpandWidth(true)));

            GUILayout.EndVertical();

            GUILayout.BeginVertical();

            var selection = _treeView.GetSelection();

            if (selection.Count == 1)
            {
                var id     = selection[0];
                var target = _targets[id - 1];
                // Stash selected item name to handle domain reloads more gracefully
                _selectedItem = target.GetDisplayName();

                bool doRefresh = false;
                bool doCopy    = false;
                int  fsi       = _fontSizeIndex;

                RenderButtonBars((position.width * 2) / 3, target, out doRefresh, out doCopy, out fsi);

                var disasm = target.Disassembly != null ? target.Disassembly[(int)_disasmKind] : null;


                var methodOptions = target.Options.Clone();

                if (doRefresh)
                {
                    // TODO: refactor this code with a proper AppendOption to avoid these "\n"
                    var options = new StringBuilder();

                    methodOptions.EnableBurstSafetyChecks = _safetyChecks;
                    methodOptions.EnableEnhancedAssembly  = _enhancedDisassembly;
                    methodOptions.DisableOptimizations    = !_optimizations;
                    methodOptions.EnableFastMath          = _fastMath;
                    // force synchronouze compilation for the inspector
                    methodOptions.EnableBurstCompileSynchronously = true;

                    string defaultOptions;
                    bool   debug; // We still show disassembly even if method has [BurstCompile(Debug = true)]
                    if (methodOptions.TryGetOptions(target.IsStaticMethod ? (MemberInfo)target.Method : target.JobType, true, out defaultOptions, out debug))
                    {
                        options.Append(defaultOptions);

                        options.AppendFormat("\n" + BurstCompilerOptions.GetOption(BurstCompilerOptions.OptionTarget, CodeGenOptions[_codeGenOptions]));

                        var baseOptions = options.ToString().Trim('\n', ' ');

                        target.Disassembly = new string[DisasmOptions.Length];

                        for (var i = 0; i < DisasmOptions.Length; ++i)
                        {
                            target.Disassembly[i] = GetDisassembly(target.Method, baseOptions + DisasmOptions[i]);
                        }

                        if (_enhancedDisassembly && (int)DisassemblyKind.Asm < target.Disassembly.Length)
                        {
                            var processor = new BurstDisassembler();
                            target.Disassembly[(int)DisassemblyKind.Asm] = processor.Process(target.Disassembly[(int)DisassemblyKind.Asm]);
                        }

                        disasm = target.Disassembly[(int)_disasmKind];
                    }
                }

                if (disasm != null)
                {
                    _textArea.Text = disasm;
                    _scrollPos     = GUILayout.BeginScrollView(_scrollPos);
                    _textArea.Render(_fixedFontStyle);
                    GUILayout.EndScrollView();
                }

                if (doCopy)
                {
                    EditorGUIUtility.systemCopyBuffer = disasm == null ? "" : disasm;
                }

                if (fsi != _fontSizeIndex)
                {
                    _fontSizeIndex = fsi;
                    EditorPrefs.SetInt(FontSizeIndexPref, fsi);
                    _fixedFontStyle = null;
                }
            }

            GUILayout.EndVertical();

            GUILayout.EndHorizontal();
        }
        public void OnGUI()
        {
            if (_targets == null)
            {
                _targets          = BurstReflection.FindExecuteMethods(AssembliesType.Editor);
                _treeView.Targets = _targets;
                _treeView.Reload();

                if (_selectedItem != null)
                {
                    _treeView.TrySelectByDisplayName(_selectedItem);
                }
            }

            if (_fontSizesText == null)
            {
                _fontSizesText = new string[FontSizes.Length];
                for (var i = 0; i < FontSizes.Length; ++i)
                {
                    _fontSizesText[i] = FontSizes[i].ToString();
                }
            }

            if (_fontSizeIndex == -1)
            {
                _fontSizeIndex = EditorPrefs.GetInt(FontSizeIndexPref, 5);
                _fontSizeIndex = Math.Max(0, _fontSizeIndex);
                _fontSizeIndex = Math.Min(_fontSizeIndex, FontSizes.Length - 1);
            }

            if (_fixedFontStyle == null)
            {
                _fixedFontStyle = new GUIStyle(GUI.skin.label);
                string fontName;
                if (Application.platform == RuntimePlatform.WindowsEditor)
                {
                    fontName = "Consolas";
                }
                else
                {
                    fontName = "Courier";
                }
                _fixedFontStyle.font = Font.CreateDynamicFontFromOSFont(fontName, FontSize);
            }

            if (_searchField == null)
            {
                _searchField = new SearchField();
            }

            if (_textArea == null)
            {
                _textArea = new LongTextArea();
            }

            GUILayout.BeginHorizontal();

            GUILayout.BeginVertical(GUILayout.Width(position.width / 3));

            GUILayout.Label("Compile Targets", EditorStyles.boldLabel);

            var newFilter = _searchField.OnGUI(_treeView.Filter);

            if (newFilter != _treeView.Filter)
            {
                _treeView.Filter = newFilter;
                _treeView.Reload();
            }

            _treeView.OnGUI(GUILayoutUtility.GetRect(GUIContent.none, GUIStyle.none, GUILayout.ExpandHeight(true),
                                                     GUILayout.ExpandWidth(true)));

            GUILayout.EndVertical();

            GUILayout.BeginVertical();

            var selection = _treeView.GetSelection();

            if (selection.Count == 1)
            {
                var id     = selection[0];
                var target = _targets[id - 1];
                // Stash selected item name to handle domain reloads more gracefully
                _selectedItem = target.GetDisplayName();

                GUILayout.BeginHorizontal();

                _enhancedDisassembly = GUILayout.Toggle(_enhancedDisassembly, "Enhanced Disassembly");
                _safetyChecks        = GUILayout.Toggle(_safetyChecks, "Safety Checks");
                _optimizations       = GUILayout.Toggle(_optimizations, "Optimizations");
                _fastMath            = GUILayout.Toggle(_fastMath, "Fast Math");
                EditorGUI.BeginDisabledGroup(!target.SupportsBurst);
                _codeGenOptions = EditorGUILayout.Popup(_codeGenOptions, CodeGenOptions);

                GUILayout.Label("Font Size");
                var fsi = EditorGUILayout.Popup(_fontSizeIndex, _fontSizesText);

                var doRefresh = GUILayout.Button("Refresh Disassembly");
                var doCopy    = GUILayout.Button("Copy to Clipboard");
                EditorGUI.EndDisabledGroup();

                GUILayout.EndHorizontal();

                _disasmKind = (DisassemblyKind)GUILayout.Toolbar((int)_disasmKind, DisassemblyKindNames);

                var disasm = target.Disassembly != null ? target.Disassembly[(int)_disasmKind] : null;

                if (doRefresh)
                {
                    // TODO: refactor this code with a proper AppendOption to avoid these "\n"
                    var options = new StringBuilder();
                    if (!_safetyChecks)
                    {
                        options.Append("\n" + GetOption(OptionDisableSafetyChecks) + "\n" + GetOption(OptionNoAlias));
                    }

                    if (_enhancedDisassembly)
                    {
                        options.Append("\n" + GetOption(OptionDebug));
                    }

                    if (!_optimizations)
                    {
                        options.Append("\n" + GetOption(OptionDisableOpt));
                    }

                    if (_fastMath)
                    {
                        options.Append("\n" + GetOption(OptionFastMath));
                    }

                    options.AppendFormat("\n" + GetOption(OptionTarget, CodeGenOptions[_codeGenOptions]));

                    var baseOptions = options.ToString().Trim('\n', ' ');

                    target.Disassembly = new string[DisasmOptions.Length];

                    for (var i = 0; i < DisasmOptions.Length; ++i)
                    {
                        target.Disassembly[i] = GetDisassembly(target.Method, baseOptions + DisasmOptions[i]);
                    }

                    if (_enhancedDisassembly && (int)DisassemblyKind.Asm < target.Disassembly.Length)
                    {
                        var processor = new BurstDisassembler();
                        target.Disassembly[(int)DisassemblyKind.Asm] = processor.Process(target.Disassembly[(int)DisassemblyKind.Asm]);
                    }

                    disasm = target.Disassembly[(int)_disasmKind];
                }

                if (disasm != null)
                {
                    _textArea.Text = disasm;
                    _scrollPos     = GUILayout.BeginScrollView(_scrollPos);
                    _textArea.Render(_fixedFontStyle);
                    GUILayout.EndScrollView();
                }

                if (doCopy)
                {
                    EditorGUIUtility.systemCopyBuffer = disasm == null ? "" : disasm;
                }

                if (fsi != _fontSizeIndex)
                {
                    _fontSizeIndex = fsi;
                    EditorPrefs.SetInt(FontSizeIndexPref, fsi);
                    _fixedFontStyle = null;
                }
            }

            GUILayout.EndVertical();

            GUILayout.EndHorizontal();
        }
示例#4
0
        public void OnGUI()
        {
            // Make sure that editor options are synchronized
            BurstEditorOptions.EnsureSynchronized();

            if (_targets == null)
            {
                _targets = BurstReflection.FindExecuteMethods(AssembliesType.Editor);
                foreach (var target in _targets)
                {
                    // Enable burst compilation by default (override globals for the inspector)
                    // This is not working as expected. This changes indirectly the global options while it shouldn't
                    // Unable to explain how it can happen
                    // so for now, if global enable burst compilation is disabled, then inspector is too
                    //target.Options.EnableBurstCompilation = true;
                }

                // Order targets per name
                _targets.Sort((left, right) => string.Compare(left.GetDisplayName(), right.GetDisplayName(), StringComparison.Ordinal));

                _treeView.Targets = _targets;
                _treeView.Reload();

                if (_selectedItem != null)
                {
                    _treeView.TrySelectByDisplayName(_selectedItem);
                }
            }

            if (_fontSizesText == null)
            {
                _fontSizesText = new string[FontSizes.Length];
                for (var i = 0; i < FontSizes.Length; ++i)
                {
                    _fontSizesText[i] = FontSizes[i].ToString();
                }
            }

            if (_fontSizeIndex == -1)
            {
                _fontSizeIndex = EditorPrefs.GetInt(FontSizeIndexPref, 5);
                _fontSizeIndex = Math.Max(0, _fontSizeIndex);
                _fontSizeIndex = Math.Min(_fontSizeIndex, FontSizes.Length - 1);
            }

            if (_fixedFontStyle == null)
            {
                _fixedFontStyle = new GUIStyle(GUI.skin.label);
                string fontName;
                if (Application.platform == RuntimePlatform.WindowsEditor)
                {
                    fontName = "Consolas";
                }
                else
                {
                    fontName = "Courier";
                }

                CleanupFont();

                _font = Font.CreateDynamicFontFromOSFont(fontName, FontSize);
                _fixedFontStyle.font     = _font;
                _fixedFontStyle.fontSize = FontSize;
            }

            if (_searchField == null)
            {
                _searchField = new SearchField();
            }

            if (_textArea == null)
            {
                _textArea = new LongTextArea();
            }

            GUILayout.BeginHorizontal();

            // SplitterGUILayout.BeginHorizontalSplit is internal in Unity but we don't have much choice
            SplitterGUILayout.BeginHorizontalSplit(TreeViewSplitterState);

            GUILayout.BeginVertical(GUILayout.Width(position.width / 3));

            GUILayout.Label("Compile Targets", EditorStyles.boldLabel);

            var newFilter = _searchField.OnGUI(_treeView.Filter);

            if (newFilter != _treeView.Filter)
            {
                _treeView.Filter = newFilter;
                _treeView.Reload();
            }

            _treeView.OnGUI(GUILayoutUtility.GetRect(GUIContent.none, GUIStyle.none, GUILayout.ExpandHeight(true), GUILayout.ExpandWidth(true)));

            GUILayout.EndVertical();

            GUILayout.BeginVertical();

            var selection = _treeView.GetSelection();

            if (selection.Count == 1)
            {
                var targetIndex   = selection[0];
                var target        = _targets[targetIndex - 1];
                var targetOptions = target.Options;

                // Stash selected item name to handle domain reloads more gracefully
                _selectedItem = target.GetDisplayName();

                // Refresh if any options are changed
                bool doCopy;
                int  fontSize;
                // -14 to add a little bit of space for the vertical scrollbar to display correctly
                RenderButtonBars((position.width * 2) / 3 - 14, target, out doCopy, out fontSize);

                // We are currently formatting only Asm output
                var isTextFormatted = _enhancedDisassembly && _disasmKind == DisassemblyKind.Asm;

                // Depending if we are formatted or not, we don't render the same text
                var textToRender = isTextFormatted ? target.FormattedDisassembly : target.RawDisassembly;

                // Only refresh if we are switching to a new selection that hasn't been disassembled yet
                // Or we are changing disassembly settings (safety checks / enhanced disassembly)
                var targetRefresh = textToRender == null ||
                                    target.DisassemblyKind != _disasmKind ||
                                    targetOptions.EnableBurstSafetyChecks != _safetyChecks ||
                                    target.TargetCpu != _targetCpu ||
                                    target.IsDarkMode != EditorGUIUtility.isProSkin;

                bool targetChanged = _previousTargetIndex != targetIndex;

                _previousTargetIndex = targetIndex;

                if (targetRefresh)
                {
                    // TODO: refactor this code with a proper AppendOption to avoid these "\n"
                    var options = new StringBuilder();

                    target.TargetCpu       = _targetCpu;
                    target.DisassemblyKind = _disasmKind;
                    targetOptions.EnableBurstSafetyChecks = _safetyChecks;
                    target.IsDarkMode = EditorGUIUtility.isProSkin;
                    targetOptions.EnableBurstCompileSynchronously = true;

                    string defaultOptions;
                    if (targetOptions.TryGetOptions(target.IsStaticMethod ? (MemberInfo)target.Method : target.JobType, true, out defaultOptions))
                    {
                        options.Append(defaultOptions);

                        options.AppendFormat("\n" + BurstCompilerOptions.GetOption(BurstCompilerOptions.OptionTarget, TargetCpuNames[(int)_targetCpu]));

                        options.AppendFormat("\n" + BurstCompilerOptions.GetOption(BurstCompilerOptions.OptionDebug));

                        var baseOptions = options.ToString().Trim('\n', ' ');

                        target.RawDisassembly = GetDisassembly(target.Method, baseOptions + DisasmOptions[(int)_disasmKind]);

                        if (isTextFormatted)
                        {
                            // Store the formatted version
                            target.FormattedDisassembly = _burstDisassembler.Process(target.RawDisassembly, IsIntel(_targetCpu) ? BurstDisassembler.AsmKind.Intel : BurstDisassembler.AsmKind.ARM, target.IsDarkMode);
                            textToRender = target.FormattedDisassembly;
                        }
                        else
                        {
                            target.FormattedDisassembly = null;
                            textToRender = target.RawDisassembly;
                        }
                    }
                }

                if (textToRender != null)
                {
                    _textArea.Text = textToRender;
                    if (targetChanged)
                    {
                        _scrollPos = Vector2.zero;
                    }
                    _scrollPos = GUILayout.BeginScrollView(_scrollPos, true, true);
                    _textArea.Render(_fixedFontStyle);
                    GUILayout.EndScrollView();
                }

                if (doCopy)
                {
                    // When copying to the clipboard, we copy the non-formatted version
                    EditorGUIUtility.systemCopyBuffer = target.RawDisassembly ?? string.Empty;
                }

                if (fontSize != _fontSizeIndex)
                {
                    _fontSizeIndex = fontSize;
                    EditorPrefs.SetInt(FontSizeIndexPref, fontSize);
                    _fixedFontStyle = null;
                }
            }

            GUILayout.EndVertical();

            SplitterGUILayout.EndHorizontalSplit();

            GUILayout.EndHorizontal();
        }