Skip to content

Commit

Permalink
Merge pull request #10397 from CesiumGS/model-experimental-statistics
Browse files Browse the repository at this point in the history
Add basic memory statistics in ModelExperimental
  • Loading branch information
j9liu authored Jun 7, 2022
2 parents 4eee06f + 9ec6d24 commit b70e22d
Show file tree
Hide file tree
Showing 56 changed files with 1,917 additions and 232 deletions.
5 changes: 5 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@

### 1.95 - 2022-07-01

##### Additions :tada:

- Memory statistics for `ModelExperimental` now appear in the `Cesium3DTilesInspector`. This includes binary metadata memory, which is not counted by `Model`. [#10397](https://github.com/CesiumGS/cesium/pull/10397)
- Added support for rendering individual models in 2D / CV using `ModelExperimental`. [#10419](https://github.com/CesiumGS/cesium/pull/10419)

##### Fixes :wrench:

- Fixed `FeatureDetection` for Microsoft Edge. [#10429](https://github.com/CesiumGS/cesium/pull/10429)
Expand Down
2 changes: 2 additions & 0 deletions Source/Renderer/Buffer.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import Check from "../Core/Check.js";
import createGuid from "../Core/createGuid.js";
import defaultValue from "../Core/defaultValue.js";
import defined from "../Core/defined.js";
import destroyObject from "../Core/destroyObject.js";
Expand Down Expand Up @@ -61,6 +62,7 @@ function Buffer(options) {
gl.bufferData(bufferTarget, hasArray ? typedArray : sizeInBytes, usage);
gl.bindBuffer(bufferTarget, null);

this._id = createGuid();
this._gl = gl;
this._webgl2 = options.context._webgl2;
this._bufferTarget = bufferTarget;
Expand Down
31 changes: 31 additions & 0 deletions Source/Scene/BatchTableHierarchy.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ export default function BatchTableHierarchy(options) {
this._parentIndexes = undefined;
this._parentIds = undefined;

// Total memory used by the typed arrays
this._byteLength = 0;

//>>includeStart('debug', pragmas.debug);
Check.typeOf.object("options.extension", options.extension);
//>>includeEnd('debug');
Expand All @@ -41,6 +44,14 @@ export default function BatchTableHierarchy(options) {
//>>includeEnd('debug');
}

Object.defineProperties(BatchTableHierarchy.prototype, {
byteLength: {
get: function () {
return this._byteLength;
},
},
});

/**
* Parse the batch table hierarchy from the
* <code>3DTILES_batch_table_hierarchy</code> extension.
Expand All @@ -61,6 +72,7 @@ function initialize(hierarchy, hierarchyJson, binaryBody) {
let parentCounts = hierarchyJson.parentCounts;
let parentIds = hierarchyJson.parentIds;
let parentIdsLength = instancesLength;
let byteLength = 0;

if (defined(classIds.byteOffset)) {
classIds.componentType = defaultValue(
Expand All @@ -74,6 +86,7 @@ function initialize(hierarchy, hierarchyJson, binaryBody) {
binaryBody.byteOffset + classIds.byteOffset,
instancesLength
);
byteLength += classIds.byteLength;
}

let parentIndexes;
Expand All @@ -90,13 +103,16 @@ function initialize(hierarchy, hierarchyJson, binaryBody) {
binaryBody.byteOffset + parentCounts.byteOffset,
instancesLength
);
byteLength += parentCounts.byteLength;
}
parentIndexes = new Uint16Array(instancesLength);
parentIdsLength = 0;
for (i = 0; i < instancesLength; ++i) {
parentIndexes[i] = parentIdsLength;
parentIdsLength += parentCounts[i];
}

byteLength += parentIndexes.byteLength;
}

if (defined(parentIds) && defined(parentIds.byteOffset)) {
Expand All @@ -111,6 +127,8 @@ function initialize(hierarchy, hierarchyJson, binaryBody) {
binaryBody.byteOffset + parentIds.byteOffset,
parentIdsLength
);

byteLength += parentIds.byteLength;
}

const classesLength = classes.length;
Expand All @@ -122,6 +140,7 @@ function initialize(hierarchy, hierarchyJson, binaryBody) {
properties,
binaryBody
);
byteLength += countBinaryPropertyMemory(binaryProperties);
classes[i].instances = combine(binaryProperties, properties);
}

Expand All @@ -132,13 +151,15 @@ function initialize(hierarchy, hierarchyJson, binaryBody) {
classIndexes[i] = classCounts[classId];
++classCounts[classId];
}
byteLength += classIndexes.byteLength;

hierarchy._classes = classes;
hierarchy._classIds = classIds;
hierarchy._classIndexes = classIndexes;
hierarchy._parentCounts = parentCounts;
hierarchy._parentIndexes = parentIndexes;
hierarchy._parentIds = parentIds;
hierarchy._byteLength = byteLength;
}

function getBinaryProperties(featuresLength, properties, binaryBody) {
Expand Down Expand Up @@ -189,6 +210,16 @@ function getBinaryProperties(featuresLength, properties, binaryBody) {
return binaryProperties;
}

function countBinaryPropertyMemory(binaryProperties) {
let byteLength = 0;
for (const name in binaryProperties) {
if (binaryProperties.hasOwnProperty(name)) {
byteLength += binaryProperties[name].typedArray.byteLength;
}
}
return byteLength;
}

//>>includeStart('debug', pragmas.debug);
const scratchValidateStack = [];
function validateHierarchy(hierarchy) {
Expand Down
8 changes: 7 additions & 1 deletion Source/Scene/BatchTexture.js
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ Object.defineProperties(BatchTexture.prototype, {
* @readonly
* @private
*/
memorySizeInBytes: {
byteLength: {
get: function () {
let memory = 0;
if (defined(this._pickTexture)) {
Expand Down Expand Up @@ -475,6 +475,9 @@ function createPickTexture(batchTexture, context) {
}

batchTexture._pickTexture = createTexture(batchTexture, context, bytes);

// Make sure the tileset statistics are updated the frame when the pick
// texture is created.
if (defined(statistics)) {
statistics.batchTableByteLength += batchTexture._pickTexture.sizeInBytes;
}
Expand Down Expand Up @@ -510,6 +513,9 @@ BatchTexture.prototype.update = function (tileset, frameState) {
// Create batch texture on-demand
if (!defined(this._batchTexture)) {
this._batchTexture = createTexture(this, context, this._batchValues);

// Make sure the tileset statistics are updated the frame when the
// batch texture is created.
if (defined(this._statistics)) {
this._statistics.batchTableByteLength += this._batchTexture.sizeInBytes;
}
Expand Down
2 changes: 1 addition & 1 deletion Source/Scene/Batched3DModel3DTileContent.js
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ Object.defineProperties(Batched3DModel3DTileContent.prototype, {

batchTableByteLength: {
get: function () {
return this.batchTable.memorySizeInBytes;
return this.batchTable.batchTableByteLength;
},
},

Expand Down
42 changes: 39 additions & 3 deletions Source/Scene/Cesium3DTileBatchTable.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,16 @@ function Cesium3DTileBatchTable(
batchTableJson,
batchTableBinary
);
this._batchTableBinaryProperties = getBinaryProperties(

const binaryProperties = getBinaryProperties(
featuresLength,
properties,
batchTableBinary
);
this._binaryPropertiesByteLength = countBinaryPropertyMemory(
binaryProperties
);
this._batchTableBinaryProperties = binaryProperties;

this._content = content;

Expand All @@ -78,9 +83,26 @@ function Cesium3DTileBatchTable(
Cesium3DTileBatchTable._deprecationWarning = deprecationWarning;

Object.defineProperties(Cesium3DTileBatchTable.prototype, {
memorySizeInBytes: {
/**
* Size of the batch table, including the batch table hierarchy's binary
* buffers and any binary properties. JSON data is not counted.
*
* @memberof Cesium3DTileBatchTable.prototype
* @type {Number}
* @readonly
* @private
*/
batchTableByteLength: {
get: function () {
return this._batchTexture.memorySizeInBytes;
let totalByteLength = this._binaryPropertiesByteLength;

if (defined(this._batchTableHierarchy)) {
totalByteLength += this._batchTableHierarchy.byteLength;
}

totalByteLength += this._batchTexture.byteLength;

return totalByteLength;
},
},
});
Expand Down Expand Up @@ -181,6 +203,20 @@ function getBinaryProperties(featuresLength, properties, binaryBody) {
return binaryProperties;
}

function countBinaryPropertyMemory(binaryProperties) {
if (!defined(binaryProperties)) {
return 0;
}

let byteLength = 0;
for (const name in binaryProperties) {
if (binaryProperties.hasOwnProperty(name)) {
byteLength += binaryProperties[name].typedArray.byteLength;
}
}
return byteLength;
}

Cesium3DTileBatchTable.getBinaryProperties = function (
featuresLength,
batchTableJson,
Expand Down
4 changes: 3 additions & 1 deletion Source/Scene/Cesium3DTileContent.js
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,9 @@ Object.defineProperties(Cesium3DTileContent.prototype, {
},

/**
* Gets the amount of memory used by the batch table textures, in bytes.
* Gets the amount of memory used by the batch table textures and any binary
* metadata properties not accounted for in geometryByteLength or
* texturesByteLength
*
* @memberof Cesium3DTileContent.prototype
*
Expand Down
3 changes: 1 addition & 2 deletions Source/Scene/Cesium3DTileset.js
Original file line number Diff line number Diff line change
Expand Up @@ -1610,8 +1610,7 @@ Object.defineProperties(Cesium3DTileset.prototype, {

/**
* The total amount of GPU memory in bytes used by the tileset. This value is estimated from
* geometry, texture, and batch table textures of loaded tiles. For point clouds, this value also
* includes per-point metadata.
* geometry, texture, batch table textures, and binary metadata of loaded tiles.
*
* @memberof Cesium3DTileset.prototype
*
Expand Down
2 changes: 1 addition & 1 deletion Source/Scene/Cesium3DTilesetStatistics.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ function Cesium3DTilesetStatistics() {
// Memory statistics
this.geometryByteLength = 0;
this.texturesByteLength = 0;
this.batchTableByteLength = 0;
this.batchTableByteLength = 0; // batch textures and any binary metadata properties not otherwise accounted for
}

Cesium3DTilesetStatistics.prototype.clear = function () {
Expand Down
4 changes: 3 additions & 1 deletion Source/Scene/Geometry3DTileContent.js
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,9 @@ Object.defineProperties(Geometry3DTileContent.prototype, {

batchTableByteLength: {
get: function () {
return defined(this._batchTable) ? this._batchTable.memorySizeInBytes : 0;
return defined(this._batchTable)
? this._batchTable.batchTableByteLength
: 0;
},
},

Expand Down
2 changes: 1 addition & 1 deletion Source/Scene/GltfIndexBufferLoader.js
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ GltfIndexBufferLoader.prototype.load = function () {
);
}

// Unload everything except the index buffer
// Unload everything except the index buffer and/or typed array.
loader.unload();

loader._buffer = buffer;
Expand Down
2 changes: 1 addition & 1 deletion Source/Scene/Instanced3DModel3DTileContent.js
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ Object.defineProperties(Instanced3DModel3DTileContent.prototype, {

batchTableByteLength: {
get: function () {
return this._batchTable.memorySizeInBytes;
return this._batchTable.batchTableByteLength;
},
},

Expand Down
20 changes: 19 additions & 1 deletion Source/Scene/MetadataTable.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,23 +35,27 @@ function MetadataTable(options) {
Check.typeOf.object("options.class", metadataClass);
//>>includeEnd('debug');

let byteLength = 0;
const properties = {};
if (defined(options.properties)) {
for (const propertyId in options.properties) {
if (options.properties.hasOwnProperty(propertyId)) {
properties[propertyId] = new MetadataTableProperty({
const property = new MetadataTableProperty({
count: count,
property: options.properties[propertyId],
classProperty: metadataClass.properties[propertyId],
bufferViews: options.bufferViews,
});
properties[propertyId] = property;
byteLength += property.byteLength;
}
}
}

this._count = count;
this._class = metadataClass;
this._properties = properties;
this._byteLength = byteLength;
}

Object.defineProperties(MetadataTable.prototype, {
Expand Down Expand Up @@ -82,6 +86,20 @@ Object.defineProperties(MetadataTable.prototype, {
return this._class;
},
},

/**
* The size of all typed arrays used in this table.
*
* @memberof MetadataTable.prototype
* @type {Number}
* @readonly
* @private
*/
byteLength: {
get: function () {
return this._byteLength;
},
},
});

/**
Expand Down
Loading

0 comments on commit b70e22d

Please sign in to comment.