示例#1
0
    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);
 }