From 3b1d4b7b0a2784cb4b06557d7df4f0bbf77d351b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=98=8C=E6=95=A6=E4=BC=9F?= Date: Wed, 19 Aug 2026 16:05:59 +0800 Subject: [PATCH] fix: balance Texture2D image dependency references (#267) (cherry picked from commit ff436d6a273b14195c3859336019fdf74e88c998) --- cocos/asset/assets/simple-texture.jsb.ts | 5 +- cocos/asset/assets/simple-texture.ts | 6 ++- tests/assets/texture-2d.test.ts | 66 +++++++++++++++--------- 3 files changed, 49 insertions(+), 28 deletions(-) diff --git a/cocos/asset/assets/simple-texture.jsb.ts b/cocos/asset/assets/simple-texture.jsb.ts index 67e0a0d320f..cfbd52e60e0 100644 --- a/cocos/asset/assets/simple-texture.jsb.ts +++ b/cocos/asset/assets/simple-texture.jsb.ts @@ -76,10 +76,11 @@ simpleTextureProto._onGFXTextureUpdated = function (gfxTexture) { simpleTextureProto._onAfterAssignImage = function (image) { if (macro.CLEANUP_IMAGE_CACHE) { const deps = dependUtil.getDeps(this._uuid); - const index = deps.indexOf(image._uuid); - if (index !== -1) { + let index = deps.indexOf(image._uuid); + while (index !== -1) { js.array.fastRemoveAt(deps, index); image.decRef(); + index = deps.indexOf(image._uuid); } } }; diff --git a/cocos/asset/assets/simple-texture.ts b/cocos/asset/assets/simple-texture.ts index 200ddf68046..ff7ce860aba 100644 --- a/cocos/asset/assets/simple-texture.ts +++ b/cocos/asset/assets/simple-texture.ts @@ -194,10 +194,12 @@ export class SimpleTexture extends TextureBase { if (macro.CLEANUP_IMAGE_CACHE) { const deps = dependUtil.getDeps(this._uuid); - const index = deps.indexOf(image._uuid); - if (index !== -1) { + let index = deps.indexOf(image._uuid); + while (index !== -1) { js.array.fastRemoveAt(deps, index); image.decRef(); + // The same UUID may occur more than once; find the next dependency edge. + index = deps.indexOf(image._uuid); } } } diff --git a/tests/assets/texture-2d.test.ts b/tests/assets/texture-2d.test.ts index bd720805362..934535de0ef 100644 --- a/tests/assets/texture-2d.test.ts +++ b/tests/assets/texture-2d.test.ts @@ -1,27 +1,45 @@ -import { Texture2D } from "../../cocos/asset/assets/texture-2d"; -import { Details } from "../../cocos/serialization/deserialize"; +import { ImageAsset } from '../../cocos/asset/assets/image-asset'; +import { Texture2D } from '../../cocos/asset/assets/texture-2d'; +import { dependMap } from '../../cocos/asset/asset-manager/depend-maps'; +import dependUtil from '../../cocos/asset/asset-manager/depend-util'; +import { setProperties } from '../../cocos/asset/asset-manager/utilities'; +import { macro } from '../../cocos/core'; -// issue: https://github.com/cocos/cocos-engine/issues/16693 -test('Texture2D serialize', function () { - const texture = new Texture2D(); - texture._mipmaps = [{ _uuid: '09f4f3e7-268b-478c-a7af-bbdf574ec3c6@6c48a' }]; - const ctxForExporting = { - _depends: [] as string[], - dependsOn(propName: string, uuid: string) { - this._depends.push(propName, uuid); - }, - _compressUuid: this.mustCompresseUuid, - }; - texture._serialize(ctxForExporting); - expect(ctxForExporting._depends).toEqual(['_textureSource', '09f4f3e7-268b-478c-a7af-bbdf574ec3c6@6c48a']); +const textureUuid = 'f41e5c8f-0e9a-4c38-bb1d-texture2d'; + +afterEach(() => { + dependUtil.remove(textureUuid); }); -test('Texture2D deserialize', function () { - const data = { base: '2,2,2,2,0,0', mipmaps: ['09f4f3e7-268b-478c-a7af-bbdf574ec3c6'] }; - const result = new Details(); - result.init(); - const handle = { result }; - const texture = new Texture2D(); - texture._deserialize(data, handle); - expect(handle.result.uuidList).toEqual(['09f4f3e7-268b-478c-a7af-bbdf574ec3c6']); -}); \ No newline at end of file +test('releases every Texture2D dependency edge for an uploaded image', () => { + const cleanupImageCache = macro.CLEANUP_IMAGE_CACHE; + macro.CLEANUP_IMAGE_CACHE = true; + + try { + const texture = new Texture2D(); + texture._uuid = textureUuid; + const image = new ImageAsset({ + _data: new Uint8Array(4), + width: 1, + height: 1, + }); + image._uuid = '6d35c119-b763-4295-96e7-image'; + const deps = [ + { uuid: image._uuid, owner: texture, prop: '_textureSource' }, + { uuid: image._uuid, owner: texture._mipmaps, prop: '0' }, + ]; + const assetsMap = { [`${image._uuid}@import`]: image }; + + dependMap.set(texture, deps); + dependUtil._depends.add(textureUuid, { deps: deps.map((dep) => dep.uuid) }); + setProperties(textureUuid, texture, assetsMap); + expect(image.refCount).toBe(2); + + texture.onLoaded(); + + expect(image.refCount).toBe(0); + expect(dependUtil.getDeps(textureUuid)).toEqual([]); + } finally { + macro.CLEANUP_IMAGE_CACHE = cleanupImageCache; + } +});