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; bool triggerPerformanceBoostChangeEvent = false; var performanceBottleneckChangeEventArgs = new PerformanceBottleneckChangeEventArgs(); var performanceBoostChangeEventArgs = new PerformanceBoostChangeEventArgs(); 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) || m_AutomaticPerformanceControlChanged) { m_AutomaticPerformanceControlChanged = false; 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; } } triggerPerformanceBoostChangeEvent = (PerformanceBoostChangeEvent != null) && (updateResult.ChangeFlags.HasFlag(Provider.Feature.CpuPerformanceBoost) || updateResult.ChangeFlags.HasFlag(Provider.Feature.GpuPerformanceBoost)); // The Subsystem may have changed the current modes (e.g. "timeout" of Samsung subsystem) if (updateResult.ChangeFlags.HasFlag(Provider.Feature.CpuPerformanceBoost)) { if (m_DevicePerfControl.CpuPerformanceBoost != updateResult.CpuPerformanceBoost) { m_DevicePerfControl.CpuPerformanceBoost = updateResult.CpuPerformanceBoost; m_RequestedCpuBoost = updateResult.CpuPerformanceBoost; } } if (updateResult.ChangeFlags.HasFlag(Provider.Feature.GpuPerformanceBoost)) { if (m_DevicePerfControl.GpuPerformanceBoost != updateResult.GpuPerformanceBoost) { m_DevicePerfControl.GpuPerformanceBoost = updateResult.GpuPerformanceBoost; m_RequestedGpuBoost = updateResult.GpuPerformanceBoost; } } if (m_NewUserCpuPerformanceBoostRequest && PerformanceBoostChangeEvent != null) { m_NewUserCpuPerformanceBoostRequest = false; m_Subsystem.PerformanceLevelControl.EnableCpuBoost(); } if (m_NewUserGpuPerformanceBoostRequest && PerformanceBoostChangeEvent != null) { m_NewUserGpuPerformanceBoostRequest = false; m_Subsystem.PerformanceLevelControl.EnableGpuBoost(); } if (m_DevicePerfControl.Update(out levelChangeEventArgs) && PerformanceLevelChangeEvent != null) { PerformanceLevelChangeEvent.Invoke(levelChangeEventArgs); } m_PerformanceMetrics.CurrentCpuLevel = m_DevicePerfControl.CurrentCpuLevel; m_PerformanceMetrics.CurrentGpuLevel = m_DevicePerfControl.CurrentGpuLevel; m_PerformanceMetrics.CpuPerformanceBoost = m_DevicePerfControl.CpuPerformanceBoost; m_PerformanceMetrics.GpuPerformanceBoost = m_DevicePerfControl.GpuPerformanceBoost; m_NewUserPerformanceLevelRequest = false; if (updateResult.ChangeFlags.HasFlag(Provider.Feature.ClusterInfo)) { m_PerformanceMetrics.ClusterInfo = updateResult.ClusterInfo; } // PerformanceLevelChangeEvent and BoostModeChangeEvent 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); } if (triggerPerformanceBoostChangeEvent) { performanceBoostChangeEventArgs.CpuBoost = m_DevicePerfControl.CpuPerformanceBoost; performanceBoostChangeEventArgs.GpuBoost = m_DevicePerfControl.GpuPerformanceBoost; PerformanceBoostChangeEvent(performanceBoostChangeEventArgs); } }
private void LogBoostEvent(PerformanceBoostChangeEventArgs ev) { APLog.Debug("[perf event] CPU boost: {0}, GPU boost: {1}", ev.CpuBoost, ev.GpuBoost); }