From 300d2a728daaa7a2b5ffc3000a73d006c3be2dda Mon Sep 17 00:00:00 2001 From: Toni Helenius Date: Sat, 28 Oct 2023 21:05:01 +0300 Subject: [PATCH] Solve issue #2127 (excessive memory use while loading GLB) (#2128) * Cache the materials * Try with resources to make sure we close the stream * Conform cache naming to the other cache usages * Just use the cache in the read method as the other caches do * Clone the material * Cache textures locally to avoid embedded textures to be read many times --- .../jme3/scene/plugins/gltf/GltfLoader.java | 25 +++++++++++++++---- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/jme3-plugins/src/gltf/java/com/jme3/scene/plugins/gltf/GltfLoader.java b/jme3-plugins/src/gltf/java/com/jme3/scene/plugins/gltf/GltfLoader.java index 6db0fd4ce2..12b477bd87 100644 --- a/jme3-plugins/src/gltf/java/com/jme3/scene/plugins/gltf/GltfLoader.java +++ b/jme3-plugins/src/gltf/java/com/jme3/scene/plugins/gltf/GltfLoader.java @@ -605,9 +605,9 @@ protected byte[] getBytes(int bufferIndex, String uri, Integer bufferLength) thr BinDataKey key = new BinDataKey(info.getKey().getFolder() + decoded); InputStream input = (InputStream) info.getManager().loadAsset(key); data = new byte[bufferLength]; - DataInputStream dataStream = new DataInputStream(input); - dataStream.readFully(data); - dataStream.close(); + try (DataInputStream dataStream = new DataInputStream(input)) { + dataStream.readFully(data); + } } } else { // no URI, this should not happen in a gltf file, only in glb files. @@ -619,6 +619,11 @@ protected byte[] getBytes(int bufferIndex, String uri, Integer bufferLength) thr public Material readMaterial(int materialIndex) throws IOException { assertNotNull(materials, "There is no material defined yet a mesh references one"); + Material material = fetchFromCache("materials", materialIndex, Material.class); + if (material != null) { + return material.clone(); + } + JsonObject matData = materials.get(materialIndex).getAsJsonObject(); JsonObject pbrMat = matData.getAsJsonObject("pbrMetallicRoughness"); @@ -688,7 +693,10 @@ public Material readMaterial(int materialIndex) throws IOException { adapter.setParam("emissiveTexture", readTexture(matData.getAsJsonObject("emissiveTexture"))); - return adapter.getMaterial(); + material = adapter.getMaterial(); + addToCache("materials", materialIndex, material, materials.size()); + + return material; } public void readCameras() throws IOException { @@ -746,12 +754,17 @@ public Texture2D readTexture(JsonObject texture, boolean flip) throws IOExceptio Integer textureIndex = getAsInteger(texture, "index"); assertNotNull(textureIndex, "Texture has no index"); assertNotNull(textures, "There are no textures, yet one is referenced by a material"); + + Texture2D texture2d = fetchFromCache("textures", textureIndex, Texture2D.class); + if (texture2d != null) { + return texture2d; + } JsonObject textureData = textures.get(textureIndex).getAsJsonObject(); Integer sourceIndex = getAsInteger(textureData, "source"); Integer samplerIndex = getAsInteger(textureData, "sampler"); - Texture2D texture2d = readImage(sourceIndex, flip); + texture2d = readImage(sourceIndex, flip); if (samplerIndex != null) { texture2d = readSampler(samplerIndex, texture2d); @@ -761,6 +774,8 @@ public Texture2D readTexture(JsonObject texture, boolean flip) throws IOExceptio texture2d = customContentManager.readExtensionAndExtras("texture", texture, texture2d); + addToCache("textures", textureIndex, texture2d, textures.size()); + return texture2d; }