engineInstrumentation.ts 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. import { Observer } from "../Misc/observable";
  2. import { PerfCounter } from "../Misc/perfCounter";
  3. import { Nullable } from "../types";
  4. import { IDisposable } from "../scene";
  5. import { Engine } from "../Engines/engine";
  6. import { _TimeToken } from "../Instrumentation/timeToken";
  7. /**
  8. * This class can be used to get instrumentation data from a Babylon engine
  9. * @see https://doc.babylonjs.com/how_to/optimizing_your_scene#engineinstrumentation
  10. */
  11. export class EngineInstrumentation implements IDisposable {
  12. private _captureGPUFrameTime = false;
  13. private _gpuFrameTimeToken: Nullable<_TimeToken>;
  14. private _gpuFrameTime = new PerfCounter();
  15. private _captureShaderCompilationTime = false;
  16. private _shaderCompilationTime = new PerfCounter();
  17. // Observers
  18. private _onBeginFrameObserver: Nullable<Observer<Engine>> = null;
  19. private _onEndFrameObserver: Nullable<Observer<Engine>> = null;
  20. private _onBeforeShaderCompilationObserver: Nullable<Observer<Engine>> = null;
  21. private _onAfterShaderCompilationObserver: Nullable<Observer<Engine>> = null;
  22. // Properties
  23. /**
  24. * Gets the perf counter used for GPU frame time
  25. */
  26. public get gpuFrameTimeCounter(): PerfCounter {
  27. return this._gpuFrameTime;
  28. }
  29. /**
  30. * Gets the GPU frame time capture status
  31. */
  32. public get captureGPUFrameTime(): boolean {
  33. return this._captureGPUFrameTime;
  34. }
  35. /**
  36. * Enable or disable the GPU frame time capture
  37. */
  38. public set captureGPUFrameTime(value: boolean) {
  39. if (value === this._captureGPUFrameTime) {
  40. return;
  41. }
  42. this._captureGPUFrameTime = value;
  43. if (value) {
  44. this._onBeginFrameObserver = this.engine.onBeginFrameObservable.add(() => {
  45. if (!this._gpuFrameTimeToken) {
  46. this._gpuFrameTimeToken = this.engine.startTimeQuery();
  47. }
  48. });
  49. this._onEndFrameObserver = this.engine.onEndFrameObservable.add(() => {
  50. if (!this._gpuFrameTimeToken) {
  51. return;
  52. }
  53. let time = this.engine.endTimeQuery(this._gpuFrameTimeToken);
  54. if (time > -1) {
  55. this._gpuFrameTimeToken = null;
  56. this._gpuFrameTime.fetchNewFrame();
  57. this._gpuFrameTime.addCount(time, true);
  58. }
  59. });
  60. } else {
  61. this.engine.onBeginFrameObservable.remove(this._onBeginFrameObserver);
  62. this._onBeginFrameObserver = null;
  63. this.engine.onEndFrameObservable.remove(this._onEndFrameObserver);
  64. this._onEndFrameObserver = null;
  65. }
  66. }
  67. /**
  68. * Gets the perf counter used for shader compilation time
  69. */
  70. public get shaderCompilationTimeCounter(): PerfCounter {
  71. return this._shaderCompilationTime;
  72. }
  73. /**
  74. * Gets the shader compilation time capture status
  75. */
  76. public get captureShaderCompilationTime(): boolean {
  77. return this._captureShaderCompilationTime;
  78. }
  79. /**
  80. * Enable or disable the shader compilation time capture
  81. */
  82. public set captureShaderCompilationTime(value: boolean) {
  83. if (value === this._captureShaderCompilationTime) {
  84. return;
  85. }
  86. this._captureShaderCompilationTime = value;
  87. if (value) {
  88. this._onBeforeShaderCompilationObserver = this.engine.onBeforeShaderCompilationObservable.add(() => {
  89. this._shaderCompilationTime.fetchNewFrame();
  90. this._shaderCompilationTime.beginMonitoring();
  91. });
  92. this._onAfterShaderCompilationObserver = this.engine.onAfterShaderCompilationObservable.add(() => {
  93. this._shaderCompilationTime.endMonitoring();
  94. });
  95. } else {
  96. this.engine.onBeforeShaderCompilationObservable.remove(this._onBeforeShaderCompilationObserver);
  97. this._onBeforeShaderCompilationObserver = null;
  98. this.engine.onAfterShaderCompilationObservable.remove(this._onAfterShaderCompilationObserver);
  99. this._onAfterShaderCompilationObserver = null;
  100. }
  101. }
  102. /**
  103. * Instantiates a new engine instrumentation.
  104. * This class can be used to get instrumentation data from a Babylon engine
  105. * @see https://doc.babylonjs.com/how_to/optimizing_your_scene#engineinstrumentation
  106. * @param engine Defines the engine to instrument
  107. */
  108. public constructor(
  109. /**
  110. * Define the instrumented engine.
  111. */
  112. public engine: Engine) {
  113. }
  114. /**
  115. * Dispose and release associated resources.
  116. */
  117. public dispose() {
  118. this.engine.onBeginFrameObservable.remove(this._onBeginFrameObserver);
  119. this._onBeginFrameObserver = null;
  120. this.engine.onEndFrameObservable.remove(this._onEndFrameObserver);
  121. this._onEndFrameObserver = null;
  122. this.engine.onBeforeShaderCompilationObservable.remove(this._onBeforeShaderCompilationObserver);
  123. this._onBeforeShaderCompilationObserver = null;
  124. this.engine.onAfterShaderCompilationObservable.remove(this._onAfterShaderCompilationObserver);
  125. this._onAfterShaderCompilationObserver = null;
  126. (<any>this.engine) = null;
  127. }
  128. }