浏览代码

test cache texture

Benjamin Guignabert 4 年之前
父节点
当前提交
cddf4fe43d

+ 4 - 0
src/Materials/Textures/internalTexture.ts

@@ -226,6 +226,10 @@ export class InternalTexture {
     public _lodGenerationOffset: number = 0;
     /** @hidden */
     public _depthStencilTexture: Nullable<InternalTexture>;
+    /** @hidden */
+    public _lastUsedRenderId = -1;
+    /** @hidden */
+    public _postProcessChannel = -1;
 
     // Multiview
     /** @hidden */

+ 0 - 22
src/Materials/Textures/renderTargetTexture.ts

@@ -501,28 +501,6 @@ export class RenderTargetTexture extends Texture {
         }
     }
 
-    public cloneCameraPostProcesses(camera?: Camera): void {
-        const scene = this.getScene();
-        const sourceCamera = camera || scene && scene.activeCamera;
-
-        if (!sourceCamera) {
-            return;
-        }
-        
-        this.clearPostProcesses(true);
-
-        for (let i = 0; i < sourceCamera._postProcesses.length; i++) {
-            const postProcess = sourceCamera._postProcesses[i]?.clone();
-            if (postProcess) {
-                this.addPostProcess(postProcess);
-            }
-        }
-
-        if (scene?._prePassRenderer) {
-            scene._prePassRenderer.markAsDirty();
-        }
-    }
-
     /** @hidden */
     public _shouldRender(): boolean {
         if (this._currentRefreshId === -1) { // At least render once

+ 91 - 28
src/PostProcesses/postProcess.ts

@@ -5,6 +5,7 @@ import { Vector2 } from "../Maths/math.vector";
 import { Camera } from "../Cameras/camera";
 import { Effect } from "../Materials/effect";
 import { Constants } from "../Engines/constants";
+import { RenderTargetCreationOptions } from "../Materials/Textures/renderTargetCreationOptions";
 import "../Shaders/postprocess.vertex";
 import { IInspectable } from '../Misc/iInspectable';
 import { Engine } from '../Engines/engine';
@@ -165,6 +166,7 @@ export class PostProcess {
 
     private _options: number | PostProcessOptions;
     private _reusable = false;
+    private _renderId = 0;
     private _textureType: number;
     private _textureFormat: number;
     /**
@@ -173,6 +175,11 @@ export class PostProcess {
     */
     public _textures = new SmartArray<InternalTexture>(2);
     /**
+    * Smart array of input and output textures for the post process.
+    * @hidden
+    */
+    private _textureCache: InternalTexture[] = [];
+    /**
     * The index in _textures that corresponds to the output texture.
     * @hidden
     */
@@ -482,6 +489,74 @@ export class PostProcess {
         this.width = -1;
     }
 
+    private _createRenderTargetTexture(textureSize: { width: number, height: number }, textureOptions: RenderTargetCreationOptions, channel = 0) {
+        for (let i = 0; i < this._textureCache.length; i++) {
+            if (this._textureCache[i].width === textureSize.width && 
+                this._textureCache[i].height === textureSize.height &&
+                this._textureCache[i]._postProcessChannel === channel) {
+                // return this._textureCache[i];
+            }
+        }
+
+        const tex = this._engine.createRenderTargetTexture(textureSize, textureOptions);
+        tex._postProcessChannel = channel;
+        this._textureCache.push(tex);
+        console.log("Texture create. Cache length : " + this._textureCache.length);
+
+        return tex;
+    }
+
+
+    private _flushTextureCache() {
+        const currentRenderId = this._renderId;
+
+        for (let i = this._textureCache.length - 1; i >= 0; i--) {
+            if (currentRenderId - this._textureCache[i]._lastUsedRenderId > 100) {
+                let currentlyUsed = false;
+                for (var j = 0; j < this._textures.length; j++) {
+                    if (this._textures.data[j] === this._textureCache[i]) {
+                        currentlyUsed = true;
+                    }
+                }
+
+                if (!currentlyUsed) {
+                    this._engine._releaseTexture(this._textureCache[i]);
+                    this._textureCache.splice(i, 1);
+                    console.log("Texture flushed. Cache length : " + this._textureCache.length);
+                }
+            }
+        }
+    }
+
+    private _resize(width: number, height: number, camera: Camera, needMipMaps: boolean, forceDepthStencil?: boolean) {
+        if (this._textures.length > 0) {
+            this._textures.reset();
+        }
+
+        this.width = width;
+        this.height = height;
+
+        let textureSize = { width: this.width, height: this.height };
+        let textureOptions = {
+            generateMipMaps: needMipMaps,
+            generateDepthBuffer: forceDepthStencil || camera._postProcesses.indexOf(this) === 0,
+            generateStencilBuffer: (forceDepthStencil || camera._postProcesses.indexOf(this) === 0) && this._engine.isStencilEnable,
+            samplingMode: this.renderTargetSamplingMode,
+            type: this._textureType,
+            format: this._textureFormat
+        };
+
+        this._textures.push(this._createRenderTargetTexture(textureSize, textureOptions, 0));
+
+        if (this._reusable) {
+            this._textures.push(this._createRenderTargetTexture(textureSize, textureOptions, 1));
+        }
+
+        this._texelSize.copyFromFloats(1.0 / this.width, 1.0 / this.height);
+
+        this.onSizeChangedObservable.notifyObservers(this);
+    }
+
     /**
      * Activates the post process by intializing the textures to be used when executed. Notifies onActivateObservable.
      * When this post process is used in a pipeline, this is call will bind the input texture of this post process to the output of the previous.
@@ -536,34 +611,7 @@ export class PostProcess {
             }
 
             if (this.width !== desiredWidth || this.height !== desiredHeight) {
-                if (this._textures.length > 0) {
-                    for (var i = 0; i < this._textures.length; i++) {
-                        this._engine._releaseTexture(this._textures.data[i]);
-                    }
-                    this._textures.reset();
-                }
-                this.width = desiredWidth;
-                this.height = desiredHeight;
-
-                let textureSize = { width: this.width, height: this.height };
-                let textureOptions = {
-                    generateMipMaps: needMipMaps,
-                    generateDepthBuffer: forceDepthStencil || camera._postProcesses.indexOf(this) === 0,
-                    generateStencilBuffer: (forceDepthStencil || camera._postProcesses.indexOf(this) === 0) && this._engine.isStencilEnable,
-                    samplingMode: this.renderTargetSamplingMode,
-                    type: this._textureType,
-                    format: this._textureFormat
-                };
-
-                this._textures.push(this._engine.createRenderTargetTexture(textureSize, textureOptions));
-
-                if (this._reusable) {
-                    this._textures.push(this._engine.createRenderTargetTexture(textureSize, textureOptions));
-                }
-
-                this._texelSize.copyFromFloats(1.0 / this.width, 1.0 / this.height);
-
-                this.onSizeChangedObservable.notifyObservers(this);
+                this._resize(desiredWidth, desiredHeight, camera, needMipMaps, forceDepthStencil);
             }
 
             this._textures.forEach((texture) => {
@@ -571,6 +619,9 @@ export class PostProcess {
                     this._engine.updateRenderTargetTextureSampleCount(texture, this.samples);
                 }
             });
+
+            this._flushTextureCache();
+            this._renderId++;
         }
 
         var target: InternalTexture;
@@ -584,6 +635,7 @@ export class PostProcess {
             this.height = this._forcedOutputTexture.height;
         } else {
             target = this.inputTexture;
+            target._lastUsedRenderId = this._renderId;
         }
 
         // Bind the input of this post process to be used as the output of the previous post process.
@@ -686,9 +738,20 @@ export class PostProcess {
         if (this._textures.length > 0) {
             for (var i = 0; i < this._textures.length; i++) {
                 this._engine._releaseTexture(this._textures.data[i]);
+
+                const cacheIndex = this._textureCache.indexOf(this._textures.data[i]);
+                if (cacheIndex !== -1) {
+                    this._textureCache.splice(cacheIndex, 1);
+                }
             }
         }
+
         this._textures.dispose();
+
+        for (let i = this._textureCache.length - 1; i >= 0; i--) {
+            this._engine._releaseTexture(this._textureCache[i]);
+            this._textureCache.splice(i, 1);
+        }
     }
 
     /**