Skip to content

Commit 084d81d

Browse files
committed
Fix memory usage for environment map manager
1 parent a93e415 commit 084d81d

File tree

3 files changed

+123
-77
lines changed

3 files changed

+123
-77
lines changed

packages/engine/Source/Scene/DynamicEnvironmentMapManager.js

Lines changed: 63 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ import ConvolveSpecularMapVS from "../Shaders/ConvolveSpecularMapVS.js";
3333
* @typedef {object} DynamicEnvironmentMapManager.ConstructorOptions
3434
* Options for the DynamicEnvironmentMapManager constructor
3535
* @property {boolean} [enabled=true] If true, the environment map and related properties will continue to update.
36-
* @property {number} [mipmapLevels=10] The number of mipmap levels to generate for specular maps. More mipmap levels will produce a higher resolution specular reflection.
36+
* @property {number} [mipmapLevels=7] The number of mipmap levels to generate for specular maps. More mipmap levels will produce a higher resolution specular reflection.
3737
* @property {number} [maximumSecondsDifference=3600] The maximum amount of elapsed seconds before a new environment map is created.
3838
* @property {number} [maximumPositionEpsilon=1000] The maximum difference in position before a new environment map is created, in meters. Small differences in position will not visibly affect results.
3939
* @property {number} [atmosphereScatteringIntensity=2.0] The intensity of the scattered light emitted from the atmosphere. This should be adjusted relative to the value of {@link Scene.light} intensity.
@@ -81,7 +81,7 @@ function DynamicEnvironmentMapManager(options) {
8181
options = defaultValue(options, defaultValue.EMPTY_OBJECT);
8282

8383
const mipmapLevels = Math.min(
84-
defaultValue(options.mipmapLevels, 10),
84+
defaultValue(options.mipmapLevels, 7),
8585
Math.log2(ContextLimits.maximumCubeMapSize),
8686
);
8787

@@ -354,6 +354,10 @@ DynamicEnvironmentMapManager._updateCommandQueue = (frameState) => {
354354
DynamicEnvironmentMapManager._activeComputeCommandCount++;
355355
command = DynamicEnvironmentMapManager._nextFrameCommandQueue.shift();
356356
}
357+
358+
if (defined(command)) {
359+
DynamicEnvironmentMapManager._nextFrameCommandQueue.push(command);
360+
}
357361
}
358362
};
359363

@@ -539,7 +543,8 @@ function updateRadianceMap(manager, frameState) {
539543
let i = 0;
540544
for (const face of CubeMap.faceNames()) {
541545
let texture = manager._radianceMapTextures[i];
542-
if (defined(texture)) {
546+
// Destroy any existing textures that have no yet been cleaned up
547+
if (defined(texture) && !texture.isDestroyed()) {
543548
texture.destroy();
544549
}
545550

@@ -570,7 +575,6 @@ function updateRadianceMap(manager, frameState) {
570575
);
571576
},
572577
},
573-
persists: true,
574578
owner: manager,
575579
postExecute: () => {
576580
const commands = manager._radianceMapComputeCommands;
@@ -583,7 +587,6 @@ function updateRadianceMap(manager, frameState) {
583587
const framebuffer = new Framebuffer({
584588
context: context,
585589
colorTextures: [manager._radianceMapTextures[index]],
586-
destroyAttachments: false,
587590
});
588591

589592
// Copy the output texture into the corresponding cubemap face
@@ -639,19 +642,34 @@ function updateSpecularMaps(manager, frameState) {
639642
facesCopied++;
640643
DynamicEnvironmentMapManager._activeComputeCommandCount--;
641644

642-
// All faces and levels have been copied
643-
if (facesCopied === manager._specularMapTextures.length) {
645+
texture.destroy();
646+
manager._specularMapTextures[index] = undefined;
647+
648+
// All faces for each mipmap level have been copied
649+
const length = manager._specularMapTextures.length;
650+
if (facesCopied >= length) {
644651
manager._irradianceCommandDirty = true;
645652
radianceCubeMap.sampler = new Sampler({
646653
minificationFilter: TextureMinificationFilter.LINEAR_MIPMAP_LINEAR,
647654
});
655+
648656
manager._shouldRegenerateShaders = true;
657+
658+
// Cleanup shared resources
659+
manager._va.destroy();
660+
manager._va = undefined;
661+
manager._convolveSP.destroy();
662+
manager._convolveSP = undefined;
649663
}
650664
};
651665

652666
let index = 0;
653667
for (let level = 1; level < mipmapLevels; ++level) {
654668
for (const face of CubeMap.faceNames()) {
669+
if (defined(manager._specularMapTextures[index])) {
670+
manager._specularMapTextures[index].destroy();
671+
}
672+
655673
const texture = (manager._specularMapTextures[index] = new Texture({
656674
context: context,
657675
width: width,
@@ -683,6 +701,8 @@ function updateSpecularMaps(manager, frameState) {
683701
shaderProgram: shaderProgram,
684702
vertexArray: vertexArray,
685703
outputTexture: texture,
704+
// Persist so we can use a shared shader progam and vertex array across all commands
705+
// Shared resources are instead destroyed in postExecute
686706
persists: true,
687707
owner: manager,
688708
uniformMap: {
@@ -717,17 +737,19 @@ function updateIrradianceResources(manager, frameState) {
717737
const dimensions = irradianceTextureDimensions;
718738

719739
let texture = manager._irradianceMapTexture;
720-
if (!defined(texture)) {
721-
texture = new Texture({
722-
context: context,
723-
width: dimensions.x,
724-
height: dimensions.y,
725-
pixelDatatype: PixelDatatype.FLOAT,
726-
pixelFormat: PixelFormat.RGBA,
727-
});
728-
manager._irradianceMapTexture = texture;
740+
if (defined(texture)) {
741+
texture.destroy();
729742
}
730743

744+
texture = new Texture({
745+
context: context,
746+
width: dimensions.x,
747+
height: dimensions.y,
748+
pixelDatatype: PixelDatatype.FLOAT,
749+
pixelFormat: PixelFormat.RGBA,
750+
});
751+
manager._irradianceMapTexture = texture;
752+
731753
let fs = manager._irradianceMapFS;
732754
if (!defined(fs)) {
733755
fs = new ShaderSource({
@@ -750,6 +772,7 @@ function updateIrradianceResources(manager, frameState) {
750772
manager._irradianceTextureDirty = false;
751773
manager._irradianceComputeCommand = undefined;
752774
manager._sphericalHarmonicCoefficientsDirty = true;
775+
manager._irradianceMapFS = undefined;
753776

754777
DynamicEnvironmentMapManager._activeComputeCommandCount--;
755778
},
@@ -768,6 +791,11 @@ function updateIrradianceResources(manager, frameState) {
768791
function updateSphericalHarmonicCoefficients(manager, frameState) {
769792
const context = frameState.context;
770793

794+
if (!defined(manager._irradianceMapTexture)) {
795+
// Operation was cancelled
796+
return;
797+
}
798+
771799
const framebuffer = new Framebuffer({
772800
context: context,
773801
colorTextures: [manager._irradianceMapTexture],
@@ -793,6 +821,8 @@ function updateSphericalHarmonicCoefficients(manager, frameState) {
793821
}
794822

795823
framebuffer.destroy();
824+
manager._irradianceMapTexture.destroy();
825+
manager._irradianceMapTexture = undefined;
796826
manager._shouldRegenerateShaders = true;
797827
}
798828

@@ -910,19 +940,33 @@ DynamicEnvironmentMapManager.prototype.destroy = function () {
910940
length = this._radianceMapTextures.length;
911941
for (let i = 0; i < length; ++i) {
912942
this._radianceMapTextures[i] =
913-
this._radianceMapTextures[i] && this._radianceMapTextures[i].destroy();
943+
this._radianceMapTextures[i] &&
944+
!this._radianceMapTextures[i].isDestroyed() &&
945+
this._radianceMapTextures[i].destroy();
914946
}
915947

916948
length = this._specularMapTextures.length;
917949
for (let i = 0; i < length; ++i) {
918950
this._specularMapTextures[i] =
919-
this._specularMapTextures[i] && this._specularMapTextures[i].destroy();
951+
this._specularMapTextures[i] &&
952+
!this._specularMapTextures[i].isDestroyed() &&
953+
this._specularMapTextures[i].destroy();
920954
}
921955

922956
this._radianceCubeMap =
923957
this._radianceCubeMap && this._radianceCubeMap.destroy();
924958
this._irradianceMapTexture =
925-
this._irradianceMapTexture && this._irradianceMapTexture.destroy();
959+
this._irradianceMapTexture &&
960+
!this._irradianceMapTexture.isDestroyed() &&
961+
this._irradianceMapTexture.destroy();
962+
963+
if (defined(this._va)) {
964+
this._va.destroy();
965+
}
966+
967+
if (defined(this._convolveSP)) {
968+
this._convolveSP.destroy();
969+
}
926970

927971
return destroyObject(this);
928972
};

packages/engine/Specs/Scene/Cesium3DTilesetSpec.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -487,6 +487,8 @@ describe(
487487
}),
488488
);
489489
expect(root.contentFailed).toBeTrue();
490+
491+
await Cesium3DTilesTester.waitForTilesLoaded(scene, tileset);
490492
});
491493

492494
it("handles failed tile requests", async function () {

0 commit comments

Comments
 (0)