暂无描述
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

AdaptivePerformanceSubsystem.cs 23KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439
  1. using System;
  2. #if UNITY_2020_2_OR_NEWER
  3. using UnityEngine.SubsystemsImplementation;
  4. #endif
  5. namespace UnityEngine.AdaptivePerformance.Provider
  6. {
  7. /// <summary>
  8. /// Feature flags
  9. /// See <see cref="PerformanceDataRecord.ChangeFlags"/> and <seealso cref="AdaptivePerformanceSubsystem.Capabilities"/>.
  10. /// </summary>
  11. [Flags]
  12. public enum Feature
  13. {
  14. /// <summary>
  15. /// No features
  16. /// </summary>
  17. None = 0,
  18. /// <summary>
  19. /// See <see cref="PerformanceDataRecord.WarningLevel"/>
  20. /// </summary>
  21. WarningLevel = 0x1,
  22. /// <summary>
  23. /// See <see cref="PerformanceDataRecord.TemperatureLevel"/>
  24. /// </summary>
  25. TemperatureLevel = 0x2,
  26. /// <summary>
  27. /// See <see cref="PerformanceDataRecord.TemperatureTrend"/>
  28. /// </summary>
  29. TemperatureTrend = 0x4,
  30. /// <summary>
  31. /// See <see cref="PerformanceDataRecord.CpuPerformanceLevel"/> and <seealso cref="IDevicePerformanceLevelControl.SetPerformanceLevel"/>
  32. /// </summary>
  33. CpuPerformanceLevel = 0x8,
  34. /// <summary>
  35. /// See <see cref="PerformanceDataRecord.GpuPerformanceLevel"/> and <seealso cref="IDevicePerformanceLevelControl.SetPerformanceLevel"/>
  36. /// </summary>
  37. GpuPerformanceLevel = 0x10,
  38. /// <summary>
  39. /// See <see cref="PerformanceDataRecord.PerformanceLevelControlAvailable"/> and <seealso cref="AdaptivePerformanceSubsystem.PerformanceLevelControl"/>
  40. /// </summary>
  41. PerformanceLevelControl = 0x20,
  42. /// <summary>
  43. /// See <see cref="PerformanceDataRecord.GpuFrameTime"/>
  44. /// </summary>
  45. GpuFrameTime = 0x40,
  46. /// <summary>
  47. /// See <see cref="PerformanceDataRecord.CpuFrameTime"/>
  48. /// </summary>
  49. CpuFrameTime = 0x80,
  50. /// <summary>
  51. /// See <see cref="PerformanceDataRecord.OverallFrameTime"/>
  52. /// </summary>
  53. OverallFrameTime = 0x100,
  54. /// <summary>
  55. /// See <see cref="PerformanceDataRecord.CpuPerformanceBoost"/> and <seealso cref="IDevicePerformanceLevelControl.EnableCpuBoost"/>
  56. /// </summary>
  57. CpuPerformanceBoost = 0x200,
  58. /// <summary>
  59. /// See <see cref="PerformanceDataRecord.GpuPerformanceBoost"/> and <seealso cref="IDevicePerformanceLevelControl.EnableGpuBoost"/>
  60. /// </summary>
  61. GpuPerformanceBoost = 0x400,
  62. /// <summary>
  63. /// See <see cref="PerformanceDataRecord.ClusterInfo"/>
  64. /// </summary>
  65. ClusterInfo = 0x800,
  66. /// <summary>
  67. /// See <see cref="PerformanceDataRecord.PerformanceMode"/>
  68. /// </summary>
  69. PerformanceMode = 0x1000
  70. }
  71. /// <summary>
  72. /// The performance data record stores all information about the thermal and performance status and delivers it from the provider subsystem to Adaptive Performance for further processing.
  73. /// </summary>
  74. public struct PerformanceDataRecord
  75. {
  76. /// <summary>
  77. /// A bitset of features which indicate if their value changed in the last frame or at startup.
  78. /// Unsupported features will never change.
  79. /// Fields not changing always have valid data as long as its capability is supported.
  80. /// </summary>
  81. /// <value>Bitset</value>
  82. public Feature ChangeFlags { get; set; }
  83. /// <summary>
  84. /// The current normalized temperature level in the range of [0.0, 1.0], or -1.0 when not supported or not available right now.
  85. /// A level of 1.0 means that the device is thermal throttling.
  86. /// The temperature level has changed when the <see cref="Feature.TemperatureLevel"/> bit is set in <see cref="ChangeFlags"/>.
  87. /// </summary>
  88. /// <value>Temperature level in the range of [0.0, 1.0] or -1.0</value>
  89. public float TemperatureLevel { get; set; }
  90. /// <summary>
  91. /// The current temperature trend in the range of [-1.0, 1.0] that is a metric of temperature change over time.
  92. /// The temperature trend is constant at 0.0 in case the feature is not supported.
  93. /// The temperature trend has changed when <see cref="Feature.TemperatureTrend"/> bit is set in <see cref="ChangeFlags"/>.
  94. /// </summary>
  95. /// <value>Temperature trend in the range of [-1.0, 1.0]</value>
  96. public float TemperatureTrend { get; set; }
  97. /// <summary>
  98. /// The current warning level as documented in <see cref="Feature.WarningLevel"/>.
  99. /// The warning level has changed when <see cref="Feature.WarningLevel"/> bit is set in <see cref="ChangeFlags"/>.
  100. /// </summary>
  101. /// <value>The current warning level</value>
  102. public WarningLevel WarningLevel { get; set; }
  103. /// <summary>
  104. /// The currently active CPU performance level. This is typically the value previously set with <see cref="IDevicePerformanceLevelControl.SetPerformanceLevel"/> once the levels are successfully applied.
  105. /// Adaptive Performance might also change this level on its own. This typically happens when the device is thermal throttling or when <see cref="IDevicePerformanceLevelControl.SetPerformanceLevel"/> failed.
  106. /// CPU performance level has a value in the range of [<see cref="Constants.MinCpuPerformanceLevel"/>, <see cref="IDevicePerformanceLevelControl.MaxCpuPerformanceLevel"/>], or <seealso cref="Constants.UnknownPerformanceLevel"/>.
  107. /// A value of <see cref="Constants.UnknownPerformanceLevel"/> means that Adaptive Performance took control of performance levels.
  108. /// CPU performance level has changed when <see cref="Feature.CpuPerformanceLevel"/> bit is set in <see cref="ChangeFlags"/>.
  109. /// </summary>
  110. /// <value></value>
  111. public int CpuPerformanceLevel { get; set; }
  112. /// <summary>
  113. /// The currently active GPU performance level. This is typically the value previously set with <see cref="IDevicePerformanceLevelControl.SetPerformanceLevel"/> once the levels are successfully applied.
  114. /// Adaptive Performance might also change this level on its own. This typically happens when the device is thermal throttling or when <see cref="IDevicePerformanceLevelControl.SetPerformanceLevel"/> failed.
  115. /// GPU performance level has a value in the range of [<see cref="Constants.MinCpuPerformanceLevel"/>, <see cref="IDevicePerformanceLevelControl.MaxGpuPerformanceLevel"/>], or <seealso cref="Constants.UnknownPerformanceLevel"/>.
  116. /// A value of <see cref="Constants.UnknownPerformanceLevel"/> means that Adaptive Performance took control of performance levels.
  117. /// GPU performance level has changed when <see cref="Feature.GpuPerformanceLevel"/> bit is set in <see cref="ChangeFlags"/>.
  118. /// </summary>
  119. public int GpuPerformanceLevel { get; set; }
  120. /// <summary>
  121. /// True if =performance levels can currently be controlled manually and aren't controlled by Adaptive Performance or the operating system.
  122. /// Has changed when <see cref="Feature.PerformanceLevelControl"/> bit is set in <see cref="ChangeFlags"/>.
  123. /// </summary>
  124. public bool PerformanceLevelControlAvailable { get; set; }
  125. /// <summary>
  126. /// The time in seconds spent by the CPU for rendering the last complete frame.
  127. /// Has changed when <see cref="Feature.CpuFrameTime"/> bit is set in <see cref="ChangeFlags"/>.
  128. /// </summary>
  129. public float CpuFrameTime { get; set; }
  130. /// <summary>
  131. /// The time in seconds spent by the GPU for rendering the last complete frame.
  132. /// Has changed when <see cref="Feature.GpuFrameTime"/> bit is set in <see cref="ChangeFlags"/>.
  133. /// </summary>
  134. public float GpuFrameTime { get; set; }
  135. /// <summary>
  136. /// The total time in seconds spent for the frame.
  137. /// Has changed when <see cref="Feature.OverallFrameTime"/> bit is set in <see cref="ChangeFlags"/>.
  138. /// </summary>
  139. public float OverallFrameTime { get; set; }
  140. /// <summary>
  141. /// The currently active CPU boost state. This is typically true if previously enabled with <see cref="IDevicePerformanceLevelControl.EnableCpuBoost"/> once the boost is successfully applied.
  142. /// Adaptive Performance might also change this level on its own. This typically happens when the device is thermal throttling or when <see cref="IDevicePerformanceLevelControl.EnableCpuBoost"/> fails.
  143. /// Once the CPU boost is enabled it is active until you receive a callback that it is disabled.
  144. /// CPU boost level has changed when <see cref="Feature.CpuPerformanceBoost"/> bit is set in <see cref="ChangeFlags"/>.
  145. /// </summary>
  146. public bool CpuPerformanceBoost { get; set; }
  147. /// <summary>
  148. /// The currently active GPU boost state. This is typically true if previously enabled with <see cref="IDevicePerformanceLevelControl.EnableGpuBoost"/> once the boost is successfully applied.
  149. /// Adaptive Performance might also change this level on its own. This typically happens when the device is thermal throttling or when <see cref="IDevicePerformanceLevelControl.EnableGpuBoost"/> fails.
  150. /// Once the GPU boost is enabled it is active until you receive a callback that it is disabled.
  151. /// GPU boost level has changed when <see cref="Feature.GpuPerformanceBoost"/> bit is set in <see cref="ChangeFlags"/>.
  152. /// </summary>
  153. public bool GpuPerformanceBoost { get; set; }
  154. /// <summary>
  155. /// Current CPU cluster information information. Includes number of big, medium and small cores use at the application startup.
  156. /// </summary>
  157. public ClusterInfo ClusterInfo { get; set; }
  158. /// <summary>
  159. /// Current Performance mode information.
  160. /// </summary>
  161. public PerformanceMode PerformanceMode { get; set; }
  162. }
  163. /// <summary>
  164. /// This interface describes how the Adaptive Performance provider lifecycle behaves.
  165. /// </summary>
  166. public interface IApplicationLifecycle
  167. {
  168. /// <summary>
  169. /// Called before an application pauses.
  170. /// To be called from `MonoBehaviour.OnApplicationPause`.
  171. /// </summary>
  172. void ApplicationPause();
  173. /// <summary>
  174. /// Called after an application resumes.
  175. /// To be called from `MonoBehaviour.OnApplicationPause`.
  176. /// </summary>
  177. void ApplicationResume();
  178. }
  179. /// <summary>
  180. /// The device performance level control lets you change CPU and GPU levels and informs you about the current levels.
  181. /// </summary>
  182. public interface IDevicePerformanceLevelControl
  183. {
  184. /// <summary>
  185. /// Maximum supported CPU performance level. This should not change after startup.
  186. /// <see cref="Constants.UnknownPerformanceLevel"/> in case performance levels are not supported.
  187. /// Value in the range of [<see cref="Constants.MinCpuPerformanceLevel"/>, 10].
  188. /// </summary>
  189. /// <value>Value in the range of [<see cref="Constants.MinCpuPerformanceLevel"/>, 10]</value>
  190. int MaxCpuPerformanceLevel { get; }
  191. /// <summary>
  192. /// Maximum supported GPU performance level. This should not change after startup.
  193. /// <see cref="Constants.UnknownPerformanceLevel"/> in case performance levels are not supported.
  194. /// Value in the range of [<see cref="Constants.MinGpuPerformanceLevel"/>, 10].
  195. /// </summary>
  196. /// <value>Value in the range of [<see cref="Constants.MinGpuPerformanceLevel"/>, 10]</value>
  197. int MaxGpuPerformanceLevel { get; }
  198. /// <summary>
  199. /// Request a performance level change.
  200. /// If <see cref="Constants.UnknownPerformanceLevel"/> is passed, the subsystem picks the level to be used.
  201. /// </summary>
  202. /// <param name="cpu">
  203. /// The new performance level. Can be <see cref="Constants.UnknownPerformanceLevel"/> or range of [<see cref="Constants.MinCpuPerformanceLevel"/>, <see cref="IDevicePerformanceLevelControl.MaxCpuPerformanceLevel"/>].
  204. /// If <see cref="Feature.CpuPerformanceLevel"/> is not supported (see <see cref="AdaptivePerformanceSubsystem.Capabilities"/>), this parameter is ignored.
  205. /// </param>
  206. /// <param name="gpu">
  207. /// The new performance level. Can be <see cref="Constants.UnknownPerformanceLevel"/> or range of [<see cref="Constants.MinCpuPerformanceLevel"/>, <see cref="IDevicePerformanceLevelControl.MaxGpuPerformanceLevel"/>].
  208. /// If <see cref="Feature.GpuPerformanceLevel"/> is not supported (see <see cref="AdaptivePerformanceSubsystem.Capabilities"/>), this parameter is ignored.
  209. /// </param>
  210. /// <returns>Returns true on success. When this fails, it means that the system took control of the active performance levels.</returns>
  211. bool SetPerformanceLevel(ref int cpu, ref int gpu);
  212. /// <summary>
  213. /// Request a CPU performance boost.
  214. /// </summary>
  215. /// If <see cref="Feature.CpuPerformanceBoost"/> is not supported (see <see cref="AdaptivePerformanceSubsystem.Capabilities"/>), this function is ignored.
  216. /// <returns>Returns true on success. When this fails, it means that the system took control and does not allow boosts.</returns>
  217. bool EnableCpuBoost();
  218. /// <summary>
  219. /// Request a GPU performance boost.
  220. /// </summary>
  221. /// If <see cref="Feature.GpuPerformanceBoost"/> is not supported (see <see cref="AdaptivePerformanceSubsystem.Capabilities"/>), this function is ignored.
  222. /// <returns>Returns true on success. When this fails, it means that the system took control and does not allow boosts.</returns>
  223. bool EnableGpuBoost();
  224. }
  225. /// <summary>
  226. /// Base class for subsystems to create your custom provider subsystem to deliver data from your provider to Adaptive Performance.
  227. /// </summary>
  228. /// <typeparam name="TSubsystem">Concrete subsystem deriving from AdaptivePerformanceSubsystemBase.</typeparam>
  229. /// <typeparam name="TSubsystemDescriptor">The subsystem descriptor for the underlying subsystem.</typeparam>
  230. /// <typeparam name="TProvider">Provider type for the AdaptivePerformanceSubsystem-derived subsystem.</typeparam>
  231. public abstract class AdaptivePerformanceSubsystemBase<TSubsystem, TSubsystemDescriptor, TProvider>
  232. : SubsystemWithProvider<TSubsystem, TSubsystemDescriptor, TProvider>
  233. where TSubsystem : SubsystemWithProvider, new()
  234. where TSubsystemDescriptor : SubsystemDescriptorWithProvider
  235. where TProvider : SubsystemProvider<TSubsystem>
  236. {
  237. /// <summary>
  238. /// Bitset of supported features.
  239. /// Does not change after startup.
  240. /// </summary>
  241. /// <value>Bitset</value>
  242. public abstract Feature Capabilities { get; protected set; }
  243. /// <summary>
  244. /// To be called once per frame.
  245. /// The returned data structure's fields are populated with the latest available data, according to the supported <see cref="Capabilities"/>.
  246. /// </summary>
  247. /// <returns>Data structure with the most recent performance data.</returns>
  248. public abstract PerformanceDataRecord Update();
  249. /// <summary>
  250. /// Application lifecycle events to be consumed by subsystem.
  251. /// Can be null if the subsystem does not need special handling on life-cycle events.
  252. /// The returned reference does not change after startup.
  253. /// </summary>
  254. /// <value>Application lifecycle object</value>
  255. public abstract IApplicationLifecycle ApplicationLifecycle { get; }
  256. /// <summary>
  257. /// Control CPU or GPU performance levels of the device.
  258. /// Can be null if the subsystem does not support controlling CPU/GPU performance levels.
  259. /// Is null when the <see cref="Feature.PerformanceLevelControl"/> bit is not set in <see cref="Capabilities"/>.
  260. /// The returned reference does not change after startup.
  261. /// </summary>
  262. /// <value>Performance level control object</value>
  263. public abstract IDevicePerformanceLevelControl PerformanceLevelControl { get; }
  264. /// <summary>
  265. /// Returns the version of the subsystem implementation.
  266. /// Can be used together with SubsystemDescriptor to identify a subsystem.
  267. /// </summary>
  268. /// <value>Version number</value>
  269. public abstract Version Version { get; }
  270. /// <summary>
  271. /// Generates a human readable string of subsystem internal stats.
  272. /// Optional and only used for development.
  273. /// </summary>
  274. /// <value>String with subsystem specific statistics</value>
  275. public abstract string Stats { get; }
  276. /// <summary>
  277. /// Returns if the subsystem is initialized successfully.
  278. /// </summary>
  279. /// <value>Boolean to tell if subsystem was initialized successfully.</value>
  280. public abstract bool Initialized { get; protected set; }
  281. }
  282. /// <summary>
  283. /// A class to define a provider subsystem for Adaptive Performance.
  284. /// </summary>
  285. public class AdaptivePerformanceSubsystem : AdaptivePerformanceSubsystemBase<AdaptivePerformanceSubsystem, AdaptivePerformanceSubsystemDescriptor, AdaptivePerformanceSubsystem.APProvider>
  286. {
  287. /// <summary>
  288. /// Main constructor, not used in the subsystem specifically.
  289. /// </summary>
  290. public AdaptivePerformanceSubsystem()
  291. {
  292. }
  293. /// <summary>
  294. /// Lifecycle of the Subsystem.
  295. /// </summary>
  296. public override IApplicationLifecycle ApplicationLifecycle => provider.ApplicationLifecycle;
  297. /// <summary>
  298. /// Control CPU or GPU performance levels of the device.
  299. /// Can be null if the subsystem does not support controlling CPU/GPU performance levels.
  300. /// Is null when the <see cref="Feature.PerformanceLevelControl"/> bit is not set in <see cref="Capabilities"/>.
  301. /// The returned reference does not change after startup.
  302. /// </summary>
  303. /// <value>Performance level control object</value>
  304. public override IDevicePerformanceLevelControl PerformanceLevelControl => provider.PerformanceLevelControl;
  305. /// <summary>
  306. /// Returns the version of the subsystem implementation.
  307. /// Can be used together with SubsystemDescriptor to identify a subsystem.
  308. /// </summary>
  309. /// <value>Version number</value>
  310. public override Version Version => provider.Version;
  311. /// <summary>
  312. /// Bitset of supported features.
  313. /// Does not change after startup.
  314. /// </summary>
  315. /// <value>Bitset</value>
  316. public override Feature Capabilities { get => provider.Capabilities; protected set => provider.Capabilities = value; }
  317. /// <summary>
  318. /// Generates a human readable string of subsystem internal stats.
  319. /// Optional and only used for development.
  320. /// </summary>
  321. /// <value>String with subsystem specific statistics</value>
  322. public override string Stats => provider.Stats;
  323. /// <summary>
  324. /// Returns if the subsystem is initialized successfully.
  325. /// </summary>
  326. /// <value>Boolean to tell if subsystem was initialized successfully.</value>
  327. public override bool Initialized { get => provider.Initialized; protected set => provider.Initialized = value; }
  328. /// <summary>
  329. /// To be called once per frame.
  330. /// The returned data structure's fields are populated with the latest available data, according to the supported <see cref="Capabilities"/>.
  331. /// </summary>
  332. /// <returns>Data structure with the most recent performance data.</returns>
  333. public override PerformanceDataRecord Update()
  334. {
  335. return provider.Update();
  336. }
  337. /// <summary>
  338. /// An abstract class to be implemented by providers of this subsystem.
  339. /// </summary>
  340. public abstract class APProvider : SubsystemProvider<AdaptivePerformanceSubsystem>
  341. {
  342. /// <summary>
  343. /// Returns if the provider is currently running.
  344. /// </summary>
  345. protected bool m_Running;
  346. /// <summary>
  347. /// Bitset of supported features.
  348. /// Does not change after startup.
  349. /// </summary>
  350. /// <value>Bitset</value>
  351. public abstract Feature Capabilities { get; set; }
  352. /// <summary>
  353. /// To be called once per frame.
  354. /// The returned data structure's fields are populated with the latest available data, according to the supported <see cref="Capabilities"/>.
  355. /// </summary>
  356. /// <returns>Data structure with the most recent performance data.</returns>
  357. public abstract PerformanceDataRecord Update();
  358. /// <summary>
  359. /// Application lifecycle events to be consumed by subsystem.
  360. /// Can be null if the subsystem does not need special handling on life-cycle events.
  361. /// The returned reference does not change after startup.
  362. /// </summary>
  363. /// <value>Application lifecycle object</value>
  364. public abstract IApplicationLifecycle ApplicationLifecycle { get; }
  365. /// <summary>
  366. /// Control CPU or GPU performance levels of the device.
  367. /// Can be null if the subsystem does not support controlling CPU/GPU performance levels.
  368. /// Is null when the <see cref="Feature.PerformanceLevelControl"/> bit is not set in <see cref="Capabilities"/>.
  369. /// The returned reference does not change after startup.
  370. /// </summary>
  371. /// <value>Performance level control object</value>
  372. public abstract IDevicePerformanceLevelControl PerformanceLevelControl { get; }
  373. /// <summary>
  374. /// Returns the version of the subsystem implementation.
  375. /// Can be used together with SubsystemDescriptor to identify a subsystem.
  376. /// </summary>
  377. /// <value>Version number</value>
  378. public abstract Version Version { get; }
  379. /// <summary>
  380. /// Generates a human readable string of subsystem internal stats.
  381. /// Optional and only used for development.
  382. /// </summary>
  383. /// <value>String with subsystem specific statistics</value>
  384. public virtual string Stats { get { return ""; } }
  385. /// <summary>
  386. /// Returns if the subsystem is initialized successfully.
  387. /// </summary>
  388. /// <value>Boolean to tell if subsystem was initialized successfully.</value>
  389. public abstract bool Initialized { get; set; }
  390. /// <summary>
  391. /// Returns if the subsystem is running.
  392. /// </summary>
  393. /// <value>Boolean to tell if subsystem is running.</value>
  394. public new bool running
  395. {
  396. get { return m_Running; }
  397. }
  398. }
  399. }
  400. }