diff --git a/packages/core/src/RenderPipeline/InstanceBuffer.ts b/packages/core/src/RenderPipeline/InstanceBuffer.ts index 5d0d4368c2..6dbd2cb250 100644 --- a/packages/core/src/RenderPipeline/InstanceBuffer.ts +++ b/packages/core/src/RenderPipeline/InstanceBuffer.ts @@ -39,6 +39,7 @@ export class InstanceBuffer { this._intView = new Int32Array(this._data); this.buffer?.destroy(); this.buffer = new Buffer(this._engine, BufferBindFlag.ConstantBuffer, totalBytes, BufferUsage.Dynamic); + this.buffer.isGCIgnored = true; } } diff --git a/tests/src/core/RenderPipeline/InstanceBuffer.test.ts b/tests/src/core/RenderPipeline/InstanceBuffer.test.ts new file mode 100644 index 0000000000..635ed15276 --- /dev/null +++ b/tests/src/core/RenderPipeline/InstanceBuffer.test.ts @@ -0,0 +1,25 @@ +import { WebGLEngine } from "@galacean/engine"; +import { afterEach, describe, expect, it } from "vitest"; + +describe("InstanceBuffer", () => { + let engine: WebGLEngine | undefined; + + afterEach(() => { + engine?.destroy(); + engine = undefined; + }); + + it("keeps its engine-owned buffer alive across resource-manager garbage collection", async () => { + engine = await WebGLEngine.create({ canvas: document.createElement("canvas") }); + const instanceBuffer = engine._batcherManager.instanceBuffer; + instanceBuffer.setLayout({ instanceFields: [], instanceMaxCount: 1, structSize: 16 }); + const buffer = instanceBuffer.buffer; + + engine.resourceManager.gc(); + + expect(buffer.destroyed).toBe(false); + + engine._batcherManager.destroy(); + expect(buffer.destroyed).toBe(true); + }); +});