OVRSystemProfilerPanel.cs 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691
  1. /************************************************************************************
  2. Copyright : Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved.
  3. Licensed under the Oculus SDK License Version 3.4.1 (the "License");
  4. you may not use the Oculus SDK except in compliance with the License,
  5. which is provided at the time of installation or download, or which
  6. otherwise accompanies this software in either electronic or hard copy form.
  7. You may obtain a copy of the License at
  8. https://developer.oculus.com/licenses/sdk-3.4.1
  9. Unless required by applicable law or agreed to in writing, the Oculus SDK
  10. distributed under the License is distributed on an "AS IS" BASIS,
  11. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. See the License for the specific language governing permissions and
  13. limitations under the License.
  14. ************************************************************************************/
  15. using System.Collections.Generic;
  16. using System;
  17. using System.Reflection;
  18. using UnityEngine;
  19. using UnityEditor;
  20. using System.Text;
  21. public class OVRSystemProfilerPanel : EditorWindow {
  22. [MenuItem("Oculus/Tools/Oculus Profiler Panel")]
  23. public static void ShowWindow()
  24. {
  25. EditorWindow.GetWindow(typeof(OVRSystemProfilerPanel), false, "Oculus Profiler");
  26. OVRPlugin.SendEvent("oculus_profiler_panel", "show_window");
  27. }
  28. bool showAndroidOptions = false;
  29. OVRNetwork.OVRNetworkTcpClient tcpClient = new OVRNetwork.OVRNetworkTcpClient();
  30. int remoteListeningPort = OVRSystemPerfMetrics.TcpListeningPort;
  31. //OVRSystemPerfMetrics.PerfMetrics lastReceivedMetrics;
  32. const int maxMetricsFrames = 120;
  33. const float metricsHistoryDuration = 1.0f;
  34. List<OVRSystemPerfMetrics.PerfMetrics> receivedMetricsList = new List<OVRSystemPerfMetrics.PerfMetrics>();
  35. bool pauseReceiveMetrics = false;
  36. bool repaintRequested = false;
  37. const float labelWidth = 140.0f;
  38. const float panelInnerRightPad = 6.0f;
  39. const float progressBarPad = 5.0f;
  40. const float progressBarHeight = 18.0f;
  41. string androidSdkRootPath;
  42. OVRADBTool adbTool;
  43. // The actual window code goes here
  44. void OnGUI()
  45. {
  46. showAndroidOptions = EditorGUILayout.Foldout(showAndroidOptions, "Android Tools");
  47. if (showAndroidOptions)
  48. {
  49. GUILayout.BeginHorizontal();
  50. EditorGUILayout.LabelField("Android SDK root path: ", androidSdkRootPath);
  51. GUILayout.EndHorizontal();
  52. GUILayout.BeginHorizontal();
  53. if (GUILayout.Button("Start Server"))
  54. {
  55. if (adbTool == null)
  56. {
  57. adbTool = new OVRADBTool(androidSdkRootPath);
  58. }
  59. if (adbTool.isReady)
  60. {
  61. int exitCode = adbTool.StartServer(null);
  62. EditorUtility.DisplayDialog("ADB StartServer", (exitCode == 0 ? "Success" : "Failure. ExitCode = " + exitCode.ToString()), "Ok");
  63. }
  64. else
  65. {
  66. EditorUtility.DisplayDialog("Can't locate ADBTool", adbTool.adbPath, "Ok");
  67. }
  68. }
  69. if (GUILayout.Button("Kill Server"))
  70. {
  71. if (adbTool == null)
  72. {
  73. adbTool = new OVRADBTool(androidSdkRootPath);
  74. }
  75. if (adbTool.isReady)
  76. {
  77. int exitCode = adbTool.KillServer(null);
  78. EditorUtility.DisplayDialog("ADB KillServer", (exitCode == 0 ? "Success" : "Failure. ExitCode = " + exitCode.ToString()), "Ok");
  79. }
  80. else
  81. {
  82. EditorUtility.DisplayDialog("Can't locate ADBTool", adbTool.adbPath, "Ok");
  83. }
  84. }
  85. if (GUILayout.Button("Forward Port"))
  86. {
  87. if (adbTool == null)
  88. {
  89. adbTool = new OVRADBTool(androidSdkRootPath);
  90. }
  91. if (adbTool.isReady)
  92. {
  93. int exitCode = adbTool.ForwardPort(remoteListeningPort, null);
  94. EditorUtility.DisplayDialog("ADB ForwardPort", (exitCode == 0 ? "Success" : "Failure. ExitCode = " + exitCode.ToString()), "Ok");
  95. OVRPlugin.SendEvent("device_metrics_profiler", (exitCode == 0 ? "adb_forward_success" : "adb_forward_failure"));
  96. }
  97. else
  98. {
  99. EditorUtility.DisplayDialog("Can't locate ADBTool", adbTool.adbPath, "Ok");
  100. }
  101. }
  102. if (GUILayout.Button("Release Port"))
  103. {
  104. if (adbTool == null)
  105. {
  106. adbTool = new OVRADBTool(androidSdkRootPath);
  107. }
  108. if (adbTool.isReady)
  109. {
  110. int exitCode = adbTool.ReleasePort(remoteListeningPort, null);
  111. EditorUtility.DisplayDialog("ADB ReleasePort", (exitCode == 0 ? "Success" : "Failure. ExitCode = " + exitCode.ToString()), "Ok");
  112. }
  113. else
  114. {
  115. EditorUtility.DisplayDialog("Can't locate ADBTool", adbTool.adbPath, "Ok");
  116. }
  117. }
  118. GUILayout.EndHorizontal();
  119. }
  120. EditorGUILayout.LabelField("", GUI.skin.horizontalSlider);
  121. GUILayout.BeginHorizontal();
  122. remoteListeningPort = EditorGUILayout.DelayedIntField("Remote Port", remoteListeningPort);
  123. if (tcpClient.connectionState == OVRNetwork.OVRNetworkTcpClient.ConnectionState.Disconnected)
  124. {
  125. if (GUILayout.Button("Connect"))
  126. {
  127. ConnectPerfMetricsTcpServer();
  128. pauseReceiveMetrics = false;
  129. OVRPlugin.SendEvent("device_metrics_profiler", "connect");
  130. }
  131. }
  132. else
  133. {
  134. if (tcpClient.connectionState == OVRNetwork.OVRNetworkTcpClient.ConnectionState.Connecting)
  135. {
  136. if (GUILayout.Button("Connecting ... Click again to Cancel"))
  137. {
  138. DisconnectPerfMetricsTcpServer();
  139. OVRPlugin.SendEvent("device_metrics_profiler", "cancel");
  140. }
  141. }
  142. else
  143. {
  144. if (GUILayout.Button("Disconnect"))
  145. {
  146. DisconnectPerfMetricsTcpServer();
  147. OVRPlugin.SendEvent("device_metrics_profiler", "disconnect");
  148. }
  149. if (GUILayout.Button(pauseReceiveMetrics ? "Continue" : "Pause"))
  150. {
  151. pauseReceiveMetrics = !pauseReceiveMetrics;
  152. }
  153. }
  154. }
  155. GUILayout.EndHorizontal();
  156. EditorGUILayout.LabelField("", GUI.skin.horizontalSlider);
  157. lock (receivedMetricsList)
  158. {
  159. PresentIntProperty("Frame Count", "frameCount");
  160. PresentIntProperty("Dropped Frame Count", "compositorDroppedFrameCount");
  161. float? avgFrameTime = GetAveragePerfValueFloat("deltaFrameTime");
  162. if (avgFrameTime.HasValue)
  163. {
  164. float fps = 1.0f / avgFrameTime.Value;
  165. EditorGUILayout.BeginHorizontal();
  166. EditorGUILayout.LabelField("FPS", GUILayout.Width(labelWidth));
  167. EditorGUILayout.LabelField(string.Format("{0:F1}", fps));
  168. EditorGUILayout.EndHorizontal();
  169. }
  170. int? deviceCpuClockLevel = GetLatestPerfValueInt("deviceCpuClockLevel");
  171. int? deviceGpuClockLevel = GetLatestPerfValueInt("deviceGpuClockLevel");
  172. float? deviceCpuClockFrequencyInMHz = GetLatestPerfValueFloat("deviceCpuClockFrequencyInMHz");
  173. float? deviceGpuClockFrequencyInMHz = GetLatestPerfValueFloat("deviceGpuClockFrequencyInMHz");
  174. if (deviceCpuClockLevel.HasValue || deviceCpuClockFrequencyInMHz.HasValue)
  175. {
  176. string cpuLabel;
  177. string cpuText;
  178. if (deviceCpuClockLevel.HasValue && deviceCpuClockFrequencyInMHz.HasValue)
  179. {
  180. cpuLabel = "CPU Level (Freq)";
  181. cpuText = string.Format("{0} ({1:F0} MHz)", deviceCpuClockLevel, deviceCpuClockFrequencyInMHz);
  182. }
  183. else if (deviceCpuClockLevel.HasValue)
  184. {
  185. cpuLabel = "CPU Level";
  186. cpuText = string.Format("{0}", deviceCpuClockLevel);
  187. }
  188. else
  189. {
  190. cpuLabel = "CPU Frequency";
  191. cpuText = string.Format("{0:F0} MHz", deviceCpuClockFrequencyInMHz);
  192. }
  193. PresentText(cpuLabel, cpuText);
  194. }
  195. if (deviceGpuClockLevel.HasValue || deviceGpuClockFrequencyInMHz.HasValue)
  196. {
  197. string cpuLabel;
  198. string cpuText;
  199. if (deviceGpuClockLevel.HasValue && deviceGpuClockFrequencyInMHz.HasValue)
  200. {
  201. cpuLabel = "GPU Level (Freq)";
  202. cpuText = string.Format("{0} ({1:F0} MHz)", deviceGpuClockLevel, deviceGpuClockFrequencyInMHz);
  203. }
  204. else if (deviceGpuClockLevel.HasValue)
  205. {
  206. cpuLabel = "GPU Level";
  207. cpuText = string.Format("{0}", deviceGpuClockLevel);
  208. }
  209. else
  210. {
  211. cpuLabel = "GPU Frequency";
  212. cpuText = string.Format("{0:F0} MHz", deviceGpuClockFrequencyInMHz);
  213. }
  214. PresentText(cpuLabel, cpuText);
  215. }
  216. PresentColumnTitles("Current", "Average", "Peak");
  217. PresentFloatTimeInMs("Frame Time", "deltaFrameTime", 0.020f, true, true);
  218. PresentFloatTimeInMs("App CPU Time", "appCpuTime", 0.020f, true, true);
  219. PresentFloatTimeInMs("App GPU Time", "appGpuTime", 0.020f, true, true);
  220. PresentFloatTimeInMs("Compositor CPU Time", "compositorCpuTime", 0.020f, true, true);
  221. PresentFloatTimeInMs("Compositor GPU Time", "compositorGpuTime", 0.020f, true, true);
  222. PresentFloatPercentage("CPU Util (Average)", "systemCpuUtilAveragePercentage", false, false);
  223. PresentFloatPercentage("CPU Util (Worst Core)", "systemCpuUtilWorstPercentage", false, false);
  224. PresentFloatPercentage("GPU Util", "systemGpuUtilPercentage", false, false);
  225. }
  226. }
  227. void GetMetricsField(string propertyName, out FieldInfo baseFieldInfo, out FieldInfo validalityFieldInfo)
  228. {
  229. baseFieldInfo = typeof(OVRSystemPerfMetrics.PerfMetrics).GetField(propertyName);
  230. validalityFieldInfo = typeof(OVRSystemPerfMetrics.PerfMetrics).GetField(propertyName + "_IsValid");
  231. }
  232. bool HasValidPerfMetrics(string propertyName)
  233. {
  234. FieldInfo baseFieldInfo, validalityFieldInfo;
  235. GetMetricsField(propertyName, out baseFieldInfo, out validalityFieldInfo);
  236. if (baseFieldInfo == null || (validalityFieldInfo != null && validalityFieldInfo.FieldType != typeof(bool)))
  237. {
  238. Debug.LogWarning("[OVRSystemProfilerPanel] Unable to find property " + propertyName);
  239. return false;
  240. }
  241. if (validalityFieldInfo == null)
  242. {
  243. return true;
  244. }
  245. for (int i = receivedMetricsList.Count - 1; i >= 0; --i)
  246. {
  247. var metrics = receivedMetricsList[i];
  248. if (validalityFieldInfo != null && (bool)validalityFieldInfo.GetValue(metrics))
  249. {
  250. return true;
  251. }
  252. }
  253. return false;
  254. }
  255. int? GetLatestPerfValueInt(string propertyName)
  256. {
  257. FieldInfo baseFieldInfo, validalityFieldInfo;
  258. GetMetricsField(propertyName, out baseFieldInfo, out validalityFieldInfo);
  259. if (baseFieldInfo == null || baseFieldInfo.FieldType != typeof(int) ||
  260. (validalityFieldInfo != null && validalityFieldInfo.FieldType != typeof(bool)))
  261. {
  262. Debug.LogWarning("[OVRSystemProfilerPanel] GetLatestPerfValueInt(): Type mismatch");
  263. return null;
  264. }
  265. if (receivedMetricsList.Count == 0)
  266. {
  267. return null;
  268. }
  269. for (int i = receivedMetricsList.Count - 1; i >= 0; --i)
  270. {
  271. var metrics = receivedMetricsList[i];
  272. if (validalityFieldInfo == null || (validalityFieldInfo != null && (bool)validalityFieldInfo.GetValue(metrics)))
  273. {
  274. return (int)baseFieldInfo.GetValue(metrics);
  275. }
  276. }
  277. return null;
  278. }
  279. float? GetLatestPerfValueFloat(string propertyName)
  280. {
  281. FieldInfo baseFieldInfo, validalityFieldInfo;
  282. GetMetricsField(propertyName, out baseFieldInfo, out validalityFieldInfo);
  283. if (baseFieldInfo == null || baseFieldInfo.FieldType != typeof(float) ||
  284. (validalityFieldInfo != null && validalityFieldInfo.FieldType != typeof(bool)))
  285. {
  286. Debug.LogWarning("[OVRSystemProfilerPanel] GetLatestPerfValueFloat(): Type mismatch");
  287. return null;
  288. }
  289. if (receivedMetricsList.Count == 0)
  290. {
  291. return null;
  292. }
  293. for (int i = receivedMetricsList.Count - 1; i >= 0; --i)
  294. {
  295. var metrics = receivedMetricsList[i];
  296. if (validalityFieldInfo == null || (validalityFieldInfo != null && (bool)validalityFieldInfo.GetValue(metrics)))
  297. {
  298. return (float)baseFieldInfo.GetValue(metrics);
  299. }
  300. }
  301. return null;
  302. }
  303. float? GetAveragePerfValueFloat(string propertyName)
  304. {
  305. FieldInfo baseFieldInfo, validalityFieldInfo;
  306. GetMetricsField(propertyName, out baseFieldInfo, out validalityFieldInfo);
  307. if (baseFieldInfo == null || baseFieldInfo.FieldType != typeof(float) ||
  308. (validalityFieldInfo != null && validalityFieldInfo.FieldType != typeof(bool)))
  309. {
  310. Debug.LogWarning("[OVRSystemProfilerPanel] GetAveragePerfValueFloat(): Type mismatch");
  311. return null;
  312. }
  313. int count = 0;
  314. float sum = 0;
  315. OVRSystemPerfMetrics.PerfMetrics lastMetrics = null;
  316. int metricsIndex;
  317. for (metricsIndex = receivedMetricsList.Count - 1; metricsIndex >= 0; --metricsIndex)
  318. {
  319. var metrics = receivedMetricsList[metricsIndex];
  320. if (validalityFieldInfo != null && !(bool)validalityFieldInfo.GetValue(metrics))
  321. {
  322. continue;
  323. }
  324. lastMetrics = metrics;
  325. break;
  326. }
  327. if (lastMetrics == null)
  328. {
  329. return null;
  330. }
  331. for (; metricsIndex >=0; -- metricsIndex)
  332. {
  333. var metrics = receivedMetricsList[metricsIndex];
  334. if (metrics.frameTime < lastMetrics.frameTime - metricsHistoryDuration)
  335. {
  336. break;
  337. }
  338. if (validalityFieldInfo != null && !(bool)validalityFieldInfo.GetValue(metrics))
  339. {
  340. continue;
  341. }
  342. sum += (float)baseFieldInfo.GetValue(metrics);
  343. count++;
  344. }
  345. if (count == 0)
  346. {
  347. return null;
  348. }
  349. else
  350. {
  351. return sum / count;
  352. }
  353. }
  354. float? GetMaxPerfValueFloat(string propertyName)
  355. {
  356. FieldInfo baseFieldInfo, validalityFieldInfo;
  357. GetMetricsField(propertyName, out baseFieldInfo, out validalityFieldInfo);
  358. if (baseFieldInfo == null || baseFieldInfo.FieldType != typeof(float) ||
  359. (validalityFieldInfo != null && validalityFieldInfo.FieldType != typeof(bool)))
  360. {
  361. Debug.LogWarning("[OVRSystemProfilerPanel] GetMaxPerfValueFloat(): Type mismatch");
  362. return null;
  363. }
  364. OVRSystemPerfMetrics.PerfMetrics lastMetrics = null;
  365. int metricsIndex;
  366. for (metricsIndex = receivedMetricsList.Count - 1; metricsIndex >= 0; --metricsIndex)
  367. {
  368. var metrics = receivedMetricsList[metricsIndex];
  369. if (validalityFieldInfo != null && !(bool)validalityFieldInfo.GetValue(metrics))
  370. {
  371. continue;
  372. }
  373. lastMetrics = metrics;
  374. break;
  375. }
  376. if (lastMetrics == null)
  377. {
  378. return null;
  379. }
  380. float? result = null;
  381. for (; metricsIndex >= 0; --metricsIndex)
  382. {
  383. var metrics = receivedMetricsList[metricsIndex];
  384. if (metrics.frameTime < lastMetrics.frameTime - metricsHistoryDuration)
  385. {
  386. break;
  387. }
  388. if (validalityFieldInfo != null && !(bool)validalityFieldInfo.GetValue(metrics))
  389. {
  390. continue;
  391. }
  392. else
  393. {
  394. float value = (float)baseFieldInfo.GetValue(metrics);
  395. if (!result.HasValue || result.Value < value)
  396. {
  397. result = value;
  398. }
  399. }
  400. }
  401. return result;
  402. }
  403. void PresentFloatPercentage(string label, string propertyName, bool displayAverage, bool displayMaximum)
  404. {
  405. float? lastValue = GetLatestPerfValueFloat(propertyName);
  406. if (!lastValue.HasValue)
  407. {
  408. return;
  409. }
  410. EditorGUILayout.BeginHorizontal();
  411. EditorGUILayout.LabelField(label, GUILayout.Width(labelWidth));
  412. Rect r = EditorGUILayout.BeginVertical();
  413. float barWidth = (r.width - panelInnerRightPad - progressBarPad * 2) / 3.0f;
  414. EditorGUI.ProgressBar(new Rect(r.x, r.y, barWidth, r.height), lastValue.Value, string.Format("{0:F1}%", lastValue.Value * 100.0f));
  415. if (displayAverage)
  416. {
  417. float? averageValue = GetAveragePerfValueFloat(propertyName);
  418. if (averageValue.HasValue)
  419. {
  420. EditorGUI.ProgressBar(new Rect(r.x + barWidth + progressBarPad, r.y, barWidth, r.height), averageValue.Value, string.Format("{0:F1}%", averageValue.Value * 100.0f));
  421. }
  422. }
  423. if (displayMaximum)
  424. {
  425. float? maxValue = GetMaxPerfValueFloat(propertyName);
  426. if (maxValue.HasValue)
  427. {
  428. EditorGUI.ProgressBar(new Rect(r.x + (barWidth + progressBarPad) * 2, r.y, barWidth, r.height), maxValue.Value, string.Format("{0:F1}%", maxValue.Value * 100.0f));
  429. }
  430. }
  431. GUILayout.Space(progressBarHeight);
  432. EditorGUILayout.EndVertical();
  433. EditorGUILayout.EndHorizontal();
  434. }
  435. void PresentFloatTimeInMs(string label, string propertyName, float maxScale, bool displayAverage, bool displayMaximum)
  436. {
  437. float? lastValue = GetLatestPerfValueFloat(propertyName);
  438. if (!lastValue.HasValue)
  439. {
  440. return;
  441. }
  442. EditorGUILayout.BeginHorizontal();
  443. EditorGUILayout.LabelField(label, GUILayout.Width(labelWidth));
  444. Rect r = EditorGUILayout.BeginVertical();
  445. float barWidth = (r.width - panelInnerRightPad - progressBarPad * 2) / 3.0f;
  446. EditorGUI.ProgressBar(new Rect(r.x, r.y, barWidth, r.height), lastValue.Value/maxScale, string.Format("{0:F1} ms", lastValue.Value * 1000.0f));
  447. if (displayAverage)
  448. {
  449. float? averageValue = GetAveragePerfValueFloat(propertyName);
  450. if (averageValue.HasValue)
  451. {
  452. EditorGUI.ProgressBar(new Rect(r.x + barWidth + progressBarPad, r.y, barWidth, r.height), averageValue.Value / maxScale, string.Format("{0:F1} ms", averageValue.Value * 1000.0f));
  453. }
  454. }
  455. if (displayMaximum)
  456. {
  457. float? maxValue = GetMaxPerfValueFloat(propertyName);
  458. if (maxValue.HasValue)
  459. {
  460. EditorGUI.ProgressBar(new Rect(r.x + (barWidth + progressBarPad) * 2, r.y, barWidth, r.height), maxValue.Value / maxScale, string.Format("{0:F1} ms", maxValue.Value * 1000.0f));
  461. }
  462. }
  463. GUILayout.Space(progressBarHeight);
  464. EditorGUILayout.EndVertical();
  465. EditorGUILayout.EndHorizontal();
  466. }
  467. void PresentIntProperty(string label, string propertyName)
  468. {
  469. int? lastValue = GetLatestPerfValueInt(propertyName);
  470. if (!lastValue.HasValue)
  471. {
  472. return;
  473. }
  474. PresentText(label, lastValue.Value.ToString());
  475. }
  476. void PresentText(string label, string text)
  477. {
  478. EditorGUILayout.BeginHorizontal();
  479. EditorGUILayout.LabelField(label, GUILayout.Width(labelWidth));
  480. EditorGUILayout.LabelField(text);
  481. EditorGUILayout.EndHorizontal();
  482. }
  483. void PresentColumnTitles(string title0, string title1, string title2)
  484. {
  485. EditorGUILayout.BeginHorizontal();
  486. EditorGUILayout.LabelField("", GUILayout.Width(labelWidth));
  487. float windowWidth = position.width;
  488. float barWidth = (windowWidth - labelWidth - panelInnerRightPad * 3 ) / 3.0f;
  489. EditorGUILayout.LabelField(title0, GUILayout.Width(barWidth));
  490. EditorGUILayout.LabelField(title1, GUILayout.Width(barWidth));
  491. EditorGUILayout.LabelField(title2, GUILayout.Width(barWidth));
  492. EditorGUILayout.EndHorizontal();
  493. }
  494. // Called as the new window is opened.
  495. private void Awake()
  496. {
  497. InitializeAndroidSdkPath();
  498. minSize = new Vector2(400, 300);
  499. }
  500. void InitializeAndroidSdkPath()
  501. {
  502. androidSdkRootPath = OVRConfig.Instance.GetAndroidSDKPath();
  503. }
  504. // OnDestroy is called to close the EditorWindow window.
  505. private void OnDestroy()
  506. {
  507. DisconnectPerfMetricsTcpServer();
  508. }
  509. // Called multiple times per second on all visible windows.
  510. private void Update()
  511. {
  512. if (tcpClient != null && tcpClient.Connected)
  513. {
  514. tcpClient.Tick();
  515. }
  516. if (repaintRequested)
  517. {
  518. Repaint();
  519. repaintRequested = false;
  520. }
  521. }
  522. void OnConnectionStateChanged()
  523. {
  524. repaintRequested = true;
  525. if (tcpClient.connectionState == OVRNetwork.OVRNetworkTcpClient.ConnectionState.Disconnected)
  526. {
  527. tcpClient.connectionStateChangedCallback -= OnConnectionStateChanged;
  528. tcpClient.payloadReceivedCallback -= OnPayloadReceived;
  529. }
  530. }
  531. void OnPayloadReceived(int payloadType, byte[] buffer, int start, int length)
  532. {
  533. if (payloadType == OVRSystemPerfMetrics.PayloadTypeMetrics)
  534. {
  535. string message = Encoding.UTF8.GetString(buffer, start, length);
  536. OnMessageReceived(message);
  537. }
  538. else
  539. {
  540. Debug.LogWarningFormat("[OVRSystemProfilerPanel] unrecongized payload type {0}", payloadType);
  541. }
  542. }
  543. void OnMessageReceived(string message)
  544. {
  545. if (pauseReceiveMetrics)
  546. {
  547. return;
  548. }
  549. var metrics = new OVRSystemPerfMetrics.PerfMetrics();
  550. if (!metrics.LoadFromJSON(message))
  551. {
  552. Debug.LogWarning("Cannot analyze metrics: " + message);
  553. return;
  554. }
  555. lock(receivedMetricsList)
  556. {
  557. if (receivedMetricsList.Count >= maxMetricsFrames)
  558. {
  559. receivedMetricsList.RemoveAt(0);
  560. }
  561. receivedMetricsList.Add(metrics);
  562. }
  563. repaintRequested = true;
  564. }
  565. void ConnectPerfMetricsTcpServer()
  566. {
  567. tcpClient.connectionStateChangedCallback += OnConnectionStateChanged;
  568. tcpClient.payloadReceivedCallback += OnPayloadReceived;
  569. tcpClient.Connect(remoteListeningPort);
  570. #if UNITY_2017_1_OR_NEWER
  571. EditorApplication.playModeStateChanged += OnApplicationPlayModeStateChanged;
  572. #endif
  573. }
  574. void DisconnectPerfMetricsTcpServer()
  575. {
  576. #if UNITY_2017_1_OR_NEWER
  577. EditorApplication.playModeStateChanged -= OnApplicationPlayModeStateChanged;
  578. #endif
  579. tcpClient.Disconnect();
  580. }
  581. #if UNITY_2017_1_OR_NEWER
  582. void OnApplicationPlayModeStateChanged(PlayModeStateChange change)
  583. {
  584. Debug.LogFormat("[OVRSystemPerfMetricsWindow] OnApplicationPlayModeStateChanged {0}", change.ToString());
  585. if (change == PlayModeStateChange.ExitingPlayMode)
  586. {
  587. tcpClient.Disconnect();
  588. }
  589. }
  590. #endif
  591. }