Selaa lähdekoodia

Add perf counters to glTF loader

Gary Hsu 7 vuotta sitten
vanhempi
commit
c02a0d0926

+ 19 - 5
loaders/src/glTF/2.0/Extensions/MSFT_lod.ts

@@ -45,23 +45,39 @@ module BABYLON.GLTF2.Extensions {
 
             this._loader._readyPromise.then(() => {
                 for (let indexLOD = 0; indexLOD < this._nodePromiseLODs.length; indexLOD++) {
-                    Promise.all(this._nodePromiseLODs[indexLOD]).then(() => {
+                    const promise = Promise.all(this._nodePromiseLODs[indexLOD]).then(() => {
+                        if (indexLOD !== 0) {
+                            this._loader._parent._endPerformanceCounter(`Node LOD ${indexLOD}`);
+                        }
+
                         this._loader._parent._log(`Loaded node LOD ${indexLOD}`);
                         this.onNodeLODsLoadedObservable.notifyObservers(indexLOD);
+
                         if (indexLOD !== this._nodePromiseLODs.length - 1) {
+                            this._loader._parent._startPerformanceCounter(`Node LOD ${indexLOD + 1}`);
                             this._nodeSignalLODs[indexLOD].resolve();
                         }
                     });
+
+                    this._loader._completePromises.push(promise);
                 }
 
                 for (let indexLOD = 0; indexLOD < this._materialPromiseLODs.length; indexLOD++) {
-                    Promise.all(this._materialPromiseLODs[indexLOD]).then(() => {
+                    const promise = Promise.all(this._materialPromiseLODs[indexLOD]).then(() => {
+                        if (indexLOD !== 0) {
+                            this._loader._parent._endPerformanceCounter(`Material LOD ${indexLOD}`);
+                        }
+
                         this._loader._parent._log(`Loaded material LOD ${indexLOD}`);
                         this.onMaterialLODsLoadedObservable.notifyObservers(indexLOD);
-                        if (indexLOD !==  this._materialPromiseLODs.length - 1) {
+
+                        if (indexLOD !== this._materialPromiseLODs.length - 1) {
+                            this._loader._parent._startPerformanceCounter(`Material LOD ${indexLOD + 1}`);
                             this._materialSignalLODs[indexLOD].resolve();
                         }
                     });
+
+                    this._loader._completePromises.push(promise);
                 }
             });
         }
@@ -110,7 +126,6 @@ module BABYLON.GLTF2.Extensions {
                         firstPromise = promise;
                     }
                     else {
-                        this._loader._completePromises.push(promise);
                         this._nodeIndexLOD = null;
                     }
 
@@ -159,7 +174,6 @@ module BABYLON.GLTF2.Extensions {
                         firstPromise = promise;
                     }
                     else {
-                        this._loader._completePromises.push(promise);
                         this._materialIndexLOD = null;
                     }
 

+ 20 - 5
loaders/src/glTF/2.0/babylon.glTFLoader.ts

@@ -147,8 +147,11 @@ module BABYLON.GLTF2 {
 
         private _loadAsync(nodes: Nullable<Array<number>>): Promise<void> {
             return Promise.resolve().then(() => {
+                this._parent._startPerformanceCounter("Loading => Ready");
+                this._parent._startPerformanceCounter("Loading => Complete");
+
                 this._state = GLTFLoaderState.LOADING;
-                this._parent._log(`Loading`);
+                this._parent._log("Loading");
 
                 const readyDeferred = new Deferred<void>();
                 this._readyPromise = readyDeferred.promise;
@@ -176,7 +179,7 @@ module BABYLON.GLTF2 {
 
                 const resultPromise = Promise.all(promises).then(() => {
                     this._state = GLTFLoaderState.READY;
-                    this._parent._log(`Ready`);
+                    this._parent._log("Ready");
 
                     readyDeferred.resolve();
 
@@ -184,6 +187,8 @@ module BABYLON.GLTF2 {
                 });
 
                 resultPromise.then(() => {
+                    this._parent._endPerformanceCounter("Loading => Ready");
+
                     if (this._rootBabylonMesh) {
                         this._rootBabylonMesh.setEnabled(true);
                     }
@@ -191,8 +196,10 @@ module BABYLON.GLTF2 {
                     Tools.SetImmediate(() => {
                         if (!this._disposed) {
                             Promise.all(this._completePromises).then(() => {
+                                this._parent._endPerformanceCounter("Loading => Complete");
+
                                 this._state = GLTFLoaderState.COMPLETE;
-                                this._parent._log(`Complete`);
+                                this._parent._log("Complete");
 
                                 this._parent.onCompleteObservable.notifyObservers(undefined);
                                 this._parent.onCompleteObservable.clear();
@@ -1667,6 +1674,8 @@ module BABYLON.GLTF2 {
         }
 
         private _compileMaterialsAsync(): Promise<void> {
+            this._parent._startPerformanceCounter("Compile materials");
+
             const promises = new Array<Promise<void>>();
 
             if (this._gltf.materials) {
@@ -1689,10 +1698,14 @@ module BABYLON.GLTF2 {
                 }
             }
 
-            return Promise.all(promises).then(() => {});
+            return Promise.all(promises).then(() => {
+                this._parent._endPerformanceCounter("Compile materials");
+            });
         }
 
         private _compileShadowGeneratorsAsync(): Promise<void> {
+            this._parent._startPerformanceCounter("Compile shadow generators");
+
             const promises = new Array<Promise<void>>();
 
             const lights = this._babylonScene.lights;
@@ -1703,7 +1716,9 @@ module BABYLON.GLTF2 {
                 }
             }
 
-            return Promise.all(promises).then(() => {});
+            return Promise.all(promises).then(() => {
+                this._parent._endPerformanceCounter("Compile shadow generators");
+            });
         }
 
         public _applyExtensions<T>(actionAsync: (extension: GLTFLoaderExtension) => Nullable<Promise<T>>): Nullable<Promise<T>> {

+ 104 - 55
loaders/src/glTF/babylon.glTFFileLoader.ts

@@ -181,39 +181,6 @@ module BABYLON {
         public _normalizeAnimationGroupsToBeginAtZero = true;
 
         /**
-         * Defines if the loader logging is enabled.
-         */
-        public loggingEnabled = false;
-
-        /**
-         * Observable raised when the loader logs a message.
-         */
-        public readonly onLogObservable = new Observable<string>();
-
-        private _logIndentLevel = 0;
-        private static readonly _logSpaces = "                                ";
-
-        /** @hidden */
-        public _log(message: string): void {
-            if (this.loggingEnabled) {
-                const spaces = GLTFFileLoader._logSpaces.substr(0, this._logIndentLevel * 2);
-                this.onLogObservable.notifyObservers(`${spaces}${message}`);
-                Tools.Log(`${spaces}${message}`);
-            }
-        }
-
-        /** @hidden */
-        public _logOpen(message: string): void {
-            this._log(message);
-            this._logIndentLevel++;
-        }
-
-        /** @hidden */
-        public _logClose(): void {
-            --this._logIndentLevel;
-        }
-
-        /**
          * Function called before loading a url referenced by the asset.
          */
         public preprocessUrlAsync = (url: string) => Promise.resolve(url);
@@ -359,6 +326,52 @@ module BABYLON {
             return this._loader ? this._loader.state : null;
         }
 
+        /**
+         * Defines if the loader logging is enabled.
+         */
+        public get loggingEnabled(): boolean {
+            return this._loggingEnabled;
+        }
+
+        public set loggingEnabled(value: boolean) {
+            if (this._loggingEnabled === value) {
+                return;
+            }
+
+            this._loggingEnabled = value;
+
+            if (this._loggingEnabled) {
+                this._log = this._logEnabled;
+            }
+            else {
+                this._log = this._logDisabled;
+            }
+        }
+
+        /**
+         * Defines if the loader should capture performance counters.
+         */
+        public get capturePerformanceCounters(): boolean {
+            return this._capturePerformanceCounters;
+        }
+
+        public set capturePerformanceCounters(value: boolean) {
+            if (this._capturePerformanceCounters === value) {
+                return;
+            }
+
+            this._capturePerformanceCounters = value;
+
+            if (this._capturePerformanceCounters) {
+                this._startPerformanceCounter = this._startPerformanceCounterEnabled;
+                this._endPerformanceCounter = this._endPerformanceCounterEnabled;
+            }
+            else {
+                this._startPerformanceCounter = this._startPerformanceCounterDisabled;
+                this._endPerformanceCounter = this._endPerformanceCounterDisabled;
+            }
+        }
+
         // #endregion
 
         private _loader: Nullable<IGLTFLoader> = null;
@@ -483,19 +496,16 @@ module BABYLON {
         }
 
         private _parse(data: string | ArrayBuffer): IGLTFLoaderData {
+            this._startPerformanceCounter("Parse");
+
             let parsedData: IGLTFLoaderData;
             if (data instanceof ArrayBuffer) {
-                if (this.loggingEnabled) {
-                    this._log(`Parsing binary`);
-                }
-
+                this._log(`Parsing binary`);
                 parsedData = this._parseBinary(data);
             }
             else {
-                if (this.loggingEnabled) {
-                    this._log(`Parsing JSON`);
-                    this._log(`JSON length: ${data.length}`);
-                }
+                this._log(`Parsing JSON`);
+                this._log(`JSON length: ${data.length}`);
 
                 parsedData = {
                     json: JSON.parse(data),
@@ -506,23 +516,16 @@ module BABYLON {
             this.onParsedObservable.notifyObservers(parsedData);
             this.onParsedObservable.clear();
 
+            this._endPerformanceCounter("Parse");
             return parsedData;
         }
 
         private _getLoader(loaderData: IGLTFLoaderData): IGLTFLoader {
             const asset = (<any>loaderData.json).asset || {};
 
-            if (this.loggingEnabled) {
-                this._log(`Asset version: ${asset.version}`);
-
-                if (asset.minVersion) {
-                    this._log(`Asset minimum version: ${asset.minVersion}`);
-                }
-
-                if (asset.generator) {
-                    this._log(`Asset generator: ${asset.generator}`);
-                }
-            }
+            this._log(`Asset version: ${asset.version}`);
+            asset.minVersion && this._log(`Asset minimum version: ${asset.minVersion}`);
+            asset.generator && this._log(`Asset generator: ${asset.generator}`);
 
             const version = GLTFFileLoader._parseVersion(asset.version);
             if (!version) {
@@ -558,9 +561,7 @@ module BABYLON {
                 Magic: 0x46546C67
             };
 
-            if (this.loggingEnabled) {
-                this._log(`Binary length: ${data.byteLength}`);
-            }
+            this._log(`Binary length: ${data.byteLength}`);
 
             const binaryReader = new BinaryReader(data);
 
@@ -699,6 +700,54 @@ module BABYLON {
 
             return result;
         }
+
+        private static readonly _logSpaces = "                                ";
+        private _logIndentLevel = 0;
+        private _loggingEnabled = false;
+
+        /** @hidden */
+        public _log = this._logDisabled;
+
+        /** @hidden */
+        public _logOpen(message: string): void {
+            this._log(message);
+            this._logIndentLevel++;
+        }
+
+        /** @hidden */
+        public _logClose(): void {
+            --this._logIndentLevel;
+        }
+
+        private _logEnabled(message: string): void {
+            const spaces = GLTFFileLoader._logSpaces.substr(0, this._logIndentLevel * 2);
+            Tools.Log(`${spaces}${message}`);
+        }
+
+        private _logDisabled(message: string): void {
+        }
+
+        private _capturePerformanceCounters = false;
+
+        /** @hidden */
+        public _startPerformanceCounter = this._startPerformanceCounterDisabled;
+
+        /** @hidden */
+        public _endPerformanceCounter = this._endPerformanceCounterDisabled;
+
+        private _startPerformanceCounterEnabled(counterName: string): void {
+            Tools.StartPerformanceCounter(counterName);
+        }
+
+        private _startPerformanceCounterDisabled(counterName: string): void {
+        }
+
+        private _endPerformanceCounterEnabled(counterName: string): void {
+            Tools.EndPerformanceCounter(counterName);
+        }
+
+        private _endPerformanceCounterDisabled(counterName: string): void {
+        }
     }
 
     class BinaryReader {