Esempio n. 1
0
        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);
            }
        }