import AssociativeArray from "../../Core/AssociativeArray.js"; import Check from "../../Core/Check.js"; /** * Rendering statistics for a single model. * * @alias ModelStatistics * @constructor * * @see Cesium3DTilesetStatistics * * @private */ function ModelStatistics() { /** * Total number of points across all POINTS primitives in this model. * * @type {number} * @private */ this.pointsLength = 0; /** * Total number of triangles across all TRIANGLES, TRIANGLE_STRIP or * TRIANGLE_FAN primitives in this model. * * @type {number} * @private */ this.trianglesLength = 0; /** * Total size of all geometry buffers in bytes. This accounts for the vertex * attributes (which includes feature IDs and property attributes) and index * buffers of all the model's primitives. Any attributes generated by the * pipeline are included in this total. * * @type {number} * @private */ this.geometryByteLength = 0; /** * Total size of all textures in bytes. This includes materials, * feature ID textures, and property textures. * * @type {number} * @private */ this.texturesByteLength = 0; /** * Total size of property tables. This excludes the batch textures used for * picking and styling. * * @type {number} * @private */ this.propertyTablesByteLength = 0; // Sets of buffers and textures that have already been counted. // This is to prevent double-counting cached assets. this._bufferIdSet = {}; this._textureIdSet = {}; // Associated array of batch textures that have already been counted. // This allows for quick look-up to check if a texture has been counted, // while also allowing for dynamic texture counting. this._batchTextureIdMap = new AssociativeArray(); } Object.defineProperties(ModelStatistics.prototype, { /** * Total size of the batch textures used for picking and styling. * Batch textures are created asynchronously, so this iterates * over the textures to ensure their memory values are accurate. * * @memberof ModelStatistics.prototype * * @type {number} * @readonly * * @private */ batchTexturesByteLength: { get: function () { const length = this._batchTextureIdMap.length; const values = this._batchTextureIdMap.values; let memory = 0; for (let i = 0; i < length; i++) { memory += values[i].byteLength; } return memory; }, }, }); /** * Reset the memory counts for this model. This should be called each time the * draw command pipeline is rebuilt. * * @private */ ModelStatistics.prototype.clear = function () { this.pointsLength = 0; this.trianglesLength = 0; this.geometryByteLength = 0; this.texturesByteLength = 0; this.propertyTablesByteLength = 0; this._bufferIdSet = {}; this._textureIdSet = {}; this._batchTextureIdMap.removeAll(); }; /** * Counts the given buffer's memory in bytes. If a buffer has * already been counted by these statistics, it will not be * counted again. * * @param {Buffer} buffer The GPU buffer associated with the model. * @param {boolean} hasCpuCopy Whether the buffer has a copy on the CPU via typed array. * * @private */ ModelStatistics.prototype.addBuffer = function (buffer, hasCpuCopy) { //>>includeStart('debug', pragmas.debug); Check.typeOf.object("buffer", buffer); Check.typeOf.bool("hasCpuCopy", hasCpuCopy); //>>includeEnd('debug'); if (!this._bufferIdSet.hasOwnProperty(buffer._id)) { // If there's a CPU copy, count the memory twice. const copies = hasCpuCopy ? 2 : 1; this.geometryByteLength += buffer.sizeInBytes * copies; } // Simulate set insertion. this._bufferIdSet[buffer._id] = true; }; /** * Counts the given texture's memory in bytes. If a texture has * already been counted by these statistics, it will not be * counted again. *

* This is used to count the materials and property textures of * a model. Batch textures function differently and are counted * using addBatchTexture instead. *

* * @param {Texture} texture The texture associated with the model. * * @private */ ModelStatistics.prototype.addTexture = function (texture) { //>>includeStart('debug', pragmas.debug); Check.typeOf.object("texture", texture); //>>includeEnd('debug'); if (!this._textureIdSet.hasOwnProperty(texture._id)) { this.texturesByteLength += texture.sizeInBytes; } // Simulate set insertion. this._textureIdSet[texture._id] = true; }; /** * Counts the batch texture's memory in bytes. If a batch texture * has already been counted by these statistics, it will not be * counted again. *

* Batch textures are handled differently than other textures. They * include the batch and pick textures for the feature table, which * are created dynamically. As such, they may not have both textures * loaded by the time they are added to the statistics. Their memory * will thus be counted dynamically. *

* * @param {BatchTexture} batchTexture The batch texture associated with the model. * * @private */ ModelStatistics.prototype.addBatchTexture = function (batchTexture) { //>>includeStart('debug', pragmas.debug); Check.typeOf.object("batchTexture", batchTexture); //>>includeEnd('debug'); if (!this._batchTextureIdMap.contains(batchTexture._id)) { this._batchTextureIdMap.set(batchTexture._id, batchTexture); } }; export default ModelStatistics;