Browse Source

Merge pull request #9318 from BabylonJS/memleak-fix

Fix gltf memory leak
David Catuhe 4 years ago
parent
commit
88d837b222
2 changed files with 23 additions and 3 deletions
  1. 1 1
      loaders/src/glTF/2.0/glTFLoader.ts
  2. 22 2
      src/Meshes/buffer.ts

+ 1 - 1
loaders/src/glTF/2.0/glTFLoader.ts

@@ -1676,7 +1676,7 @@ export class GLTFLoader implements IGLTFLoader {
             accessor._babylonVertexBuffer = this._loadVertexBufferViewAsync(bufferView, kind).then((babylonBuffer) => {
                 const size = GLTFLoader._GetNumComponents(context, accessor.type);
                 return new VertexBuffer(this._babylonScene.getEngine(), babylonBuffer, kind, false, false, bufferView.byteStride,
-                    false, accessor.byteOffset, size, accessor.componentType, accessor.normalized, true);
+                    false, accessor.byteOffset, size, accessor.componentType, accessor.normalized, true, 1, true);
             });
         }
 

+ 22 - 2
src/Meshes/buffer.ts

@@ -13,6 +13,7 @@ export class Buffer {
     private _updatable: boolean;
     private _instanced: boolean;
     private _divisor: number;
+    private _isAlreadyOwned = false;
 
     /**
      * Gets the byte stride.
@@ -168,6 +169,20 @@ export class Buffer {
         }
     }
 
+    /** @hidden */
+    public _increaseReferences() {
+        if (!this._buffer) {
+            return;
+        }
+
+        if (!this._isAlreadyOwned) {
+            this._isAlreadyOwned = true;
+            return;
+        }
+
+        this._buffer.references++;
+    }
+
     /**
      * Release all resources
      */
@@ -279,12 +294,17 @@ export class VertexBuffer {
      * @param normalized whether the data contains normalized data (optional)
      * @param useBytes set to true if stride and offset are in bytes (optional)
      * @param divisor defines the instance divisor to use (1 by default)
+     * @param takeBufferOwnership defines if the buffer should be released when the vertex buffer is disposed
      */
     constructor(engine: any, data: DataArray | Buffer, kind: string, updatable: boolean, postponeInternalCreation?: boolean, stride?: number,
-        instanced?: boolean, offset?: number, size?: number, type?: number, normalized = false, useBytes = false, divisor = 1) {
+        instanced?: boolean, offset?: number, size?: number, type?: number, normalized = false, useBytes = false, divisor = 1, takeBufferOwnership = false) {
         if (data instanceof Buffer) {
             this._buffer = data;
-            this._ownsBuffer = false;
+            this._ownsBuffer = takeBufferOwnership;
+
+            if (takeBufferOwnership) {
+                this._buffer._increaseReferences();
+            }
         } else {
             this._buffer = new Buffer(engine, data, updatable, stride, postponeInternalCreation, instanced, useBytes);
             this._ownsBuffer = true;