Skip to content
Merged

Leak #5151

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,24 @@ suite('TextureUtils', () => {
expect(texture.name).to.be.eq(EQUI_URL);
expect(texture.mapping).to.be.eq(EquirectangularReflectionMapping);
});
test('decodes a gainmap and disposes intermediate render targets', async () => {
const GAINMAP_URL = assetPath('environments/spruit_sunrise_1k_HDR.jpg');
const THREE = await import('three');
let disposeCount = 0;
const originalDispose = THREE.WebGLRenderTarget.prototype.dispose;
THREE.WebGLRenderTarget.prototype.dispose = function() {
disposeCount++;
return originalDispose.call(this);
};

try {
const texture = await textureUtils.loadEquirect(GAINMAP_URL);
texture.dispose();
expect(disposeCount).to.be.greaterThan(0);
} finally {
THREE.WebGLRenderTarget.prototype.dispose = originalDispose;
}
});
test('loads a valid KTX2 texture from URL', async () => {
let texture = await textureUtils.loadImage(KTX2_URL, false);
texture.dispose();
Expand Down
30 changes: 27 additions & 3 deletions packages/model-viewer/src/three-components/TextureUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -140,8 +140,32 @@ export default class TextureUtils {
const {renderTarget} =
result as QuadRenderer<1016, GainMapDecoderMaterial>;
if (renderTarget != null) {
const {texture} = renderTarget;
result.dispose(false);
let texture: Texture;
try {
const dataTexture = result.toDataTexture();
dataTexture.needsUpdate = true;
const data = dataTexture.image.data as ArrayLike<number>;
let hasContent = false;
const len = data.length;
for (let i = 0; i < len; i++) {
if (data[i] !== 0) {
hasContent = true;
break;
}
}
if (hasContent) {
texture = dataTexture;
result.dispose(true);
} else {
console.warn('Decoded DataTexture is completely black, falling back to render target texture.');
texture = renderTarget.texture;
result.dispose(false);
}
} catch (e) {
console.warn('Failed to convert gainmap to DataTexture, falling back to render target texture:', e);
texture = renderTarget.texture;
result.dispose(false);
}
resolve(texture);
} else {
resolve(result as DataTexture);
Expand All @@ -157,7 +181,7 @@ export default class TextureUtils {
texture.name = url;
texture.mapping = EquirectangularReflectionMapping;

if (!isHDR) {
if (!isHDR && texture.type !== HalfFloatType) {
texture.colorSpace = SRGBColorSpace;
}

Expand Down
Loading