Skip to content

Commit

Permalink
fix(destory): confirm reference count before destruction (#164)
Browse files Browse the repository at this point in the history
can't remove default res
confirm reference count before destruction
confirm reference count before destruction
  • Loading branch information
ZenderJK authored May 19, 2023
1 parent 016fdd9 commit 071ac16
Show file tree
Hide file tree
Showing 12 changed files with 104 additions and 68 deletions.
2 changes: 1 addition & 1 deletion public
Submodule public updated 1 files
+1 −20,150 json/anim_0.json
1 change: 1 addition & 0 deletions samples/base/Sample_AddRemove.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ class Sample_AddRemove {
if (obj) {
list.splice(index, 1)
this.view.scene.removeChild(obj)
obj.destroy(true);
}
});

Expand Down
61 changes: 29 additions & 32 deletions samples/base/Sample_Destroy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,39 +38,36 @@ class Sample_Destroy {
// add light object
scene3D.addChild(light)
{
// create new object
const obj: Object3D = new Object3D()
// add MeshRenderer
let mr: MeshRenderer = obj.addComponent(MeshRenderer)
// set geometry
mr.geometry = new BoxGeometry(1, 1, 1)
// set material
mr.material = new LitMaterial()
// set rotation
obj.rotationY = 45
obj.x = -2
// add object
scene3D.addChild(obj)
}
{
// create new object
const obj: Object3D = new Object3D()
// add MeshRenderer
let mr: MeshRenderer = obj.addComponent(MeshRenderer)
// set geometry
mr.geometry = new BoxGeometry(1, 1, 1)
// set material
mr.material = new LitMaterial()
// set rotation
obj.rotationY = 45
obj.x = 2
// add object
scene3D.addChild(obj)
let list: Object3D[] = [];
GUIHelp.addButton("add", () => {
for (let i = 0; i < 20; i++) {
// create new object
const obj: Object3D = new Object3D()
// add MeshRenderer
let mr: MeshRenderer = obj.addComponent(MeshRenderer)
// set geometry
mr.geometry = new BoxGeometry(1, 1, 1)
// set material
mr.material = new LitMaterial()
// set rotation
obj.rotationY = 45
obj.x = 2
// add object
scene3D.addChild(obj)
obj.x = Math.random() * 50 - 25;
obj.y = Math.random() * 50 - 25;
obj.z = Math.random() * 50 - 25;
list.push(obj);
}
});

GUIHelp.addButton("del", () => {
for (let i = 0; i < list.length; i++) {
const obj = list[i];
obj.destroy(true);
}
});

// debug gui
GUIHelp.addButton('destroy', () => {
obj.destroy(true)
})
}
// create a view with target scene and camera
let view = new View3D()
Expand Down
19 changes: 16 additions & 3 deletions src/assets/Res.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import { GUIAtlasTexture } from '../components/gui/core/GUIAtlasTexture';
import { FontParser, FontInfo } from '../loader/parser/FontParser';
import { fonts } from './Fonts';
import { AtlasParser } from '../loader/parser/AtlasParser';
import { Reference } from '../util/Reference';

/**
* Resource management classes for textures, materials, models, and preset bodies.
Expand Down Expand Up @@ -435,13 +436,25 @@ export class Res {
this.grayTexture = this.createTexture(32, 32, 128, 128, 128, 255.0, 'default-grayTexture');

let brdf = new BRDFLUTGenerate();
let texture = brdf.generateBRDFLUTTexture();
let BRDFLUT = texture.name = 'BRDFLUT';
this.addTexture(BRDFLUT, texture);
let brdf_texture = brdf.generateBRDFLUTTexture();
let BRDFLUT = brdf_texture.name = 'BRDFLUT';
this.addTexture(BRDFLUT, brdf_texture);

this.defaultSky = new HDRTextureCube();
this.defaultSky.createFromTexture(128, this.blackTexture);

Reference.getInstance().attached(this.defaultSky, this);
Reference.getInstance().attached(brdf_texture, this);

Reference.getInstance().attached(this.normalTexture, this);
Reference.getInstance().attached(this.maskTexture, this);
Reference.getInstance().attached(this.whiteTexture, this);
Reference.getInstance().attached(this.blackTexture, this);
Reference.getInstance().attached(this.redTexture, this);
Reference.getInstance().attached(this.blueTexture, this);
Reference.getInstance().attached(this.greenTexture, this);
Reference.getInstance().attached(this.yellowTexture, this);
Reference.getInstance().attached(this.grayTexture, this);
this.defaultGUITexture = new GUITexture(this.whiteTexture);
this.defaultGUISprite = new GUISprite(this.defaultGUITexture);
this.defaultGUISprite.trimSize.set(4, 4)
Expand Down
14 changes: 4 additions & 10 deletions src/components/renderer/MeshRenderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { RendererType } from '../../gfx/renderJob/passRenderer/state/RendererTyp
import { MaterialBase } from '../../materials/MaterialBase';
import { MorphTargetData } from '../anim/morphAnim/MorphTargetData';
import { RenderNode } from './RenderNode';
import { Reference } from '../..';

/**
* The mesh renderer component is a component used to render the mesh
Expand Down Expand Up @@ -40,7 +41,8 @@ export class MeshRenderer extends RenderNode {
}

public set geometry(value: GeometryBase) {
this._geometry = value;
//this must use super geometry has reference in super
super.geometry = value;
let isMorphTarget = value.morphTargetDictionary != null;
if (isMorphTarget) {
this.morphData ||= new MorphTargetData();
Expand All @@ -56,7 +58,6 @@ export class MeshRenderer extends RenderNode {
}

this.object3D.bound = this._geometry.bounds.clone();

if (this._readyPipeline) {
this.initPipeline();
}
Expand Down Expand Up @@ -121,18 +122,11 @@ export class MeshRenderer extends RenderNode {
}
}
}

super.nodeUpdate(view, passType, renderPassState, clusterLightingBuffer);
}

public destroy(force?: boolean): void {
if (force) {
this.geometry.destroy(force);
this.materials.forEach(mat => {
mat.destroy(force);
});
}
super.destroy();
super.destroy(force);
}

cloneTo(obj: Object3D) {
Expand Down
38 changes: 33 additions & 5 deletions src/components/renderer/RenderNode.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ShadowLightsCollect } from "../..";
import { Reference, ShadowLightsCollect } from "../..";
import { Engine3D } from "../../Engine3D";
import { View3D } from "../../core/View3D";
import { GeometryBase } from "../../core/geometry/GeometryBase";
Expand Down Expand Up @@ -67,6 +67,12 @@ export class RenderNode extends ComponentBase {
}

public set geometry(value: GeometryBase) {
if (this._geometry != value) {
if (this._geometry) {
Reference.getInstance().detached(this._geometry, this)
}
Reference.getInstance().attached(value, this)
}
this._geometry = value;
}

Expand Down Expand Up @@ -95,6 +101,15 @@ export class RenderNode extends ComponentBase {
}

public set materials(value: MaterialBase[]) {
for (let i = 0; i < this._materials.length; i++) {
let mat = this._materials[i];
Reference.getInstance().detached(mat, this)
}
for (let i = 0; i < value.length; i++) {
let mat = value[i];
Reference.getInstance().attached(mat, this)
}

this._materials = value;
let transparent = false;
let sort = 0;
Expand Down Expand Up @@ -413,15 +428,15 @@ export class RenderNode extends ComponentBase {
renderShader.setTexture(`brdflutMap`, bdrflutTex);

let shadowRenderer = Engine3D.getRenderJob(view).shadowMapPassRenderer;
if (shadowRenderer && shadowRenderer.depth2DTextureArray) {
renderShader.setTexture(`shadowMap`, Engine3D.getRenderJob(view).shadowMapPassRenderer.depth2DTextureArray);
if (shadowRenderer && shadowRenderer.depth2DArrayTexture) {
renderShader.setTexture(`shadowMap`, Engine3D.getRenderJob(view).shadowMapPassRenderer.depth2DArrayTexture);
renderShader.setStorageBuffer(`shadowBuffer`, ShadowLightsCollect.shadowBuffer.get(view.scene));
}
// let shadowLight = ShadowLights.list;
// if (shadowLight.length) {
let pointShadowRenderer = Engine3D.getRenderJob(view).pointLightShadowRenderer;
if (pointShadowRenderer && pointShadowRenderer.cubeTextureArray) {
renderShader.setTexture(`pointShadowMap`, pointShadowRenderer.cubeTextureArray);
if (pointShadowRenderer && pointShadowRenderer.cubeArrayTexture) {
renderShader.setTexture(`pointShadowMap`, pointShadowRenderer.cubeArrayTexture);
}
// }

Expand Down Expand Up @@ -459,6 +474,19 @@ export class RenderNode extends ComponentBase {
public destroy(force?: boolean) {
super.destroy(force);

Reference.getInstance().detached(this._geometry, this);
if (!Reference.getInstance().hasReference(this._geometry)) {
this._geometry.destroy(force);
}

for (let i = 0; i < this._materials.length; i++) {
const mat = this._materials[i];
Reference.getInstance().detached(mat, this);
if (!Reference.getInstance().hasReference(mat)) {
mat.destroy(force);
}
}

this._geometry = null;
this._materials = null;
this._combineShaderRefection = null;
Expand Down
4 changes: 2 additions & 2 deletions src/gfx/graphics/webGpu/shader/ComputeShader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ export class ComputeShader extends ShaderBase {
resource: texture.getGPUView(),
}
entries.push(entry);
Reference.getInstance().attache(texture, this);
Reference.getInstance().attached(texture, this);
} else {
console.error(`ComputeShader(${this.instanceID})`, `texture ${refs.varName} is missing! `);
}
Expand All @@ -186,7 +186,7 @@ export class ComputeShader extends ShaderBase {
resource: texture.getGPUView(),
}
entries.push(entry);
Reference.getInstance().attache(texture, this);
Reference.getInstance().attached(texture, this);
} else {
console.error(`ComputeShader(${this.instanceID})`, `texture ${refs.varName} is missing! `);
}
Expand Down
6 changes: 3 additions & 3 deletions src/gfx/graphics/webGpu/shader/RenderShader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -627,7 +627,7 @@ export class RenderShader extends ShaderBase {
// if(info.binding == 8){
// console.log(info.binding, entry );
// }
Reference.getInstance().attache(texture, this);
Reference.getInstance().attached(texture, this);
}
break;
case `texture_external`:
Expand All @@ -641,7 +641,7 @@ export class RenderShader extends ShaderBase {
entries.push(entry);
this._textureGroup = index;
// console.log(info.binding, entry );
Reference.getInstance().attache(texture, this);
Reference.getInstance().attached(texture, this);
}
break;
default:
Expand All @@ -655,7 +655,7 @@ export class RenderShader extends ShaderBase {
entries.push(entry);
this._textureGroup = index;
// console.log(info.binding, entry );
Reference.getInstance().attache(texture, this);
Reference.getInstance().attached(texture, this);
}
break;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import { WebGPUDescriptorCreator } from '../../../graphics/webGpu/descriptor/Web
import { RendererPassState } from '../state/RendererPassState';
import { RendererType } from '../state/RendererType';
import { ILight } from '../../../../components/lights/ILight';
import { Reference } from '../../../..';

type CubeShadowMapInfo = {
cubeCamera: CubeCamera,
Expand All @@ -37,7 +38,7 @@ export class PointLightShadowRenderer extends RendererBase {
private _forceUpdate = false;
private _shadowCameraDic: Map<ILight, CubeShadowMapInfo>;
public shadowCamera: Camera3D;
public cubeTextureArray: DepthCubeArrayTexture;
public cubeArrayTexture: DepthCubeArrayTexture;
public colorTexture: VirtualTexture;
public shadowSize: number = 1024;
constructor() {
Expand All @@ -46,11 +47,11 @@ export class PointLightShadowRenderer extends RendererBase {

// this.shadowSize = Engine3D.setting.shadow.pointShadowSize;
this._shadowCameraDic = new Map<ILight, CubeShadowMapInfo>();
this.cubeTextureArray = new DepthCubeArrayTexture(this.shadowSize, this.shadowSize, 8);
this.cubeArrayTexture = new DepthCubeArrayTexture(this.shadowSize, this.shadowSize, 8);
this.colorTexture = new VirtualTexture(this.shadowSize, this.shadowSize, GPUTextureFormat.bgra8unorm, false);
}


Reference.getInstance().attached(this.cubeArrayTexture, this);
}

public getShadowCamera(view: View3D, lightBase: ILight): CubeShadowMapInfo {
let cubeShadowMapInfo: CubeShadowMapInfo;
Expand All @@ -63,7 +64,7 @@ export class PointLightShadowRenderer extends RendererBase {
let rendererPassStates: RendererPassState[] = [];
for (let i = 0; i < 6; i++) {

let depthTexture = new VirtualTexture(this.shadowSize, this.shadowSize, this.cubeTextureArray.format, false);
let depthTexture = new VirtualTexture(this.shadowSize, this.shadowSize, this.cubeArrayTexture.format, false);
let rtFrame = new RTFrame([this.colorTexture], [new RTDescriptor()]);
depthTexture.name = `shadowDepthTexture_` + lightBase.name + i + "_face";
rtFrame.depthTexture = depthTexture;
Expand Down Expand Up @@ -152,7 +153,7 @@ export class PointLightShadowRenderer extends RendererBase {
origin: { x: 0, y: 0, z: 0 },
},
{
texture: this.cubeTextureArray.getGPUTexture(),
texture: this.cubeArrayTexture.getGPUTexture(),
mipLevel: 0,
origin: { x: 0, y: 0, z: light.shadowIndex * 6 + i },
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import { RendererPassState } from "../state/RendererPassState";
import { RendererType } from "../state/RendererType";
import { RendererBase } from "../RendererBase";
import { ClusterLightingBuffer } from "../cluster/ClusterLightingBuffer";
import { Reference } from "../../../../util/Reference";

/**
* @internal
Expand All @@ -28,7 +29,7 @@ import { ClusterLightingBuffer } from "../cluster/ClusterLightingBuffer";
export class ShadowMapPassRenderer extends RendererBase {
// public shadowCamera: Camera3D;
public shadowPassCount: number;
public depth2DTextureArray: Depth2DTextureArray;
public depth2DArrayTexture: Depth2DTextureArray;
public rendererPassStates: RendererPassState[];
private _forceUpdate = false;
constructor() {
Expand All @@ -45,7 +46,8 @@ export class ShadowMapPassRenderer extends RendererBase {

setShadowMap(size: number) {
this.rendererPassStates = [];
this.depth2DTextureArray = new Depth2DTextureArray(size, size);
this.depth2DArrayTexture = new Depth2DTextureArray(size, size);
Reference.getInstance().attached(this.depth2DArrayTexture, this);

for (let i = 0; i < 8; i++) {
let rtFrame = new RTFrame([], []);
Expand Down Expand Up @@ -115,7 +117,7 @@ export class ShadowMapPassRenderer extends RendererBase {
origin: { x: 0, y: 0, z: 0 },
},
{
texture: this.depth2DTextureArray.getGPUTexture(),
texture: this.depth2DArrayTexture.getGPUTexture(),
mipLevel: 0,
origin: { x: 0, y: 0, z: light.shadowIndex },
},
Expand Down
2 changes: 1 addition & 1 deletion src/gfx/renderJob/post/PostBase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export class PostBase {
let rt = RTResourceMap.createRTTexture(name, rtWidth, rtHeight, format, useMipmap, sampleCount);
rt.name = name;
this.virtualTexture.set(name, rt);
Reference.getInstance().attache(rt, this);
Reference.getInstance().attached(rt, this);
return rt;
}

Expand Down
4 changes: 2 additions & 2 deletions src/util/Reference.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@ export class Reference {
}

/**
* current instance attache from parent instance
* current instance attached from parent instance
* @param ref reference current
* @param target reference parent
*/
public attache(ref: any, target: any) {
public attached(ref: any, target: any) {
this.reference ||= new Map<any, Map<any, any>>();

let refMap = this.reference.get(ref);
Expand Down

0 comments on commit 071ac16

Please sign in to comment.