babylon.sceneInstrumentation.ts 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508
  1. module BABYLON {
  2. /**
  3. * This class can be used to get instrumentation data from a Babylon engine
  4. */
  5. export class SceneInstrumentation implements IDisposable {
  6. private _captureActiveMeshesEvaluationTime = false;
  7. private _activeMeshesEvaluationTime = new PerfCounter();
  8. private _captureRenderTargetsRenderTime = false;
  9. private _renderTargetsRenderTime = new PerfCounter();
  10. private _captureFrameTime = false;
  11. private _frameTime = new PerfCounter();
  12. private _captureRenderTime = false;
  13. private _renderTime = new PerfCounter();
  14. private _captureInterFrameTime = false;
  15. private _interFrameTime = new PerfCounter();
  16. private _captureParticlesRenderTime = false;
  17. private _particlesRenderTime = new PerfCounter();
  18. private _captureSpritesRenderTime = false;
  19. private _spritesRenderTime = new PerfCounter();
  20. private _capturePhysicsTime = false;
  21. private _physicsTime = new PerfCounter();
  22. private _captureAnimationsTime = false;
  23. private _animationsTime = new PerfCounter();
  24. // Observers
  25. private _onBeforeActiveMeshesEvaluationObserver: Nullable<Observer<Scene>> = null;
  26. private _onAfterActiveMeshesEvaluationObserver: Nullable<Observer<Scene>> = null;
  27. private _onBeforeRenderTargetsRenderObserver: Nullable<Observer<Scene>> = null;
  28. private _onAfterRenderTargetsRenderObserver: Nullable<Observer<Scene>> = null;
  29. private _onAfterRenderObserver: Nullable<Observer<Scene>> = null;
  30. private _onBeforeDrawPhaseObserver: Nullable<Observer<Scene>> = null;
  31. private _onAfterDrawPhaseObserver: Nullable<Observer<Scene>> = null;
  32. private _onBeforeAnimationsObserver: Nullable<Observer<Scene>> = null;
  33. private _onBeforeParticlesRenderingObserver: Nullable<Observer<Scene>> = null;
  34. private _onAfterParticlesRenderingObserver: Nullable<Observer<Scene>> = null;
  35. private _onBeforeSpritesRenderingObserver: Nullable<Observer<Scene>> = null;
  36. private _onAfterSpritesRenderingObserver: Nullable<Observer<Scene>> = null;
  37. private _onBeforePhysicsObserver: Nullable<Observer<Scene>> = null;
  38. private _onAfterPhysicsObserver: Nullable<Observer<Scene>> = null;
  39. private _onAfterAnimationsObserver: Nullable<Observer<Scene>> = null;
  40. // Properties
  41. /**
  42. * Gets the perf counter used for active meshes evaluation time
  43. */
  44. public get activeMeshesEvaluationTimeCounter(): PerfCounter {
  45. return this._activeMeshesEvaluationTime;
  46. }
  47. /**
  48. * Gets the active meshes evaluation time capture status
  49. */
  50. public get captureActiveMeshesEvaluationTime(): boolean {
  51. return this._captureActiveMeshesEvaluationTime;
  52. }
  53. /**
  54. * Enable or disable the active meshes evaluation time capture
  55. */
  56. public set captureActiveMeshesEvaluationTime(value: boolean) {
  57. if (value === this._captureActiveMeshesEvaluationTime) {
  58. return;
  59. }
  60. this._captureActiveMeshesEvaluationTime = value;
  61. if (value) {
  62. this._onBeforeActiveMeshesEvaluationObserver = this.scene.onBeforeActiveMeshesEvaluationObservable.add(() => {
  63. Tools.StartPerformanceCounter("Active meshes evaluation");
  64. this._activeMeshesEvaluationTime.beginMonitoring();
  65. });
  66. this._onAfterActiveMeshesEvaluationObserver = this.scene.onAfterActiveMeshesEvaluationObservable.add(() => {
  67. Tools.EndPerformanceCounter("Active meshes evaluation");
  68. this._activeMeshesEvaluationTime.endMonitoring();
  69. });
  70. } else {
  71. this.scene.onBeforeActiveMeshesEvaluationObservable.remove(this._onBeforeActiveMeshesEvaluationObserver);
  72. this._onBeforeActiveMeshesEvaluationObserver = null;
  73. this.scene.onAfterActiveMeshesEvaluationObservable.remove(this._onAfterActiveMeshesEvaluationObserver);
  74. this._onAfterActiveMeshesEvaluationObserver = null;
  75. }
  76. }
  77. /**
  78. * Gets the perf counter used for render targets render time
  79. */
  80. public get renderTargetsRenderTimeCounter(): PerfCounter {
  81. return this._renderTargetsRenderTime;
  82. }
  83. /**
  84. * Gets the render targets render time capture status
  85. */
  86. public get captureRenderTargetsRenderTime(): boolean {
  87. return this._captureRenderTargetsRenderTime;
  88. }
  89. /**
  90. * Enable or disable the render targets render time capture
  91. */
  92. public set captureRenderTargetsRenderTime(value: boolean) {
  93. if (value === this._captureRenderTargetsRenderTime) {
  94. return;
  95. }
  96. this._captureRenderTargetsRenderTime = value;
  97. if (value) {
  98. this._onBeforeRenderTargetsRenderObserver = this.scene.onBeforeRenderTargetsRenderObservable.add(() => {
  99. Tools.StartPerformanceCounter("Render targets rendering");
  100. this._renderTargetsRenderTime.beginMonitoring();
  101. });
  102. this._onAfterRenderTargetsRenderObserver = this.scene.onAfterRenderTargetsRenderObservable.add(() => {
  103. Tools.EndPerformanceCounter("Render targets rendering");
  104. this._renderTargetsRenderTime.endMonitoring(false);
  105. });
  106. } else {
  107. this.scene.onBeforeRenderTargetsRenderObservable.remove(this._onBeforeRenderTargetsRenderObserver);
  108. this._onBeforeRenderTargetsRenderObserver = null;
  109. this.scene.onAfterRenderTargetsRenderObservable.remove(this._onAfterRenderTargetsRenderObserver);
  110. this._onAfterRenderTargetsRenderObserver = null;
  111. }
  112. }
  113. /**
  114. * Gets the perf counter used for particles render time
  115. */
  116. public get particlesRenderTimeCounter(): PerfCounter {
  117. return this._particlesRenderTime;
  118. }
  119. /**
  120. * Gets the particles render time capture status
  121. */
  122. public get captureParticlesRenderTime(): boolean {
  123. return this._captureParticlesRenderTime;
  124. }
  125. /**
  126. * Enable or disable the particles render time capture
  127. */
  128. public set captureParticlesRenderTime(value: boolean) {
  129. if (value === this._captureParticlesRenderTime) {
  130. return;
  131. }
  132. this._captureParticlesRenderTime = value;
  133. if (value) {
  134. this._onBeforeParticlesRenderingObserver = this.scene.onBeforeParticlesRenderingObservable.add(() => {
  135. Tools.StartPerformanceCounter("Particles");
  136. this._particlesRenderTime.beginMonitoring();
  137. });
  138. this._onAfterParticlesRenderingObserver = this.scene.onAfterParticlesRenderingObservable.add(() => {
  139. Tools.EndPerformanceCounter("Particles");
  140. this._particlesRenderTime.endMonitoring(false);
  141. });
  142. } else {
  143. this.scene.onBeforeParticlesRenderingObservable.remove(this._onBeforeParticlesRenderingObserver);
  144. this._onBeforeParticlesRenderingObserver = null;
  145. this.scene.onAfterParticlesRenderingObservable.remove(this._onAfterParticlesRenderingObserver);
  146. this._onAfterParticlesRenderingObserver = null;
  147. }
  148. }
  149. /**
  150. * Gets the perf counter used for sprites render time
  151. */
  152. public get spritesRenderTimeCounter(): PerfCounter {
  153. return this._spritesRenderTime;
  154. }
  155. /**
  156. * Gets the sprites render time capture status
  157. */
  158. public get captureSpritesRenderTime(): boolean {
  159. return this._captureSpritesRenderTime;
  160. }
  161. /**
  162. * Enable or disable the sprites render time capture
  163. */
  164. public set captureSpritesRenderTime(value: boolean) {
  165. if (value === this._captureSpritesRenderTime) {
  166. return;
  167. }
  168. this._captureSpritesRenderTime = value;
  169. if (value) {
  170. this._onBeforeSpritesRenderingObserver = this.scene.onBeforeSpritesRenderingObservable.add(() => {
  171. Tools.StartPerformanceCounter("Sprites");
  172. this._spritesRenderTime.beginMonitoring();
  173. });
  174. this._onAfterSpritesRenderingObserver = this.scene.onAfterSpritesRenderingObservable.add(() => {
  175. Tools.EndPerformanceCounter("Sprites");
  176. this._spritesRenderTime.endMonitoring(false);
  177. });
  178. } else {
  179. this.scene.onBeforeSpritesRenderingObservable.remove(this._onBeforeSpritesRenderingObserver);
  180. this._onBeforeSpritesRenderingObserver = null;
  181. this.scene.onAfterSpritesRenderingObservable.remove(this._onAfterSpritesRenderingObserver);
  182. this._onAfterSpritesRenderingObserver = null;
  183. }
  184. }
  185. /**
  186. * Gets the perf counter used for physics time
  187. */
  188. public get physicsTimeCounter(): PerfCounter {
  189. return this._physicsTime;
  190. }
  191. /**
  192. * Gets the physics time capture status
  193. */
  194. public get capturePhysicsTime(): boolean {
  195. return this._capturePhysicsTime;
  196. }
  197. /**
  198. * Enable or disable the physics time capture
  199. */
  200. public set capturePhysicsTime(value: boolean) {
  201. if (value === this._capturePhysicsTime) {
  202. return;
  203. }
  204. this._capturePhysicsTime = value;
  205. if (value) {
  206. this._onBeforePhysicsObserver = this.scene.onBeforePhysicsObservable.add(() => {
  207. Tools.StartPerformanceCounter("Physics");
  208. this._physicsTime.beginMonitoring();
  209. });
  210. this._onAfterPhysicsObserver = this.scene.onAfterPhysicsObservable.add(() => {
  211. Tools.EndPerformanceCounter("Physics");
  212. this._physicsTime.endMonitoring();
  213. });
  214. } else {
  215. this.scene.onBeforePhysicsObservable.remove(this._onBeforePhysicsObserver);
  216. this._onBeforePhysicsObserver = null;
  217. this.scene.onAfterPhysicsObservable.remove(this._onAfterPhysicsObserver);
  218. this._onAfterPhysicsObserver = null;
  219. }
  220. }
  221. /**
  222. * Gets the perf counter used for animations time
  223. */
  224. public get animationsTimeCounter(): PerfCounter {
  225. return this._animationsTime;
  226. }
  227. /**
  228. * Gets the animations time capture status
  229. */
  230. public get captureAnimationsTime(): boolean {
  231. return this._captureAnimationsTime;
  232. }
  233. /**
  234. * Enable or disable the animations time capture
  235. */
  236. public set captureAnimationsTime(value: boolean) {
  237. if (value === this._captureAnimationsTime) {
  238. return;
  239. }
  240. this._captureAnimationsTime = value;
  241. if (value) {
  242. this._onAfterAnimationsObserver = this.scene.onAfterAnimationsObservable.add(() => {
  243. this._animationsTime.endMonitoring();
  244. });
  245. } else {
  246. this.scene.onAfterAnimationsObservable.remove(this._onAfterAnimationsObserver);
  247. this._onAfterAnimationsObserver = null;
  248. }
  249. }
  250. /**
  251. * Gets the perf counter used for frame time capture
  252. */
  253. public get frameTimeCounter(): PerfCounter {
  254. return this._frameTime;
  255. }
  256. /**
  257. * Gets the frame time capture status
  258. */
  259. public get captureFrameTime(): boolean {
  260. return this._captureFrameTime;
  261. }
  262. /**
  263. * Enable or disable the frame time capture
  264. */
  265. public set captureFrameTime(value: boolean) {
  266. this._captureFrameTime = value;
  267. }
  268. /**
  269. * Gets the perf counter used for inter-frames time capture
  270. */
  271. public get interFrameTimeCounter(): PerfCounter {
  272. return this._interFrameTime;
  273. }
  274. /**
  275. * Gets the inter-frames time capture status
  276. */
  277. public get captureInterFrameTime(): boolean {
  278. return this._captureInterFrameTime;
  279. }
  280. /**
  281. * Enable or disable the inter-frames time capture
  282. */
  283. public set captureInterFrameTime(value: boolean) {
  284. this._captureInterFrameTime = value;
  285. }
  286. /**
  287. * Gets the perf counter used for render time capture
  288. */
  289. public get renderTimeCounter(): PerfCounter {
  290. return this._renderTime;
  291. }
  292. /**
  293. * Gets the render time capture status
  294. */
  295. public get captureRenderTime(): boolean {
  296. return this._captureRenderTime;
  297. }
  298. /**
  299. * Enable or disable the render time capture
  300. */
  301. public set captureRenderTime(value: boolean) {
  302. if (value === this._captureRenderTime) {
  303. return;
  304. }
  305. this._captureRenderTime = value;
  306. if (value) {
  307. this._onBeforeDrawPhaseObserver = this.scene.onBeforeDrawPhaseObservable.add(() => {
  308. this._renderTime.beginMonitoring();
  309. Tools.StartPerformanceCounter("Main render");
  310. });
  311. this._onAfterDrawPhaseObserver = this.scene.onAfterDrawPhaseObservable.add(() => {
  312. this._renderTime.endMonitoring(false);
  313. Tools.EndPerformanceCounter("Main render");
  314. });
  315. } else {
  316. this.scene.onBeforeDrawPhaseObservable.remove(this._onBeforeDrawPhaseObserver);
  317. this._onBeforeDrawPhaseObserver = null;
  318. this.scene.onAfterDrawPhaseObservable.remove(this._onAfterDrawPhaseObserver);
  319. this._onAfterDrawPhaseObserver = null;
  320. }
  321. }
  322. /**
  323. * Gets the perf counter used for draw calls
  324. */
  325. public get drawCallsCounter(): PerfCounter {
  326. return this.scene.getEngine()._drawCalls;
  327. }
  328. /**
  329. * Gets the perf counter used for texture collisions
  330. */
  331. public get textureCollisionsCounter(): PerfCounter {
  332. return this.scene.getEngine()._textureCollisions;
  333. }
  334. public constructor(public scene: Scene) {
  335. // Before render
  336. this._onBeforeAnimationsObserver = scene.onBeforeAnimationsObservable.add(() => {
  337. if (this._captureActiveMeshesEvaluationTime) {
  338. this._activeMeshesEvaluationTime.fetchNewFrame();
  339. }
  340. if (this._captureRenderTargetsRenderTime) {
  341. this._renderTargetsRenderTime.fetchNewFrame();
  342. }
  343. if (this._captureFrameTime) {
  344. Tools.StartPerformanceCounter("Scene rendering");
  345. this._frameTime.beginMonitoring();
  346. }
  347. if (this._captureInterFrameTime) {
  348. this._interFrameTime.endMonitoring();
  349. }
  350. if (this._captureParticlesRenderTime) {
  351. this._particlesRenderTime.fetchNewFrame();
  352. }
  353. if (this._captureSpritesRenderTime) {
  354. this._spritesRenderTime.fetchNewFrame();
  355. }
  356. if (this._captureAnimationsTime) {
  357. this._animationsTime.beginMonitoring();
  358. }
  359. this.scene.getEngine()._drawCalls.fetchNewFrame();
  360. this.scene.getEngine()._textureCollisions.fetchNewFrame();
  361. });
  362. // After render
  363. this._onAfterRenderObserver = scene.onAfterRenderObservable.add(() => {
  364. if (this._captureFrameTime) {
  365. Tools.EndPerformanceCounter("Scene rendering");
  366. this._frameTime.endMonitoring();
  367. }
  368. if (this._captureRenderTime) {
  369. this._renderTime.endMonitoring(false);
  370. }
  371. if (this._captureInterFrameTime) {
  372. this._interFrameTime.beginMonitoring();
  373. }
  374. });
  375. }
  376. public dispose() {
  377. this.scene.onAfterRenderObservable.remove(this._onAfterRenderObserver);
  378. this._onAfterRenderObserver = null;
  379. this.scene.onBeforeActiveMeshesEvaluationObservable.remove(this._onBeforeActiveMeshesEvaluationObserver);
  380. this._onBeforeActiveMeshesEvaluationObserver = null;
  381. this.scene.onAfterActiveMeshesEvaluationObservable.remove(this._onAfterActiveMeshesEvaluationObserver);
  382. this._onAfterActiveMeshesEvaluationObserver = null;
  383. this.scene.onBeforeRenderTargetsRenderObservable.remove(this._onBeforeRenderTargetsRenderObserver);
  384. this._onBeforeRenderTargetsRenderObserver = null;
  385. this.scene.onAfterRenderTargetsRenderObservable.remove(this._onAfterRenderTargetsRenderObserver);
  386. this._onAfterRenderTargetsRenderObserver = null;
  387. this.scene.onBeforeAnimationsObservable.remove(this._onBeforeAnimationsObserver);
  388. this._onBeforeAnimationsObserver = null;
  389. this.scene.onBeforeParticlesRenderingObservable.remove(this._onBeforeParticlesRenderingObserver);
  390. this._onBeforeParticlesRenderingObserver = null;
  391. this.scene.onAfterParticlesRenderingObservable.remove(this._onAfterParticlesRenderingObserver);
  392. this._onAfterParticlesRenderingObserver = null;
  393. this.scene.onBeforeSpritesRenderingObservable.remove(this._onBeforeSpritesRenderingObserver);
  394. this._onBeforeSpritesRenderingObserver = null;
  395. this.scene.onAfterSpritesRenderingObservable.remove(this._onAfterSpritesRenderingObserver);
  396. this._onAfterSpritesRenderingObserver = null;
  397. this.scene.onBeforeDrawPhaseObservable.remove(this._onBeforeDrawPhaseObserver);
  398. this._onBeforeDrawPhaseObserver = null;
  399. this.scene.onAfterDrawPhaseObservable.remove(this._onAfterDrawPhaseObserver);
  400. this._onAfterDrawPhaseObserver = null;
  401. this.scene.onBeforePhysicsObservable.remove(this._onBeforePhysicsObserver);
  402. this._onBeforePhysicsObserver = null;
  403. this.scene.onAfterPhysicsObservable.remove(this._onAfterPhysicsObserver);
  404. this._onAfterPhysicsObserver = null;
  405. this.scene.onAfterAnimationsObservable.remove(this._onAfterAnimationsObserver);
  406. this._onAfterAnimationsObserver = null;
  407. (<any>this.scene) = null;
  408. }
  409. }
  410. }