public IEnumerator PerformanceLevelChangeEvent_Works() { var subsystem = AdaptivePerformance.StartupSettings.PreferredSubsystem as AdaptivePerformance.Provider.TestAdaptivePerformanceSubsystem; var ap = AdaptivePerformance.Holder.Instance; var ctrl = ap.DevicePerformanceControl; ctrl.AutomaticPerformanceControl = false; var ps = ap.PerformanceStatus; ctrl.CpuLevel = 1; ctrl.GpuLevel = 2; yield return(null); Assert.AreEqual(1, ps.PerformanceMetrics.CurrentCpuLevel); Assert.AreEqual(2, ps.PerformanceMetrics.CurrentGpuLevel); var eventArgs = new AdaptivePerformance.PerformanceLevelChangeEventArgs(); AdaptivePerformance.PerformanceLevelChangeHandler eventHandler = delegate(AdaptivePerformance.PerformanceLevelChangeEventArgs args) { eventArgs = args; }; ps.PerformanceLevelChangeEvent += eventHandler; ctrl.CpuLevel = 4; ctrl.GpuLevel = 0; yield return(null); Assert.AreEqual(4, ps.PerformanceMetrics.CurrentCpuLevel); Assert.AreEqual(4, eventArgs.CpuLevel); Assert.AreEqual(0, ps.PerformanceMetrics.CurrentGpuLevel); Assert.AreEqual(0, eventArgs.GpuLevel); Assert.AreEqual(3, eventArgs.CpuLevelDelta); Assert.AreEqual(-2, eventArgs.GpuLevelDelta); Assert.AreEqual(false, eventArgs.ManualOverride); Assert.AreEqual(AdaptivePerformance.PerformanceControlMode.Manual, eventArgs.PerformanceControlMode); }
private void UpdateSubsystem() { Provider.PerformanceDataRecord updateResult = m_Subsystem.Update(); m_PerformanceMetrics.CurrentCpuLevel = updateResult.CpuPerformanceLevel; m_PerformanceMetrics.CurrentGpuLevel = updateResult.GpuPerformanceLevel; m_ThermalMetrics.WarningLevel = updateResult.WarningLevel; m_ThermalMetrics.TemperatureLevel = updateResult.TemperatureLevel; if (!m_JustResumed) { // Update overall frame time m_OverallFrameTime.AddValue(m_Subsystem.Capabilities.HasFlag(Provider.Feature.OverallFrameTime) ? updateResult.OverallFrameTime : Time.unscaledDeltaTime); AddNonNegativeValue(m_GpuFrameTime, updateResult.GpuFrameTime); AddNonNegativeValue(m_CpuFrameTime, m_CpuFrameTimeProvider != null ? m_CpuFrameTimeProvider.CpuFrameTime : updateResult.CpuFrameTime); m_TemperatureTrend.Update(updateResult.TemperatureTrend, updateResult.TemperatureLevel, updateResult.ChangeFlags.HasFlag(Provider.Feature.TemperatureLevel), Time.time); } else { m_TemperatureTrend.Reset(updateResult.TemperatureTrend, updateResult.TemperatureLevel, Time.time); m_JustResumed = false; } m_ThermalMetrics.TemperatureTrend = m_TemperatureTrend.ThermalTrend; // Update frame timing info and calculate performance bottleneck m_FrameTiming.AverageFrameTime = m_OverallFrameTime.GetAverage(); m_FrameTiming.CurrentFrameTime = m_OverallFrameTime.GetMostRecentValue(); m_FrameTiming.AverageGpuFrameTime = m_GpuFrameTime.GetAverage(); m_FrameTiming.CurrentGpuFrameTime = m_GpuFrameTime.GetMostRecentValue(); m_FrameTiming.AverageCpuFrameTime = m_CpuFrameTime.GetAverage(); m_FrameTiming.CurrentCpuFrameTime = m_CpuFrameTime.GetMostRecentValue(); float targerFrameRate = EffectiveTargetFrameRate(); float targetFrameTime = -1.0f; if (targerFrameRate > 0) { targetFrameTime = 1.0f / targerFrameRate; } if (m_OverallFrameTime.GetNumValues() == m_OverallFrameTime.GetSampleWindowSize() && m_GpuFrameTime.GetNumValues() == m_GpuFrameTime.GetSampleWindowSize()) { PerformanceBottleneck bottleneck = BottleneckUtil.DetermineBottleneck(m_PerformanceMetrics.PerformanceBottleneck, m_FrameTiming.AverageCpuFrameTime, m_FrameTiming.AverageGpuFrameTime, m_FrameTiming.AverageFrameTime, targetFrameTime); if (bottleneck != m_PerformanceMetrics.PerformanceBottleneck) { m_PerformanceMetrics.PerformanceBottleneck = bottleneck; var args = new PerformanceBottleneckChangeEventArgs(); args.PerformanceBottleneck = bottleneck; if (PerformanceBottleneckChangeEvent != null) { PerformanceBottleneckChangeEvent.Invoke(args); } } } if (updateResult.ChangeFlags.HasFlag(Provider.Feature.WarningLevel) || updateResult.ChangeFlags.HasFlag(Provider.Feature.TemperatureLevel) || updateResult.ChangeFlags.HasFlag(Provider.Feature.TemperatureTrend)) { if (ThermalEvent != null) { ThermalEvent.Invoke(m_ThermalMetrics); } } // Update PerformanceControlMode if (updateResult.ChangeFlags.HasFlag(Provider.Feature.PerformanceLevelControl)) { if (updateResult.PerformanceLevelControlAvailable) { if (AutomaticPerformanceControl) { m_DevicePerfControl.PerformanceControlMode = PerformanceControlMode.Automatic; } else { m_DevicePerfControl.PerformanceControlMode = PerformanceControlMode.Manual; } } else { m_DevicePerfControl.PerformanceControlMode = PerformanceControlMode.System; } } // Apply performance levels according to PerformanceControlMode m_AutoPerformanceLevelController.TargetFrameTime = targetFrameTime; m_AutoPerformanceLevelController.Enabled = (m_DevicePerfControl.PerformanceControlMode == PerformanceControlMode.Automatic); PerformanceLevelChangeEventArgs levelChangeEventArgs = new PerformanceLevelChangeEventArgs(); if (m_DevicePerfControl.PerformanceControlMode != PerformanceControlMode.System) { if (m_AutoPerformanceLevelController.Enabled) { if (m_NewUserPerformanceLevelRequest) { m_AutoPerformanceLevelController.Override(m_RequestedCpuLevel, m_RequestedGpuLevel); levelChangeEventArgs.ManualOverride = true; } m_AutoPerformanceLevelController.Update(); } else { m_DevicePerfControl.CpuLevel = m_RequestedCpuLevel; m_DevicePerfControl.GpuLevel = m_RequestedGpuLevel; } } if (m_DevicePerfControl.Update(out levelChangeEventArgs) && PerformanceLevelChangeEvent != null) { PerformanceLevelChangeEvent.Invoke(levelChangeEventArgs); } m_PerformanceMetrics.CurrentCpuLevel = m_DevicePerfControl.CurrentCpuLevel; m_PerformanceMetrics.CurrentGpuLevel = m_DevicePerfControl.CurrentGpuLevel; m_NewUserPerformanceLevelRequest = false; }
private void UpdateSubsystem() { Provider.PerformanceDataRecord updateResult = m_Subsystem.Update(); m_ThermalMetrics.WarningLevel = updateResult.WarningLevel; m_ThermalMetrics.TemperatureLevel = updateResult.TemperatureLevel; if (!m_JustResumed) { // Update overall frame time if (!m_UseProviderOverallFrameTime) { AccumulateTimingValue(ref m_OverallFrameTimeAccu, Time.unscaledDeltaTime); } if (WillCurrentFrameRender()) { AddNonNegativeValue(m_OverallFrameTime, m_UseProviderOverallFrameTime ? updateResult.OverallFrameTime : m_OverallFrameTimeAccu); AddNonNegativeValue(m_GpuFrameTime, m_GpuFrameTimeProvider == null ? updateResult.GpuFrameTime : m_GpuFrameTimeProvider.GpuFrameTime); AddNonNegativeValue(m_CpuFrameTime, m_CpuFrameTimeProvider == null ? updateResult.CpuFrameTime : m_CpuFrameTimeProvider.CpuFrameTime); m_OverallFrameTimeAccu = 0.0f; } m_TemperatureTrend.Update(updateResult.TemperatureTrend, updateResult.TemperatureLevel, updateResult.ChangeFlags.HasFlag(Provider.Feature.TemperatureLevel), Time.time); } else { m_TemperatureTrend.Reset(); m_JustResumed = false; } m_ThermalMetrics.TemperatureTrend = m_TemperatureTrend.ThermalTrend; // Update frame timing info and calculate performance bottleneck const float invalidTimingValue = -1.0f; m_FrameTiming.AverageFrameTime = m_OverallFrameTime.GetAverageOr(invalidTimingValue); m_FrameTiming.CurrentFrameTime = m_OverallFrameTime.GetMostRecentValueOr(invalidTimingValue); m_FrameTiming.AverageGpuFrameTime = m_GpuFrameTime.GetAverageOr(invalidTimingValue); m_FrameTiming.CurrentGpuFrameTime = m_GpuFrameTime.GetMostRecentValueOr(invalidTimingValue); m_FrameTiming.AverageCpuFrameTime = m_CpuFrameTime.GetAverageOr(invalidTimingValue); m_FrameTiming.CurrentCpuFrameTime = m_CpuFrameTime.GetMostRecentValueOr(invalidTimingValue); float targerFrameRate = EffectiveTargetFrameRate(); float targetFrameTime = -1.0f; if (targerFrameRate > 0) { targetFrameTime = 1.0f / targerFrameRate; } bool triggerPerformanceBottleneckChangeEvent = false; bool triggerThermalEventEvent = false; var performanceBottleneckChangeEventArgs = new PerformanceBottleneckChangeEventArgs(); if (m_OverallFrameTime.GetNumValues() == m_OverallFrameTime.GetSampleWindowSize() && m_GpuFrameTime.GetNumValues() == m_GpuFrameTime.GetSampleWindowSize() && m_CpuFrameTime.GetNumValues() == m_CpuFrameTime.GetSampleWindowSize()) { PerformanceBottleneck bottleneck = BottleneckUtil.DetermineBottleneck(m_PerformanceMetrics.PerformanceBottleneck, m_FrameTiming.AverageCpuFrameTime, m_FrameTiming.AverageGpuFrameTime, m_FrameTiming.AverageFrameTime, targetFrameTime); if (bottleneck != m_PerformanceMetrics.PerformanceBottleneck) { m_PerformanceMetrics.PerformanceBottleneck = bottleneck; performanceBottleneckChangeEventArgs.PerformanceBottleneck = bottleneck; triggerPerformanceBottleneckChangeEvent = (PerformanceBottleneckChangeEvent != null); } } triggerThermalEventEvent = (ThermalEvent != null) && (updateResult.ChangeFlags.HasFlag(Provider.Feature.WarningLevel) || updateResult.ChangeFlags.HasFlag(Provider.Feature.TemperatureLevel) || updateResult.ChangeFlags.HasFlag(Provider.Feature.TemperatureTrend)); // The Subsystem may have changed the current levels (e.g. "timeout" of Samsung subsystem) if (updateResult.ChangeFlags.HasFlag(Provider.Feature.CpuPerformanceLevel)) { m_DevicePerfControl.CurrentCpuLevel = updateResult.CpuPerformanceLevel; } if (updateResult.ChangeFlags.HasFlag(Provider.Feature.GpuPerformanceLevel)) { m_DevicePerfControl.CurrentGpuLevel = updateResult.GpuPerformanceLevel; } // Update PerformanceControlMode if (updateResult.ChangeFlags.HasFlag(Provider.Feature.PerformanceLevelControl)) { if (updateResult.PerformanceLevelControlAvailable) { if (AutomaticPerformanceControl) { m_DevicePerfControl.PerformanceControlMode = PerformanceControlMode.Automatic; } else { m_DevicePerfControl.PerformanceControlMode = PerformanceControlMode.Manual; } } else { m_DevicePerfControl.PerformanceControlMode = PerformanceControlMode.System; } } // Apply performance levels according to PerformanceControlMode m_AutoPerformanceLevelController.TargetFrameTime = targetFrameTime; m_AutoPerformanceLevelController.Enabled = (m_DevicePerfControl.PerformanceControlMode == PerformanceControlMode.Automatic); PerformanceLevelChangeEventArgs levelChangeEventArgs = new PerformanceLevelChangeEventArgs(); if (m_DevicePerfControl.PerformanceControlMode != PerformanceControlMode.System) { if (m_AutoPerformanceLevelController.Enabled) { if (m_NewUserPerformanceLevelRequest) { m_AutoPerformanceLevelController.Override(m_RequestedCpuLevel, m_RequestedGpuLevel); levelChangeEventArgs.ManualOverride = true; } m_AutoPerformanceLevelController.Update(); } else { m_DevicePerfControl.CpuLevel = m_RequestedCpuLevel; m_DevicePerfControl.GpuLevel = m_RequestedGpuLevel; } } if (m_DevicePerfControl.Update(out levelChangeEventArgs) && PerformanceLevelChangeEvent != null) { PerformanceLevelChangeEvent.Invoke(levelChangeEventArgs); } m_PerformanceMetrics.CurrentCpuLevel = m_DevicePerfControl.CurrentCpuLevel; m_PerformanceMetrics.CurrentGpuLevel = m_DevicePerfControl.CurrentGpuLevel; m_NewUserPerformanceLevelRequest = false; // PerformanceLevelChangeEvent triggers before those since it's useful for the user to know when the auto cpu/gpu level controller already made adjustments if (triggerThermalEventEvent) { ThermalEvent.Invoke(m_ThermalMetrics); } if (triggerPerformanceBottleneckChangeEvent) { PerformanceBottleneckChangeEvent(performanceBottleneckChangeEventArgs); } }
private void LogPerformanceLevelEvent(PerformanceLevelChangeEventArgs ev) { APLog.Debug("[perf level change] cpu: {0}({1}) gpu: {2}({3})", ev.CpuLevel, ToStringWithSign(ev.CpuLevelDelta), ev.GpuLevel, ToStringWithSign(ev.GpuLevelDelta)); }
private void LogPerformanceLevelEvent(PerformanceLevelChangeEventArgs ev) { APLog.Debug("[perf level change] cpu: {0}({1}) gpu: {2}({3}) control mode: {4} manual override: {5}", ev.CpuLevel, ToStringWithSign(ev.CpuLevelDelta), ev.GpuLevel, ToStringWithSign(ev.GpuLevelDelta), ev.PerformanceControlMode, ev.ManualOverride); }