engine.query.js 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. import { Engine } from "../../Engines/engine.js";
  2. import { AbstractMesh } from "../../Meshes/abstractMesh.js";
  3. import { _TimeToken } from "../../Instrumentation/timeToken.js";
  4. import { PerfCounter } from "../../Misc/perfCounter.js";
  5. import "../AbstractEngine/abstractEngine.query.js";
  6. Engine.prototype.createQuery = function () {
  7. const query = this._gl.createQuery();
  8. if (!query) {
  9. throw new Error("Unable to create Occlusion Query");
  10. }
  11. return query;
  12. };
  13. Engine.prototype.deleteQuery = function (query) {
  14. this._gl.deleteQuery(query);
  15. return this;
  16. };
  17. Engine.prototype.isQueryResultAvailable = function (query) {
  18. return this._gl.getQueryParameter(query, this._gl.QUERY_RESULT_AVAILABLE);
  19. };
  20. Engine.prototype.getQueryResult = function (query) {
  21. return this._gl.getQueryParameter(query, this._gl.QUERY_RESULT);
  22. };
  23. Engine.prototype.beginOcclusionQuery = function (algorithmType, query) {
  24. const glAlgorithm = this._getGlAlgorithmType(algorithmType);
  25. this._gl.beginQuery(glAlgorithm, query);
  26. return true;
  27. };
  28. Engine.prototype.endOcclusionQuery = function (algorithmType) {
  29. const glAlgorithm = this._getGlAlgorithmType(algorithmType);
  30. this._gl.endQuery(glAlgorithm);
  31. return this;
  32. };
  33. Engine.prototype._createTimeQuery = function () {
  34. const timerQuery = this.getCaps().timerQuery;
  35. if (timerQuery.createQueryEXT) {
  36. return timerQuery.createQueryEXT();
  37. }
  38. return this.createQuery();
  39. };
  40. Engine.prototype._deleteTimeQuery = function (query) {
  41. const timerQuery = this.getCaps().timerQuery;
  42. if (timerQuery.deleteQueryEXT) {
  43. timerQuery.deleteQueryEXT(query);
  44. return;
  45. }
  46. this.deleteQuery(query);
  47. };
  48. Engine.prototype._getTimeQueryResult = function (query) {
  49. const timerQuery = this.getCaps().timerQuery;
  50. if (timerQuery.getQueryObjectEXT) {
  51. return timerQuery.getQueryObjectEXT(query, timerQuery.QUERY_RESULT_EXT);
  52. }
  53. return this.getQueryResult(query);
  54. };
  55. Engine.prototype._getTimeQueryAvailability = function (query) {
  56. const timerQuery = this.getCaps().timerQuery;
  57. if (timerQuery.getQueryObjectEXT) {
  58. return timerQuery.getQueryObjectEXT(query, timerQuery.QUERY_RESULT_AVAILABLE_EXT);
  59. }
  60. return this.isQueryResultAvailable(query);
  61. };
  62. Engine.prototype.startTimeQuery = function () {
  63. const caps = this.getCaps();
  64. const timerQuery = caps.timerQuery;
  65. if (!timerQuery) {
  66. return null;
  67. }
  68. const token = new _TimeToken();
  69. this._gl.getParameter(timerQuery.GPU_DISJOINT_EXT);
  70. if (caps.canUseTimestampForTimerQuery) {
  71. token._startTimeQuery = this._createTimeQuery();
  72. if (token._startTimeQuery) {
  73. timerQuery.queryCounterEXT(token._startTimeQuery, timerQuery.TIMESTAMP_EXT);
  74. }
  75. }
  76. else {
  77. if (this._currentNonTimestampToken) {
  78. return this._currentNonTimestampToken;
  79. }
  80. token._timeElapsedQuery = this._createTimeQuery();
  81. if (token._timeElapsedQuery) {
  82. if (timerQuery.beginQueryEXT) {
  83. timerQuery.beginQueryEXT(timerQuery.TIME_ELAPSED_EXT, token._timeElapsedQuery);
  84. }
  85. else {
  86. this._gl.beginQuery(timerQuery.TIME_ELAPSED_EXT, token._timeElapsedQuery);
  87. }
  88. }
  89. this._currentNonTimestampToken = token;
  90. }
  91. return token;
  92. };
  93. Engine.prototype.endTimeQuery = function (token) {
  94. const caps = this.getCaps();
  95. const timerQuery = caps.timerQuery;
  96. if (!timerQuery || !token) {
  97. return -1;
  98. }
  99. if (caps.canUseTimestampForTimerQuery) {
  100. if (!token._startTimeQuery) {
  101. return -1;
  102. }
  103. if (!token._endTimeQuery) {
  104. token._endTimeQuery = this._createTimeQuery();
  105. if (token._endTimeQuery) {
  106. timerQuery.queryCounterEXT(token._endTimeQuery, timerQuery.TIMESTAMP_EXT);
  107. }
  108. }
  109. }
  110. else if (!token._timeElapsedQueryEnded) {
  111. if (!token._timeElapsedQuery) {
  112. return -1;
  113. }
  114. if (timerQuery.endQueryEXT) {
  115. timerQuery.endQueryEXT(timerQuery.TIME_ELAPSED_EXT);
  116. }
  117. else {
  118. this._gl.endQuery(timerQuery.TIME_ELAPSED_EXT);
  119. this._currentNonTimestampToken = null;
  120. }
  121. token._timeElapsedQueryEnded = true;
  122. }
  123. const disjoint = this._gl.getParameter(timerQuery.GPU_DISJOINT_EXT);
  124. let available = false;
  125. if (token._endTimeQuery) {
  126. available = this._getTimeQueryAvailability(token._endTimeQuery);
  127. }
  128. else if (token._timeElapsedQuery) {
  129. available = this._getTimeQueryAvailability(token._timeElapsedQuery);
  130. }
  131. if (available && !disjoint) {
  132. let result = 0;
  133. if (caps.canUseTimestampForTimerQuery) {
  134. if (!token._startTimeQuery || !token._endTimeQuery) {
  135. return -1;
  136. }
  137. const timeStart = this._getTimeQueryResult(token._startTimeQuery);
  138. const timeEnd = this._getTimeQueryResult(token._endTimeQuery);
  139. result = timeEnd - timeStart;
  140. this._deleteTimeQuery(token._startTimeQuery);
  141. this._deleteTimeQuery(token._endTimeQuery);
  142. token._startTimeQuery = null;
  143. token._endTimeQuery = null;
  144. }
  145. else {
  146. if (!token._timeElapsedQuery) {
  147. return -1;
  148. }
  149. result = this._getTimeQueryResult(token._timeElapsedQuery);
  150. this._deleteTimeQuery(token._timeElapsedQuery);
  151. token._timeElapsedQuery = null;
  152. token._timeElapsedQueryEnded = false;
  153. }
  154. return result;
  155. }
  156. return -1;
  157. };
  158. Engine.prototype._captureGPUFrameTime = false;
  159. Engine.prototype._gpuFrameTime = new PerfCounter();
  160. Engine.prototype.getGPUFrameTimeCounter = function () {
  161. return this._gpuFrameTime;
  162. };
  163. Engine.prototype.captureGPUFrameTime = function (value) {
  164. if (value === this._captureGPUFrameTime) {
  165. return;
  166. }
  167. this._captureGPUFrameTime = value;
  168. if (value) {
  169. this._onBeginFrameObserver = this.onBeginFrameObservable.add(() => {
  170. if (!this._gpuFrameTimeToken) {
  171. this._gpuFrameTimeToken = this.startTimeQuery();
  172. }
  173. });
  174. this._onEndFrameObserver = this.onEndFrameObservable.add(() => {
  175. if (!this._gpuFrameTimeToken) {
  176. return;
  177. }
  178. const time = this.endTimeQuery(this._gpuFrameTimeToken);
  179. if (time > -1) {
  180. this._gpuFrameTimeToken = null;
  181. this._gpuFrameTime.fetchNewFrame();
  182. this._gpuFrameTime.addCount(time, true);
  183. }
  184. });
  185. }
  186. else {
  187. this.onBeginFrameObservable.remove(this._onBeginFrameObserver);
  188. this._onBeginFrameObserver = null;
  189. this.onEndFrameObservable.remove(this._onEndFrameObserver);
  190. this._onEndFrameObserver = null;
  191. }
  192. };
  193. Engine.prototype._getGlAlgorithmType = function (algorithmType) {
  194. return algorithmType === AbstractMesh.OCCLUSION_ALGORITHM_TYPE_CONSERVATIVE ? this._gl.ANY_SAMPLES_PASSED_CONSERVATIVE : this._gl.ANY_SAMPLES_PASSED;
  195. };
  196. //# sourceMappingURL=engine.query.js.map