# IEnergyUsageProvider

> Optional provider interface for per-subsystem energy tracking. A provider implements this interface when it can report Feature.EnergyUsage. Adaptive Performance discovers the implementation through AdaptivePerformanceSubsystem.EnergyUsageControl and surfaces it to users as IEnergyUsageControl.

## Definition

* **Type:** Interface
* **Namespace:** [UnityEngine.AdaptivePerformance.Provider](/engine/6000.7/script-reference/unityengine/adaptiveperformance/provider.md)
* **Assembly:** UnityEngine.AdaptivePerformanceModule

```csharp
public interface IEnergyUsageProvider
```

## Remarks

Implement this interface on the provider class itself, the one that derives from [AdaptivePerformanceSubsystem.APProvider](/engine/6000.7/script-reference/unityengine/adaptiveperformance/provider/adaptiveperformancesubsystem/approvider.md). Adaptive Performance casts the provider to this interface, so an implementation on a separate object isn't discovered.

Include [Feature.EnergyUsage](/engine/6000.7/script-reference/unityengine/adaptiveperformance/provider/feature/energyusage.md) in [AdaptivePerformanceSubsystem.APProvider.Capabilities](/engine/6000.7/script-reference/unityengine/adaptiveperformance/provider/adaptiveperformancesubsystem/approvider/capabilities.md) at startup. Capabilities don't change afterwards, and without that bit Adaptive Performance reports [IEnergyUsageControl.EnergyUsageTrackingSupported](/engine/6000.7/script-reference/unityengine/adaptiveperformance/ienergyusagecontrol/energyusagetrackingsupported.md) as false and never starts tracking.

Report readings from [AdaptivePerformanceSubsystem.APProvider.Update](/engine/6000.7/script-reference/unityengine/adaptiveperformance/provider/adaptiveperformancesubsystem/approvider/update.md): assign [PerformanceDataRecord.EnergyUsage](/engine/6000.7/script-reference/unityengine/adaptiveperformance/provider/performancedatarecord/energyusage.md) and set the [Feature.EnergyUsage](/engine/6000.7/script-reference/unityengine/adaptiveperformance/provider/feature/energyusage.md) bit in [PerformanceDataRecord.ChangeFlags](/engine/6000.7/script-reference/unityengine/adaptiveperformance/provider/performancedatarecord/changeflags.md). Adaptive Performance ignores the value when that bit is clear, so set it whenever the platform produces a new sample. Report each subsystem the device can't measure with [EnergyUsageReading.Available](/engine/6000.7/script-reference/unityengine/adaptiveperformance/energyusagereading/available.md) set to false rather than reporting zero energy for it.

[EnergyUsageReading.Energy](/engine/6000.7/script-reference/unityengine/adaptiveperformance/energyusagereading/energy.md) is cumulative microwatt-seconds since tracking last started or reset, and [EnergyUsageReading.Interval](/engine/6000.7/script-reference/unityengine/adaptiveperformance/energyusagereading/interval.md) is the number of milliseconds that value covers.

Additional Resources: [IEnergyUsageControl](/engine/6000.7/script-reference/unityengine/adaptiveperformance/ienergyusagecontrol.md), [EnergyUsage](/engine/6000.7/script-reference/unityengine/adaptiveperformance/energyusage.md), [AdaptivePerformanceSubsystem.EnergyUsageControl](/engine/6000.7/script-reference/unityengine/adaptiveperformance/provider/adaptiveperformancesubsystem/energyusagecontrol.md)

The following example outlines a provider that reports CPU energy consumption.

## Examples

```csharp
using System;
using UnityEngine.AdaptivePerformance;
using UnityEngine.AdaptivePerformance.Provider;

public class ExampleEnergyUsageProvider : AdaptivePerformanceSubsystem.APProvider, IEnergyUsageProvider
{
    PerformanceDataRecord updateResult;
    bool trackingActive;

    public ExampleEnergyUsageProvider()
    {
        // Declare the capability at startup, otherwise Adaptive Performance never starts tracking.
        Capabilities = Feature.EnergyUsage;
    }

    public override Feature Capabilities { get; set; }

    public override PerformanceDataRecord Update()
    {
        updateResult.ChangeFlags = Feature.None;

        // Platforms produce new samples far less often than once per frame.
        if (trackingActive && TryReadCpuEnergy(out long energy, out long interval))
        {
            updateResult.EnergyUsage = new EnergyUsage(
                (EnergyUsageSubsystem.Cpu, new EnergyUsageReading(true, energy, interval)),
                // Subsystems this device can't measure are reported as unavailable.
                (EnergyUsageSubsystem.Gpu, new EnergyUsageReading(false, 0, 0)));

            // Adaptive Performance only picks up EnergyUsage when this bit is set.
            updateResult.ChangeFlags |= Feature.EnergyUsage;
        }

        return updateResult;
    }

    public bool StartEnergyUsageTracking()
    {
        // Adaptive Performance also calls this while tracking is active, to reset the baseline.
        trackingActive = ResetPlatformCounters();
        return trackingActive;
    }

    public void StopEnergyUsageTracking()
    {
        // Safe to call when tracking isn't active, because shutdown also calls it.
        trackingActive = false;
    }

    // Platform-specific: resets the counters that Energy is measured from.
    bool ResetPlatformCounters() => true;

    // Platform-specific: reads cumulative microwatt-seconds and the milliseconds they cover.
    bool TryReadCpuEnergy(out long energy, out long interval)
    {
        energy = 0;
        interval = 0;
        return false;
    }

    public override void Start() => Initialized = true;
    public override void Stop() => StopEnergyUsageTracking();
    public override void Destroy() => StopEnergyUsageTracking();

    public override IApplicationLifecycle ApplicationLifecycle => null;
    public override IDevicePerformanceLevelControl PerformanceLevelControl => null;
    public override Version Version => new Version(1, 0, 0);
    public override bool Initialized { get; set; }
}
```

## Methods

| Method                                                                                                                                                | Description                                                                                 |
| ----------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------- |
| [StartEnergyUsageTracking](/engine/6000.7/script-reference/unityengine/adaptiveperformance/provider/ienergyusageprovider/startenergyusagetracking.md) | Starts per-subsystem energy tracking, or resets the baseline if tracking is already active. |
| [StopEnergyUsageTracking](/engine/6000.7/script-reference/unityengine/adaptiveperformance/provider/ienergyusageprovider/stopenergyusagetracking.md)   | Stops per-subsystem energy tracking.                                                        |
