@itwin/frontend-devtools 5.0.0-dev.9 → 5.0.0-dev.90

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (259) hide show
  1. package/CHANGELOG.md +51 -1
  2. package/lib/cjs/ClipboardUtilities.js.map +1 -1
  3. package/lib/cjs/FrontEndDevTools.js +1 -1
  4. package/lib/cjs/FrontEndDevTools.js.map +1 -1
  5. package/lib/cjs/effects/Convolution.js +23 -23
  6. package/lib/cjs/effects/Convolution.js.map +1 -1
  7. package/lib/cjs/effects/EffectTools.js +2 -2
  8. package/lib/cjs/effects/EffectTools.js.map +1 -1
  9. package/lib/cjs/effects/Explosion.js +37 -25
  10. package/lib/cjs/effects/Explosion.js.map +1 -1
  11. package/lib/cjs/effects/FlipImage.js +22 -22
  12. package/lib/cjs/effects/FlipImage.js.map +1 -1
  13. package/lib/cjs/effects/LensDistortion.js +25 -25
  14. package/lib/cjs/effects/LensDistortion.js.map +1 -1
  15. package/lib/cjs/effects/Random.js.map +1 -1
  16. package/lib/cjs/effects/Saturation.js +30 -30
  17. package/lib/cjs/effects/Saturation.js.map +1 -1
  18. package/lib/cjs/effects/Snow.d.ts +1 -1
  19. package/lib/cjs/effects/Snow.d.ts.map +1 -1
  20. package/lib/cjs/effects/Snow.js +19 -8
  21. package/lib/cjs/effects/Snow.js.map +1 -1
  22. package/lib/cjs/effects/Vignette.js +41 -41
  23. package/lib/cjs/effects/Vignette.js.map +1 -1
  24. package/lib/cjs/frontend-devtools.js.map +1 -1
  25. package/lib/cjs/tools/AnimationIntervalTool.js +1 -1
  26. package/lib/cjs/tools/AnimationIntervalTool.js.map +1 -1
  27. package/lib/cjs/tools/ChangeUnitsTool.js +1 -1
  28. package/lib/cjs/tools/ChangeUnitsTool.js.map +1 -1
  29. package/lib/cjs/tools/ClipTools.js +6 -8
  30. package/lib/cjs/tools/ClipTools.js.map +1 -1
  31. package/lib/cjs/tools/DisplayStyleTools.js +21 -25
  32. package/lib/cjs/tools/DisplayStyleTools.js.map +1 -1
  33. package/lib/cjs/tools/EmphasizeElementsTool.js +7 -13
  34. package/lib/cjs/tools/EmphasizeElementsTool.js.map +1 -1
  35. package/lib/cjs/tools/FrustumDecoration.js +28 -9
  36. package/lib/cjs/tools/FrustumDecoration.js.map +1 -1
  37. package/lib/cjs/tools/InspectElementTool.js +7 -6
  38. package/lib/cjs/tools/InspectElementTool.js.map +1 -1
  39. package/lib/cjs/tools/MapLayerTool.js +24 -20
  40. package/lib/cjs/tools/MapLayerTool.js.map +1 -1
  41. package/lib/cjs/tools/MeasureTileLoadTime.js +4 -1
  42. package/lib/cjs/tools/MeasureTileLoadTime.js.map +1 -1
  43. package/lib/cjs/tools/ModelAppearanceTools.js +9 -9
  44. package/lib/cjs/tools/ModelAppearanceTools.js.map +1 -1
  45. package/lib/cjs/tools/PlanProjectionTools.js +8 -15
  46. package/lib/cjs/tools/PlanProjectionTools.js.map +1 -1
  47. package/lib/cjs/tools/PlanarMaskTools.js +21 -26
  48. package/lib/cjs/tools/PlanarMaskTools.js.map +1 -1
  49. package/lib/cjs/tools/ProjectExtents.js +6 -3
  50. package/lib/cjs/tools/ProjectExtents.js.map +1 -1
  51. package/lib/cjs/tools/RealityModelTools.js +10 -10
  52. package/lib/cjs/tools/RealityModelTools.js.map +1 -1
  53. package/lib/cjs/tools/RealityTransitionTool.js +1 -1
  54. package/lib/cjs/tools/RealityTransitionTool.js.map +1 -1
  55. package/lib/cjs/tools/RenderSystemTools.js +4 -3
  56. package/lib/cjs/tools/RenderSystemTools.js.map +1 -1
  57. package/lib/cjs/tools/RenderTargetTools.d.ts +1 -1
  58. package/lib/cjs/tools/RenderTargetTools.d.ts.map +1 -1
  59. package/lib/cjs/tools/RenderTargetTools.js +15 -20
  60. package/lib/cjs/tools/RenderTargetTools.js.map +1 -1
  61. package/lib/cjs/tools/ReportWebGLCompatibilityTool.js +1 -1
  62. package/lib/cjs/tools/ReportWebGLCompatibilityTool.js.map +1 -1
  63. package/lib/cjs/tools/SavedViews.js +4 -7
  64. package/lib/cjs/tools/SavedViews.js.map +1 -1
  65. package/lib/cjs/tools/ScheduleScriptTools.d.ts.map +1 -1
  66. package/lib/cjs/tools/ScheduleScriptTools.js +11 -12
  67. package/lib/cjs/tools/ScheduleScriptTools.js.map +1 -1
  68. package/lib/cjs/tools/SelectionTools.js +4 -6
  69. package/lib/cjs/tools/SelectionTools.js.map +1 -1
  70. package/lib/cjs/tools/SetGpuMemoryLimitTool.js +1 -1
  71. package/lib/cjs/tools/SetGpuMemoryLimitTool.js.map +1 -1
  72. package/lib/cjs/tools/SourceAspectIdTools.js +2 -2
  73. package/lib/cjs/tools/SourceAspectIdTools.js.map +1 -1
  74. package/lib/cjs/tools/TileRequestDecoration.js +6 -3
  75. package/lib/cjs/tools/TileRequestDecoration.js.map +1 -1
  76. package/lib/cjs/tools/TileTreeBoundsDecoration.d.ts.map +1 -1
  77. package/lib/cjs/tools/TileTreeBoundsDecoration.js +8 -4
  78. package/lib/cjs/tools/TileTreeBoundsDecoration.js.map +1 -1
  79. package/lib/cjs/tools/ToolTipProvider.js +2 -1
  80. package/lib/cjs/tools/ToolTipProvider.js.map +1 -1
  81. package/lib/cjs/tools/ViewportTools.js +22 -19
  82. package/lib/cjs/tools/ViewportTools.js.map +1 -1
  83. package/lib/cjs/tools/parseArgs.js.map +1 -1
  84. package/lib/cjs/tools/parseBoolean.js.map +1 -1
  85. package/lib/cjs/tools/parseToggle.js.map +1 -1
  86. package/lib/cjs/ui/Button.js.map +1 -1
  87. package/lib/cjs/ui/CheckBox.js.map +1 -1
  88. package/lib/cjs/ui/ColorInput.js.map +1 -1
  89. package/lib/cjs/ui/ComboBox.js.map +1 -1
  90. package/lib/cjs/ui/DataList.js.map +1 -1
  91. package/lib/cjs/ui/NestedMenu.js.map +1 -1
  92. package/lib/cjs/ui/NumericInput.js.map +1 -1
  93. package/lib/cjs/ui/RadioBox.js.map +1 -1
  94. package/lib/cjs/ui/Slider.js.map +1 -1
  95. package/lib/cjs/ui/TextBox.js.map +1 -1
  96. package/lib/cjs/widgets/DiagnosticsPanel.d.ts +1 -1
  97. package/lib/cjs/widgets/DiagnosticsPanel.d.ts.map +1 -1
  98. package/lib/cjs/widgets/DiagnosticsPanel.js +11 -1
  99. package/lib/cjs/widgets/DiagnosticsPanel.js.map +1 -1
  100. package/lib/cjs/widgets/FpsTracker.d.ts +1 -1
  101. package/lib/cjs/widgets/FpsTracker.d.ts.map +1 -1
  102. package/lib/cjs/widgets/FpsTracker.js +5 -1
  103. package/lib/cjs/widgets/FpsTracker.js.map +1 -1
  104. package/lib/cjs/widgets/GpuProfiler.d.ts +1 -1
  105. package/lib/cjs/widgets/GpuProfiler.d.ts.map +1 -1
  106. package/lib/cjs/widgets/GpuProfiler.js +89 -82
  107. package/lib/cjs/widgets/GpuProfiler.js.map +1 -1
  108. package/lib/cjs/widgets/KeyinField.js +8 -1
  109. package/lib/cjs/widgets/KeyinField.js.map +1 -1
  110. package/lib/cjs/widgets/MemoryTracker.d.ts +1 -1
  111. package/lib/cjs/widgets/MemoryTracker.d.ts.map +1 -1
  112. package/lib/cjs/widgets/MemoryTracker.js +16 -4
  113. package/lib/cjs/widgets/MemoryTracker.js.map +1 -1
  114. package/lib/cjs/widgets/RenderCommandBreakdown.d.ts +1 -1
  115. package/lib/cjs/widgets/RenderCommandBreakdown.d.ts.map +1 -1
  116. package/lib/cjs/widgets/RenderCommandBreakdown.js +6 -2
  117. package/lib/cjs/widgets/RenderCommandBreakdown.js.map +1 -1
  118. package/lib/cjs/widgets/TileMemoryBreakdown.d.ts +1 -1
  119. package/lib/cjs/widgets/TileMemoryBreakdown.d.ts.map +1 -1
  120. package/lib/cjs/widgets/TileMemoryBreakdown.js +10 -8
  121. package/lib/cjs/widgets/TileMemoryBreakdown.js.map +1 -1
  122. package/lib/cjs/widgets/TileStatisticsTracker.d.ts +1 -1
  123. package/lib/cjs/widgets/TileStatisticsTracker.d.ts.map +1 -1
  124. package/lib/cjs/widgets/TileStatisticsTracker.js +5 -2
  125. package/lib/cjs/widgets/TileStatisticsTracker.js.map +1 -1
  126. package/lib/cjs/widgets/ToolSettingsTracker.d.ts +1 -1
  127. package/lib/cjs/widgets/ToolSettingsTracker.d.ts.map +1 -1
  128. package/lib/cjs/widgets/ToolSettingsTracker.js +2 -2
  129. package/lib/cjs/widgets/ToolSettingsTracker.js.map +1 -1
  130. package/lib/esm/ClipboardUtilities.js.map +1 -1
  131. package/lib/esm/FrontEndDevTools.js +1 -1
  132. package/lib/esm/FrontEndDevTools.js.map +1 -1
  133. package/lib/esm/effects/Convolution.js +23 -23
  134. package/lib/esm/effects/Convolution.js.map +1 -1
  135. package/lib/esm/effects/EffectTools.js +2 -2
  136. package/lib/esm/effects/EffectTools.js.map +1 -1
  137. package/lib/esm/effects/Explosion.js +37 -25
  138. package/lib/esm/effects/Explosion.js.map +1 -1
  139. package/lib/esm/effects/FlipImage.js +22 -22
  140. package/lib/esm/effects/FlipImage.js.map +1 -1
  141. package/lib/esm/effects/LensDistortion.js +25 -25
  142. package/lib/esm/effects/LensDistortion.js.map +1 -1
  143. package/lib/esm/effects/Random.js.map +1 -1
  144. package/lib/esm/effects/Saturation.js +30 -30
  145. package/lib/esm/effects/Saturation.js.map +1 -1
  146. package/lib/esm/effects/Snow.d.ts +1 -1
  147. package/lib/esm/effects/Snow.d.ts.map +1 -1
  148. package/lib/esm/effects/Snow.js +19 -8
  149. package/lib/esm/effects/Snow.js.map +1 -1
  150. package/lib/esm/effects/Vignette.js +41 -41
  151. package/lib/esm/effects/Vignette.js.map +1 -1
  152. package/lib/esm/frontend-devtools.js.map +1 -1
  153. package/lib/esm/tools/AnimationIntervalTool.js +1 -1
  154. package/lib/esm/tools/AnimationIntervalTool.js.map +1 -1
  155. package/lib/esm/tools/ChangeUnitsTool.js +1 -1
  156. package/lib/esm/tools/ChangeUnitsTool.js.map +1 -1
  157. package/lib/esm/tools/ClipTools.js +6 -8
  158. package/lib/esm/tools/ClipTools.js.map +1 -1
  159. package/lib/esm/tools/DisplayStyleTools.js +21 -25
  160. package/lib/esm/tools/DisplayStyleTools.js.map +1 -1
  161. package/lib/esm/tools/EmphasizeElementsTool.js +7 -13
  162. package/lib/esm/tools/EmphasizeElementsTool.js.map +1 -1
  163. package/lib/esm/tools/FrustumDecoration.js +28 -9
  164. package/lib/esm/tools/FrustumDecoration.js.map +1 -1
  165. package/lib/esm/tools/InspectElementTool.js +7 -6
  166. package/lib/esm/tools/InspectElementTool.js.map +1 -1
  167. package/lib/esm/tools/MapLayerTool.js +24 -20
  168. package/lib/esm/tools/MapLayerTool.js.map +1 -1
  169. package/lib/esm/tools/MeasureTileLoadTime.js +4 -1
  170. package/lib/esm/tools/MeasureTileLoadTime.js.map +1 -1
  171. package/lib/esm/tools/ModelAppearanceTools.js +9 -9
  172. package/lib/esm/tools/ModelAppearanceTools.js.map +1 -1
  173. package/lib/esm/tools/PlanProjectionTools.js +8 -15
  174. package/lib/esm/tools/PlanProjectionTools.js.map +1 -1
  175. package/lib/esm/tools/PlanarMaskTools.js +21 -26
  176. package/lib/esm/tools/PlanarMaskTools.js.map +1 -1
  177. package/lib/esm/tools/ProjectExtents.js +6 -3
  178. package/lib/esm/tools/ProjectExtents.js.map +1 -1
  179. package/lib/esm/tools/RealityModelTools.js +10 -10
  180. package/lib/esm/tools/RealityModelTools.js.map +1 -1
  181. package/lib/esm/tools/RealityTransitionTool.js +1 -1
  182. package/lib/esm/tools/RealityTransitionTool.js.map +1 -1
  183. package/lib/esm/tools/RenderSystemTools.js +4 -3
  184. package/lib/esm/tools/RenderSystemTools.js.map +1 -1
  185. package/lib/esm/tools/RenderTargetTools.d.ts +1 -1
  186. package/lib/esm/tools/RenderTargetTools.d.ts.map +1 -1
  187. package/lib/esm/tools/RenderTargetTools.js +15 -20
  188. package/lib/esm/tools/RenderTargetTools.js.map +1 -1
  189. package/lib/esm/tools/ReportWebGLCompatibilityTool.js +1 -1
  190. package/lib/esm/tools/ReportWebGLCompatibilityTool.js.map +1 -1
  191. package/lib/esm/tools/SavedViews.js +4 -7
  192. package/lib/esm/tools/SavedViews.js.map +1 -1
  193. package/lib/esm/tools/ScheduleScriptTools.d.ts.map +1 -1
  194. package/lib/esm/tools/ScheduleScriptTools.js +11 -12
  195. package/lib/esm/tools/ScheduleScriptTools.js.map +1 -1
  196. package/lib/esm/tools/SelectionTools.js +4 -6
  197. package/lib/esm/tools/SelectionTools.js.map +1 -1
  198. package/lib/esm/tools/SetGpuMemoryLimitTool.js +1 -1
  199. package/lib/esm/tools/SetGpuMemoryLimitTool.js.map +1 -1
  200. package/lib/esm/tools/SourceAspectIdTools.js +2 -2
  201. package/lib/esm/tools/SourceAspectIdTools.js.map +1 -1
  202. package/lib/esm/tools/TileRequestDecoration.js +6 -3
  203. package/lib/esm/tools/TileRequestDecoration.js.map +1 -1
  204. package/lib/esm/tools/TileTreeBoundsDecoration.d.ts.map +1 -1
  205. package/lib/esm/tools/TileTreeBoundsDecoration.js +8 -4
  206. package/lib/esm/tools/TileTreeBoundsDecoration.js.map +1 -1
  207. package/lib/esm/tools/ToolTipProvider.js +2 -1
  208. package/lib/esm/tools/ToolTipProvider.js.map +1 -1
  209. package/lib/esm/tools/ViewportTools.js +22 -19
  210. package/lib/esm/tools/ViewportTools.js.map +1 -1
  211. package/lib/esm/tools/parseArgs.js.map +1 -1
  212. package/lib/esm/tools/parseBoolean.js.map +1 -1
  213. package/lib/esm/tools/parseToggle.js.map +1 -1
  214. package/lib/esm/ui/Button.js.map +1 -1
  215. package/lib/esm/ui/CheckBox.js.map +1 -1
  216. package/lib/esm/ui/ColorInput.js.map +1 -1
  217. package/lib/esm/ui/ComboBox.js.map +1 -1
  218. package/lib/esm/ui/DataList.js.map +1 -1
  219. package/lib/esm/ui/NestedMenu.js.map +1 -1
  220. package/lib/esm/ui/NumericInput.js.map +1 -1
  221. package/lib/esm/ui/RadioBox.js.map +1 -1
  222. package/lib/esm/ui/Slider.js.map +1 -1
  223. package/lib/esm/ui/TextBox.js.map +1 -1
  224. package/lib/esm/widgets/DiagnosticsPanel.d.ts +1 -1
  225. package/lib/esm/widgets/DiagnosticsPanel.d.ts.map +1 -1
  226. package/lib/esm/widgets/DiagnosticsPanel.js +11 -1
  227. package/lib/esm/widgets/DiagnosticsPanel.js.map +1 -1
  228. package/lib/esm/widgets/FpsTracker.d.ts +1 -1
  229. package/lib/esm/widgets/FpsTracker.d.ts.map +1 -1
  230. package/lib/esm/widgets/FpsTracker.js +5 -1
  231. package/lib/esm/widgets/FpsTracker.js.map +1 -1
  232. package/lib/esm/widgets/GpuProfiler.d.ts +1 -1
  233. package/lib/esm/widgets/GpuProfiler.d.ts.map +1 -1
  234. package/lib/esm/widgets/GpuProfiler.js +89 -82
  235. package/lib/esm/widgets/GpuProfiler.js.map +1 -1
  236. package/lib/esm/widgets/KeyinField.js +8 -1
  237. package/lib/esm/widgets/KeyinField.js.map +1 -1
  238. package/lib/esm/widgets/MemoryTracker.d.ts +1 -1
  239. package/lib/esm/widgets/MemoryTracker.d.ts.map +1 -1
  240. package/lib/esm/widgets/MemoryTracker.js +16 -4
  241. package/lib/esm/widgets/MemoryTracker.js.map +1 -1
  242. package/lib/esm/widgets/RenderCommandBreakdown.d.ts +1 -1
  243. package/lib/esm/widgets/RenderCommandBreakdown.d.ts.map +1 -1
  244. package/lib/esm/widgets/RenderCommandBreakdown.js +6 -2
  245. package/lib/esm/widgets/RenderCommandBreakdown.js.map +1 -1
  246. package/lib/esm/widgets/TileMemoryBreakdown.d.ts +1 -1
  247. package/lib/esm/widgets/TileMemoryBreakdown.d.ts.map +1 -1
  248. package/lib/esm/widgets/TileMemoryBreakdown.js +10 -8
  249. package/lib/esm/widgets/TileMemoryBreakdown.js.map +1 -1
  250. package/lib/esm/widgets/TileStatisticsTracker.d.ts +1 -1
  251. package/lib/esm/widgets/TileStatisticsTracker.d.ts.map +1 -1
  252. package/lib/esm/widgets/TileStatisticsTracker.js +5 -2
  253. package/lib/esm/widgets/TileStatisticsTracker.js.map +1 -1
  254. package/lib/esm/widgets/ToolSettingsTracker.d.ts +1 -1
  255. package/lib/esm/widgets/ToolSettingsTracker.d.ts.map +1 -1
  256. package/lib/esm/widgets/ToolSettingsTracker.js +2 -2
  257. package/lib/esm/widgets/ToolSettingsTracker.js.map +1 -1
  258. package/lib/public/locales/en/FrontendDevTools.json +494 -494
  259. package/package.json +10 -10
@@ -15,6 +15,10 @@ const CheckBox_1 = require("../ui/CheckBox");
15
15
  * @beta
16
16
  */
17
17
  class FpsTracker {
18
+ _label;
19
+ _metrics;
20
+ _curIntervalId;
21
+ _vp;
18
22
  constructor(parent, viewport) {
19
23
  this._vp = viewport;
20
24
  this._label = (0, CheckBox_1.createCheckBox)({
@@ -24,7 +28,7 @@ class FpsTracker {
24
28
  handler: (cb) => this.toggle(cb.checked),
25
29
  }).label;
26
30
  }
27
- dispose() {
31
+ [Symbol.dispose]() {
28
32
  this.toggle(false);
29
33
  }
30
34
  clearInterval() {
@@ -1 +1 @@
1
- {"version":3,"file":"FpsTracker.js","sourceRoot":"","sources":["../../../src/widgets/FpsTracker.ts"],"names":[],"mappings":";AAAA;;;+FAG+F;;;AAE/F;;GAEG;AAEH,wDAA4E;AAC5E,6CAAgD;AAEhD;;;GAGG;AACH,MAAa,UAAU;IAMrB,YAAmB,MAAmB,EAAE,QAAkB;QACxD,IAAI,CAAC,GAAG,GAAG,QAAQ,CAAC;QACpB,IAAI,CAAC,MAAM,GAAG,IAAA,yBAAc,EAAC;YAC3B,MAAM;YACN,IAAI,EAAE,WAAW;YACjB,EAAE,EAAE,mBAAmB;YACvB,OAAO,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,OAAO,CAAC;SACzC,CAAC,CAAC,KAAK,CAAC;IACX,CAAC;IAEM,OAAO;QACZ,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACrB,CAAC;IAEO,aAAa;QACnB,IAAI,SAAS,KAAK,IAAI,CAAC,cAAc,EAAE,CAAC;YACtC,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;YAC1C,IAAI,CAAC,cAAc,GAAG,SAAS,CAAC;QAClC,CAAC;IACH,CAAC;IAEO,MAAM,CAAC,OAAgB;QAC7B,IAAI,CAAC,GAAG,CAAC,mBAAmB,GAAG,OAAO,CAAC;QACvC,IAAI,OAAO,EAAE,CAAC;YACZ,IAAI,CAAC,QAAQ,GAAG,IAAI,kCAAkB,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;YACpD,IAAI,CAAC,cAAc,GAAG,MAAM,CAAC,WAAW,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,SAAS,EAAE,EAAE,GAAG,CAAC,CAAC;YACtE,IAAI,CAAC,MAAM,CAAC,SAAS,GAAG,iBAAiB,CAAC;QAC5C,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,QAAQ,GAAG,SAAS,CAAC;YAC1B,IAAI,CAAC,aAAa,EAAE,CAAC;YACrB,IAAI,CAAC,MAAM,CAAC,SAAS,GAAG,WAAW,CAAC;QACtC,CAAC;QAEA,IAAI,CAAC,GAAG,CAAC,MAAiB,CAAC,kBAAkB,GAAG,IAAI,CAAC,QAAQ,CAAC;IACjE,CAAC;IAEO,SAAS;QACf,MAAM,OAAO,GAAG,IAAI,CAAC,QAAS,CAAC;QAC/B,MAAM,GAAG,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;QAClE,IAAI,CAAC,MAAM,CAAC,SAAS,GAAG,QAAQ,GAAG,EAAE,CAAC;IACxC,CAAC;CACF;AA/CD,gCA+CC","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n* See LICENSE.md in the project root for license terms and full copyright notice.\r\n*--------------------------------------------------------------------------------------------*/\r\n\r\n/** @packageDocumentation\r\n * @module Widgets\r\n */\r\n\r\nimport { PerformanceMetrics, Target, Viewport } from \"@itwin/core-frontend\";\r\nimport { createCheckBox } from \"../ui/CheckBox\";\r\n\r\n/** Displays average frames-per-second.\r\n * NOTE: Enabling fps tracking causes a new frame to render on every tick of the render loop, which may negatively impact battery life.\r\n * @beta\r\n */\r\nexport class FpsTracker {\r\n private readonly _label: HTMLLabelElement;\r\n private _metrics?: PerformanceMetrics;\r\n private _curIntervalId?: number;\r\n private readonly _vp: Viewport;\r\n\r\n public constructor(parent: HTMLElement, viewport: Viewport) {\r\n this._vp = viewport;\r\n this._label = createCheckBox({\r\n parent,\r\n name: \"Track FPS\",\r\n id: \"fpsTracker_toggle\",\r\n handler: (cb) => this.toggle(cb.checked),\r\n }).label;\r\n }\r\n\r\n public dispose(): void {\r\n this.toggle(false);\r\n }\r\n\r\n private clearInterval(): void {\r\n if (undefined !== this._curIntervalId) {\r\n window.clearInterval(this._curIntervalId);\r\n this._curIntervalId = undefined;\r\n }\r\n }\r\n\r\n private toggle(enabled: boolean): void {\r\n this._vp.continuousRendering = enabled;\r\n if (enabled) {\r\n this._metrics = new PerformanceMetrics(false, true);\r\n this._curIntervalId = window.setInterval(() => this.updateFPS(), 500);\r\n this._label.innerText = \"Tracking FPS...\";\r\n } else {\r\n this._metrics = undefined;\r\n this.clearInterval();\r\n this._label.innerText = \"Track FPS\";\r\n }\r\n\r\n (this._vp.target as Target).performanceMetrics = this._metrics;\r\n }\r\n\r\n private updateFPS(): void {\r\n const metrics = this._metrics!;\r\n const fps = (metrics.spfTimes.length / metrics.spfSum).toFixed(2);\r\n this._label.innerText = `FPS: ${fps}`;\r\n }\r\n}\r\n"]}
1
+ {"version":3,"file":"FpsTracker.js","sourceRoot":"","sources":["../../../src/widgets/FpsTracker.ts"],"names":[],"mappings":";AAAA;;;+FAG+F;;;AAE/F;;GAEG;AAEH,wDAA4E;AAC5E,6CAAgD;AAEhD;;;GAGG;AACH,MAAa,UAAU;IACJ,MAAM,CAAmB;IAClC,QAAQ,CAAsB;IAC9B,cAAc,CAAU;IACf,GAAG,CAAW;IAE/B,YAAmB,MAAmB,EAAE,QAAkB;QACxD,IAAI,CAAC,GAAG,GAAG,QAAQ,CAAC;QACpB,IAAI,CAAC,MAAM,GAAG,IAAA,yBAAc,EAAC;YAC3B,MAAM;YACN,IAAI,EAAE,WAAW;YACjB,EAAE,EAAE,mBAAmB;YACvB,OAAO,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,OAAO,CAAC;SACzC,CAAC,CAAC,KAAK,CAAC;IACX,CAAC;IAEM,CAAC,MAAM,CAAC,OAAO,CAAC;QACrB,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACrB,CAAC;IAEO,aAAa;QACnB,IAAI,SAAS,KAAK,IAAI,CAAC,cAAc,EAAE,CAAC;YACtC,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;YAC1C,IAAI,CAAC,cAAc,GAAG,SAAS,CAAC;QAClC,CAAC;IACH,CAAC;IAEO,MAAM,CAAC,OAAgB;QAC7B,IAAI,CAAC,GAAG,CAAC,mBAAmB,GAAG,OAAO,CAAC;QACvC,IAAI,OAAO,EAAE,CAAC;YACZ,IAAI,CAAC,QAAQ,GAAG,IAAI,kCAAkB,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;YACpD,IAAI,CAAC,cAAc,GAAG,MAAM,CAAC,WAAW,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,SAAS,EAAE,EAAE,GAAG,CAAC,CAAC;YACtE,IAAI,CAAC,MAAM,CAAC,SAAS,GAAG,iBAAiB,CAAC;QAC5C,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,QAAQ,GAAG,SAAS,CAAC;YAC1B,IAAI,CAAC,aAAa,EAAE,CAAC;YACrB,IAAI,CAAC,MAAM,CAAC,SAAS,GAAG,WAAW,CAAC;QACtC,CAAC;QAEA,IAAI,CAAC,GAAG,CAAC,MAAiB,CAAC,kBAAkB,GAAG,IAAI,CAAC,QAAQ,CAAC;IACjE,CAAC;IAEO,SAAS;QACf,MAAM,OAAO,GAAG,IAAI,CAAC,QAAS,CAAC;QAC/B,MAAM,GAAG,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;QAClE,IAAI,CAAC,MAAM,CAAC,SAAS,GAAG,QAAQ,GAAG,EAAE,CAAC;IACxC,CAAC;CACF;AA/CD,gCA+CC","sourcesContent":["/*---------------------------------------------------------------------------------------------\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n* See LICENSE.md in the project root for license terms and full copyright notice.\n*--------------------------------------------------------------------------------------------*/\n\n/** @packageDocumentation\n * @module Widgets\n */\n\nimport { PerformanceMetrics, Target, Viewport } from \"@itwin/core-frontend\";\nimport { createCheckBox } from \"../ui/CheckBox\";\n\n/** Displays average frames-per-second.\n * NOTE: Enabling fps tracking causes a new frame to render on every tick of the render loop, which may negatively impact battery life.\n * @beta\n */\nexport class FpsTracker {\n private readonly _label: HTMLLabelElement;\n private _metrics?: PerformanceMetrics;\n private _curIntervalId?: number;\n private readonly _vp: Viewport;\n\n public constructor(parent: HTMLElement, viewport: Viewport) {\n this._vp = viewport;\n this._label = createCheckBox({\n parent,\n name: \"Track FPS\",\n id: \"fpsTracker_toggle\",\n handler: (cb) => this.toggle(cb.checked),\n }).label;\n }\n\n public [Symbol.dispose](): void {\n this.toggle(false);\n }\n\n private clearInterval(): void {\n if (undefined !== this._curIntervalId) {\n window.clearInterval(this._curIntervalId);\n this._curIntervalId = undefined;\n }\n }\n\n private toggle(enabled: boolean): void {\n this._vp.continuousRendering = enabled;\n if (enabled) {\n this._metrics = new PerformanceMetrics(false, true);\n this._curIntervalId = window.setInterval(() => this.updateFPS(), 500);\n this._label.innerText = \"Tracking FPS...\";\n } else {\n this._metrics = undefined;\n this.clearInterval();\n this._label.innerText = \"Track FPS\";\n }\n\n (this._vp.target as Target).performanceMetrics = this._metrics;\n }\n\n private updateFPS(): void {\n const metrics = this._metrics!;\n const fps = (metrics.spfTimes.length / metrics.spfSum).toFixed(2);\n this._label.innerText = `FPS: ${fps}`;\n }\n}\n"]}
@@ -8,7 +8,7 @@ export declare class GpuProfiler {
8
8
  private _recordedResults;
9
9
  private _isRecording;
10
10
  constructor(parent: HTMLElement);
11
- dispose(): void;
11
+ [Symbol.dispose](): void;
12
12
  private toggleProfileCheckBox;
13
13
  private _clickRecord;
14
14
  private stopRecording;
@@ -1 +1 @@
1
- {"version":3,"file":"GpuProfiler.d.ts","sourceRoot":"","sources":["../../../src/widgets/GpuProfiler.ts"],"names":[],"mappings":"AA2FA,aAAa;AACb,qBAAa,WAAW;IACtB,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAiB;IACtC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAiB;IAC7C,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAuB;IAChD,OAAO,CAAC,QAAQ,CAAC,aAAa,CAA2B;IAEzD,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAqB;IACnD,OAAO,CAAC,gBAAgB,CAAkB;IAC1C,OAAO,CAAC,YAAY,CAAU;gBAEX,MAAM,EAAE,WAAW;IAmC/B,OAAO,IAAI,IAAI;IAItB,OAAO,CAAC,qBAAqB;IAY7B,OAAO,CAAC,YAAY,CAQlB;IAEF,OAAO,CAAC,aAAa;IAYrB,OAAO,CAAC,gBAAgB,CA0EtB;CACH"}
1
+ {"version":3,"file":"GpuProfiler.d.ts","sourceRoot":"","sources":["../../../src/widgets/GpuProfiler.ts"],"names":[],"mappings":"AA2FA,aAAa;AACb,qBAAa,WAAW;IACtB,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAiB;IACtC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAiB;IAC7C,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAuB;IAChD,OAAO,CAAC,QAAQ,CAAC,aAAa,CAA2B;IAEzD,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAqB;IACnD,OAAO,CAAC,gBAAgB,CAAkB;IAC1C,OAAO,CAAC,YAAY,CAAU;gBAEX,MAAM,EAAE,WAAW;IAmC/B,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,IAAI;IAI/B,OAAO,CAAC,qBAAqB;IAY7B,OAAO,CAAC,YAAY,CAQlB;IAEF,OAAO,CAAC,aAAa;IAYrB,OAAO,CAAC,gBAAgB,CA0EtB;CACH"}
@@ -54,88 +54,14 @@ function createTraceFromTimerResults(timerResults) {
54
54
  }
55
55
  /** @alpha */
56
56
  class GpuProfiler {
57
+ _div;
58
+ _resultsDiv;
59
+ _results;
60
+ _debugControl;
61
+ _recordButton;
62
+ _recordedResults;
63
+ _isRecording;
57
64
  constructor(parent) {
58
- this._clickRecord = () => {
59
- if (!this._isRecording) {
60
- this._isRecording = true;
61
- this._recordButton.innerText = "Stop Recording";
62
- return;
63
- }
64
- this.stopRecording();
65
- };
66
- this._resultsCallback = (result) => {
67
- if (this._isRecording)
68
- this._recordedResults.push(result);
69
- const fragment = document.createDocumentFragment();
70
- const numSavedFrames = 120;
71
- let lastValue;
72
- const changedResults = new Array(this._results.length); // default values false
73
- const printDepth = (depth, currentRes) => {
74
- const index = this._results.findIndex((res) => res.label === currentRes.label);
75
- if (index < 0) { // Add brand new entry
76
- const data = {
77
- label: currentRes.label,
78
- paddingLeft: `${depth}em`,
79
- sum: currentRes.nanoseconds,
80
- values: [currentRes.nanoseconds],
81
- };
82
- if (lastValue === undefined) {
83
- this._results.unshift(data);
84
- changedResults.unshift(true);
85
- }
86
- else if (currentRes.label === "Read Pixels") {
87
- this._results.push(data); // Read Pixels should go at the end of the list
88
- changedResults.push(true);
89
- }
90
- else {
91
- const prevIndex = this._results.findIndex((res) => res.label === lastValue);
92
- this._results.splice(prevIndex + 1, 0, data);
93
- changedResults.splice(prevIndex + 1, 0, true);
94
- }
95
- }
96
- else { // Edit old entry
97
- let oldVal = 0.0;
98
- const savedResults = this._results[index];
99
- if (savedResults.values.length >= numSavedFrames) { // keep up to numSavedFrames values to average between
100
- oldVal = savedResults.values.shift();
101
- }
102
- const newVal = currentRes.nanoseconds < 100 ? 0.0 : currentRes.nanoseconds; // high-pass filter, empty queries have some noise
103
- savedResults.sum += newVal - oldVal;
104
- savedResults.values.push(newVal);
105
- changedResults[index] = true;
106
- }
107
- lastValue = currentRes.label;
108
- if (!currentRes.children)
109
- return;
110
- for (const childRes of currentRes.children)
111
- printDepth(depth + 1, childRes);
112
- };
113
- printDepth(0, result);
114
- this._results.forEach((value, index) => {
115
- if (!changedResults[index]) { // if no data received on this item, add a value of 0.0 to the avg.
116
- const oldVal = value.values.length >= numSavedFrames ? value.values.shift() : 0.0;
117
- value.sum -= oldVal;
118
- value.values.push(0.0);
119
- }
120
- const div = document.createElement("div");
121
- div.style.display = "flex";
122
- div.style.width = "75%";
123
- const textLabel = document.createElement("text");
124
- textLabel.innerText = `${value.label}`;
125
- textLabel.style.paddingLeft = value.paddingLeft;
126
- div.appendChild(textLabel);
127
- const divLine = document.createElement("div");
128
- divLine.style.flexGrow = "1";
129
- divLine.style.borderBottom = "dotted 1px";
130
- div.appendChild(divLine);
131
- const textValue = document.createElement("text");
132
- textValue.innerText = `${(value.sum / value.values.length / 1.E6).toFixed(3)} ms\n`;
133
- div.appendChild(textValue);
134
- fragment.appendChild(div);
135
- });
136
- this._resultsDiv.innerHTML = "";
137
- this._resultsDiv.appendChild(fragment);
138
- };
139
65
  this._debugControl = core_frontend_1.IModelApp.renderSystem.debugControl;
140
66
  const checkBox = (0, CheckBox_1.createCheckBox)({
141
67
  parent,
@@ -163,7 +89,7 @@ class GpuProfiler {
163
89
  this._div.appendChild(this._resultsDiv);
164
90
  parent.appendChild(this._div);
165
91
  }
166
- dispose() {
92
+ [Symbol.dispose]() {
167
93
  this._debugControl.resultsCallback = undefined;
168
94
  }
169
95
  toggleProfileCheckBox(isEnabled) {
@@ -178,6 +104,14 @@ class GpuProfiler {
178
104
  this.stopRecording();
179
105
  }
180
106
  }
107
+ _clickRecord = () => {
108
+ if (!this._isRecording) {
109
+ this._isRecording = true;
110
+ this._recordButton.innerText = "Stop Recording";
111
+ return;
112
+ }
113
+ this.stopRecording();
114
+ };
181
115
  stopRecording() {
182
116
  this._isRecording = false;
183
117
  this._recordButton.innerText = "Record Profile";
@@ -188,6 +122,79 @@ class GpuProfiler {
188
122
  this._recordedResults = [];
189
123
  }
190
124
  }
125
+ _resultsCallback = (result) => {
126
+ if (this._isRecording)
127
+ this._recordedResults.push(result);
128
+ const fragment = document.createDocumentFragment();
129
+ const numSavedFrames = 120;
130
+ let lastValue;
131
+ const changedResults = new Array(this._results.length); // default values false
132
+ const printDepth = (depth, currentRes) => {
133
+ const index = this._results.findIndex((res) => res.label === currentRes.label);
134
+ if (index < 0) { // Add brand new entry
135
+ const data = {
136
+ label: currentRes.label,
137
+ paddingLeft: `${depth}em`,
138
+ sum: currentRes.nanoseconds,
139
+ values: [currentRes.nanoseconds],
140
+ };
141
+ if (lastValue === undefined) {
142
+ this._results.unshift(data);
143
+ changedResults.unshift(true);
144
+ }
145
+ else if (currentRes.label === "Read Pixels") {
146
+ this._results.push(data); // Read Pixels should go at the end of the list
147
+ changedResults.push(true);
148
+ }
149
+ else {
150
+ const prevIndex = this._results.findIndex((res) => res.label === lastValue);
151
+ this._results.splice(prevIndex + 1, 0, data);
152
+ changedResults.splice(prevIndex + 1, 0, true);
153
+ }
154
+ }
155
+ else { // Edit old entry
156
+ let oldVal = 0.0;
157
+ const savedResults = this._results[index];
158
+ if (savedResults.values.length >= numSavedFrames) { // keep up to numSavedFrames values to average between
159
+ oldVal = savedResults.values.shift();
160
+ }
161
+ const newVal = currentRes.nanoseconds < 100 ? 0.0 : currentRes.nanoseconds; // high-pass filter, empty queries have some noise
162
+ savedResults.sum += newVal - oldVal;
163
+ savedResults.values.push(newVal);
164
+ changedResults[index] = true;
165
+ }
166
+ lastValue = currentRes.label;
167
+ if (!currentRes.children)
168
+ return;
169
+ for (const childRes of currentRes.children)
170
+ printDepth(depth + 1, childRes);
171
+ };
172
+ printDepth(0, result);
173
+ this._results.forEach((value, index) => {
174
+ if (!changedResults[index]) { // if no data received on this item, add a value of 0.0 to the avg.
175
+ const oldVal = value.values.length >= numSavedFrames ? value.values.shift() : 0.0;
176
+ value.sum -= oldVal;
177
+ value.values.push(0.0);
178
+ }
179
+ const div = document.createElement("div");
180
+ div.style.display = "flex";
181
+ div.style.width = "75%";
182
+ const textLabel = document.createElement("text");
183
+ textLabel.innerText = `${value.label}`;
184
+ textLabel.style.paddingLeft = value.paddingLeft;
185
+ div.appendChild(textLabel);
186
+ const divLine = document.createElement("div");
187
+ divLine.style.flexGrow = "1";
188
+ divLine.style.borderBottom = "dotted 1px";
189
+ div.appendChild(divLine);
190
+ const textValue = document.createElement("text");
191
+ textValue.innerText = `${(value.sum / value.values.length / 1.E6).toFixed(3)} ms\n`;
192
+ div.appendChild(textValue);
193
+ fragment.appendChild(div);
194
+ });
195
+ this._resultsDiv.innerHTML = "";
196
+ this._resultsDiv.appendChild(fragment);
197
+ };
191
198
  }
192
199
  exports.GpuProfiler = GpuProfiler;
193
200
  //# sourceMappingURL=GpuProfiler.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"GpuProfiler.js","sourceRoot":"","sources":["../../../src/widgets/GpuProfiler.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n* See LICENSE.md in the project root for license terms and full copyright notice.\r\n*--------------------------------------------------------------------------------------------*/\r\n\r\n/** @packageDocumentation\r\n * @module Widgets\r\n */\r\n\r\nimport { saveAs } from \"file-saver\";\r\nimport { GLTimerResult, IModelApp, RenderSystemDebugControl } from \"@itwin/core-frontend\";\r\nimport { createCheckBox } from \"../ui/CheckBox\";\r\n\r\n/** Trace Event Format, viewable with chrome://tracing\r\n * https://docs.google.com/document/d/1CvAClvFfyA5R-PhYUmn5OOQtYMH4h6I0nSsKchNAySU/edit\r\n */\r\ninterface ChromeTrace {\r\n traceEvents: ChromeTraceEvent[];\r\n}\r\n\r\ninterface ChromeTraceEvent {\r\n /** Required by chrome://tracing */\r\n pid: 1;\r\n /** Timestamp in microseconds */\r\n ts: number;\r\n /** Duration in microseconds */\r\n dur: number;\r\n /** Denotes \"complete\" event */\r\n ph: \"X\";\r\n /** Label for chrome://tracing view */\r\n name: string;\r\n /** dummy value, args must be defined for entries to be clickable in chrome://tracing */\r\n args: ChromeTraceEventArgs;\r\n}\r\n\r\ninterface ChromeTraceEventArgs { 0: 0 }\r\nconst dummyArgs: ChromeTraceEventArgs = { 0: 0 }; // Reuse instead of allocating for each entry\r\n\r\n/**\r\n * @param name Label for the trace event\r\n * @param start Timestamp in microseconds of when trace event started\r\n * @param duration Duration in microseconds of trace event\r\n */\r\nfunction createTraceEvent(name: string, start: number, duration: number): ChromeTraceEvent {\r\n return {\r\n pid: 1,\r\n ts: start,\r\n dur: duration,\r\n ph: \"X\",\r\n name,\r\n args: dummyArgs,\r\n };\r\n}\r\n\r\nfunction createTraceFromTimerResults(timerResults: GLTimerResult[]): ChromeTrace {\r\n const traceEvents: ChromeTraceEvent[] = [];\r\n\r\n const addChildren = (startTime: number, children: GLTimerResult[]) => {\r\n for (const child of children) {\r\n if (child.nanoseconds < 100)\r\n continue;\r\n const microseconds = child.nanoseconds / 1E3;\r\n traceEvents.push(createTraceEvent(child.label, startTime, microseconds));\r\n if (child.children)\r\n addChildren(startTime, child.children);\r\n startTime += microseconds;\r\n }\r\n };\r\n\r\n let frameStartTime = 0;\r\n let frameNumber = 0;\r\n for (const tr of timerResults) {\r\n const microseconds = tr.nanoseconds / 1E3;\r\n traceEvents.push(createTraceEvent(`Frame ${frameNumber}`, frameStartTime, microseconds));\r\n if (tr.children)\r\n addChildren(frameStartTime, tr.children);\r\n frameStartTime += microseconds;\r\n ++frameNumber;\r\n }\r\n\r\n return { traceEvents };\r\n}\r\n\r\n/** @internal */\r\ninterface GpuProfilerResults {\r\n label: string;\r\n sum: number;\r\n paddingLeft: string;\r\n values: number[];\r\n}\r\n\r\n/** @alpha */\r\nexport class GpuProfiler {\r\n private readonly _div: HTMLDivElement;\r\n private readonly _resultsDiv: HTMLDivElement;\r\n private readonly _results: GpuProfilerResults[];\r\n private readonly _debugControl: RenderSystemDebugControl;\r\n\r\n private readonly _recordButton!: HTMLButtonElement;\r\n private _recordedResults: GLTimerResult[];\r\n private _isRecording: boolean;\r\n\r\n public constructor(parent: HTMLElement) {\r\n this._debugControl = IModelApp.renderSystem.debugControl!;\r\n\r\n const checkBox = createCheckBox({\r\n parent,\r\n name: \"Profile GPU\",\r\n id: \"gpu-profiler-toggle\",\r\n handler: (cb) => this.toggleProfileCheckBox(cb.checked),\r\n });\r\n\r\n if (!this._debugControl.isGLTimerSupported) {\r\n checkBox.checkbox.disabled = true;\r\n checkBox.div.title = \"EXT_disjoint_timer_query is not available in this browser\";\r\n }\r\n\r\n this._div = document.createElement(\"div\");\r\n this._div.style.display = \"none\";\r\n\r\n this._recordButton = document.createElement(\"button\");\r\n this._recordButton.style.textAlign = \"center\";\r\n this._isRecording = false;\r\n this._recordButton.innerText = \"Record Profile\";\r\n this._recordButton.title = \"Record a profile to open with chrome://tracing\";\r\n this._recordedResults = [];\r\n this._recordButton.addEventListener(\"click\", this._clickRecord);\r\n this._div.appendChild(this._recordButton);\r\n\r\n this._results = [];\r\n this._resultsDiv = document.createElement(\"div\");\r\n this._resultsDiv.style.textAlign = \"left\";\r\n this._div.appendChild(this._resultsDiv);\r\n\r\n parent.appendChild(this._div);\r\n }\r\n\r\n public dispose(): void {\r\n this._debugControl.resultsCallback = undefined;\r\n }\r\n\r\n private toggleProfileCheckBox(isEnabled: boolean): void {\r\n if (isEnabled) {\r\n this._debugControl.resultsCallback = this._resultsCallback;\r\n this._resultsDiv.innerHTML = \"\";\r\n this._div.style.display = \"block\";\r\n } else {\r\n this._debugControl.resultsCallback = undefined;\r\n this._div.style.display = \"none\";\r\n this.stopRecording();\r\n }\r\n }\r\n\r\n private _clickRecord = () => {\r\n if (!this._isRecording) {\r\n this._isRecording = true;\r\n this._recordButton.innerText = \"Stop Recording\";\r\n return;\r\n }\r\n\r\n this.stopRecording();\r\n };\r\n\r\n private stopRecording() {\r\n this._isRecording = false;\r\n this._recordButton.innerText = \"Record Profile\";\r\n\r\n if (this._recordedResults.length !== 0) {\r\n const chromeTrace = createTraceFromTimerResults(this._recordedResults);\r\n const blob = new Blob([JSON.stringify(chromeTrace)], { type: \"application/json;charset=utf-8\" });\r\n saveAs(blob, \"gpu-profile.json\");\r\n this._recordedResults = [];\r\n }\r\n }\r\n\r\n private _resultsCallback = (result: GLTimerResult): void => {\r\n if (this._isRecording)\r\n this._recordedResults.push(result);\r\n\r\n const fragment = document.createDocumentFragment();\r\n const numSavedFrames = 120;\r\n let lastValue: string;\r\n const changedResults = new Array<boolean>(this._results.length); // default values false\r\n const printDepth = (depth: number, currentRes: GLTimerResult) => {\r\n const index = this._results.findIndex((res) => res.label === currentRes.label);\r\n if (index < 0) { // Add brand new entry\r\n const data: GpuProfilerResults = {\r\n label: currentRes.label,\r\n paddingLeft: `${depth}em`,\r\n sum: currentRes.nanoseconds,\r\n values: [currentRes.nanoseconds],\r\n };\r\n if (lastValue === undefined) {\r\n this._results.unshift(data);\r\n changedResults.unshift(true);\r\n } else if (currentRes.label === \"Read Pixels\") {\r\n this._results.push(data); // Read Pixels should go at the end of the list\r\n changedResults.push(true);\r\n } else {\r\n const prevIndex = this._results.findIndex((res) => res.label === lastValue);\r\n this._results.splice(prevIndex + 1, 0, data);\r\n changedResults.splice(prevIndex + 1, 0, true);\r\n }\r\n } else { // Edit old entry\r\n let oldVal = 0.0;\r\n const savedResults = this._results[index];\r\n if (savedResults.values.length >= numSavedFrames) { // keep up to numSavedFrames values to average between\r\n oldVal = savedResults.values.shift()!;\r\n }\r\n const newVal = currentRes.nanoseconds < 100 ? 0.0 : currentRes.nanoseconds; // high-pass filter, empty queries have some noise\r\n savedResults.sum += newVal - oldVal;\r\n savedResults.values.push(newVal);\r\n changedResults[index] = true;\r\n }\r\n lastValue = currentRes.label;\r\n\r\n if (!currentRes.children)\r\n return;\r\n\r\n for (const childRes of currentRes.children)\r\n printDepth(depth + 1, childRes);\r\n };\r\n printDepth(0, result);\r\n\r\n this._results.forEach((value, index) => {\r\n if (!changedResults[index]) { // if no data received on this item, add a value of 0.0 to the avg.\r\n const oldVal = value.values.length >= numSavedFrames ? value.values.shift()! : 0.0;\r\n value.sum -= oldVal;\r\n value.values.push(0.0);\r\n }\r\n const div = document.createElement(\"div\");\r\n div.style.display = \"flex\";\r\n div.style.width = \"75%\";\r\n const textLabel = document.createElement(\"text\");\r\n textLabel.innerText = `${value.label}`;\r\n textLabel.style.paddingLeft = value.paddingLeft;\r\n div.appendChild(textLabel);\r\n const divLine = document.createElement(\"div\");\r\n divLine.style.flexGrow = \"1\";\r\n divLine.style.borderBottom = \"dotted 1px\";\r\n div.appendChild(divLine);\r\n const textValue = document.createElement(\"text\");\r\n textValue.innerText = `${(value.sum / value.values.length / 1.E6).toFixed(3)} ms\\n`;\r\n div.appendChild(textValue);\r\n fragment.appendChild(div);\r\n });\r\n\r\n this._resultsDiv.innerHTML = \"\";\r\n this._resultsDiv.appendChild(fragment);\r\n };\r\n}\r\n"]}
1
+ {"version":3,"file":"GpuProfiler.js","sourceRoot":"","sources":["../../../src/widgets/GpuProfiler.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n* See LICENSE.md in the project root for license terms and full copyright notice.\n*--------------------------------------------------------------------------------------------*/\n\n/** @packageDocumentation\n * @module Widgets\n */\n\nimport { saveAs } from \"file-saver\";\nimport { GLTimerResult, IModelApp, RenderSystemDebugControl } from \"@itwin/core-frontend\";\nimport { createCheckBox } from \"../ui/CheckBox\";\n\n/** Trace Event Format, viewable with chrome://tracing\n * https://docs.google.com/document/d/1CvAClvFfyA5R-PhYUmn5OOQtYMH4h6I0nSsKchNAySU/edit\n */\ninterface ChromeTrace {\n traceEvents: ChromeTraceEvent[];\n}\n\ninterface ChromeTraceEvent {\n /** Required by chrome://tracing */\n pid: 1;\n /** Timestamp in microseconds */\n ts: number;\n /** Duration in microseconds */\n dur: number;\n /** Denotes \"complete\" event */\n ph: \"X\";\n /** Label for chrome://tracing view */\n name: string;\n /** dummy value, args must be defined for entries to be clickable in chrome://tracing */\n args: ChromeTraceEventArgs;\n}\n\ninterface ChromeTraceEventArgs { 0: 0 }\nconst dummyArgs: ChromeTraceEventArgs = { 0: 0 }; // Reuse instead of allocating for each entry\n\n/**\n * @param name Label for the trace event\n * @param start Timestamp in microseconds of when trace event started\n * @param duration Duration in microseconds of trace event\n */\nfunction createTraceEvent(name: string, start: number, duration: number): ChromeTraceEvent {\n return {\n pid: 1,\n ts: start,\n dur: duration,\n ph: \"X\",\n name,\n args: dummyArgs,\n };\n}\n\nfunction createTraceFromTimerResults(timerResults: GLTimerResult[]): ChromeTrace {\n const traceEvents: ChromeTraceEvent[] = [];\n\n const addChildren = (startTime: number, children: GLTimerResult[]) => {\n for (const child of children) {\n if (child.nanoseconds < 100)\n continue;\n const microseconds = child.nanoseconds / 1E3;\n traceEvents.push(createTraceEvent(child.label, startTime, microseconds));\n if (child.children)\n addChildren(startTime, child.children);\n startTime += microseconds;\n }\n };\n\n let frameStartTime = 0;\n let frameNumber = 0;\n for (const tr of timerResults) {\n const microseconds = tr.nanoseconds / 1E3;\n traceEvents.push(createTraceEvent(`Frame ${frameNumber}`, frameStartTime, microseconds));\n if (tr.children)\n addChildren(frameStartTime, tr.children);\n frameStartTime += microseconds;\n ++frameNumber;\n }\n\n return { traceEvents };\n}\n\n/** @internal */\ninterface GpuProfilerResults {\n label: string;\n sum: number;\n paddingLeft: string;\n values: number[];\n}\n\n/** @alpha */\nexport class GpuProfiler {\n private readonly _div: HTMLDivElement;\n private readonly _resultsDiv: HTMLDivElement;\n private readonly _results: GpuProfilerResults[];\n private readonly _debugControl: RenderSystemDebugControl;\n\n private readonly _recordButton!: HTMLButtonElement;\n private _recordedResults: GLTimerResult[];\n private _isRecording: boolean;\n\n public constructor(parent: HTMLElement) {\n this._debugControl = IModelApp.renderSystem.debugControl!;\n\n const checkBox = createCheckBox({\n parent,\n name: \"Profile GPU\",\n id: \"gpu-profiler-toggle\",\n handler: (cb) => this.toggleProfileCheckBox(cb.checked),\n });\n\n if (!this._debugControl.isGLTimerSupported) {\n checkBox.checkbox.disabled = true;\n checkBox.div.title = \"EXT_disjoint_timer_query is not available in this browser\";\n }\n\n this._div = document.createElement(\"div\");\n this._div.style.display = \"none\";\n\n this._recordButton = document.createElement(\"button\");\n this._recordButton.style.textAlign = \"center\";\n this._isRecording = false;\n this._recordButton.innerText = \"Record Profile\";\n this._recordButton.title = \"Record a profile to open with chrome://tracing\";\n this._recordedResults = [];\n this._recordButton.addEventListener(\"click\", this._clickRecord);\n this._div.appendChild(this._recordButton);\n\n this._results = [];\n this._resultsDiv = document.createElement(\"div\");\n this._resultsDiv.style.textAlign = \"left\";\n this._div.appendChild(this._resultsDiv);\n\n parent.appendChild(this._div);\n }\n\n public [Symbol.dispose](): void {\n this._debugControl.resultsCallback = undefined;\n }\n\n private toggleProfileCheckBox(isEnabled: boolean): void {\n if (isEnabled) {\n this._debugControl.resultsCallback = this._resultsCallback;\n this._resultsDiv.innerHTML = \"\";\n this._div.style.display = \"block\";\n } else {\n this._debugControl.resultsCallback = undefined;\n this._div.style.display = \"none\";\n this.stopRecording();\n }\n }\n\n private _clickRecord = () => {\n if (!this._isRecording) {\n this._isRecording = true;\n this._recordButton.innerText = \"Stop Recording\";\n return;\n }\n\n this.stopRecording();\n };\n\n private stopRecording() {\n this._isRecording = false;\n this._recordButton.innerText = \"Record Profile\";\n\n if (this._recordedResults.length !== 0) {\n const chromeTrace = createTraceFromTimerResults(this._recordedResults);\n const blob = new Blob([JSON.stringify(chromeTrace)], { type: \"application/json;charset=utf-8\" });\n saveAs(blob, \"gpu-profile.json\");\n this._recordedResults = [];\n }\n }\n\n private _resultsCallback = (result: GLTimerResult): void => {\n if (this._isRecording)\n this._recordedResults.push(result);\n\n const fragment = document.createDocumentFragment();\n const numSavedFrames = 120;\n let lastValue: string;\n const changedResults = new Array<boolean>(this._results.length); // default values false\n const printDepth = (depth: number, currentRes: GLTimerResult) => {\n const index = this._results.findIndex((res) => res.label === currentRes.label);\n if (index < 0) { // Add brand new entry\n const data: GpuProfilerResults = {\n label: currentRes.label,\n paddingLeft: `${depth}em`,\n sum: currentRes.nanoseconds,\n values: [currentRes.nanoseconds],\n };\n if (lastValue === undefined) {\n this._results.unshift(data);\n changedResults.unshift(true);\n } else if (currentRes.label === \"Read Pixels\") {\n this._results.push(data); // Read Pixels should go at the end of the list\n changedResults.push(true);\n } else {\n const prevIndex = this._results.findIndex((res) => res.label === lastValue);\n this._results.splice(prevIndex + 1, 0, data);\n changedResults.splice(prevIndex + 1, 0, true);\n }\n } else { // Edit old entry\n let oldVal = 0.0;\n const savedResults = this._results[index];\n if (savedResults.values.length >= numSavedFrames) { // keep up to numSavedFrames values to average between\n oldVal = savedResults.values.shift()!;\n }\n const newVal = currentRes.nanoseconds < 100 ? 0.0 : currentRes.nanoseconds; // high-pass filter, empty queries have some noise\n savedResults.sum += newVal - oldVal;\n savedResults.values.push(newVal);\n changedResults[index] = true;\n }\n lastValue = currentRes.label;\n\n if (!currentRes.children)\n return;\n\n for (const childRes of currentRes.children)\n printDepth(depth + 1, childRes);\n };\n printDepth(0, result);\n\n this._results.forEach((value, index) => {\n if (!changedResults[index]) { // if no data received on this item, add a value of 0.0 to the avg.\n const oldVal = value.values.length >= numSavedFrames ? value.values.shift()! : 0.0;\n value.sum -= oldVal;\n value.values.push(0.0);\n }\n const div = document.createElement(\"div\");\n div.style.display = \"flex\";\n div.style.width = \"75%\";\n const textLabel = document.createElement(\"text\");\n textLabel.innerText = `${value.label}`;\n textLabel.style.paddingLeft = value.paddingLeft;\n div.appendChild(textLabel);\n const divLine = document.createElement(\"div\");\n divLine.style.flexGrow = \"1\";\n divLine.style.borderBottom = \"dotted 1px\";\n div.appendChild(divLine);\n const textValue = document.createElement(\"text\");\n textValue.innerText = `${(value.sum / value.values.length / 1.E6).toFixed(3)} ms\\n`;\n div.appendChild(textValue);\n fragment.appendChild(div);\n });\n\n this._resultsDiv.innerHTML = \"\";\n this._resultsDiv.appendChild(fragment);\n };\n}\n"]}
@@ -36,8 +36,15 @@ var KeyinFieldLocalization;
36
36
  * @beta
37
37
  */
38
38
  class KeyinField {
39
+ /** @alpha */
40
+ autoCompleteList;
41
+ textBox;
42
+ keyins;
43
+ _historyIndex;
44
+ _historyLength = 0;
45
+ _history;
46
+ _localization;
39
47
  constructor(props) {
40
- this._historyLength = 0;
41
48
  this._localization = props.localization ?? KeyinFieldLocalization.NonLocalized;
42
49
  this.keyins = this.findKeyins();
43
50
  const autoCompleteListId = `${props.baseId}_autoComplete`;
@@ -1 +1 @@
1
- {"version":3,"file":"KeyinField.js","sourceRoot":"","sources":["../../../src/widgets/KeyinField.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n* See LICENSE.md in the project root for license terms and full copyright notice.\r\n*--------------------------------------------------------------------------------------------*/\r\n\r\n/** @packageDocumentation\r\n * @module Widgets\r\n */\r\n\r\nimport { IModelApp, MessageBoxIconType, MessageBoxType, ParseAndRunResult } from \"@itwin/core-frontend\";\r\nimport { createButton } from \"../ui/Button\";\r\nimport { appendDataListEntries, createDataList, DataList, DataListEntry } from \"../ui/DataList\";\r\nimport { createTextBox, TextBox } from \"../ui/TextBox\";\r\n\r\nfunction keyinsToDataListEntries(keyins: string[]): DataListEntry[] {\r\n const entries: DataListEntry[] = [];\r\n for (const keyin of keyins) {\r\n entries.push({ value: keyin });\r\n }\r\n\r\n return entries;\r\n}\r\n\r\n/** Controls whether localized and/or non-localized key-in strings appear in a KeyinField's auto-completion list.\r\n * @beta\r\n */\r\nexport enum KeyinFieldLocalization {\r\n /** Include only non-localized key-in strings. */\r\n NonLocalized,\r\n /** Include only localized key-in strings. */\r\n Localized,\r\n /** Include localized and non-localized strings for each key-in. */\r\n Both,\r\n}\r\n\r\n/** Properties controlling how a KeyinField is created.\r\n * @beta\r\n */\r\nexport interface KeyinFieldProps {\r\n /** If supplied, the keyin field's elements will be added as children of this parent element. */\r\n parent?: HTMLElement;\r\n /** Required, unique ID prefix used to produce unique IDs for child elements. */\r\n baseId: string;\r\n /** Default: false. */\r\n wantButton?: boolean;\r\n /** Default: false. */\r\n wantLabel?: boolean;\r\n /** The maximum number of submitted key-ins to store in the history.\r\n * If greater than zero, pressing up/down while the KeyinField has focus will move backwards/forwards through the history.\r\n * Default: zero;\r\n */\r\n historyLength?: number;\r\n /** Controls whether localized and/or non-localized keyin strings appear in the autocompletion list.\r\n * Note: the KeyinField will still accept either localized or non-localized strings; this option only controls what is displayed in the auto-completion list.\r\n * Default: non-localized\r\n */\r\n localization?: KeyinFieldLocalization;\r\n}\r\n\r\n/** A textbox allowing input of key-ins (localized tool names) combined with a drop-down that lists all registered key-ins, filtered by substring match on the current input.\r\n * Press `enter` or click the Enter button to run the key-in.\r\n * @beta\r\n */\r\nexport class KeyinField {\r\n /** @alpha */\r\n public readonly autoCompleteList: DataList;\r\n public readonly textBox: TextBox;\r\n public readonly keyins: string[];\r\n private _historyIndex?: number;\r\n private _historyLength = 0;\r\n private readonly _history: string[] | undefined;\r\n private readonly _localization: KeyinFieldLocalization;\r\n\r\n public constructor(props: KeyinFieldProps) {\r\n this._localization = props.localization ?? KeyinFieldLocalization.NonLocalized;\r\n this.keyins = this.findKeyins();\r\n const autoCompleteListId = `${props.baseId}_autoComplete`;\r\n this.autoCompleteList = createDataList({\r\n parent: props.parent,\r\n entries: keyinsToDataListEntries(this.keyins),\r\n id: autoCompleteListId,\r\n inline: true,\r\n });\r\n\r\n this.textBox = createTextBox({\r\n label: props.wantLabel ? \"Key-in: \" : undefined,\r\n id: `${props.baseId}_textBox`,\r\n parent: props.parent,\r\n handler: () => this.selectAll(),\r\n keypresshandler: async (_tb, ev) => { await this.handleKeyPress(ev); },\r\n focushandler: (_tb) => { this.respondToKeyinFocus(); },\r\n tooltip: \"Type the key-in text here\",\r\n inline: true,\r\n list: autoCompleteListId,\r\n });\r\n\r\n if (props.wantButton) {\r\n createButton({\r\n handler: async (_bt) => { await this.submitKeyin(); },\r\n parent: props.parent,\r\n value: \"Enter\",\r\n inline: true,\r\n tooltip: \"Click here to execute the key-in\",\r\n });\r\n }\r\n\r\n if (undefined !== props.historyLength && props.historyLength > 0) {\r\n this.textBox.textbox.onkeydown = (ev) => this.handleKeyDown(ev); // eslint-disable-line @typescript-eslint/promise-function-async\r\n this._historyLength = props.historyLength;\r\n this._history = [];\r\n }\r\n }\r\n\r\n public focus() { this.textBox.textbox.focus(); }\r\n public loseFocus() { this.textBox.textbox.blur(); }\r\n\r\n public selectAll(): void {\r\n this.textBox.textbox.setSelectionRange(0, this.textBox.textbox.value.length);\r\n }\r\n\r\n private async handleKeyPress(ev: KeyboardEvent): Promise<void> {\r\n ev.stopPropagation();\r\n\r\n if (\"Enter\" === ev.key)\r\n await this.submitKeyin();\r\n }\r\n\r\n private async handleKeyDown(ev: KeyboardEvent): Promise<void> {\r\n ev.stopPropagation();\r\n\r\n if (undefined === this._history || 0 === this._history.length)\r\n return;\r\n\r\n // NB: History list is ordered by most to least recent so moving \"backwards\" means incrementing the index.\r\n const direction = ev.key === \"ArrowDown\" ? 1 : (ev.key === \"ArrowUp\" ? 1 : 0);\r\n if (0 === direction)\r\n return;\r\n\r\n ev.preventDefault();\r\n ev.stopPropagation();\r\n\r\n if (this._historyIndex === undefined) {\r\n if (direction < 0)\r\n return;\r\n else\r\n this._historyIndex = -1;\r\n }\r\n\r\n const newIndex = this._historyIndex + direction;\r\n if (newIndex >= 0 && newIndex < this._history.length) {\r\n this._historyIndex = newIndex;\r\n if (this._historyIndex >= 0)\r\n this.textBox.textbox.value = this._history[newIndex];\r\n }\r\n }\r\n\r\n private resetHistoryIndex(): void {\r\n this._historyIndex = undefined;\r\n }\r\n\r\n private pushHistory(keyin: string): void {\r\n if (undefined === this._history)\r\n return;\r\n\r\n this.textBox.textbox.value = \"\";\r\n this.resetHistoryIndex();\r\n if (this._history.length === 0 || keyin.toLowerCase() !== this._history[0].toLowerCase()) {\r\n this._history.unshift(keyin);\r\n if (this._history.length > this._historyLength)\r\n this._history.pop();\r\n }\r\n }\r\n\r\n private async submitKeyin(): Promise<void> {\r\n this.selectAll();\r\n const textBox = this.textBox.textbox;\r\n\r\n const input = textBox.value;\r\n this.pushHistory(input);\r\n\r\n let message: string | undefined;\r\n try {\r\n switch (await IModelApp.tools.parseAndRun(input)) {\r\n case ParseAndRunResult.ToolNotFound:\r\n message = `Cannot find a key-in that matches: ${input}`;\r\n break;\r\n case ParseAndRunResult.BadArgumentCount:\r\n message = \"Incorrect number of arguments\";\r\n break;\r\n case ParseAndRunResult.FailedToRun:\r\n message = \"Key-in failed to run\";\r\n break;\r\n }\r\n } catch (ex) {\r\n message = `Key-in produced exception: ${ex}`;\r\n }\r\n\r\n if (undefined !== message)\r\n await IModelApp.notifications.openMessageBox(MessageBoxType.MediumAlert, message, MessageBoxIconType.Warning);\r\n }\r\n\r\n private respondToKeyinFocus() {\r\n this.resetHistoryIndex();\r\n\r\n // Handle case in which new tools were registered since we last populated the auto-complete list.\r\n // This can occur e.g. as a result of loading a extension, or deferred initialization of a package like markup.\r\n const keyins = this.findKeyins();\r\n if (keyins.length > this.keyins.length) {\r\n const newKeyins: string[] = [];\r\n for (const keyin of keyins)\r\n if (!this.keyins.includes(keyin)) {\r\n newKeyins.push(keyin);\r\n this.keyins.push(keyin);\r\n }\r\n\r\n if (newKeyins.length > 0)\r\n appendDataListEntries(this.autoCompleteList, keyinsToDataListEntries(newKeyins));\r\n }\r\n }\r\n\r\n private findKeyins(): string[] {\r\n const keyins: string[] = [];\r\n const tools = IModelApp.tools.getToolList();\r\n for (const tool of tools) {\r\n switch (this._localization) {\r\n case KeyinFieldLocalization.Localized:\r\n keyins.push(tool.keyin);\r\n break;\r\n case KeyinFieldLocalization.Both:\r\n keyins.push(tool.keyin);\r\n if (tool.keyin === tool.englishKeyin)\r\n break;\r\n /* falls through */\r\n default:\r\n case KeyinFieldLocalization.NonLocalized:\r\n keyins.push(tool.englishKeyin);\r\n break;\r\n }\r\n }\r\n\r\n return keyins;\r\n }\r\n}\r\n"]}
1
+ {"version":3,"file":"KeyinField.js","sourceRoot":"","sources":["../../../src/widgets/KeyinField.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n* See LICENSE.md in the project root for license terms and full copyright notice.\n*--------------------------------------------------------------------------------------------*/\n\n/** @packageDocumentation\n * @module Widgets\n */\n\nimport { IModelApp, MessageBoxIconType, MessageBoxType, ParseAndRunResult } from \"@itwin/core-frontend\";\nimport { createButton } from \"../ui/Button\";\nimport { appendDataListEntries, createDataList, DataList, DataListEntry } from \"../ui/DataList\";\nimport { createTextBox, TextBox } from \"../ui/TextBox\";\n\nfunction keyinsToDataListEntries(keyins: string[]): DataListEntry[] {\n const entries: DataListEntry[] = [];\n for (const keyin of keyins) {\n entries.push({ value: keyin });\n }\n\n return entries;\n}\n\n/** Controls whether localized and/or non-localized key-in strings appear in a KeyinField's auto-completion list.\n * @beta\n */\nexport enum KeyinFieldLocalization {\n /** Include only non-localized key-in strings. */\n NonLocalized,\n /** Include only localized key-in strings. */\n Localized,\n /** Include localized and non-localized strings for each key-in. */\n Both,\n}\n\n/** Properties controlling how a KeyinField is created.\n * @beta\n */\nexport interface KeyinFieldProps {\n /** If supplied, the keyin field's elements will be added as children of this parent element. */\n parent?: HTMLElement;\n /** Required, unique ID prefix used to produce unique IDs for child elements. */\n baseId: string;\n /** Default: false. */\n wantButton?: boolean;\n /** Default: false. */\n wantLabel?: boolean;\n /** The maximum number of submitted key-ins to store in the history.\n * If greater than zero, pressing up/down while the KeyinField has focus will move backwards/forwards through the history.\n * Default: zero;\n */\n historyLength?: number;\n /** Controls whether localized and/or non-localized keyin strings appear in the autocompletion list.\n * Note: the KeyinField will still accept either localized or non-localized strings; this option only controls what is displayed in the auto-completion list.\n * Default: non-localized\n */\n localization?: KeyinFieldLocalization;\n}\n\n/** A textbox allowing input of key-ins (localized tool names) combined with a drop-down that lists all registered key-ins, filtered by substring match on the current input.\n * Press `enter` or click the Enter button to run the key-in.\n * @beta\n */\nexport class KeyinField {\n /** @alpha */\n public readonly autoCompleteList: DataList;\n public readonly textBox: TextBox;\n public readonly keyins: string[];\n private _historyIndex?: number;\n private _historyLength = 0;\n private readonly _history: string[] | undefined;\n private readonly _localization: KeyinFieldLocalization;\n\n public constructor(props: KeyinFieldProps) {\n this._localization = props.localization ?? KeyinFieldLocalization.NonLocalized;\n this.keyins = this.findKeyins();\n const autoCompleteListId = `${props.baseId}_autoComplete`;\n this.autoCompleteList = createDataList({\n parent: props.parent,\n entries: keyinsToDataListEntries(this.keyins),\n id: autoCompleteListId,\n inline: true,\n });\n\n this.textBox = createTextBox({\n label: props.wantLabel ? \"Key-in: \" : undefined,\n id: `${props.baseId}_textBox`,\n parent: props.parent,\n handler: () => this.selectAll(),\n keypresshandler: async (_tb, ev) => { await this.handleKeyPress(ev); },\n focushandler: (_tb) => { this.respondToKeyinFocus(); },\n tooltip: \"Type the key-in text here\",\n inline: true,\n list: autoCompleteListId,\n });\n\n if (props.wantButton) {\n createButton({\n handler: async (_bt) => { await this.submitKeyin(); },\n parent: props.parent,\n value: \"Enter\",\n inline: true,\n tooltip: \"Click here to execute the key-in\",\n });\n }\n\n if (undefined !== props.historyLength && props.historyLength > 0) {\n this.textBox.textbox.onkeydown = (ev) => this.handleKeyDown(ev); // eslint-disable-line @typescript-eslint/promise-function-async\n this._historyLength = props.historyLength;\n this._history = [];\n }\n }\n\n public focus() { this.textBox.textbox.focus(); }\n public loseFocus() { this.textBox.textbox.blur(); }\n\n public selectAll(): void {\n this.textBox.textbox.setSelectionRange(0, this.textBox.textbox.value.length);\n }\n\n private async handleKeyPress(ev: KeyboardEvent): Promise<void> {\n ev.stopPropagation();\n\n if (\"Enter\" === ev.key)\n await this.submitKeyin();\n }\n\n private async handleKeyDown(ev: KeyboardEvent): Promise<void> {\n ev.stopPropagation();\n\n if (undefined === this._history || 0 === this._history.length)\n return;\n\n // NB: History list is ordered by most to least recent so moving \"backwards\" means incrementing the index.\n const direction = ev.key === \"ArrowDown\" ? 1 : (ev.key === \"ArrowUp\" ? 1 : 0);\n if (0 === direction)\n return;\n\n ev.preventDefault();\n ev.stopPropagation();\n\n if (this._historyIndex === undefined) {\n if (direction < 0)\n return;\n else\n this._historyIndex = -1;\n }\n\n const newIndex = this._historyIndex + direction;\n if (newIndex >= 0 && newIndex < this._history.length) {\n this._historyIndex = newIndex;\n if (this._historyIndex >= 0)\n this.textBox.textbox.value = this._history[newIndex];\n }\n }\n\n private resetHistoryIndex(): void {\n this._historyIndex = undefined;\n }\n\n private pushHistory(keyin: string): void {\n if (undefined === this._history)\n return;\n\n this.textBox.textbox.value = \"\";\n this.resetHistoryIndex();\n if (this._history.length === 0 || keyin.toLowerCase() !== this._history[0].toLowerCase()) {\n this._history.unshift(keyin);\n if (this._history.length > this._historyLength)\n this._history.pop();\n }\n }\n\n private async submitKeyin(): Promise<void> {\n this.selectAll();\n const textBox = this.textBox.textbox;\n\n const input = textBox.value;\n this.pushHistory(input);\n\n let message: string | undefined;\n try {\n switch (await IModelApp.tools.parseAndRun(input)) {\n case ParseAndRunResult.ToolNotFound:\n message = `Cannot find a key-in that matches: ${input}`;\n break;\n case ParseAndRunResult.BadArgumentCount:\n message = \"Incorrect number of arguments\";\n break;\n case ParseAndRunResult.FailedToRun:\n message = \"Key-in failed to run\";\n break;\n }\n } catch (ex) {\n message = `Key-in produced exception: ${ex}`;\n }\n\n if (undefined !== message)\n await IModelApp.notifications.openMessageBox(MessageBoxType.MediumAlert, message, MessageBoxIconType.Warning);\n }\n\n private respondToKeyinFocus() {\n this.resetHistoryIndex();\n\n // Handle case in which new tools were registered since we last populated the auto-complete list.\n // This can occur e.g. as a result of loading a extension, or deferred initialization of a package like markup.\n const keyins = this.findKeyins();\n if (keyins.length > this.keyins.length) {\n const newKeyins: string[] = [];\n for (const keyin of keyins)\n if (!this.keyins.includes(keyin)) {\n newKeyins.push(keyin);\n this.keyins.push(keyin);\n }\n\n if (newKeyins.length > 0)\n appendDataListEntries(this.autoCompleteList, keyinsToDataListEntries(newKeyins));\n }\n }\n\n private findKeyins(): string[] {\n const keyins: string[] = [];\n const tools = IModelApp.tools.getToolList();\n for (const tool of tools) {\n switch (this._localization) {\n case KeyinFieldLocalization.Localized:\n keyins.push(tool.keyin);\n break;\n case KeyinFieldLocalization.Both:\n keyins.push(tool.keyin);\n if (tool.keyin === tool.englishKeyin)\n break;\n /* falls through */\n default:\n case KeyinFieldLocalization.NonLocalized:\n keyins.push(tool.englishKeyin);\n break;\n }\n }\n\n return keyins;\n }\n}\n"]}
@@ -16,7 +16,7 @@ export declare class MemoryTracker {
16
16
  private readonly _textures;
17
17
  private readonly _buffers;
18
18
  constructor(parent: HTMLElement, vp: Viewport);
19
- dispose(): void;
19
+ [Symbol.dispose](): void;
20
20
  private addSelector;
21
21
  private addPurgeButton;
22
22
  private addStatistics;
@@ -1 +1 @@
1
- {"version":3,"file":"MemoryTracker.d.ts","sourceRoot":"","sources":["../../../src/widgets/MemoryTracker.ts"],"names":[],"mappings":"AAUA,OAAO,EACmE,QAAQ,EACjF,MAAM,sBAAsB,CAAC;AAoG9B,gBAAgB;AAChB,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAYrD;AAgDD;;GAEG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAiC;IACxD,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAW;IAC/B,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAiB;IACtC,OAAO,CAAC,cAAc,CAAC,CAAS;IAChC,OAAO,CAAC,SAAS,CAAiB;IAClC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAc;IACzC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAc;IAC9C,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAoB;IACjD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAc;IACxC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAc;gBAEpB,MAAM,EAAE,WAAW,EAAE,EAAE,EAAE,QAAQ;IAwC7C,OAAO,IAAI,IAAI;IAItB,OAAO,CAAC,WAAW;IAenB,OAAO,CAAC,cAAc;IActB,OAAO,CAAC,aAAa;IASrB,OAAO,CAAC,aAAa;IAOrB,OAAO,CAAC,MAAM;IAqBd,OAAO,CAAC,MAAM;IAWd,OAAO,CAAC,KAAK;CAQd"}
1
+ {"version":3,"file":"MemoryTracker.d.ts","sourceRoot":"","sources":["../../../src/widgets/MemoryTracker.ts"],"names":[],"mappings":"AAUA,OAAO,EACmE,QAAQ,EACjF,MAAM,sBAAsB,CAAC;AAoG9B,gBAAgB;AAChB,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAYrD;AAgDD;;GAEG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAiC;IACxD,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAW;IAC/B,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAiB;IACtC,OAAO,CAAC,cAAc,CAAC,CAAS;IAChC,OAAO,CAAC,SAAS,CAAiB;IAClC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAc;IACzC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAc;IAC9C,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAoB;IACjD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAc;IACxC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAc;gBAEpB,MAAM,EAAE,WAAW,EAAE,EAAE,EAAE,QAAQ;IAwC7C,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,IAAI;IAI/B,OAAO,CAAC,WAAW;IAenB,OAAO,CAAC,cAAc;IActB,OAAO,CAAC,aAAa;IASrB,OAAO,CAAC,aAAa;IAOrB,OAAO,CAAC,MAAM;IAqBd,OAAO,CAAC,MAAM;IAWd,OAAO,CAAC,KAAK;CAQd"}
@@ -96,8 +96,12 @@ function formatMemory(numBytes) {
96
96
  return numBytes.toFixed(2) + suffix;
97
97
  }
98
98
  class MemoryPanel {
99
+ _label;
100
+ _labels;
101
+ _elems = [];
102
+ _div;
103
+ _header;
99
104
  constructor(parent, label, labels) {
100
- this._elems = [];
101
105
  this._label = label;
102
106
  this._labels = labels;
103
107
  this._div = document.createElement("div");
@@ -132,9 +136,17 @@ class MemoryPanel {
132
136
  * @beta
133
137
  */
134
138
  class MemoryTracker {
139
+ _stats = new core_frontend_1.RenderMemory.Statistics();
140
+ _vp;
141
+ _div;
142
+ _curIntervalId;
143
+ _memIndex = -1 /* MemIndex.None */;
144
+ _totalElem;
145
+ _totalTreesElem;
146
+ _purgeButton;
147
+ _textures;
148
+ _buffers;
135
149
  constructor(parent, vp) {
136
- this._stats = new core_frontend_1.RenderMemory.Statistics();
137
- this._memIndex = -1 /* MemIndex.None */;
138
150
  this._vp = vp;
139
151
  this._div = document.createElement("div");
140
152
  this._div.style.display = "none";
@@ -165,7 +177,7 @@ class MemoryTracker {
165
177
  this._purgeButton = this.addPurgeButton(this._div);
166
178
  parent.appendChild(this._div);
167
179
  }
168
- dispose() {
180
+ [Symbol.dispose]() {
169
181
  this.clearInterval();
170
182
  }
171
183
  addSelector(parent) {
@@ -1 +1 @@
1
- {"version":3,"file":"MemoryTracker.js","sourceRoot":"","sources":["../../../src/widgets/MemoryTracker.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n* See LICENSE.md in the project root for license terms and full copyright notice.\r\n*--------------------------------------------------------------------------------------------*/\r\n\r\n/** @packageDocumentation\r\n * @module Widgets\r\n */\r\n\r\nimport { assert, BeTimePoint } from \"@itwin/core-bentley\";\r\nimport {\r\n DisclosedTileTreeSet, IModelApp, RenderMemory, TileTree, TileTreeOwner, Viewport,\r\n} from \"@itwin/core-frontend\";\r\nimport { ComboBoxEntry, createComboBox } from \"../ui/ComboBox\";\r\n\r\nfunction collectTileTreeMemory(stats: RenderMemory.Statistics, owner: TileTreeOwner): void {\r\n const tree = owner.tileTree;\r\n if (undefined !== tree)\r\n tree.collectStatistics(stats);\r\n}\r\n\r\n// Returns the number of tile trees processed.\r\ntype CalcMem = (stats: RenderMemory.Statistics, vp: Viewport) => number;\r\ntype PurgeMem = (olderThan?: BeTimePoint) => void;\r\n\r\nconst enum MemIndex { // eslint-disable-line no-restricted-syntax\r\n None = -1,\r\n ViewportTileTrees,\r\n SelectedTiles,\r\n AllTileTrees,\r\n RenderTarget,\r\n // eslint-disable-next-line @typescript-eslint/no-shadow\r\n Viewport, // RenderTarget + Viewed Tile Trees\r\n System,\r\n All, // All Tile Trees + System + (RenderTarget for each ViewManager viewport)\r\n\r\n COUNT,\r\n}\r\n\r\n// Includes None (-1) at index 0\r\nconst memLabels = [\r\n \"None\",\r\n \"Viewed Tile Trees\",\r\n \"Selected Tiles\",\r\n \"All Tile Trees\",\r\n \"Render Target\",\r\n \"Viewport\",\r\n \"System\",\r\n \"All\",\r\n];\r\n\r\nfunction collectStatisticsForViewedTileTrees(vp: Viewport, stats: RenderMemory.Statistics): number {\r\n vp.collectStatistics(stats);\r\n const trees = new DisclosedTileTreeSet();\r\n vp.discloseTileTrees(trees);\r\n return trees.size;\r\n}\r\n\r\nfunction collectStatisticsForSelectedTiles(vp: Viewport, stats: RenderMemory.Statistics): number {\r\n const trees = new Set<TileTree>();\r\n const selectedTiles = IModelApp.tileAdmin.getTilesForUser(vp)?.selected;\r\n if (selectedTiles) {\r\n for (const tile of selectedTiles) {\r\n trees.add(tile.tree);\r\n tile.collectStatistics(stats);\r\n }\r\n }\r\n\r\n return trees.size;\r\n}\r\n\r\nfunction collectStatisticsForAllTileTrees(vp: Viewport, stats: RenderMemory.Statistics): number {\r\n let numTrees = 0;\r\n vp.view.iModel.tiles.forEachTreeOwner((owner) => {\r\n collectTileTreeMemory(stats, owner);\r\n if (undefined !== owner.tileTree)\r\n ++numTrees;\r\n });\r\n return numTrees;\r\n}\r\n\r\nconst calcMem: CalcMem[] = [\r\n (stats, vp) => collectStatisticsForViewedTileTrees(vp, stats),\r\n (stats, vp) => collectStatisticsForSelectedTiles(vp, stats),\r\n (stats, vp) => collectStatisticsForAllTileTrees(vp, stats),\r\n (stats, vp) => {\r\n vp.target.collectStatistics(stats);\r\n return 0;\r\n },\r\n (stats, vp) => {\r\n vp.target.collectStatistics(stats);\r\n return collectStatisticsForViewedTileTrees(vp, stats);\r\n },\r\n (stats, vp) => {\r\n vp.target.renderSystem.collectStatistics(stats);\r\n return 0;\r\n },\r\n (stats, vp) => {\r\n vp.target.renderSystem.collectStatistics(stats);\r\n for (const x of IModelApp.viewManager)\r\n x.target.collectStatistics(stats);\r\n\r\n return collectStatisticsForAllTileTrees(vp, stats);\r\n },\r\n];\r\n\r\n// ###TODO...\r\nconst purgeMem: Array<PurgeMem | undefined> = [\r\n undefined,\r\n (olderThan?) => IModelApp.viewManager.purgeTileTrees(olderThan ? olderThan : BeTimePoint.now()),\r\n];\r\n\r\n/** @internal */\r\nexport function formatMemory(numBytes: number): string {\r\n let suffix = \"b\";\r\n if (numBytes >= 1024) {\r\n numBytes /= 1024;\r\n suffix = \"kb\";\r\n if (numBytes >= 1024) {\r\n numBytes /= 1024;\r\n suffix = \"mb\";\r\n }\r\n }\r\n\r\n return numBytes.toFixed(2) + suffix;\r\n}\r\n\r\nclass MemoryPanel {\r\n private readonly _label: string;\r\n private readonly _labels: string[];\r\n private readonly _elems: HTMLElement[] = [];\r\n private readonly _div: HTMLDivElement;\r\n private readonly _header: HTMLElement;\r\n\r\n public constructor(parent: HTMLElement, label: string, labels: string[]) {\r\n this._label = label;\r\n this._labels = labels;\r\n this._div = document.createElement(\"div\");\r\n\r\n this._header = document.createElement(\"label\")!;\r\n this._header.style.fontWeight = \"bold\";\r\n this._div.appendChild(this._header);\r\n\r\n const numElems = labels.length;\r\n for (let i = 0; i < numElems; i++) {\r\n const elem = document.createElement(\"label\");\r\n this._elems.push(elem);\r\n this._div.appendChild(elem);\r\n }\r\n\r\n parent.appendChild(this._div);\r\n }\r\n\r\n public update(stats: RenderMemory.Consumers[], total: number): void {\r\n assert(this._labels.length === stats.length);\r\n assert(this._labels.length === this._elems.length);\r\n\r\n this._header.innerHTML = `${this._label}: ${formatMemory(total)}`;\r\n\r\n for (let i = 0; i < this._labels.length; i++) {\r\n const elem = this._elems[i];\r\n const stat = stats[i];\r\n if (0 === stat.totalBytes) {\r\n elem.style.display = \"none\";\r\n continue;\r\n }\r\n\r\n elem.style.display = \"block\";\r\n elem.innerHTML = `${this._labels[i]} (${stat.count}): ${formatMemory(stat.totalBytes)}`; // + \"\\n(max: \" + formatMemory(stat.maxBytes) + \")\";\r\n }\r\n }\r\n}\r\n\r\n/** Displays GPU memory allocated to tile trees - either all tile trees in the system, or only those associated with a specific Viewport.\r\n * @beta\r\n */\r\nexport class MemoryTracker {\r\n private readonly _stats = new RenderMemory.Statistics();\r\n private readonly _vp: Viewport;\r\n private readonly _div: HTMLDivElement;\r\n private _curIntervalId?: number;\r\n private _memIndex = MemIndex.None;\r\n private readonly _totalElem: HTMLElement;\r\n private readonly _totalTreesElem: HTMLElement;\r\n private readonly _purgeButton: HTMLButtonElement;\r\n private readonly _textures: MemoryPanel;\r\n private readonly _buffers: MemoryPanel;\r\n\r\n public constructor(parent: HTMLElement, vp: Viewport) {\r\n this._vp = vp;\r\n\r\n this._div = document.createElement(\"div\");\r\n this._div.style.display = \"none\";\r\n this._div.style.textAlign = \"right\";\r\n\r\n this.addSelector(parent);\r\n\r\n const table = document.createElement(\"table\");\r\n table.style.width = \"100%\";\r\n table.setAttribute(\"border\", \"1\");\r\n this._div.appendChild(table);\r\n\r\n const row0 = document.createElement(\"tr\");\r\n const cell00 = document.createElement(\"td\");\r\n const cell01 = document.createElement(\"td\");\r\n cell00.style.width = cell01.style.width = \"50%\";\r\n row0.appendChild(cell00);\r\n row0.appendChild(cell01);\r\n table.appendChild(row0);\r\n\r\n const row1 = document.createElement(\"tr\");\r\n const cell10 = document.createElement(\"td\");\r\n const cell11 = document.createElement(\"td\");\r\n cell10.style.width = cell11.style.width = \"50%\";\r\n row1.appendChild(cell10);\r\n row1.appendChild(cell11);\r\n table.appendChild(row1);\r\n\r\n this._textures = new MemoryPanel(cell00, \"Textures\", [\"Surface Textures\", \"Vertex Tables\", \"Edge Tables\", \"Feature Tables\", \"Feature Overrides\", \"Clip Volumes\", \"Planar Classifiers\", \"Shadow Maps\", \"Texture Attachments\", \"Thematic Textures\"]);\r\n this._buffers = new MemoryPanel(cell01, \"Buffers\", [\"Surfaces\", \"Visible Edges\", \"Silhouettes\", \"Polyline Edges\", \"Indexed Edges\", \"Polylines\", \"Point Strings\", \"Point Clouds\", \"Instances\", \"Terrain\", \"Reality Mesh\"]);\r\n this._totalElem = this.addStatistics(cell10);\r\n this._totalTreesElem = this.addStatistics(cell11);\r\n\r\n this._purgeButton = this.addPurgeButton(this._div);\r\n\r\n parent.appendChild(this._div);\r\n }\r\n\r\n public dispose(): void {\r\n this.clearInterval();\r\n }\r\n\r\n private addSelector(parent: HTMLElement): void {\r\n const entries: ComboBoxEntry[] = [];\r\n for (let i = MemIndex.None; i < MemIndex.COUNT; i++)\r\n entries.push({ name: memLabels[i + 1], value: i });\r\n\r\n createComboBox({\r\n parent,\r\n name: \"Track Memory: \",\r\n id: \"memTracker_type\",\r\n value: MemIndex.None,\r\n handler: (select) => this.change(Number.parseInt(select.value, 10)),\r\n entries,\r\n });\r\n }\r\n\r\n private addPurgeButton(parent: HTMLElement): HTMLButtonElement {\r\n const div = document.createElement(\"div\");\r\n div.style.textAlign = \"center\";\r\n\r\n const button = document.createElement(\"button\");\r\n button.innerText = \"Purge\";\r\n button.addEventListener(\"click\", () => this.purge());\r\n\r\n div.appendChild(button);\r\n parent.appendChild(div);\r\n\r\n return button;\r\n }\r\n\r\n private addStatistics(parent: HTMLElement): HTMLElement {\r\n const div = document.createElement(\"div\");\r\n const text = document.createElement(\"text\");\r\n text.style.fontWeight = \"bold\";\r\n div.appendChild(text);\r\n parent.appendChild(div);\r\n return text;\r\n }\r\n\r\n private clearInterval(): void {\r\n if (undefined !== this._curIntervalId) {\r\n window.clearInterval(this._curIntervalId);\r\n this._curIntervalId = undefined;\r\n }\r\n }\r\n\r\n private change(newIndex: MemIndex): void {\r\n if (newIndex === this._memIndex)\r\n return;\r\n\r\n this._memIndex = newIndex;\r\n if (MemIndex.None === newIndex) {\r\n this.clearInterval();\r\n this._div.style.display = \"none\";\r\n return;\r\n }\r\n\r\n if (undefined === this._curIntervalId) {\r\n this._curIntervalId = window.setInterval(() => this.update(), 1000);\r\n this._div.style.display = \"block\";\r\n }\r\n\r\n this._purgeButton.disabled = undefined === purgeMem[this._memIndex];\r\n\r\n this.update();\r\n }\r\n\r\n private update(): void {\r\n const calc = calcMem[this._memIndex];\r\n this._stats.clear();\r\n const numTrees = calc(this._stats, this._vp);\r\n this._totalElem.innerText = `Total: ${formatMemory(this._stats.totalBytes)}`;\r\n this._totalTreesElem.innerText = `Total Tile Trees: ${numTrees}`;\r\n\r\n this._textures.update(this._stats.consumers, this._stats.totalBytes - this._stats.buffers.totalBytes);\r\n this._buffers.update(this._stats.buffers.consumers, this._stats.buffers.totalBytes);\r\n }\r\n\r\n private purge(): void {\r\n const purge = purgeMem[this._memIndex];\r\n if (undefined !== purge) {\r\n purge();\r\n this._vp.invalidateScene(); // to trigger reloading of tiles we actually do want to continue drawing\r\n this.update();\r\n }\r\n }\r\n}\r\n"]}
1
+ {"version":3,"file":"MemoryTracker.js","sourceRoot":"","sources":["../../../src/widgets/MemoryTracker.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n* See LICENSE.md in the project root for license terms and full copyright notice.\n*--------------------------------------------------------------------------------------------*/\n\n/** @packageDocumentation\n * @module Widgets\n */\n\nimport { assert, BeTimePoint } from \"@itwin/core-bentley\";\nimport {\n DisclosedTileTreeSet, IModelApp, RenderMemory, TileTree, TileTreeOwner, Viewport,\n} from \"@itwin/core-frontend\";\nimport { ComboBoxEntry, createComboBox } from \"../ui/ComboBox\";\n\nfunction collectTileTreeMemory(stats: RenderMemory.Statistics, owner: TileTreeOwner): void {\n const tree = owner.tileTree;\n if (undefined !== tree)\n tree.collectStatistics(stats);\n}\n\n// Returns the number of tile trees processed.\ntype CalcMem = (stats: RenderMemory.Statistics, vp: Viewport) => number;\ntype PurgeMem = (olderThan?: BeTimePoint) => void;\n\nconst enum MemIndex { // eslint-disable-line no-restricted-syntax\n None = -1,\n ViewportTileTrees,\n SelectedTiles,\n AllTileTrees,\n RenderTarget,\n // eslint-disable-next-line @typescript-eslint/no-shadow\n Viewport, // RenderTarget + Viewed Tile Trees\n System,\n All, // All Tile Trees + System + (RenderTarget for each ViewManager viewport)\n\n COUNT,\n}\n\n// Includes None (-1) at index 0\nconst memLabels = [\n \"None\",\n \"Viewed Tile Trees\",\n \"Selected Tiles\",\n \"All Tile Trees\",\n \"Render Target\",\n \"Viewport\",\n \"System\",\n \"All\",\n];\n\nfunction collectStatisticsForViewedTileTrees(vp: Viewport, stats: RenderMemory.Statistics): number {\n vp.collectStatistics(stats);\n const trees = new DisclosedTileTreeSet();\n vp.discloseTileTrees(trees);\n return trees.size;\n}\n\nfunction collectStatisticsForSelectedTiles(vp: Viewport, stats: RenderMemory.Statistics): number {\n const trees = new Set<TileTree>();\n const selectedTiles = IModelApp.tileAdmin.getTilesForUser(vp)?.selected;\n if (selectedTiles) {\n for (const tile of selectedTiles) {\n trees.add(tile.tree);\n tile.collectStatistics(stats);\n }\n }\n\n return trees.size;\n}\n\nfunction collectStatisticsForAllTileTrees(vp: Viewport, stats: RenderMemory.Statistics): number {\n let numTrees = 0;\n vp.view.iModel.tiles.forEachTreeOwner((owner) => {\n collectTileTreeMemory(stats, owner);\n if (undefined !== owner.tileTree)\n ++numTrees;\n });\n return numTrees;\n}\n\nconst calcMem: CalcMem[] = [\n (stats, vp) => collectStatisticsForViewedTileTrees(vp, stats),\n (stats, vp) => collectStatisticsForSelectedTiles(vp, stats),\n (stats, vp) => collectStatisticsForAllTileTrees(vp, stats),\n (stats, vp) => {\n vp.target.collectStatistics(stats);\n return 0;\n },\n (stats, vp) => {\n vp.target.collectStatistics(stats);\n return collectStatisticsForViewedTileTrees(vp, stats);\n },\n (stats, vp) => {\n vp.target.renderSystem.collectStatistics(stats);\n return 0;\n },\n (stats, vp) => {\n vp.target.renderSystem.collectStatistics(stats);\n for (const x of IModelApp.viewManager)\n x.target.collectStatistics(stats);\n\n return collectStatisticsForAllTileTrees(vp, stats);\n },\n];\n\n// ###TODO...\nconst purgeMem: Array<PurgeMem | undefined> = [\n undefined,\n (olderThan?) => IModelApp.viewManager.purgeTileTrees(olderThan ? olderThan : BeTimePoint.now()),\n];\n\n/** @internal */\nexport function formatMemory(numBytes: number): string {\n let suffix = \"b\";\n if (numBytes >= 1024) {\n numBytes /= 1024;\n suffix = \"kb\";\n if (numBytes >= 1024) {\n numBytes /= 1024;\n suffix = \"mb\";\n }\n }\n\n return numBytes.toFixed(2) + suffix;\n}\n\nclass MemoryPanel {\n private readonly _label: string;\n private readonly _labels: string[];\n private readonly _elems: HTMLElement[] = [];\n private readonly _div: HTMLDivElement;\n private readonly _header: HTMLElement;\n\n public constructor(parent: HTMLElement, label: string, labels: string[]) {\n this._label = label;\n this._labels = labels;\n this._div = document.createElement(\"div\");\n\n this._header = document.createElement(\"label\")!;\n this._header.style.fontWeight = \"bold\";\n this._div.appendChild(this._header);\n\n const numElems = labels.length;\n for (let i = 0; i < numElems; i++) {\n const elem = document.createElement(\"label\");\n this._elems.push(elem);\n this._div.appendChild(elem);\n }\n\n parent.appendChild(this._div);\n }\n\n public update(stats: RenderMemory.Consumers[], total: number): void {\n assert(this._labels.length === stats.length);\n assert(this._labels.length === this._elems.length);\n\n this._header.innerHTML = `${this._label}: ${formatMemory(total)}`;\n\n for (let i = 0; i < this._labels.length; i++) {\n const elem = this._elems[i];\n const stat = stats[i];\n if (0 === stat.totalBytes) {\n elem.style.display = \"none\";\n continue;\n }\n\n elem.style.display = \"block\";\n elem.innerHTML = `${this._labels[i]} (${stat.count}): ${formatMemory(stat.totalBytes)}`; // + \"\\n(max: \" + formatMemory(stat.maxBytes) + \")\";\n }\n }\n}\n\n/** Displays GPU memory allocated to tile trees - either all tile trees in the system, or only those associated with a specific Viewport.\n * @beta\n */\nexport class MemoryTracker {\n private readonly _stats = new RenderMemory.Statistics();\n private readonly _vp: Viewport;\n private readonly _div: HTMLDivElement;\n private _curIntervalId?: number;\n private _memIndex = MemIndex.None;\n private readonly _totalElem: HTMLElement;\n private readonly _totalTreesElem: HTMLElement;\n private readonly _purgeButton: HTMLButtonElement;\n private readonly _textures: MemoryPanel;\n private readonly _buffers: MemoryPanel;\n\n public constructor(parent: HTMLElement, vp: Viewport) {\n this._vp = vp;\n\n this._div = document.createElement(\"div\");\n this._div.style.display = \"none\";\n this._div.style.textAlign = \"right\";\n\n this.addSelector(parent);\n\n const table = document.createElement(\"table\");\n table.style.width = \"100%\";\n table.setAttribute(\"border\", \"1\");\n this._div.appendChild(table);\n\n const row0 = document.createElement(\"tr\");\n const cell00 = document.createElement(\"td\");\n const cell01 = document.createElement(\"td\");\n cell00.style.width = cell01.style.width = \"50%\";\n row0.appendChild(cell00);\n row0.appendChild(cell01);\n table.appendChild(row0);\n\n const row1 = document.createElement(\"tr\");\n const cell10 = document.createElement(\"td\");\n const cell11 = document.createElement(\"td\");\n cell10.style.width = cell11.style.width = \"50%\";\n row1.appendChild(cell10);\n row1.appendChild(cell11);\n table.appendChild(row1);\n\n this._textures = new MemoryPanel(cell00, \"Textures\", [\"Surface Textures\", \"Vertex Tables\", \"Edge Tables\", \"Feature Tables\", \"Feature Overrides\", \"Clip Volumes\", \"Planar Classifiers\", \"Shadow Maps\", \"Texture Attachments\", \"Thematic Textures\"]);\n this._buffers = new MemoryPanel(cell01, \"Buffers\", [\"Surfaces\", \"Visible Edges\", \"Silhouettes\", \"Polyline Edges\", \"Indexed Edges\", \"Polylines\", \"Point Strings\", \"Point Clouds\", \"Instances\", \"Terrain\", \"Reality Mesh\"]);\n this._totalElem = this.addStatistics(cell10);\n this._totalTreesElem = this.addStatistics(cell11);\n\n this._purgeButton = this.addPurgeButton(this._div);\n\n parent.appendChild(this._div);\n }\n\n public [Symbol.dispose](): void {\n this.clearInterval();\n }\n\n private addSelector(parent: HTMLElement): void {\n const entries: ComboBoxEntry[] = [];\n for (let i = MemIndex.None; i < MemIndex.COUNT; i++)\n entries.push({ name: memLabels[i + 1], value: i });\n\n createComboBox({\n parent,\n name: \"Track Memory: \",\n id: \"memTracker_type\",\n value: MemIndex.None,\n handler: (select) => this.change(Number.parseInt(select.value, 10)),\n entries,\n });\n }\n\n private addPurgeButton(parent: HTMLElement): HTMLButtonElement {\n const div = document.createElement(\"div\");\n div.style.textAlign = \"center\";\n\n const button = document.createElement(\"button\");\n button.innerText = \"Purge\";\n button.addEventListener(\"click\", () => this.purge());\n\n div.appendChild(button);\n parent.appendChild(div);\n\n return button;\n }\n\n private addStatistics(parent: HTMLElement): HTMLElement {\n const div = document.createElement(\"div\");\n const text = document.createElement(\"text\");\n text.style.fontWeight = \"bold\";\n div.appendChild(text);\n parent.appendChild(div);\n return text;\n }\n\n private clearInterval(): void {\n if (undefined !== this._curIntervalId) {\n window.clearInterval(this._curIntervalId);\n this._curIntervalId = undefined;\n }\n }\n\n private change(newIndex: MemIndex): void {\n if (newIndex === this._memIndex)\n return;\n\n this._memIndex = newIndex;\n if (MemIndex.None === newIndex) {\n this.clearInterval();\n this._div.style.display = \"none\";\n return;\n }\n\n if (undefined === this._curIntervalId) {\n this._curIntervalId = window.setInterval(() => this.update(), 1000);\n this._div.style.display = \"block\";\n }\n\n this._purgeButton.disabled = undefined === purgeMem[this._memIndex];\n\n this.update();\n }\n\n private update(): void {\n const calc = calcMem[this._memIndex];\n this._stats.clear();\n const numTrees = calc(this._stats, this._vp);\n this._totalElem.innerText = `Total: ${formatMemory(this._stats.totalBytes)}`;\n this._totalTreesElem.innerText = `Total Tile Trees: ${numTrees}`;\n\n this._textures.update(this._stats.consumers, this._stats.totalBytes - this._stats.buffers.totalBytes);\n this._buffers.update(this._stats.buffers.consumers, this._stats.buffers.totalBytes);\n }\n\n private purge(): void {\n const purge = purgeMem[this._memIndex];\n if (undefined !== purge) {\n purge();\n this._vp.invalidateScene(); // to trigger reloading of tiles we actually do want to continue drawing\n this.update();\n }\n }\n}\n"]}
@@ -8,7 +8,7 @@ export declare class RenderCommandBreakdown {
8
8
  private readonly _cells;
9
9
  private readonly _total;
10
10
  constructor(parent: HTMLElement);
11
- dispose(): void;
11
+ [Symbol.dispose](): void;
12
12
  private toggle;
13
13
  private clearInterval;
14
14
  private update;
@@ -1 +1 @@
1
- {"version":3,"file":"RenderCommandBreakdown.d.ts","sourceRoot":"","sources":["../../../src/widgets/RenderCommandBreakdown.ts"],"names":[],"mappings":"AAIA;;GAEG;AAKH,qBAAa,sBAAsB;IACjC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAiB;IACtC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAiB;IAC1C,OAAO,CAAC,cAAc,CAAC,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAkC;IACzD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAc;gBAElB,MAAM,EAAE,WAAW;IAkB/B,OAAO,IAAI,IAAI;IAItB,OAAO,CAAC,MAAM;IAWd,OAAO,CAAC,aAAa;IAOrB,OAAO,CAAC,MAAM;CAoBf"}
1
+ {"version":3,"file":"RenderCommandBreakdown.d.ts","sourceRoot":"","sources":["../../../src/widgets/RenderCommandBreakdown.ts"],"names":[],"mappings":"AAIA;;GAEG;AAKH,qBAAa,sBAAsB;IACjC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAiB;IACtC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAiB;IAC1C,OAAO,CAAC,cAAc,CAAC,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAkC;IACzD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAc;gBAElB,MAAM,EAAE,WAAW;IAkB/B,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,IAAI;IAI/B,OAAO,CAAC,MAAM;IAWd,OAAO,CAAC,aAAa;IAOrB,OAAO,CAAC,MAAM;CAoBf"}
@@ -11,8 +11,12 @@ exports.RenderCommandBreakdown = void 0;
11
11
  const core_frontend_1 = require("@itwin/core-frontend");
12
12
  const CheckBox_1 = require("../ui/CheckBox");
13
13
  class RenderCommandBreakdown {
14
+ _div;
15
+ _cellDiv;
16
+ _curIntervalId;
17
+ _cells = new Map();
18
+ _total;
14
19
  constructor(parent) {
15
- this._cells = new Map();
16
20
  (0, CheckBox_1.createCheckBox)({
17
21
  parent,
18
22
  name: "Render Commands",
@@ -26,7 +30,7 @@ class RenderCommandBreakdown {
26
30
  this._div.appendChild(this._total = document.createElement("div"));
27
31
  this._total.innerText = "Total: 0";
28
32
  }
29
- dispose() {
33
+ [Symbol.dispose]() {
30
34
  this.clearInterval();
31
35
  }
32
36
  toggle() {