void SyncDeviceSettingsToSimulator() { SimulatorAdaptivePerformanceSubsystem subsystem = Subsystem(); if (subsystem == null) { return; } subsystem.SetClusterInfo(m_ClusterInfo); }
SimulatorAdaptivePerformanceSubsystem Subsystem() { if (!Application.isPlaying) { return(null); } var loader = AdaptivePerformanceGeneralSettings.Instance?.Manager.activeLoader; if (m_Subsystem == null && loader != null) { m_Subsystem = loader.GetLoadedSubsystem <SimulatorAdaptivePerformanceSubsystem>(); } return(m_Subsystem); }
void SetBottleneck(PerformanceBottleneck performanceBottleneck, SimulatorAdaptivePerformanceSubsystem subsystem) { if (subsystem == null) { return; } var targetFrameRate = Application.targetFrameRate; // default target framerate is -1 to use default platform framerate so we assume it's 60 if (targetFrameRate == -1) { targetFrameRate = 60; } var currentTargetFramerateHalfMS = 1.0f / targetFrameRate / 2.0f; var currentTargetFramerateMS = 1.0f / targetFrameRate; switch (performanceBottleneck) { case PerformanceBottleneck.CPU: // averageOverallFrametime > targetFramerate && averageCpuFrametime >= averageOverallFrametime subsystem.NextCpuFrameTime = currentTargetFramerateMS + 0.001f; subsystem.NextGpuFrameTime = currentTargetFramerateHalfMS; subsystem.NextOverallFrameTime = currentTargetFramerateMS + 0.001f; break; case PerformanceBottleneck.GPU: // averageOverallFrametime > targetFramerate && averageGpuFrametime >= averageOverallFrametime subsystem.NextCpuFrameTime = currentTargetFramerateHalfMS; subsystem.NextGpuFrameTime = currentTargetFramerateMS + 0.001f; subsystem.NextOverallFrameTime = currentTargetFramerateMS + 0.001f; break; case PerformanceBottleneck.TargetFrameRate: // averageOverallFrametime == targetFramerate subsystem.NextCpuFrameTime = currentTargetFramerateHalfMS; subsystem.NextGpuFrameTime = currentTargetFramerateHalfMS; subsystem.NextOverallFrameTime = currentTargetFramerateMS; break; //PerformanceBottleneck.Unknowe - averageOverallFrametime > targetFramerate default: subsystem.NextCpuFrameTime = currentTargetFramerateHalfMS; subsystem.NextGpuFrameTime = currentTargetFramerateHalfMS; subsystem.NextOverallFrameTime = currentTargetFramerateMS + 0.001f; break; } }
public void OnExtendDeviceSimulator(VisualElement visualElement) { m_ExtensionFoldout = visualElement; #endif var tree = AssetDatabase.LoadAssetAtPath <VisualTreeAsset>("Packages/com.unity.adaptiveperformance/Editor/DeviceSimulator/AdaptivePerformanceExtension.uxml"); if (tree == null) { Label warningLabel = new Label("Simulator provider is not installed. Please install and enable the provider in Project Settings > Adaptive Performance > Standalone > Providers. After installation, close and reopen the Device Simulator to take effect."); warningLabel.style.whiteSpace = WhiteSpace.Normal; m_ExtensionFoldout.Add(warningLabel); #if UNITY_2021_1_OR_NEWER return(m_ExtensionFoldout); #else return; #endif } m_ExtensionFoldout.Add(tree.CloneTree()); m_ThermalFoldout = m_ExtensionFoldout.Q <Foldout>("thermal"); m_ThermalFoldout.value = m_SerializationStates.thermalFoldout; m_WarningLevel = m_ExtensionFoldout.Q <EnumField>("thermal-warning-level"); m_TemperatureLevel = m_ExtensionFoldout.Q <Slider>("thermal-temperature-level"); m_TemperatureLevelField = m_ExtensionFoldout.Q <FloatField>("thermal-temperature-level-field"); m_TemperatureTrend = m_ExtensionFoldout.Q <Slider>("thermal-temperature-trend"); m_TemperatureTrendField = m_ExtensionFoldout.Q <FloatField>("thermal-temperature-trend-field"); m_PerformanceFoldout = m_ExtensionFoldout.Q <Foldout>("performance"); m_PerformanceFoldout.value = m_SerializationStates.performanceFoldout; m_TargetFPS = m_ExtensionFoldout.Q <SliderInt>("performance-target-fps"); m_TargetFPSField = m_ExtensionFoldout.Q <IntegerField>("performance-target-fps-field"); m_ControlAutoMode = m_ExtensionFoldout.Q <Toggle>("performance-control-auto-mode"); m_CpuLevel = m_ExtensionFoldout.Q <SliderInt>("performance-cpu-level"); m_CpuLevelField = m_ExtensionFoldout.Q <IntegerField>("performance-cpu-level-field"); m_GpuLevel = m_ExtensionFoldout.Q <SliderInt>("performance-gpu-level"); m_GpuLevelField = m_ExtensionFoldout.Q <IntegerField>("performance-gpu-level-field"); m_CpuBoost = m_ExtensionFoldout.Q <Toggle>("performance-control-cpu-boost"); m_GpuBoost = m_ExtensionFoldout.Q <Toggle>("performance-control-gpu-boost"); m_Bottleneck = m_ExtensionFoldout.Q <EnumField>("performance-bottleneck"); m_DevLogging = m_ExtensionFoldout.Q <Toggle>("developer-logging"); m_DevLoggingFrequency = m_ExtensionFoldout.Q <IntegerField>("developer-logging-frequency"); m_DeveloperFoldout = m_ExtensionFoldout.Q <Foldout>("developer-options"); m_DeveloperFoldout.value = m_SerializationStates.developerFoldout; m_IndexerFoldout = m_ExtensionFoldout.Q <Foldout>("indexer"); m_IndexerFoldout.value = m_SerializationStates.indexerFoldout; m_ThermalAction = m_IndexerFoldout.Q <EnumField>("indexer-thermal-action"); m_PerformanceAction = m_IndexerFoldout.Q <EnumField>("indexer-performance-action"); m_ScalersFoldout = m_ExtensionFoldout.Q <Foldout>("scalers"); m_ScalersFoldout.value = m_SerializationStates.scalersFoldout; m_DeviceSettingsFoldout = m_ExtensionFoldout.Q <Foldout>("device-settings"); m_DeviceSettingsFoldout.value = m_SerializationStates.deviceSettingsFoldout; m_BigCores = m_ExtensionFoldout.Q <IntegerField>("cluster-info-big-cores"); m_MediumCores = m_ExtensionFoldout.Q <IntegerField>("cluster-info-medium-cores"); m_LittleCores = m_ExtensionFoldout.Q <IntegerField>("cluster-info-little-cores"); // Create settings for each one of the scalers Type ti = typeof(AdaptivePerformanceScaler); var scalerTree = AssetDatabase.LoadAssetAtPath <VisualTreeAsset>("Packages/com.unity.adaptiveperformance/Editor/DeviceSimulator/ScalerControl.uxml"); foreach (Assembly asm in AppDomain.CurrentDomain.GetAssemblies()) { foreach (Type t in asm.GetTypes()) { if (ti.IsAssignableFrom(t) && !t.IsAbstract) { var scalerInstance = ScriptableObject.CreateInstance(t) as AdaptivePerformanceScaler; if (scalerInstance == null) { continue; } // Load the UI elements var container = scalerTree.CloneTree(); var foldout = container.Q <Foldout>("scaler"); var toggle = container.Q <Toggle>("scaler-toggle"); var valueField = container.Q <IntegerField>("scaler-value"); var maxLevelField = container.Q <IntegerField>("scaler-max-level-value"); var minValueField = container.Q <FloatField>("scaler-min-value"); var maxValueField = container.Q <FloatField>("scaler-max-value"); // Set the values and additional config for these elements toggle.value = scalerInstance.Enabled; toggle.name = $"{t.Name}-scaler-toggle"; valueField.value = scalerInstance.CurrentLevel; valueField.name = $"{t.Name}-scaler-value"; valueField.SetEnabled(scalerInstance.Enabled); maxLevelField.value = scalerInstance.MaxLevel; maxLevelField.name = $"{t.Name}-scaler-max-level-value"; maxLevelField.SetEnabled(scalerInstance.Enabled); minValueField.value = scalerInstance.MinBound; minValueField.name = $"{t.Name}-scaler-min-value"; minValueField.SetEnabled(scalerInstance.Enabled); maxValueField.value = scalerInstance.MaxBound; maxValueField.name = $"{t.Name}-scaler-max-value"; maxValueField.SetEnabled(scalerInstance.Enabled); foldout.text = t.Name.Substring(8); // Now set up the callback actions toggle.RegisterCallback <ChangeEvent <bool> >(evt => { var scaler = FindScalerObject(t); if (scaler == null) { return; } scaler.Enabled = evt.newValue; valueField.SetEnabled(evt.newValue); maxLevelField.SetEnabled(evt.newValue); minValueField.SetEnabled(evt.newValue); maxValueField.SetEnabled(evt.newValue); }); valueField.RegisterCallback <ChangeEvent <int> >(evt => { var scaler = FindScalerObject(t); if (evt.newValue < 0 || scaler == null) { valueField.SetValueWithoutNotify(0); return; } else if (evt.newValue > scaler.MaxLevel) { valueField.SetValueWithoutNotify(scaler.MaxLevel); return; } scaler.OverrideLevel = Mathf.Clamp(evt.newValue, 0, scaler.MaxLevel); valueField.SetValueWithoutNotify(scaler.OverrideLevel); }); maxLevelField.RegisterCallback <ChangeEvent <int> >(evt => { var scaler = FindScalerObject(t); if (evt.newValue < 1 || scaler == null) { maxLevelField.SetValueWithoutNotify(1); return; } else if (evt.newValue > 100) { maxLevelField.SetValueWithoutNotify(100); return; } scaler.MaxLevel = evt.newValue; }); minValueField.RegisterCallback <ChangeEvent <float> >(evt => { var scaler = FindScalerObject(t); if (evt.newValue < 0 || scaler == null) { minValueField.SetValueWithoutNotify(0); return; } else if (evt.newValue > 10000) { minValueField.SetValueWithoutNotify(10000); return; } else if (evt.newValue > maxValueField.value) { minValueField.SetValueWithoutNotify(maxValueField.value); return; } scaler.MinBound = evt.newValue; }); maxValueField.RegisterCallback <ChangeEvent <float> >(evt => { var scaler = FindScalerObject(t); if (evt.newValue < minValueField.value || scaler == null) { maxValueField.SetValueWithoutNotify(minValueField.value); return; } else if (evt.newValue > 10000) { maxValueField.SetValueWithoutNotify(10000); return; } scaler.MaxBound = evt.newValue; }); m_ScalersFoldout.Add(container); } } } m_WarningLevel.RegisterCallback <ChangeEvent <Enum> >(evt => { SimulatorAdaptivePerformanceSubsystem subsystem = Subsystem(); if (subsystem == null) { return; } subsystem.WarningLevel = (WarningLevel)evt.newValue; }); m_TemperatureLevel.RegisterCallback <ChangeEvent <float> >(evt => { m_TemperatureLevelField.value = evt.newValue; SimulatorAdaptivePerformanceSubsystem subsystem = Subsystem(); if (subsystem == null) { return; } subsystem.TemperatureLevel = evt.newValue; }); m_TemperatureLevelField.RegisterCallback <ChangeEvent <float> >(evt => { var newTemperatureLevel = evt.newValue; if (newTemperatureLevel < m_TemperatureLevel.lowValue) { newTemperatureLevel = m_TemperatureLevel.lowValue; m_TemperatureLevelField.value = newTemperatureLevel; } if (newTemperatureLevel > m_TemperatureLevel.highValue) { newTemperatureLevel = m_TemperatureLevel.highValue; m_TemperatureLevelField.value = newTemperatureLevel; } m_TemperatureLevel.value = newTemperatureLevel; SimulatorAdaptivePerformanceSubsystem subsystem = Subsystem(); if (subsystem == null) { return; } subsystem.TemperatureLevel = newTemperatureLevel; }); m_TemperatureTrend.RegisterCallback <ChangeEvent <float> >(evt => { m_TemperatureTrendField.value = evt.newValue; SimulatorAdaptivePerformanceSubsystem subsystem = Subsystem(); if (subsystem == null) { return; } subsystem.TemperatureTrend = evt.newValue; }); m_TemperatureTrendField.RegisterCallback <ChangeEvent <float> >(evt => { var newTemperatureTrend = evt.newValue; if (newTemperatureTrend < m_TemperatureTrend.lowValue) { newTemperatureTrend = m_TemperatureTrend.lowValue; m_TemperatureTrendField.value = newTemperatureTrend; } if (newTemperatureTrend > m_TemperatureTrend.highValue) { newTemperatureTrend = m_TemperatureTrend.highValue; m_TemperatureTrendField.value = newTemperatureTrend; } m_TemperatureTrend.value = newTemperatureTrend; SimulatorAdaptivePerformanceSubsystem subsystem = Subsystem(); if (subsystem == null) { return; } subsystem.TemperatureTrend = newTemperatureTrend; }); m_TargetFPS.RegisterCallback <ChangeEvent <int> >(evt => { // sync value field m_TargetFPSField.value = evt.newValue; Application.targetFrameRate = evt.newValue; SetBottleneck((PerformanceBottleneck)m_Bottleneck.value, Subsystem()); }); m_TargetFPSField.RegisterCallback <ChangeEvent <int> >(evt => { var newTargetFPS = evt.newValue; if (newTargetFPS < m_TargetFPS.lowValue) { newTargetFPS = m_TargetFPS.lowValue; m_TargetFPSField.SetValueWithoutNotify(newTargetFPS); } if (newTargetFPS > m_TargetFPS.highValue) { newTargetFPS = m_TargetFPS.highValue; m_TargetFPSField.SetValueWithoutNotify(newTargetFPS); } m_TargetFPS.value = newTargetFPS; Application.targetFrameRate = newTargetFPS; SetBottleneck((PerformanceBottleneck)m_Bottleneck.value, Subsystem()); }); m_ControlAutoMode.RegisterCallback <ChangeEvent <bool> >((evt) => { var ap = Holder.Instance; if (ap == null) { return; } var ctrl = ap.DevicePerformanceControl; ctrl.AutomaticPerformanceControl = evt.newValue; SimulatorAdaptivePerformanceSubsystem subsystem = Subsystem(); if (subsystem == null) { return; } subsystem.AcceptsPerformanceLevel = true; }); m_CpuLevel.RegisterCallback <ChangeEvent <int> >(evt => { // sync value field m_CpuLevelField.value = evt.newValue; var ap = Holder.Instance; if (ap == null) { return; } ap.DevicePerformanceControl.CpuLevel = evt.newValue; }); m_CpuLevelField.RegisterCallback <ChangeEvent <int> >(evt => { var newCPULevel = evt.newValue; if (newCPULevel < m_CpuLevel.lowValue) { newCPULevel = m_CpuLevel.lowValue; m_CpuLevelField.SetValueWithoutNotify(newCPULevel); } if (newCPULevel > m_CpuLevel.highValue) { newCPULevel = m_CpuLevel.highValue; m_CpuLevelField.SetValueWithoutNotify(newCPULevel); } m_CpuLevel.value = newCPULevel; var ap = Holder.Instance; if (ap == null) { return; } ap.DevicePerformanceControl.CpuLevel = newCPULevel; }); m_GpuLevel.RegisterCallback <ChangeEvent <int> >(evt => { // sync value field m_GpuLevelField.value = evt.newValue; var ap = Holder.Instance; if (ap == null) { return; } ap.DevicePerformanceControl.GpuLevel = evt.newValue; }); m_GpuLevelField.RegisterCallback <ChangeEvent <int> >(evt => { var newGPULevel = evt.newValue; if (newGPULevel < m_GpuLevel.lowValue) { newGPULevel = m_GpuLevel.lowValue; m_GpuLevelField.SetValueWithoutNotify(newGPULevel); } if (newGPULevel > m_GpuLevel.highValue) { newGPULevel = m_GpuLevel.highValue; m_GpuLevelField.SetValueWithoutNotify(newGPULevel); } m_GpuLevel.value = newGPULevel; var ap = Holder.Instance; if (ap == null) { return; } ap.DevicePerformanceControl.GpuLevel = newGPULevel; }); m_CpuBoost.RegisterCallback <ChangeEvent <bool> >((evt) => { var ap = Holder.Instance; if (ap == null) { return; } if (evt.newValue) { var ctrl = ap.DevicePerformanceControl; ctrl.CpuPerformanceBoost = evt.newValue; m_GpuBoost.SetEnabled(false); } else { SimulatorAdaptivePerformanceSubsystem subsystem = Subsystem(); if (subsystem == null) { return; } subsystem.CpuPerformanceBoost = false; } }); m_GpuBoost.RegisterCallback <ChangeEvent <bool> >((evt) => { var ap = Holder.Instance; if (ap == null) { return; } if (evt.newValue) { var ctrl = ap.DevicePerformanceControl; ctrl.GpuPerformanceBoost = evt.newValue; m_GpuBoost.SetEnabled(false); } else { SimulatorAdaptivePerformanceSubsystem subsystem = Subsystem(); if (subsystem == null) { return; } subsystem.GpuPerformanceBoost = false; } }); m_Bottleneck.RegisterCallback <ChangeEvent <Enum> >(evt => { SimulatorAdaptivePerformanceSubsystem subsystem = Subsystem(); if (subsystem == null) { return; } SetBottleneck((PerformanceBottleneck)evt.newValue, subsystem); }); m_DevLogging.RegisterCallback <ChangeEvent <bool> >((evt) => { var ap = Holder.Instance; if (ap == null) { return; } var devSettings = ap.DevelopmentSettings; devSettings.Logging = evt.newValue; }); m_DevLoggingFrequency.RegisterCallback <ChangeEvent <int> >(evt => { var ap = Holder.Instance; if (ap == null) { return; } var devSettings = ap.DevelopmentSettings; devSettings.LoggingFrequencyInFrames = evt.newValue; }); m_ThermalAction.RegisterCallback <ChangeEvent <Enum> >(evt => { var ap = Holder.Instance; if (ap == null) { return; } var indexer = ap.Indexer; if (indexer == null) { return; } SimulatorAdaptivePerformanceSubsystem subsystem = Subsystem(); if (subsystem == null) { return; } var temperatureTrend = 0.0f; var warningLevel = WarningLevel.NoWarning; var temperatureLevel = 0.0f; switch (evt.newValue) { case StateAction.Stale: temperatureTrend = 0; warningLevel = WarningLevel.Throttling; temperatureLevel = 0.7f; break; case StateAction.Decrease: temperatureTrend = 0.3f; warningLevel = WarningLevel.Throttling; temperatureLevel = 0.7f; break; case StateAction.FastDecrease: temperatureTrend = 0.6f; warningLevel = WarningLevel.Throttling; temperatureLevel = 1.0f; break; case StateAction.Increase: temperatureTrend = 0; warningLevel = WarningLevel.NoWarning; temperatureLevel = 0.2f; break; } // Set subsystem values subsystem.TemperatureLevel = temperatureLevel; subsystem.TemperatureTrend = temperatureTrend; subsystem.WarningLevel = warningLevel; // Update the UI to match m_TemperatureLevel.SetValueWithoutNotify(temperatureLevel); m_TemperatureTrend.SetValueWithoutNotify(temperatureTrend); m_WarningLevel.SetValueWithoutNotify(warningLevel); }); m_PerformanceAction.RegisterCallback <ChangeEvent <Enum> >(evt => { var ap = Holder.Instance; if (ap == null) { return; } var indexer = ap.Indexer; if (indexer == null) { return; } SimulatorAdaptivePerformanceSubsystem subsystem = Subsystem(); if (subsystem == null) { return; } var targetFrameRate = Application.targetFrameRate; if (m_OriginalTargetFramerate == 0) { m_OriginalTargetFramerate = targetFrameRate; } // default target framerate is -1 to use default platform framerate so we assume it's 60 if (targetFrameRate == -1) { targetFrameRate = 60; } var frameMs = Holder.Instance.PerformanceStatus.FrameTiming.AverageFrameTime; switch (evt.newValue) { case StateAction.Increase: case StateAction.Stale: targetFrameRate = m_OriginalTargetFramerate; break; case StateAction.Decrease: targetFrameRate = (int)((1.0f + 0.2f) / frameMs); break; case StateAction.FastDecrease: targetFrameRate = (int)((1.0f + 0.4f) / frameMs); break; } Application.targetFrameRate = targetFrameRate; }); m_BigCores.RegisterCallback <ChangeEvent <int> >(evt => { SimulatorAdaptivePerformanceSubsystem subsystem = Subsystem(); if (subsystem == null) { return; } m_ClusterInfo.BigCore = evt.newValue; subsystem.SetClusterInfo(m_ClusterInfo); }); m_MediumCores.RegisterCallback <ChangeEvent <int> >(evt => { SimulatorAdaptivePerformanceSubsystem subsystem = Subsystem(); if (subsystem == null) { return; } m_ClusterInfo.MediumCore = evt.newValue; subsystem.SetClusterInfo(m_ClusterInfo); }); m_LittleCores.RegisterCallback <ChangeEvent <int> >(evt => { SimulatorAdaptivePerformanceSubsystem subsystem = Subsystem(); if (subsystem == null) { return; } m_ClusterInfo.LittleCore = evt.newValue; subsystem.SetClusterInfo(m_ClusterInfo); }); EditorApplication.playModeStateChanged += LogPlayModeState; SyncAPSubsystemSettingsToEditor(); #if UNITY_2021_1_OR_NEWER return(m_ExtensionFoldout); #endif }