@itwin/frontend-devtools 3.7.0-dev.2 → 3.7.0-dev.5

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 (371) hide show
  1. package/CHANGELOG.md +11 -1
  2. package/lib/cjs/ClipboardUtilities.d.ts +8 -8
  3. package/lib/cjs/ClipboardUtilities.js +26 -26
  4. package/lib/cjs/ClipboardUtilities.js.map +1 -1
  5. package/lib/cjs/FrontEndDevTools.d.ts +19 -19
  6. package/lib/cjs/FrontEndDevTools.js +221 -221
  7. package/lib/cjs/FrontEndDevTools.js.map +1 -1
  8. package/lib/cjs/effects/Convolution.d.ts +68 -68
  9. package/lib/cjs/effects/Convolution.js +165 -165
  10. package/lib/cjs/effects/Convolution.js.map +1 -1
  11. package/lib/cjs/effects/EffectTools.d.ts +33 -33
  12. package/lib/cjs/effects/EffectTools.js +68 -68
  13. package/lib/cjs/effects/EffectTools.js.map +1 -1
  14. package/lib/cjs/effects/Explosion.d.ts +12 -12
  15. package/lib/cjs/effects/Explosion.js +168 -168
  16. package/lib/cjs/effects/Explosion.js.map +1 -1
  17. package/lib/cjs/effects/FlipImage.d.ts +30 -30
  18. package/lib/cjs/effects/FlipImage.js +99 -99
  19. package/lib/cjs/effects/FlipImage.js.map +1 -1
  20. package/lib/cjs/effects/LensDistortion.d.ts +34 -34
  21. package/lib/cjs/effects/LensDistortion.js +109 -109
  22. package/lib/cjs/effects/LensDistortion.js.map +1 -1
  23. package/lib/cjs/effects/Random.d.ts +24 -24
  24. package/lib/cjs/effects/Random.js +49 -49
  25. package/lib/cjs/effects/Random.js.map +1 -1
  26. package/lib/cjs/effects/Saturation.d.ts +30 -30
  27. package/lib/cjs/effects/Saturation.js +85 -85
  28. package/lib/cjs/effects/Saturation.js.map +1 -1
  29. package/lib/cjs/effects/Snow.d.ts +76 -76
  30. package/lib/cjs/effects/Snow.js +187 -187
  31. package/lib/cjs/effects/Snow.js.map +1 -1
  32. package/lib/cjs/effects/Vignette.d.ts +39 -39
  33. package/lib/cjs/effects/Vignette.js +108 -108
  34. package/lib/cjs/effects/Vignette.js.map +1 -1
  35. package/lib/cjs/frontend-devtools.d.ts +82 -82
  36. package/lib/cjs/frontend-devtools.js +98 -98
  37. package/lib/cjs/frontend-devtools.js.map +1 -1
  38. package/lib/cjs/tools/AnimationIntervalTool.d.ts +15 -15
  39. package/lib/cjs/tools/AnimationIntervalTool.js +30 -30
  40. package/lib/cjs/tools/AnimationIntervalTool.js.map +1 -1
  41. package/lib/cjs/tools/ChangeUnitsTool.d.ts +15 -15
  42. package/lib/cjs/tools/ChangeUnitsTool.js +41 -41
  43. package/lib/cjs/tools/ChangeUnitsTool.js.map +1 -1
  44. package/lib/cjs/tools/ClipTools.d.ts +67 -67
  45. package/lib/cjs/tools/ClipTools.js +164 -164
  46. package/lib/cjs/tools/ClipTools.js.map +1 -1
  47. package/lib/cjs/tools/DisplayStyleTools.d.ts +145 -145
  48. package/lib/cjs/tools/DisplayStyleTools.js +370 -370
  49. package/lib/cjs/tools/DisplayStyleTools.js.map +1 -1
  50. package/lib/cjs/tools/EmphasizeElementsTool.d.ts +60 -60
  51. package/lib/cjs/tools/EmphasizeElementsTool.js +154 -154
  52. package/lib/cjs/tools/EmphasizeElementsTool.js.map +1 -1
  53. package/lib/cjs/tools/FrustumDecoration.d.ts +57 -57
  54. package/lib/cjs/tools/FrustumDecoration.js +374 -374
  55. package/lib/cjs/tools/FrustumDecoration.js.map +1 -1
  56. package/lib/cjs/tools/InspectElementTool.d.ts +42 -42
  57. package/lib/cjs/tools/InspectElementTool.js +198 -198
  58. package/lib/cjs/tools/InspectElementTool.js.map +1 -1
  59. package/lib/cjs/tools/MapLayerTool.d.ts +264 -264
  60. package/lib/cjs/tools/MapLayerTool.js +507 -507
  61. package/lib/cjs/tools/MapLayerTool.js.map +1 -1
  62. package/lib/cjs/tools/MeasureTileLoadTime.d.ts +12 -12
  63. package/lib/cjs/tools/MeasureTileLoadTime.js +63 -63
  64. package/lib/cjs/tools/MeasureTileLoadTime.js.map +1 -1
  65. package/lib/cjs/tools/ModelAppearanceTools.d.ts +86 -86
  66. package/lib/cjs/tools/ModelAppearanceTools.js +183 -183
  67. package/lib/cjs/tools/ModelAppearanceTools.js.map +1 -1
  68. package/lib/cjs/tools/PlanProjectionTools.d.ts +40 -40
  69. package/lib/cjs/tools/PlanProjectionTools.js +149 -149
  70. package/lib/cjs/tools/PlanProjectionTools.js.map +1 -1
  71. package/lib/cjs/tools/PlanarMaskTools.d.ts +182 -182
  72. package/lib/cjs/tools/PlanarMaskTools.js +393 -393
  73. package/lib/cjs/tools/PlanarMaskTools.js.map +1 -1
  74. package/lib/cjs/tools/ProjectExtents.d.ts +41 -41
  75. package/lib/cjs/tools/ProjectExtents.js +110 -110
  76. package/lib/cjs/tools/ProjectExtents.js.map +1 -1
  77. package/lib/cjs/tools/RealityModelTools.d.ts +116 -116
  78. package/lib/cjs/tools/RealityModelTools.js +281 -281
  79. package/lib/cjs/tools/RealityModelTools.js.map +1 -1
  80. package/lib/cjs/tools/RealityTransitionTool.d.ts +25 -25
  81. package/lib/cjs/tools/RealityTransitionTool.js +116 -116
  82. package/lib/cjs/tools/RealityTransitionTool.js.map +1 -1
  83. package/lib/cjs/tools/RenderSystemTools.d.ts +38 -38
  84. package/lib/cjs/tools/RenderSystemTools.js +70 -70
  85. package/lib/cjs/tools/RenderSystemTools.js.map +1 -1
  86. package/lib/cjs/tools/RenderTargetTools.d.ts +107 -107
  87. package/lib/cjs/tools/RenderTargetTools.js +174 -174
  88. package/lib/cjs/tools/RenderTargetTools.js.map +1 -1
  89. package/lib/cjs/tools/ReportWebGLCompatibilityTool.d.ts +11 -11
  90. package/lib/cjs/tools/ReportWebGLCompatibilityTool.js +30 -30
  91. package/lib/cjs/tools/ReportWebGLCompatibilityTool.js.map +1 -1
  92. package/lib/cjs/tools/SavedViews.d.ts +46 -46
  93. package/lib/cjs/tools/SavedViews.js +136 -136
  94. package/lib/cjs/tools/SavedViews.js.map +1 -1
  95. package/lib/cjs/tools/ScheduleScriptTools.d.ts +37 -37
  96. package/lib/cjs/tools/ScheduleScriptTools.js +159 -159
  97. package/lib/cjs/tools/ScheduleScriptTools.js.map +1 -1
  98. package/lib/cjs/tools/SelectionTools.d.ts +28 -28
  99. package/lib/cjs/tools/SelectionTools.js +87 -87
  100. package/lib/cjs/tools/SelectionTools.js.map +1 -1
  101. package/lib/cjs/tools/SetGpuMemoryLimitTool.d.ts +15 -15
  102. package/lib/cjs/tools/SetGpuMemoryLimitTool.js +33 -33
  103. package/lib/cjs/tools/SetGpuMemoryLimitTool.js.map +1 -1
  104. package/lib/cjs/tools/SourceAspectIdTools.d.ts +40 -40
  105. package/lib/cjs/tools/SourceAspectIdTools.d.ts.map +1 -1
  106. package/lib/cjs/tools/SourceAspectIdTools.js +87 -86
  107. package/lib/cjs/tools/SourceAspectIdTools.js.map +1 -1
  108. package/lib/cjs/tools/TileRequestDecoration.d.ts +12 -12
  109. package/lib/cjs/tools/TileRequestDecoration.js +83 -83
  110. package/lib/cjs/tools/TileRequestDecoration.js.map +1 -1
  111. package/lib/cjs/tools/TileTreeBoundsDecoration.d.ts +11 -11
  112. package/lib/cjs/tools/TileTreeBoundsDecoration.js +74 -74
  113. package/lib/cjs/tools/TileTreeBoundsDecoration.js.map +1 -1
  114. package/lib/cjs/tools/ToolTipProvider.d.ts +15 -15
  115. package/lib/cjs/tools/ToolTipProvider.js +66 -66
  116. package/lib/cjs/tools/ToolTipProvider.js.map +1 -1
  117. package/lib/cjs/tools/ViewportTools.d.ts +218 -218
  118. package/lib/cjs/tools/ViewportTools.js +516 -516
  119. package/lib/cjs/tools/ViewportTools.js.map +1 -1
  120. package/lib/cjs/tools/parseArgs.d.ts +23 -23
  121. package/lib/cjs/tools/parseArgs.js +51 -51
  122. package/lib/cjs/tools/parseArgs.js.map +1 -1
  123. package/lib/cjs/tools/parseBoolean.d.ts +8 -8
  124. package/lib/cjs/tools/parseBoolean.js +26 -26
  125. package/lib/cjs/tools/parseBoolean.js.map +1 -1
  126. package/lib/cjs/tools/parseToggle.d.ts +8 -8
  127. package/lib/cjs/tools/parseToggle.js +25 -25
  128. package/lib/cjs/tools/parseToggle.js.map +1 -1
  129. package/lib/cjs/ui/Button.d.ts +29 -29
  130. package/lib/cjs/ui/Button.js +26 -26
  131. package/lib/cjs/ui/Button.js.map +1 -1
  132. package/lib/cjs/ui/CheckBox.d.ts +23 -23
  133. package/lib/cjs/ui/CheckBox.js +27 -27
  134. package/lib/cjs/ui/CheckBox.js.map +1 -1
  135. package/lib/cjs/ui/ColorInput.d.ts +27 -27
  136. package/lib/cjs/ui/ColorInput.js +53 -53
  137. package/lib/cjs/ui/ColorInput.js.map +1 -1
  138. package/lib/cjs/ui/ComboBox.d.ts +28 -28
  139. package/lib/cjs/ui/ComboBox.js +42 -42
  140. package/lib/cjs/ui/ComboBox.js.map +1 -1
  141. package/lib/cjs/ui/DataList.d.ts +27 -27
  142. package/lib/cjs/ui/DataList.js +39 -39
  143. package/lib/cjs/ui/DataList.js.map +1 -1
  144. package/lib/cjs/ui/NestedMenu.d.ts +19 -19
  145. package/lib/cjs/ui/NestedMenu.js +46 -46
  146. package/lib/cjs/ui/NestedMenu.js.map +1 -1
  147. package/lib/cjs/ui/NumericInput.d.ts +35 -35
  148. package/lib/cjs/ui/NumericInput.js +61 -61
  149. package/lib/cjs/ui/NumericInput.js.map +1 -1
  150. package/lib/cjs/ui/RadioBox.d.ts +29 -29
  151. package/lib/cjs/ui/RadioBox.js +76 -76
  152. package/lib/cjs/ui/RadioBox.js.map +1 -1
  153. package/lib/cjs/ui/Slider.d.ts +28 -28
  154. package/lib/cjs/ui/Slider.js +42 -42
  155. package/lib/cjs/ui/Slider.js.map +1 -1
  156. package/lib/cjs/ui/TextBox.d.ts +32 -32
  157. package/lib/cjs/ui/TextBox.js +56 -56
  158. package/lib/cjs/ui/TextBox.js.map +1 -1
  159. package/lib/cjs/widgets/DiagnosticsPanel.d.ts +37 -37
  160. package/lib/cjs/widgets/DiagnosticsPanel.js +81 -81
  161. package/lib/cjs/widgets/DiagnosticsPanel.js.map +1 -1
  162. package/lib/cjs/widgets/FpsTracker.d.ts +19 -19
  163. package/lib/cjs/widgets/FpsTracker.js +56 -56
  164. package/lib/cjs/widgets/FpsTracker.js.map +1 -1
  165. package/lib/cjs/widgets/GpuProfiler.d.ts +16 -16
  166. package/lib/cjs/widgets/GpuProfiler.js +192 -192
  167. package/lib/cjs/widgets/GpuProfiler.js.map +1 -1
  168. package/lib/cjs/widgets/KeyinField.d.ts +61 -61
  169. package/lib/cjs/widgets/KeyinField.js +187 -187
  170. package/lib/cjs/widgets/KeyinField.js.map +1 -1
  171. package/lib/cjs/widgets/MemoryTracker.d.ts +27 -27
  172. package/lib/cjs/widgets/MemoryTracker.js +243 -243
  173. package/lib/cjs/widgets/MemoryTracker.js.map +1 -1
  174. package/lib/cjs/widgets/RenderCommandBreakdown.d.ts +15 -15
  175. package/lib/cjs/widgets/RenderCommandBreakdown.js +68 -68
  176. package/lib/cjs/widgets/RenderCommandBreakdown.js.map +1 -1
  177. package/lib/cjs/widgets/TileMemoryBreakdown.d.ts +30 -30
  178. package/lib/cjs/widgets/TileMemoryBreakdown.js +204 -204
  179. package/lib/cjs/widgets/TileMemoryBreakdown.js.map +1 -1
  180. package/lib/cjs/widgets/TileStatisticsTracker.d.ts +21 -21
  181. package/lib/cjs/widgets/TileStatisticsTracker.js +142 -142
  182. package/lib/cjs/widgets/TileStatisticsTracker.js.map +1 -1
  183. package/lib/cjs/widgets/ToolSettingsTracker.d.ts +9 -9
  184. package/lib/cjs/widgets/ToolSettingsTracker.js +211 -211
  185. package/lib/cjs/widgets/ToolSettingsTracker.js.map +1 -1
  186. package/lib/esm/ClipboardUtilities.d.ts +8 -8
  187. package/lib/esm/ClipboardUtilities.js +22 -22
  188. package/lib/esm/ClipboardUtilities.js.map +1 -1
  189. package/lib/esm/FrontEndDevTools.d.ts +19 -19
  190. package/lib/esm/FrontEndDevTools.js +217 -217
  191. package/lib/esm/FrontEndDevTools.js.map +1 -1
  192. package/lib/esm/effects/Convolution.d.ts +68 -68
  193. package/lib/esm/effects/Convolution.js +155 -155
  194. package/lib/esm/effects/Convolution.js.map +1 -1
  195. package/lib/esm/effects/EffectTools.d.ts +33 -33
  196. package/lib/esm/effects/EffectTools.js +62 -62
  197. package/lib/esm/effects/EffectTools.js.map +1 -1
  198. package/lib/esm/effects/Explosion.d.ts +12 -12
  199. package/lib/esm/effects/Explosion.js +164 -164
  200. package/lib/esm/effects/Explosion.js.map +1 -1
  201. package/lib/esm/effects/FlipImage.d.ts +30 -30
  202. package/lib/esm/effects/FlipImage.js +94 -94
  203. package/lib/esm/effects/FlipImage.js.map +1 -1
  204. package/lib/esm/effects/LensDistortion.d.ts +34 -34
  205. package/lib/esm/effects/LensDistortion.js +104 -104
  206. package/lib/esm/effects/LensDistortion.js.map +1 -1
  207. package/lib/esm/effects/Random.d.ts +24 -24
  208. package/lib/esm/effects/Random.js +41 -41
  209. package/lib/esm/effects/Random.js.map +1 -1
  210. package/lib/esm/effects/Saturation.d.ts +30 -30
  211. package/lib/esm/effects/Saturation.js +80 -80
  212. package/lib/esm/effects/Saturation.js.map +1 -1
  213. package/lib/esm/effects/Snow.d.ts +76 -76
  214. package/lib/esm/effects/Snow.js +182 -182
  215. package/lib/esm/effects/Snow.js.map +1 -1
  216. package/lib/esm/effects/Vignette.d.ts +39 -39
  217. package/lib/esm/effects/Vignette.js +103 -103
  218. package/lib/esm/effects/Vignette.js.map +1 -1
  219. package/lib/esm/frontend-devtools.d.ts +82 -82
  220. package/lib/esm/frontend-devtools.js +86 -86
  221. package/lib/esm/frontend-devtools.js.map +1 -1
  222. package/lib/esm/tools/AnimationIntervalTool.d.ts +15 -15
  223. package/lib/esm/tools/AnimationIntervalTool.js +26 -26
  224. package/lib/esm/tools/AnimationIntervalTool.js.map +1 -1
  225. package/lib/esm/tools/ChangeUnitsTool.d.ts +15 -15
  226. package/lib/esm/tools/ChangeUnitsTool.js +37 -37
  227. package/lib/esm/tools/ChangeUnitsTool.js.map +1 -1
  228. package/lib/esm/tools/ClipTools.d.ts +67 -67
  229. package/lib/esm/tools/ClipTools.js +158 -158
  230. package/lib/esm/tools/ClipTools.js.map +1 -1
  231. package/lib/esm/tools/DisplayStyleTools.d.ts +145 -145
  232. package/lib/esm/tools/DisplayStyleTools.js +356 -356
  233. package/lib/esm/tools/DisplayStyleTools.js.map +1 -1
  234. package/lib/esm/tools/EmphasizeElementsTool.d.ts +60 -60
  235. package/lib/esm/tools/EmphasizeElementsTool.js +145 -145
  236. package/lib/esm/tools/EmphasizeElementsTool.js.map +1 -1
  237. package/lib/esm/tools/FrustumDecoration.d.ts +57 -57
  238. package/lib/esm/tools/FrustumDecoration.js +367 -367
  239. package/lib/esm/tools/FrustumDecoration.js.map +1 -1
  240. package/lib/esm/tools/InspectElementTool.d.ts +42 -42
  241. package/lib/esm/tools/InspectElementTool.js +194 -194
  242. package/lib/esm/tools/InspectElementTool.js.map +1 -1
  243. package/lib/esm/tools/MapLayerTool.d.ts +264 -264
  244. package/lib/esm/tools/MapLayerTool.js +485 -485
  245. package/lib/esm/tools/MapLayerTool.js.map +1 -1
  246. package/lib/esm/tools/MeasureTileLoadTime.d.ts +12 -12
  247. package/lib/esm/tools/MeasureTileLoadTime.js +59 -59
  248. package/lib/esm/tools/MeasureTileLoadTime.js.map +1 -1
  249. package/lib/esm/tools/ModelAppearanceTools.d.ts +86 -86
  250. package/lib/esm/tools/ModelAppearanceTools.js +172 -172
  251. package/lib/esm/tools/ModelAppearanceTools.js.map +1 -1
  252. package/lib/esm/tools/PlanProjectionTools.d.ts +40 -40
  253. package/lib/esm/tools/PlanProjectionTools.js +143 -143
  254. package/lib/esm/tools/PlanProjectionTools.js.map +1 -1
  255. package/lib/esm/tools/PlanarMaskTools.d.ts +182 -182
  256. package/lib/esm/tools/PlanarMaskTools.js +377 -377
  257. package/lib/esm/tools/PlanarMaskTools.js.map +1 -1
  258. package/lib/esm/tools/ProjectExtents.d.ts +41 -41
  259. package/lib/esm/tools/ProjectExtents.js +104 -104
  260. package/lib/esm/tools/ProjectExtents.js.map +1 -1
  261. package/lib/esm/tools/RealityModelTools.d.ts +116 -116
  262. package/lib/esm/tools/RealityModelTools.js +268 -268
  263. package/lib/esm/tools/RealityModelTools.js.map +1 -1
  264. package/lib/esm/tools/RealityTransitionTool.d.ts +25 -25
  265. package/lib/esm/tools/RealityTransitionTool.js +112 -112
  266. package/lib/esm/tools/RealityTransitionTool.js.map +1 -1
  267. package/lib/esm/tools/RenderSystemTools.d.ts +38 -38
  268. package/lib/esm/tools/RenderSystemTools.js +63 -63
  269. package/lib/esm/tools/RenderSystemTools.js.map +1 -1
  270. package/lib/esm/tools/RenderTargetTools.d.ts +107 -107
  271. package/lib/esm/tools/RenderTargetTools.js +159 -159
  272. package/lib/esm/tools/RenderTargetTools.js.map +1 -1
  273. package/lib/esm/tools/ReportWebGLCompatibilityTool.d.ts +11 -11
  274. package/lib/esm/tools/ReportWebGLCompatibilityTool.js +26 -26
  275. package/lib/esm/tools/ReportWebGLCompatibilityTool.js.map +1 -1
  276. package/lib/esm/tools/SavedViews.d.ts +46 -46
  277. package/lib/esm/tools/SavedViews.js +128 -128
  278. package/lib/esm/tools/SavedViews.js.map +1 -1
  279. package/lib/esm/tools/ScheduleScriptTools.d.ts +37 -37
  280. package/lib/esm/tools/ScheduleScriptTools.js +153 -153
  281. package/lib/esm/tools/ScheduleScriptTools.js.map +1 -1
  282. package/lib/esm/tools/SelectionTools.d.ts +28 -28
  283. package/lib/esm/tools/SelectionTools.js +82 -82
  284. package/lib/esm/tools/SelectionTools.js.map +1 -1
  285. package/lib/esm/tools/SetGpuMemoryLimitTool.d.ts +15 -15
  286. package/lib/esm/tools/SetGpuMemoryLimitTool.js +29 -29
  287. package/lib/esm/tools/SetGpuMemoryLimitTool.js.map +1 -1
  288. package/lib/esm/tools/SourceAspectIdTools.d.ts +40 -40
  289. package/lib/esm/tools/SourceAspectIdTools.d.ts.map +1 -1
  290. package/lib/esm/tools/SourceAspectIdTools.js +81 -80
  291. package/lib/esm/tools/SourceAspectIdTools.js.map +1 -1
  292. package/lib/esm/tools/TileRequestDecoration.d.ts +12 -12
  293. package/lib/esm/tools/TileRequestDecoration.js +79 -79
  294. package/lib/esm/tools/TileRequestDecoration.js.map +1 -1
  295. package/lib/esm/tools/TileTreeBoundsDecoration.d.ts +11 -11
  296. package/lib/esm/tools/TileTreeBoundsDecoration.js +70 -70
  297. package/lib/esm/tools/TileTreeBoundsDecoration.js.map +1 -1
  298. package/lib/esm/tools/ToolTipProvider.d.ts +15 -15
  299. package/lib/esm/tools/ToolTipProvider.js +62 -62
  300. package/lib/esm/tools/ToolTipProvider.js.map +1 -1
  301. package/lib/esm/tools/ViewportTools.d.ts +218 -218
  302. package/lib/esm/tools/ViewportTools.js +492 -492
  303. package/lib/esm/tools/ViewportTools.js.map +1 -1
  304. package/lib/esm/tools/parseArgs.d.ts +23 -23
  305. package/lib/esm/tools/parseArgs.js +47 -47
  306. package/lib/esm/tools/parseArgs.js.map +1 -1
  307. package/lib/esm/tools/parseBoolean.d.ts +8 -8
  308. package/lib/esm/tools/parseBoolean.js +22 -22
  309. package/lib/esm/tools/parseBoolean.js.map +1 -1
  310. package/lib/esm/tools/parseToggle.d.ts +8 -8
  311. package/lib/esm/tools/parseToggle.js +21 -21
  312. package/lib/esm/tools/parseToggle.js.map +1 -1
  313. package/lib/esm/ui/Button.d.ts +29 -29
  314. package/lib/esm/ui/Button.js +22 -22
  315. package/lib/esm/ui/Button.js.map +1 -1
  316. package/lib/esm/ui/CheckBox.d.ts +23 -23
  317. package/lib/esm/ui/CheckBox.js +23 -23
  318. package/lib/esm/ui/CheckBox.js.map +1 -1
  319. package/lib/esm/ui/ColorInput.d.ts +27 -27
  320. package/lib/esm/ui/ColorInput.js +48 -48
  321. package/lib/esm/ui/ColorInput.js.map +1 -1
  322. package/lib/esm/ui/ComboBox.d.ts +28 -28
  323. package/lib/esm/ui/ComboBox.js +38 -38
  324. package/lib/esm/ui/ComboBox.js.map +1 -1
  325. package/lib/esm/ui/DataList.d.ts +27 -27
  326. package/lib/esm/ui/DataList.js +34 -34
  327. package/lib/esm/ui/DataList.js.map +1 -1
  328. package/lib/esm/ui/NestedMenu.d.ts +19 -19
  329. package/lib/esm/ui/NestedMenu.js +42 -42
  330. package/lib/esm/ui/NestedMenu.js.map +1 -1
  331. package/lib/esm/ui/NumericInput.d.ts +35 -35
  332. package/lib/esm/ui/NumericInput.js +56 -56
  333. package/lib/esm/ui/NumericInput.js.map +1 -1
  334. package/lib/esm/ui/RadioBox.d.ts +29 -29
  335. package/lib/esm/ui/RadioBox.js +72 -72
  336. package/lib/esm/ui/RadioBox.js.map +1 -1
  337. package/lib/esm/ui/Slider.d.ts +28 -28
  338. package/lib/esm/ui/Slider.js +38 -38
  339. package/lib/esm/ui/Slider.js.map +1 -1
  340. package/lib/esm/ui/TextBox.d.ts +32 -32
  341. package/lib/esm/ui/TextBox.js +52 -52
  342. package/lib/esm/ui/TextBox.js.map +1 -1
  343. package/lib/esm/widgets/DiagnosticsPanel.d.ts +37 -37
  344. package/lib/esm/widgets/DiagnosticsPanel.js +77 -77
  345. package/lib/esm/widgets/DiagnosticsPanel.js.map +1 -1
  346. package/lib/esm/widgets/FpsTracker.d.ts +19 -19
  347. package/lib/esm/widgets/FpsTracker.js +52 -52
  348. package/lib/esm/widgets/FpsTracker.js.map +1 -1
  349. package/lib/esm/widgets/GpuProfiler.d.ts +16 -16
  350. package/lib/esm/widgets/GpuProfiler.js +188 -188
  351. package/lib/esm/widgets/GpuProfiler.js.map +1 -1
  352. package/lib/esm/widgets/KeyinField.d.ts +61 -61
  353. package/lib/esm/widgets/KeyinField.js +183 -183
  354. package/lib/esm/widgets/KeyinField.js.map +1 -1
  355. package/lib/esm/widgets/MemoryTracker.d.ts +27 -27
  356. package/lib/esm/widgets/MemoryTracker.js +238 -238
  357. package/lib/esm/widgets/MemoryTracker.js.map +1 -1
  358. package/lib/esm/widgets/RenderCommandBreakdown.d.ts +15 -15
  359. package/lib/esm/widgets/RenderCommandBreakdown.js +64 -64
  360. package/lib/esm/widgets/RenderCommandBreakdown.js.map +1 -1
  361. package/lib/esm/widgets/TileMemoryBreakdown.d.ts +30 -30
  362. package/lib/esm/widgets/TileMemoryBreakdown.js +200 -200
  363. package/lib/esm/widgets/TileMemoryBreakdown.js.map +1 -1
  364. package/lib/esm/widgets/TileStatisticsTracker.d.ts +21 -21
  365. package/lib/esm/widgets/TileStatisticsTracker.js +138 -138
  366. package/lib/esm/widgets/TileStatisticsTracker.js.map +1 -1
  367. package/lib/esm/widgets/ToolSettingsTracker.d.ts +9 -9
  368. package/lib/esm/widgets/ToolSettingsTracker.js +207 -207
  369. package/lib/esm/widgets/ToolSettingsTracker.js.map +1 -1
  370. package/lib/public/locales/en/FrontendDevTools.json +484 -484
  371. package/package.json +7 -7
@@ -1,53 +1,53 @@
1
- /*---------------------------------------------------------------------------------------------
2
- * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
3
- * See LICENSE.md in the project root for license terms and full copyright notice.
4
- *--------------------------------------------------------------------------------------------*/
5
- /** @packageDocumentation
6
- * @module Widgets
7
- */
8
- import { PerformanceMetrics } from "@itwin/core-frontend";
9
- import { createCheckBox } from "../ui/CheckBox";
10
- /** Displays average frames-per-second.
11
- * NOTE: Enabling fps tracking causes a new frame to render on every tick of the render loop, which may negatively impact battery life.
12
- * @beta
13
- */
14
- export class FpsTracker {
15
- constructor(parent, viewport) {
16
- this._vp = viewport;
17
- this._label = createCheckBox({
18
- parent,
19
- name: "Track FPS",
20
- id: "fpsTracker_toggle",
21
- handler: (cb) => this.toggle(cb.checked),
22
- }).label;
23
- }
24
- dispose() {
25
- this.toggle(false);
26
- }
27
- clearInterval() {
28
- if (undefined !== this._curIntervalId) {
29
- clearInterval(this._curIntervalId);
30
- this._curIntervalId = undefined;
31
- }
32
- }
33
- toggle(enabled) {
34
- this._vp.continuousRendering = enabled;
35
- if (enabled) {
36
- this._metrics = new PerformanceMetrics(false, true);
37
- this._curIntervalId = setInterval(() => this.updateFPS(), 500);
38
- this._label.innerText = "Tracking FPS...";
39
- }
40
- else {
41
- this._metrics = undefined;
42
- this.clearInterval();
43
- this._label.innerText = "Track FPS";
44
- }
45
- this._vp.target.performanceMetrics = this._metrics;
46
- }
47
- updateFPS() {
48
- const metrics = this._metrics;
49
- const fps = (metrics.spfTimes.length / metrics.spfSum).toFixed(2);
50
- this._label.innerText = `FPS: ${fps}`;
51
- }
52
- }
1
+ /*---------------------------------------------------------------------------------------------
2
+ * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
3
+ * See LICENSE.md in the project root for license terms and full copyright notice.
4
+ *--------------------------------------------------------------------------------------------*/
5
+ /** @packageDocumentation
6
+ * @module Widgets
7
+ */
8
+ import { PerformanceMetrics } from "@itwin/core-frontend";
9
+ import { createCheckBox } from "../ui/CheckBox";
10
+ /** Displays average frames-per-second.
11
+ * NOTE: Enabling fps tracking causes a new frame to render on every tick of the render loop, which may negatively impact battery life.
12
+ * @beta
13
+ */
14
+ export class FpsTracker {
15
+ constructor(parent, viewport) {
16
+ this._vp = viewport;
17
+ this._label = createCheckBox({
18
+ parent,
19
+ name: "Track FPS",
20
+ id: "fpsTracker_toggle",
21
+ handler: (cb) => this.toggle(cb.checked),
22
+ }).label;
23
+ }
24
+ dispose() {
25
+ this.toggle(false);
26
+ }
27
+ clearInterval() {
28
+ if (undefined !== this._curIntervalId) {
29
+ clearInterval(this._curIntervalId);
30
+ this._curIntervalId = undefined;
31
+ }
32
+ }
33
+ toggle(enabled) {
34
+ this._vp.continuousRendering = enabled;
35
+ if (enabled) {
36
+ this._metrics = new PerformanceMetrics(false, true);
37
+ this._curIntervalId = setInterval(() => this.updateFPS(), 500);
38
+ this._label.innerText = "Tracking FPS...";
39
+ }
40
+ else {
41
+ this._metrics = undefined;
42
+ this.clearInterval();
43
+ this._label.innerText = "Track FPS";
44
+ }
45
+ this._vp.target.performanceMetrics = this._metrics;
46
+ }
47
+ updateFPS() {
48
+ const metrics = this._metrics;
49
+ const fps = (metrics.spfTimes.length / metrics.spfSum).toFixed(2);
50
+ this._label.innerText = `FPS: ${fps}`;
51
+ }
52
+ }
53
53
  //# sourceMappingURL=FpsTracker.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"FpsTracker.js","sourceRoot":"","sources":["../../../src/widgets/FpsTracker.ts"],"names":[],"mappings":"AAAA;;;+FAG+F;AAE/F;;GAEG;AAEH,OAAO,EAAE,kBAAkB,EAAoB,MAAM,sBAAsB,CAAC;AAC5E,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAEhD;;;GAGG;AACH,MAAM,OAAO,UAAU;IAMrB,YAAmB,MAAmB,EAAE,QAAkB;QACxD,IAAI,CAAC,GAAG,GAAG,QAAQ,CAAC;QACpB,IAAI,CAAC,MAAM,GAAG,cAAc,CAAC;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;YACrC,aAAa,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;YACnC,IAAI,CAAC,cAAc,GAAG,SAAS,CAAC;SACjC;IACH,CAAC;IAEO,MAAM,CAAC,OAAgB;QAC7B,IAAI,CAAC,GAAG,CAAC,mBAAmB,GAAG,OAAO,CAAC;QACvC,IAAI,OAAO,EAAE;YACX,IAAI,CAAC,QAAQ,GAAG,IAAI,kBAAkB,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;YACpD,IAAI,CAAC,cAAc,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,SAAS,EAAE,EAAE,GAAG,CAAC,CAAC;YAC/D,IAAI,CAAC,MAAM,CAAC,SAAS,GAAG,iBAAiB,CAAC;SAC3C;aAAM;YACL,IAAI,CAAC,QAAQ,GAAG,SAAS,CAAC;YAC1B,IAAI,CAAC,aAAa,EAAE,CAAC;YACrB,IAAI,CAAC,MAAM,CAAC,SAAS,GAAG,WAAW,CAAC;SACrC;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","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?: NodeJS.Timer;\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 dispose(): void {\n this.toggle(false);\n }\n\n private clearInterval(): void {\n if (undefined !== this._curIntervalId) {\n 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 = 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"]}
1
+ {"version":3,"file":"FpsTracker.js","sourceRoot":"","sources":["../../../src/widgets/FpsTracker.ts"],"names":[],"mappings":"AAAA;;;+FAG+F;AAE/F;;GAEG;AAEH,OAAO,EAAE,kBAAkB,EAAoB,MAAM,sBAAsB,CAAC;AAC5E,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAEhD;;;GAGG;AACH,MAAM,OAAO,UAAU;IAMrB,YAAmB,MAAmB,EAAE,QAAkB;QACxD,IAAI,CAAC,GAAG,GAAG,QAAQ,CAAC;QACpB,IAAI,CAAC,MAAM,GAAG,cAAc,CAAC;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;YACrC,aAAa,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;YACnC,IAAI,CAAC,cAAc,GAAG,SAAS,CAAC;SACjC;IACH,CAAC;IAEO,MAAM,CAAC,OAAgB;QAC7B,IAAI,CAAC,GAAG,CAAC,mBAAmB,GAAG,OAAO,CAAC;QACvC,IAAI,OAAO,EAAE;YACX,IAAI,CAAC,QAAQ,GAAG,IAAI,kBAAkB,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;YACpD,IAAI,CAAC,cAAc,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,SAAS,EAAE,EAAE,GAAG,CAAC,CAAC;YAC/D,IAAI,CAAC,MAAM,CAAC,SAAS,GAAG,iBAAiB,CAAC;SAC3C;aAAM;YACL,IAAI,CAAC,QAAQ,GAAG,SAAS,CAAC;YAC1B,IAAI,CAAC,aAAa,EAAE,CAAC;YACrB,IAAI,CAAC,MAAM,CAAC,SAAS,GAAG,WAAW,CAAC;SACrC;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","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?: NodeJS.Timer;\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 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 = 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,17 +1,17 @@
1
- /** @alpha */
2
- export declare class GpuProfiler {
3
- private readonly _div;
4
- private readonly _resultsDiv;
5
- private readonly _results;
6
- private readonly _debugControl;
7
- private readonly _recordButton;
8
- private _recordedResults;
9
- private _isRecording;
10
- constructor(parent: HTMLElement);
11
- dispose(): void;
12
- private toggleProfileCheckBox;
13
- private _clickRecord;
14
- private stopRecording;
15
- private _resultsCallback;
16
- }
1
+ /** @alpha */
2
+ export declare class GpuProfiler {
3
+ private readonly _div;
4
+ private readonly _resultsDiv;
5
+ private readonly _results;
6
+ private readonly _debugControl;
7
+ private readonly _recordButton;
8
+ private _recordedResults;
9
+ private _isRecording;
10
+ constructor(parent: HTMLElement);
11
+ dispose(): void;
12
+ private toggleProfileCheckBox;
13
+ private _clickRecord;
14
+ private stopRecording;
15
+ private _resultsCallback;
16
+ }
17
17
  //# sourceMappingURL=GpuProfiler.d.ts.map
@@ -1,189 +1,189 @@
1
- /*---------------------------------------------------------------------------------------------
2
- * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
3
- * See LICENSE.md in the project root for license terms and full copyright notice.
4
- *--------------------------------------------------------------------------------------------*/
5
- /** @packageDocumentation
6
- * @module Widgets
7
- */
8
- import { saveAs } from "file-saver";
9
- import { IModelApp } from "@itwin/core-frontend";
10
- import { createCheckBox } from "../ui/CheckBox";
11
- const dummyArgs = { 0: 0 }; // Reuse instead of allocating for each entry
12
- /**
13
- * @param name Label for the trace event
14
- * @param start Timestamp in microseconds of when trace event started
15
- * @param duration Duration in microseconds of trace event
16
- */
17
- function createTraceEvent(name, start, duration) {
18
- return {
19
- pid: 1,
20
- ts: start,
21
- dur: duration,
22
- ph: "X",
23
- name,
24
- args: dummyArgs,
25
- };
26
- }
27
- function createTraceFromTimerResults(timerResults) {
28
- const traceEvents = [];
29
- const addChildren = (startTime, children) => {
30
- for (const child of children) {
31
- if (child.nanoseconds < 100)
32
- continue;
33
- const microseconds = child.nanoseconds / 1E3;
34
- traceEvents.push(createTraceEvent(child.label, startTime, microseconds));
35
- if (child.children)
36
- addChildren(startTime, child.children);
37
- startTime += microseconds;
38
- }
39
- };
40
- let frameStartTime = 0;
41
- let frameNumber = 0;
42
- for (const tr of timerResults) {
43
- const microseconds = tr.nanoseconds / 1E3;
44
- traceEvents.push(createTraceEvent(`Frame ${frameNumber}`, frameStartTime, microseconds));
45
- if (tr.children)
46
- addChildren(frameStartTime, tr.children);
47
- frameStartTime += microseconds;
48
- ++frameNumber;
49
- }
50
- return { traceEvents };
51
- }
52
- /** @alpha */
53
- export class GpuProfiler {
54
- constructor(parent) {
55
- this._clickRecord = () => {
56
- if (!this._isRecording) {
57
- this._isRecording = true;
58
- this._recordButton.innerText = "Stop Recording";
59
- return;
60
- }
61
- this.stopRecording();
62
- };
63
- this._resultsCallback = (result) => {
64
- if (this._isRecording)
65
- this._recordedResults.push(result);
66
- const fragment = document.createDocumentFragment();
67
- const numSavedFrames = 120;
68
- let lastValue;
69
- const changedResults = new Array(this._results.length); // default values false
70
- const printDepth = (depth, currentRes) => {
71
- const index = this._results.findIndex((res) => res.label === currentRes.label);
72
- if (index < 0) { // Add brand new entry
73
- const data = {
74
- label: currentRes.label,
75
- paddingLeft: `${depth}em`,
76
- sum: currentRes.nanoseconds,
77
- values: [currentRes.nanoseconds],
78
- };
79
- if (lastValue === undefined) {
80
- this._results.unshift(data);
81
- changedResults.unshift(true);
82
- }
83
- else if (currentRes.label === "Read Pixels") {
84
- this._results.push(data); // Read Pixels should go at the end of the list
85
- changedResults.push(true);
86
- }
87
- else {
88
- const prevIndex = this._results.findIndex((res) => res.label === lastValue);
89
- this._results.splice(prevIndex + 1, 0, data);
90
- changedResults.splice(prevIndex + 1, 0, true);
91
- }
92
- }
93
- else { // Edit old entry
94
- let oldVal = 0.0;
95
- const savedResults = this._results[index];
96
- if (savedResults.values.length >= numSavedFrames) { // keep up to numSavedFrames values to average between
97
- oldVal = savedResults.values.shift();
98
- }
99
- const newVal = currentRes.nanoseconds < 100 ? 0.0 : currentRes.nanoseconds; // high-pass filter, empty queries have some noise
100
- savedResults.sum += newVal - oldVal;
101
- savedResults.values.push(newVal);
102
- changedResults[index] = true;
103
- }
104
- lastValue = currentRes.label;
105
- if (!currentRes.children)
106
- return;
107
- for (const childRes of currentRes.children)
108
- printDepth(depth + 1, childRes);
109
- };
110
- printDepth(0, result);
111
- this._results.forEach((value, index) => {
112
- if (!changedResults[index]) { // if no data received on this item, add a value of 0.0 to the avg.
113
- const oldVal = value.values.length >= numSavedFrames ? value.values.shift() : 0.0;
114
- value.sum -= oldVal;
115
- value.values.push(0.0);
116
- }
117
- const div = document.createElement("div");
118
- div.style.display = "flex";
119
- div.style.width = "75%";
120
- const textLabel = document.createElement("text");
121
- textLabel.innerText = `${value.label}`;
122
- textLabel.style.paddingLeft = value.paddingLeft;
123
- div.appendChild(textLabel);
124
- const divLine = document.createElement("div");
125
- divLine.style.flexGrow = "1";
126
- divLine.style.borderBottom = "dotted 1px";
127
- div.appendChild(divLine);
128
- const textValue = document.createElement("text");
129
- textValue.innerText = `${(value.sum / value.values.length / 1.E6).toFixed(3)} ms\n`;
130
- div.appendChild(textValue);
131
- fragment.appendChild(div);
132
- });
133
- this._resultsDiv.innerHTML = "";
134
- this._resultsDiv.appendChild(fragment);
135
- };
136
- this._debugControl = IModelApp.renderSystem.debugControl;
137
- const checkBox = createCheckBox({
138
- parent,
139
- name: "Profile GPU",
140
- id: "gpu-profiler-toggle",
141
- handler: (cb) => this.toggleProfileCheckBox(cb.checked),
142
- });
143
- if (!this._debugControl.isGLTimerSupported) {
144
- checkBox.checkbox.disabled = true;
145
- checkBox.div.title = "EXT_disjoint_timer_query is not available in this browser";
146
- }
147
- this._div = document.createElement("div");
148
- this._div.style.display = "none";
149
- this._recordButton = document.createElement("button");
150
- this._recordButton.style.textAlign = "center";
151
- this._isRecording = false;
152
- this._recordButton.innerText = "Record Profile";
153
- this._recordButton.title = "Record a profile to open with chrome://tracing";
154
- this._recordedResults = [];
155
- this._recordButton.addEventListener("click", this._clickRecord);
156
- this._div.appendChild(this._recordButton);
157
- this._results = [];
158
- this._resultsDiv = document.createElement("div");
159
- this._resultsDiv.style.textAlign = "left";
160
- this._div.appendChild(this._resultsDiv);
161
- parent.appendChild(this._div);
162
- }
163
- dispose() {
164
- this._debugControl.resultsCallback = undefined;
165
- }
166
- toggleProfileCheckBox(isEnabled) {
167
- if (isEnabled) {
168
- this._debugControl.resultsCallback = this._resultsCallback;
169
- this._resultsDiv.innerHTML = "";
170
- this._div.style.display = "block";
171
- }
172
- else {
173
- this._debugControl.resultsCallback = undefined;
174
- this._div.style.display = "none";
175
- this.stopRecording();
176
- }
177
- }
178
- stopRecording() {
179
- this._isRecording = false;
180
- this._recordButton.innerText = "Record Profile";
181
- if (this._recordedResults.length !== 0) {
182
- const chromeTrace = createTraceFromTimerResults(this._recordedResults);
183
- const blob = new Blob([JSON.stringify(chromeTrace)], { type: "application/json;charset=utf-8" });
184
- saveAs(blob, "gpu-profile.json");
185
- this._recordedResults = [];
186
- }
187
- }
188
- }
1
+ /*---------------------------------------------------------------------------------------------
2
+ * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
3
+ * See LICENSE.md in the project root for license terms and full copyright notice.
4
+ *--------------------------------------------------------------------------------------------*/
5
+ /** @packageDocumentation
6
+ * @module Widgets
7
+ */
8
+ import { saveAs } from "file-saver";
9
+ import { IModelApp } from "@itwin/core-frontend";
10
+ import { createCheckBox } from "../ui/CheckBox";
11
+ const dummyArgs = { 0: 0 }; // Reuse instead of allocating for each entry
12
+ /**
13
+ * @param name Label for the trace event
14
+ * @param start Timestamp in microseconds of when trace event started
15
+ * @param duration Duration in microseconds of trace event
16
+ */
17
+ function createTraceEvent(name, start, duration) {
18
+ return {
19
+ pid: 1,
20
+ ts: start,
21
+ dur: duration,
22
+ ph: "X",
23
+ name,
24
+ args: dummyArgs,
25
+ };
26
+ }
27
+ function createTraceFromTimerResults(timerResults) {
28
+ const traceEvents = [];
29
+ const addChildren = (startTime, children) => {
30
+ for (const child of children) {
31
+ if (child.nanoseconds < 100)
32
+ continue;
33
+ const microseconds = child.nanoseconds / 1E3;
34
+ traceEvents.push(createTraceEvent(child.label, startTime, microseconds));
35
+ if (child.children)
36
+ addChildren(startTime, child.children);
37
+ startTime += microseconds;
38
+ }
39
+ };
40
+ let frameStartTime = 0;
41
+ let frameNumber = 0;
42
+ for (const tr of timerResults) {
43
+ const microseconds = tr.nanoseconds / 1E3;
44
+ traceEvents.push(createTraceEvent(`Frame ${frameNumber}`, frameStartTime, microseconds));
45
+ if (tr.children)
46
+ addChildren(frameStartTime, tr.children);
47
+ frameStartTime += microseconds;
48
+ ++frameNumber;
49
+ }
50
+ return { traceEvents };
51
+ }
52
+ /** @alpha */
53
+ export class GpuProfiler {
54
+ constructor(parent) {
55
+ this._clickRecord = () => {
56
+ if (!this._isRecording) {
57
+ this._isRecording = true;
58
+ this._recordButton.innerText = "Stop Recording";
59
+ return;
60
+ }
61
+ this.stopRecording();
62
+ };
63
+ this._resultsCallback = (result) => {
64
+ if (this._isRecording)
65
+ this._recordedResults.push(result);
66
+ const fragment = document.createDocumentFragment();
67
+ const numSavedFrames = 120;
68
+ let lastValue;
69
+ const changedResults = new Array(this._results.length); // default values false
70
+ const printDepth = (depth, currentRes) => {
71
+ const index = this._results.findIndex((res) => res.label === currentRes.label);
72
+ if (index < 0) { // Add brand new entry
73
+ const data = {
74
+ label: currentRes.label,
75
+ paddingLeft: `${depth}em`,
76
+ sum: currentRes.nanoseconds,
77
+ values: [currentRes.nanoseconds],
78
+ };
79
+ if (lastValue === undefined) {
80
+ this._results.unshift(data);
81
+ changedResults.unshift(true);
82
+ }
83
+ else if (currentRes.label === "Read Pixels") {
84
+ this._results.push(data); // Read Pixels should go at the end of the list
85
+ changedResults.push(true);
86
+ }
87
+ else {
88
+ const prevIndex = this._results.findIndex((res) => res.label === lastValue);
89
+ this._results.splice(prevIndex + 1, 0, data);
90
+ changedResults.splice(prevIndex + 1, 0, true);
91
+ }
92
+ }
93
+ else { // Edit old entry
94
+ let oldVal = 0.0;
95
+ const savedResults = this._results[index];
96
+ if (savedResults.values.length >= numSavedFrames) { // keep up to numSavedFrames values to average between
97
+ oldVal = savedResults.values.shift();
98
+ }
99
+ const newVal = currentRes.nanoseconds < 100 ? 0.0 : currentRes.nanoseconds; // high-pass filter, empty queries have some noise
100
+ savedResults.sum += newVal - oldVal;
101
+ savedResults.values.push(newVal);
102
+ changedResults[index] = true;
103
+ }
104
+ lastValue = currentRes.label;
105
+ if (!currentRes.children)
106
+ return;
107
+ for (const childRes of currentRes.children)
108
+ printDepth(depth + 1, childRes);
109
+ };
110
+ printDepth(0, result);
111
+ this._results.forEach((value, index) => {
112
+ if (!changedResults[index]) { // if no data received on this item, add a value of 0.0 to the avg.
113
+ const oldVal = value.values.length >= numSavedFrames ? value.values.shift() : 0.0;
114
+ value.sum -= oldVal;
115
+ value.values.push(0.0);
116
+ }
117
+ const div = document.createElement("div");
118
+ div.style.display = "flex";
119
+ div.style.width = "75%";
120
+ const textLabel = document.createElement("text");
121
+ textLabel.innerText = `${value.label}`;
122
+ textLabel.style.paddingLeft = value.paddingLeft;
123
+ div.appendChild(textLabel);
124
+ const divLine = document.createElement("div");
125
+ divLine.style.flexGrow = "1";
126
+ divLine.style.borderBottom = "dotted 1px";
127
+ div.appendChild(divLine);
128
+ const textValue = document.createElement("text");
129
+ textValue.innerText = `${(value.sum / value.values.length / 1.E6).toFixed(3)} ms\n`;
130
+ div.appendChild(textValue);
131
+ fragment.appendChild(div);
132
+ });
133
+ this._resultsDiv.innerHTML = "";
134
+ this._resultsDiv.appendChild(fragment);
135
+ };
136
+ this._debugControl = IModelApp.renderSystem.debugControl;
137
+ const checkBox = createCheckBox({
138
+ parent,
139
+ name: "Profile GPU",
140
+ id: "gpu-profiler-toggle",
141
+ handler: (cb) => this.toggleProfileCheckBox(cb.checked),
142
+ });
143
+ if (!this._debugControl.isGLTimerSupported) {
144
+ checkBox.checkbox.disabled = true;
145
+ checkBox.div.title = "EXT_disjoint_timer_query is not available in this browser";
146
+ }
147
+ this._div = document.createElement("div");
148
+ this._div.style.display = "none";
149
+ this._recordButton = document.createElement("button");
150
+ this._recordButton.style.textAlign = "center";
151
+ this._isRecording = false;
152
+ this._recordButton.innerText = "Record Profile";
153
+ this._recordButton.title = "Record a profile to open with chrome://tracing";
154
+ this._recordedResults = [];
155
+ this._recordButton.addEventListener("click", this._clickRecord);
156
+ this._div.appendChild(this._recordButton);
157
+ this._results = [];
158
+ this._resultsDiv = document.createElement("div");
159
+ this._resultsDiv.style.textAlign = "left";
160
+ this._div.appendChild(this._resultsDiv);
161
+ parent.appendChild(this._div);
162
+ }
163
+ dispose() {
164
+ this._debugControl.resultsCallback = undefined;
165
+ }
166
+ toggleProfileCheckBox(isEnabled) {
167
+ if (isEnabled) {
168
+ this._debugControl.resultsCallback = this._resultsCallback;
169
+ this._resultsDiv.innerHTML = "";
170
+ this._div.style.display = "block";
171
+ }
172
+ else {
173
+ this._debugControl.resultsCallback = undefined;
174
+ this._div.style.display = "none";
175
+ this.stopRecording();
176
+ }
177
+ }
178
+ stopRecording() {
179
+ this._isRecording = false;
180
+ this._recordButton.innerText = "Record Profile";
181
+ if (this._recordedResults.length !== 0) {
182
+ const chromeTrace = createTraceFromTimerResults(this._recordedResults);
183
+ const blob = new Blob([JSON.stringify(chromeTrace)], { type: "application/json;charset=utf-8" });
184
+ saveAs(blob, "gpu-profile.json");
185
+ this._recordedResults = [];
186
+ }
187
+ }
188
+ }
189
189
  //# 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":["/*---------------------------------------------------------------------------------------------\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 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"]}
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"]}