private void OnBottleneckChange(PerformanceBottleneckChangeEventArgs ev) { if (ev.PerformanceBottleneck == PerformanceBottleneck.TargetFrameRate) { m_TargetFrameRateHitTimestamp = Time.time; } if (ev.PerformanceBottleneck == PerformanceBottleneck.Unknown) { m_BottleneckUnknownTimestamp = Time.time; } else { m_TriedToResolveUnknownBottleneck = false; } }
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 LogBottleneckEvent(PerformanceBottleneckChangeEventArgs ev) { APLog.Debug("[perf event] bottleneck: {0}", ev.PerformanceBottleneck); }
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); } }