ModelStatistics.js 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. import AssociativeArray from "../../Core/AssociativeArray.js";
  2. import Check from "../../Core/Check.js";
  3. /**
  4. * Rendering statistics for a single model.
  5. *
  6. * @alias ModelStatistics
  7. * @constructor
  8. *
  9. * @see Cesium3DTilesetStatistics
  10. *
  11. * @private
  12. */
  13. function ModelStatistics() {
  14. /**
  15. * Total number of points across all POINTS primitives in this model.
  16. *
  17. * @type {number}
  18. * @private
  19. */
  20. this.pointsLength = 0;
  21. /**
  22. * Total number of triangles across all TRIANGLES, TRIANGLE_STRIP or
  23. * TRIANGLE_FAN primitives in this model.
  24. *
  25. * @type {number}
  26. * @private
  27. */
  28. this.trianglesLength = 0;
  29. /**
  30. * Total size of all geometry buffers in bytes. This accounts for the vertex
  31. * attributes (which includes feature IDs and property attributes) and index
  32. * buffers of all the model's primitives. Any attributes generated by the
  33. * pipeline are included in this total.
  34. *
  35. * @type {number}
  36. * @private
  37. */
  38. this.geometryByteLength = 0;
  39. /**
  40. * Total size of all textures in bytes. This includes materials,
  41. * feature ID textures, and property textures.
  42. *
  43. * @type {number}
  44. * @private
  45. */
  46. this.texturesByteLength = 0;
  47. /**
  48. * Total size of property tables. This excludes the batch textures used for
  49. * picking and styling.
  50. *
  51. * @type {number}
  52. * @private
  53. */
  54. this.propertyTablesByteLength = 0;
  55. // Sets of buffers and textures that have already been counted.
  56. // This is to prevent double-counting cached assets.
  57. this._bufferIdSet = {};
  58. this._textureIdSet = {};
  59. // Associated array of batch textures that have already been counted.
  60. // This allows for quick look-up to check if a texture has been counted,
  61. // while also allowing for dynamic texture counting.
  62. this._batchTextureIdMap = new AssociativeArray();
  63. }
  64. Object.defineProperties(ModelStatistics.prototype, {
  65. /**
  66. * Total size of the batch textures used for picking and styling.
  67. * Batch textures are created asynchronously, so this iterates
  68. * over the textures to ensure their memory values are accurate.
  69. *
  70. * @memberof ModelStatistics.prototype
  71. *
  72. * @type {number}
  73. * @readonly
  74. *
  75. * @private
  76. */
  77. batchTexturesByteLength: {
  78. get: function () {
  79. const length = this._batchTextureIdMap.length;
  80. const values = this._batchTextureIdMap.values;
  81. let memory = 0;
  82. for (let i = 0; i < length; i++) {
  83. memory += values[i].byteLength;
  84. }
  85. return memory;
  86. },
  87. },
  88. });
  89. /**
  90. * Reset the memory counts for this model. This should be called each time the
  91. * draw command pipeline is rebuilt.
  92. *
  93. * @private
  94. */
  95. ModelStatistics.prototype.clear = function () {
  96. this.pointsLength = 0;
  97. this.trianglesLength = 0;
  98. this.geometryByteLength = 0;
  99. this.texturesByteLength = 0;
  100. this.propertyTablesByteLength = 0;
  101. this._bufferIdSet = {};
  102. this._textureIdSet = {};
  103. this._batchTextureIdMap.removeAll();
  104. };
  105. /**
  106. * Counts the given buffer's memory in bytes. If a buffer has
  107. * already been counted by these statistics, it will not be
  108. * counted again.
  109. *
  110. * @param {Buffer} buffer The GPU buffer associated with the model.
  111. * @param {boolean} hasCpuCopy Whether the buffer has a copy on the CPU via typed array.
  112. *
  113. * @private
  114. */
  115. ModelStatistics.prototype.addBuffer = function (buffer, hasCpuCopy) {
  116. //>>includeStart('debug', pragmas.debug);
  117. Check.typeOf.object("buffer", buffer);
  118. Check.typeOf.bool("hasCpuCopy", hasCpuCopy);
  119. //>>includeEnd('debug');
  120. if (!this._bufferIdSet.hasOwnProperty(buffer._id)) {
  121. // If there's a CPU copy, count the memory twice.
  122. const copies = hasCpuCopy ? 2 : 1;
  123. this.geometryByteLength += buffer.sizeInBytes * copies;
  124. }
  125. // Simulate set insertion.
  126. this._bufferIdSet[buffer._id] = true;
  127. };
  128. /**
  129. * Counts the given texture's memory in bytes. If a texture has
  130. * already been counted by these statistics, it will not be
  131. * counted again.
  132. * <p>
  133. * This is used to count the materials and property textures of
  134. * a model. Batch textures function differently and are counted
  135. * using <code>addBatchTexture</code> instead.
  136. * </p>
  137. *
  138. * @param {Texture} texture The texture associated with the model.
  139. *
  140. * @private
  141. */
  142. ModelStatistics.prototype.addTexture = function (texture) {
  143. //>>includeStart('debug', pragmas.debug);
  144. Check.typeOf.object("texture", texture);
  145. //>>includeEnd('debug');
  146. if (!this._textureIdSet.hasOwnProperty(texture._id)) {
  147. this.texturesByteLength += texture.sizeInBytes;
  148. }
  149. // Simulate set insertion.
  150. this._textureIdSet[texture._id] = true;
  151. };
  152. /**
  153. * Counts the batch texture's memory in bytes. If a batch texture
  154. * has already been counted by these statistics, it will not be
  155. * counted again.
  156. * <p>
  157. * Batch textures are handled differently than other textures. They
  158. * include the batch and pick textures for the feature table, which
  159. * are created dynamically. As such, they may not have both textures
  160. * loaded by the time they are added to the statistics. Their memory
  161. * will thus be counted dynamically.
  162. * </p>
  163. *
  164. * @param {BatchTexture} batchTexture The batch texture associated with the model.
  165. *
  166. * @private
  167. */
  168. ModelStatistics.prototype.addBatchTexture = function (batchTexture) {
  169. //>>includeStart('debug', pragmas.debug);
  170. Check.typeOf.object("batchTexture", batchTexture);
  171. //>>includeEnd('debug');
  172. if (!this._batchTextureIdMap.contains(batchTexture._id)) {
  173. this._batchTextureIdMap.set(batchTexture._id, batchTexture);
  174. }
  175. };
  176. export default ModelStatistics;